|
12 | 12 | #ifndef _LINUX_SLAB_H |
13 | 13 | #define _LINUX_SLAB_H |
14 | 14 |
|
| 15 | +#include <linux/bug.h> |
15 | 16 | #include <linux/cache.h> |
16 | 17 | #include <linux/gfp.h> |
17 | 18 | #include <linux/overflow.h> |
@@ -965,6 +966,111 @@ static __always_inline __alloc_size(1) void *kmalloc_noprof(size_t size, gfp_t f |
965 | 966 | void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); |
966 | 967 | #define kmalloc_nolock(...) alloc_hooks(kmalloc_nolock_noprof(__VA_ARGS__)) |
967 | 968 |
|
| 969 | +/** |
| 970 | + * __alloc_objs - Allocate objects of a given type using |
| 971 | + * @KMALLOC: which size-based kmalloc wrapper to allocate with. |
| 972 | + * @GFP: GFP flags for the allocation. |
| 973 | + * @TYPE: type to allocate space for. |
| 974 | + * @COUNT: how many @TYPE objects to allocate. |
| 975 | + * |
| 976 | + * Returns: Newly allocated pointer to (first) @TYPE of @COUNT-many |
| 977 | + * allocated @TYPE objects, or NULL on failure. |
| 978 | + */ |
| 979 | +#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT) \ |
| 980 | +({ \ |
| 981 | + const size_t __obj_size = size_mul(sizeof(TYPE), COUNT); \ |
| 982 | + (TYPE *)KMALLOC(__obj_size, GFP); \ |
| 983 | +}) |
| 984 | + |
| 985 | +/** |
| 986 | + * __alloc_flex - Allocate an object that has a trailing flexible array |
| 987 | + * @KMALLOC: kmalloc wrapper function to use for allocation. |
| 988 | + * @GFP: GFP flags for the allocation. |
| 989 | + * @TYPE: type of structure to allocate space for. |
| 990 | + * @FAM: The name of the flexible array member of @TYPE structure. |
| 991 | + * @COUNT: how many @FAM elements to allocate space for. |
| 992 | + * |
| 993 | + * Returns: Newly allocated pointer to @TYPE with @COUNT-many trailing |
| 994 | + * @FAM elements, or NULL on failure or if @COUNT cannot be represented |
| 995 | + * by the member of @TYPE that counts the @FAM elements (annotated via |
| 996 | + * __counted_by()). |
| 997 | + */ |
| 998 | +#define __alloc_flex(KMALLOC, GFP, TYPE, FAM, COUNT) \ |
| 999 | +({ \ |
| 1000 | + const size_t __count = (COUNT); \ |
| 1001 | + const size_t __obj_size = struct_size_t(TYPE, FAM, __count); \ |
| 1002 | + TYPE *__obj_ptr; \ |
| 1003 | + if (WARN_ON_ONCE(overflows_flex_counter_type(TYPE, FAM, __count))) \ |
| 1004 | + __obj_ptr = NULL; \ |
| 1005 | + else \ |
| 1006 | + __obj_ptr = KMALLOC(__obj_size, GFP); \ |
| 1007 | + if (__obj_ptr) \ |
| 1008 | + __set_flex_counter(__obj_ptr->FAM, __count); \ |
| 1009 | + __obj_ptr; \ |
| 1010 | +}) |
| 1011 | + |
| 1012 | +/** |
| 1013 | + * kmalloc_obj - Allocate a single instance of the given type |
| 1014 | + * @VAR_OR_TYPE: Variable or type to allocate. |
| 1015 | + * @GFP: GFP flags for the allocation. |
| 1016 | + * |
| 1017 | + * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL |
| 1018 | + * on failure. |
| 1019 | + */ |
| 1020 | +#define kmalloc_obj(VAR_OR_TYPE, GFP) \ |
| 1021 | + __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), 1) |
| 1022 | + |
| 1023 | +/** |
| 1024 | + * kmalloc_objs - Allocate an array of the given type |
| 1025 | + * @VAR_OR_TYPE: Variable or type to allocate an array of. |
| 1026 | + * @COUNT: How many elements in the array. |
| 1027 | + * @GFP: GFP flags for the allocation. |
| 1028 | + * |
| 1029 | + * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success, |
| 1030 | + * or NULL on failure. |
| 1031 | + */ |
| 1032 | +#define kmalloc_objs(VAR_OR_TYPE, COUNT, GFP) \ |
| 1033 | + __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), COUNT) |
| 1034 | + |
| 1035 | +/** |
| 1036 | + * kmalloc_flex - Allocate a single instance of the given flexible structure |
| 1037 | + * @VAR_OR_TYPE: Variable or type to allocate (with its flex array). |
| 1038 | + * @FAM: The name of the flexible array member of the structure. |
| 1039 | + * @COUNT: How many flexible array member elements are desired. |
| 1040 | + * @GFP: GFP flags for the allocation. |
| 1041 | + * |
| 1042 | + * Returns: newly allocated pointer to @VAR_OR_TYPE on success, NULL on |
| 1043 | + * failure. If @FAM has been annotated with __counted_by(), the allocation |
| 1044 | + * will immediately fail if @COUNT is larger than what the type of the |
| 1045 | + * struct's counter variable can represent. |
| 1046 | + */ |
| 1047 | +#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, GFP) \ |
| 1048 | + __alloc_flex(kmalloc, GFP, typeof(VAR_OR_TYPE), FAM, COUNT) |
| 1049 | + |
| 1050 | +/* All kzalloc aliases for kmalloc_(obj|objs|flex). */ |
| 1051 | +#define kzalloc_obj(P, GFP) \ |
| 1052 | + __alloc_objs(kzalloc, GFP, typeof(P), 1) |
| 1053 | +#define kzalloc_objs(P, COUNT, GFP) \ |
| 1054 | + __alloc_objs(kzalloc, GFP, typeof(P), COUNT) |
| 1055 | +#define kzalloc_flex(P, FAM, COUNT, GFP) \ |
| 1056 | + __alloc_flex(kzalloc, GFP, typeof(P), FAM, COUNT) |
| 1057 | + |
| 1058 | +/* All kvmalloc aliases for kmalloc_(obj|objs|flex). */ |
| 1059 | +#define kvmalloc_obj(P, GFP) \ |
| 1060 | + __alloc_objs(kvmalloc, GFP, typeof(P), 1) |
| 1061 | +#define kvmalloc_objs(P, COUNT, GFP) \ |
| 1062 | + __alloc_objs(kvmalloc, GFP, typeof(P), COUNT) |
| 1063 | +#define kvmalloc_flex(P, FAM, COUNT, GFP) \ |
| 1064 | + __alloc_flex(kvmalloc, GFP, typeof(P), FAM, COUNT) |
| 1065 | + |
| 1066 | +/* All kvzalloc aliases for kmalloc_(obj|objs|flex). */ |
| 1067 | +#define kvzalloc_obj(P, GFP) \ |
| 1068 | + __alloc_objs(kvzalloc, GFP, typeof(P), 1) |
| 1069 | +#define kvzalloc_objs(P, COUNT, GFP) \ |
| 1070 | + __alloc_objs(kvzalloc, GFP, typeof(P), COUNT) |
| 1071 | +#define kvzalloc_flex(P, FAM, COUNT, GFP) \ |
| 1072 | + __alloc_flex(kvzalloc, GFP, typeof(P), FAM, COUNT) |
| 1073 | + |
968 | 1074 | #define kmem_buckets_alloc(_b, _size, _flags) \ |
969 | 1075 | alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE)) |
970 | 1076 |
|
|
0 commit comments