mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
Merge tag 'slab-for-7.2-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab
Pull more slab updates from Vlastimil Babka:
- Introduce and wire up a new alloc_flags parameter for modifying
slab-specific behavior without adding or reusing gfp flags. Also
introduce slab_alloc_context to keep function parameter bloat in
check. Both are similar to what the page allocator does.
kmalloc_flags() exposes alloc_flags for mm-internal users.
- SLAB_ALLOC_NOLOCK flag is used to implement kmalloc_nolock()
behavior without relying on lack of __GFP_RECLAIM, which caused
false positives with workarounds like fd3634312a ("debugobject:
Make it work with deferred page initialization - again").
- SLAB_ALLOC_NO_RECURSE replaces __GFP_NO_OBJ_EXT, which could have
been removed, but pending memory allocation profiling changes in
mm tree have grown a new user - there is however a work ongoing
to replace that too, so __GFP_NO_OBJ_EXT should eventually be
removed. (Vlastimil Babka)
- Add kmem_buckets_alloc_track_caller() with a user to be added in the
net tree (Pedro Falcato)
- Fixes for kernel-doc and slabinfo (Randy Dunlap, Yichong Chen)
* tag 'slab-for-7.2-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab:
tools/mm/slabinfo: fix total_objects attribute name
slab: recognize @GFP parameter as optional in kernel-doc
mm/slab: add a node-track-caller variant for kmem buckets allocation
mm/slab: replace __GFP_NO_OBJ_EXT with SLAB_ALLOC_NO_RECURSE for sheaves
mm/slab: remove __GFP_NO_OBJ_EXT usage from alloc_slab_obj_exts()
mm/slab: introduce kmalloc_flags()
mm/slab: allow __GFP_NOMEMALLOC and __GFP_NOWARN for kmalloc_nolock()
mm/slab: pass slab_alloc_context to __do_kmalloc_node()
mm/slab: allow kmem_cache_alloc_bulk() with any gfp flags
mm/slab: replace slab_alloc_node() parameters with slab_alloc_context
mm/slab: pass alloc_flags through slab_post_alloc_hook() chain
mm/slab: pass alloc_flags to new slab allocation
mm/slab: add alloc_flags to slab_alloc_context
mm/slab: replace struct partial_context with slab_alloc_context
mm/slab: introduce alloc_flags and SLAB_ALLOC_NOLOCK
mm/slab: introduce slab_alloc_context
mm/slab: stop inlining __slab_alloc_node()
mm/slab: do not init any kfence objects on allocation
This commit is contained in:
@@ -1039,8 +1039,9 @@ void *_kmalloc_nolock_noprof(DECL_TOKEN_PARAMS(size, token), gfp_t gfp_flags, in
|
||||
/**
|
||||
* kmalloc_nolock - Allocate an object of given size from any context.
|
||||
* @size: size to allocate
|
||||
* @gfp_flags: GFP flags. Only __GFP_ACCOUNT, __GFP_ZERO, __GFP_NO_OBJ_EXT
|
||||
* allowed.
|
||||
* @gfp_flags: GFP flags. Only __GFP_ACCOUNT and __GFP_ZERO allowed. Also
|
||||
* __GFP_NOWARN and __GFP_NOMEMALLOC are allowed but added internally thus not
|
||||
* necessary.
|
||||
* @node: node number of the target node.
|
||||
*
|
||||
* Return: pointer to the new object or NULL in case of error.
|
||||
@@ -1093,7 +1094,7 @@ void *kmalloc_nolock(size_t size, gfp_t gfp_flags, int node);
|
||||
/**
|
||||
* kmalloc_obj - Allocate a single instance of the given type
|
||||
* @VAR_OR_TYPE: Variable or type to allocate.
|
||||
* @GFP: GFP flags for the allocation.
|
||||
* @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
|
||||
*
|
||||
* Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL
|
||||
* on failure.
|
||||
@@ -1105,7 +1106,7 @@ void *kmalloc_nolock(size_t size, gfp_t gfp_flags, int node);
|
||||
* kmalloc_objs - Allocate an array of the given type
|
||||
* @VAR_OR_TYPE: Variable or type to allocate an array of.
|
||||
* @COUNT: How many elements in the array.
|
||||
* @GFP: GFP flags for the allocation.
|
||||
* @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
|
||||
*
|
||||
* Returns: newly allocated pointer to array of @VAR_OR_TYPE on success,
|
||||
* or NULL on failure.
|
||||
@@ -1118,7 +1119,7 @@ void *kmalloc_nolock(size_t size, gfp_t gfp_flags, int node);
|
||||
* @VAR_OR_TYPE: Variable or type to allocate (with its flex array).
|
||||
* @FAM: The name of the flexible array member of the structure.
|
||||
* @COUNT: How many flexible array member elements are desired.
|
||||
* @GFP: GFP flags for the allocation.
|
||||
* @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
|
||||
*
|
||||
* Returns: newly allocated pointer to @VAR_OR_TYPE on success, NULL on
|
||||
* failure. If @FAM has been annotated with __counted_by(), the allocation
|
||||
@@ -1155,8 +1156,11 @@ void *kmalloc_nolock(size_t size, gfp_t gfp_flags, int node);
|
||||
#define kmem_buckets_alloc(_b, _size, _flags) \
|
||||
alloc_hooks(__kmalloc_node_noprof(PASS_KMALLOC_PARAMS(_size, _b, __kmalloc_token(_size)), _flags, NUMA_NO_NODE))
|
||||
|
||||
#define kmem_buckets_alloc_track_caller(_b, _size, _flags) \
|
||||
alloc_hooks(__kmalloc_node_track_caller_noprof(PASS_KMALLOC_PARAMS(_size, _b, __kmalloc_token(_size)), _flags, NUMA_NO_NODE, _RET_IP_))
|
||||
#define kmem_buckets_alloc_node_track_caller(_b, _size, _flags, _node) \
|
||||
alloc_hooks(__kmalloc_node_track_caller_noprof(PASS_KMALLOC_PARAMS(_size, _b, __kmalloc_token(_size)), _flags, _node, _RET_IP_))
|
||||
|
||||
#define kmem_buckets_alloc_track_caller(_b, _size, _flags) \
|
||||
kmem_buckets_alloc_node_track_caller(_b, _size, _flags, NUMA_NO_NODE)
|
||||
|
||||
static __always_inline __alloc_size(1) void *_kmalloc_node_noprof(size_t size, gfp_t flags, int node, kmalloc_token_t token)
|
||||
{
|
||||
|
||||
@@ -505,7 +505,7 @@ static void *kfence_guarded_alloc(struct kmem_cache *cache, size_t size, gfp_t g
|
||||
|
||||
/*
|
||||
* We check slab_want_init_on_alloc() ourselves, rather than letting
|
||||
* SL*B do the initialization, as otherwise we might overwrite KFENCE's
|
||||
* slab do the initialization, as otherwise it might overwrite KFENCE's
|
||||
* redzone.
|
||||
*/
|
||||
if (unlikely(slab_want_init_on_alloc(gfp, cache)))
|
||||
|
||||
@@ -3535,7 +3535,8 @@ static inline size_t obj_full_size(struct kmem_cache *s)
|
||||
}
|
||||
|
||||
bool __memcg_slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
|
||||
gfp_t flags, size_t size, void **p)
|
||||
gfp_t flags, unsigned int slab_alloc_flags,
|
||||
size_t size, void **p)
|
||||
{
|
||||
size_t obj_size = obj_full_size(s);
|
||||
struct obj_cgroup *objcg;
|
||||
@@ -3583,7 +3584,7 @@ bool __memcg_slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
|
||||
slab = virt_to_slab(p[i]);
|
||||
|
||||
if (!slab_obj_exts(slab) &&
|
||||
alloc_slab_obj_exts(slab, s, flags, false)) {
|
||||
alloc_slab_obj_exts(slab, s, flags, slab_alloc_flags)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
29
mm/slab.h
29
mm/slab.h
@@ -11,11 +11,35 @@
|
||||
#include <linux/memcontrol.h>
|
||||
#include <linux/kfence.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/*
|
||||
* Internal slab definitions
|
||||
*/
|
||||
|
||||
/* slab's alloc_flags definitions */
|
||||
#define SLAB_ALLOC_DEFAULT 0x00 /* no flags */
|
||||
#define SLAB_ALLOC_NOLOCK 0x01 /* a kmalloc_nolock() allocation */
|
||||
#define SLAB_ALLOC_NEW_SLAB 0x02 /* a flag for alloc_slab_obj_exts() */
|
||||
#define SLAB_ALLOC_NO_RECURSE 0x04 /* prevent kmalloc() recursion */
|
||||
|
||||
static inline bool alloc_flags_allow_spinning(const unsigned int alloc_flags)
|
||||
{
|
||||
return !(alloc_flags & SLAB_ALLOC_NOLOCK);
|
||||
}
|
||||
|
||||
void *__kmalloc_flags_noprof(DECL_TOKEN_PARAMS(size, token), gfp_t flags,
|
||||
unsigned int alloc_flags, int node)
|
||||
__assume_kmalloc_alignment __alloc_size(1);
|
||||
|
||||
static __always_inline __alloc_size(1) void *_kmalloc_flags_noprof(size_t size,
|
||||
gfp_t flags, unsigned int alloc_flags, int node, kmalloc_token_t token)
|
||||
{
|
||||
return __kmalloc_flags_noprof(PASS_TOKEN_PARAMS(size, token), flags, alloc_flags, node);
|
||||
}
|
||||
#define kmalloc_flags_noprof(...) _kmalloc_flags_noprof(__VA_ARGS__, __kmalloc_token(__VA_ARGS__))
|
||||
#define kmalloc_flags(...) alloc_hooks(kmalloc_flags_noprof(__VA_ARGS__))
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
# ifdef system_has_cmpxchg128
|
||||
# define system_has_freelist_aba() system_has_cmpxchg128()
|
||||
@@ -603,7 +627,7 @@ static inline struct slabobj_ext *slab_obj_ext(struct slab *slab,
|
||||
}
|
||||
|
||||
int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s,
|
||||
gfp_t gfp, bool new_slab);
|
||||
gfp_t gfp, unsigned int alloc_flags);
|
||||
|
||||
#else /* CONFIG_SLAB_OBJ_EXT */
|
||||
|
||||
@@ -633,7 +657,8 @@ static inline enum node_stat_item cache_vmstat_idx(struct kmem_cache *s)
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
bool __memcg_slab_post_alloc_hook(struct kmem_cache *s, struct list_lru *lru,
|
||||
gfp_t flags, size_t size, void **p);
|
||||
gfp_t flags, unsigned int slab_alloc_flags,
|
||||
size_t size, void **p);
|
||||
void __memcg_slab_free_hook(struct kmem_cache *s, struct slab *slab,
|
||||
void **p, int objects, unsigned long obj_exts);
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,7 @@ struct slabinfo {
|
||||
unsigned int hwcache_align, object_size, objs_per_slab;
|
||||
unsigned int sanity_checks, slab_size, store_user, trace;
|
||||
int order, poison, reclaim_account, red_zone;
|
||||
unsigned long partial, objects, slabs, objects_partial, objects_total;
|
||||
unsigned long partial, objects, slabs, objects_partial, total_objects;
|
||||
unsigned long alloc_fastpath, alloc_slowpath;
|
||||
unsigned long free_fastpath, free_slowpath;
|
||||
unsigned long free_frozen, free_add_partial, free_remove_partial;
|
||||
@@ -1262,7 +1262,7 @@ static void read_slab_dir(void)
|
||||
slab->object_size = get_obj("object_size");
|
||||
slab->objects = get_obj("objects");
|
||||
slab->objects_partial = get_obj("objects_partial");
|
||||
slab->objects_total = get_obj("objects_total");
|
||||
slab->total_objects = get_obj("total_objects");
|
||||
slab->objs_per_slab = get_obj("objs_per_slab");
|
||||
slab->order = get_obj("order");
|
||||
slab->partial = get_obj_and_str("partial", &t);
|
||||
|
||||
Reference in New Issue
Block a user