aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2026-04-14 15:13:18 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2026-04-18 01:12:13 +0000
commitc72ac6af086962d236f4712761abacac0c62b48e (patch)
treedc38fc73569012bf0f72ad38af488bfd8460bb52
parentd2c85255d4fca37ec9774f85f867f8fc89a51269 (diff)
LinuxKPI: add kmalloc_obj[s], kzalloc_obj[s], and kzalloc_flex
Drivers in Linux v7.0 seem to have changed to the new allocation macros using a sweep. Add the ones I encountered with wireless drivers so far. They all take an optional argument for a gfp_t, which default_gfp() deals with. The plural version "objs" takes an extra nitems argument in addition to the size. We use size_mul() to possibly detect overflows. The "flex" version uses an extra variable to track the variable sized array allocations and if supported by the compiler will use __builtin_counted_by_ref() to properly track bounds. Sponsored by: The FreeBSD Foundation MFC after: 3 days Reviewed by: dumbbell Differential Revision: https://reviews.freebsd.org/D56395
-rw-r--r--sys/compat/linuxkpi/common/include/linux/slab.h24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h
index 0e649e1e3c4a..6c05c77819a5 100644
--- a/sys/compat/linuxkpi/common/include/linux/slab.h
+++ b/sys/compat/linuxkpi/common/include/linux/slab.h
@@ -4,7 +4,7 @@
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2021 Mellanox Technologies, Ltd.
* All rights reserved.
- * Copyright (c) 2024-2025 The FreeBSD Foundation
+ * Copyright (c) 2024-2026 The FreeBSD Foundation
*
* Portions of this software were developed by Björn Zeeb
* under sponsorship from the FreeBSD Foundation.
@@ -51,6 +51,22 @@ MALLOC_DECLARE(M_KMALLOC);
#define kvcalloc(n, size, flags) kvmalloc_array(n, size, (flags) | __GFP_ZERO)
#define kzalloc(size, flags) kmalloc(size, (flags) | __GFP_ZERO)
#define kzalloc_node(size, flags, node) kmalloc_node(size, (flags) | __GFP_ZERO, node)
+#define kzalloc_obj(_p, ...) \
+ kzalloc(sizeof(typeof(_p)), default_gfp(__VA_ARGS__))
+#define kzalloc_objs(_p, _n, ...) \
+ kzalloc(size_mul((_n), sizeof(typeof(_p))), default_gfp(__VA_ARGS__))
+#define kzalloc_flex(_p, _field, _n, ...) \
+({ \
+ const size_t __n = (_n); \
+ const size_t __psize = struct_size_t(typeof(_p), _field, __n); \
+ typeof(_p) *__p_obj; \
+ \
+ __p_obj = kzalloc(__psize, default_gfp(__VA_ARGS__)); \
+ if (__p_obj != NULL) \
+ __set_flex_counter(__p_obj->_field, __n); \
+ \
+ __p_obj; \
+})
#define kfree_const(ptr) kfree(ptr)
#define kfree_async(ptr) kfree(ptr) /* drm-kmod 5.4 compat */
#define vzalloc(size) __vmalloc(size, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, 0)
@@ -143,6 +159,12 @@ kmalloc_node(size_t size, gfp_t flags, int node)
return (lkpi___kmalloc_node(size, flags, node));
}
+#define kmalloc_obj(_p, ...) \
+ kmalloc(sizeof(typeof(_p)), default_gfp(__VA_ARGS__))
+
+#define kmalloc_objs(_p, _n, ...) \
+ kmalloc(size_mul((_n) * sizeof(typeof(_p))), default_gfp(__VA_ARGS__))
+
static inline void *
krealloc(void *ptr, size_t size, gfp_t flags)
{