162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * SLUB: A slab allocator that limits cache line use instead of queuing
462306a36Sopenharmony_ci * objects in per cpu and per node lists.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * The allocator synchronizes using per slab locks or atomic operations
762306a36Sopenharmony_ci * and only uses a centralized lock to manage a pool of partial slabs.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * (C) 2007 SGI, Christoph Lameter
1062306a36Sopenharmony_ci * (C) 2011 Linux Foundation, Christoph Lameter
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/mm.h>
1462306a36Sopenharmony_ci#include <linux/swap.h> /* mm_account_reclaimed_pages() */
1562306a36Sopenharmony_ci#include <linux/module.h>
1662306a36Sopenharmony_ci#include <linux/bit_spinlock.h>
1762306a36Sopenharmony_ci#include <linux/interrupt.h>
1862306a36Sopenharmony_ci#include <linux/swab.h>
1962306a36Sopenharmony_ci#include <linux/bitops.h>
2062306a36Sopenharmony_ci#include <linux/slab.h>
2162306a36Sopenharmony_ci#include "slab.h"
2262306a36Sopenharmony_ci#include <linux/proc_fs.h>
2362306a36Sopenharmony_ci#include <linux/seq_file.h>
2462306a36Sopenharmony_ci#include <linux/kasan.h>
2562306a36Sopenharmony_ci#include <linux/kmsan.h>
2662306a36Sopenharmony_ci#include <linux/cpu.h>
2762306a36Sopenharmony_ci#include <linux/cpuset.h>
2862306a36Sopenharmony_ci#include <linux/mempolicy.h>
2962306a36Sopenharmony_ci#include <linux/ctype.h>
3062306a36Sopenharmony_ci#include <linux/stackdepot.h>
3162306a36Sopenharmony_ci#include <linux/debugobjects.h>
3262306a36Sopenharmony_ci#include <linux/kallsyms.h>
3362306a36Sopenharmony_ci#include <linux/kfence.h>
3462306a36Sopenharmony_ci#include <linux/memory.h>
3562306a36Sopenharmony_ci#include <linux/math64.h>
3662306a36Sopenharmony_ci#include <linux/fault-inject.h>
3762306a36Sopenharmony_ci#include <linux/stacktrace.h>
3862306a36Sopenharmony_ci#include <linux/prefetch.h>
3962306a36Sopenharmony_ci#include <linux/memcontrol.h>
4062306a36Sopenharmony_ci#include <linux/random.h>
4162306a36Sopenharmony_ci#include <kunit/test.h>
4262306a36Sopenharmony_ci#include <kunit/test-bug.h>
4362306a36Sopenharmony_ci#include <linux/sort.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include <linux/debugfs.h>
4662306a36Sopenharmony_ci#include <trace/events/kmem.h>
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#include "internal.h"
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/*
5162306a36Sopenharmony_ci * Lock order:
5262306a36Sopenharmony_ci *   1. slab_mutex (Global Mutex)
5362306a36Sopenharmony_ci *   2. node->list_lock (Spinlock)
5462306a36Sopenharmony_ci *   3. kmem_cache->cpu_slab->lock (Local lock)
5562306a36Sopenharmony_ci *   4. slab_lock(slab) (Only on some arches)
5662306a36Sopenharmony_ci *   5. object_map_lock (Only for debugging)
5762306a36Sopenharmony_ci *
5862306a36Sopenharmony_ci *   slab_mutex
5962306a36Sopenharmony_ci *
6062306a36Sopenharmony_ci *   The role of the slab_mutex is to protect the list of all the slabs
6162306a36Sopenharmony_ci *   and to synchronize major metadata changes to slab cache structures.
6262306a36Sopenharmony_ci *   Also synchronizes memory hotplug callbacks.
6362306a36Sopenharmony_ci *
6462306a36Sopenharmony_ci *   slab_lock
6562306a36Sopenharmony_ci *
6662306a36Sopenharmony_ci *   The slab_lock is a wrapper around the page lock, thus it is a bit
6762306a36Sopenharmony_ci *   spinlock.
6862306a36Sopenharmony_ci *
6962306a36Sopenharmony_ci *   The slab_lock is only used on arches that do not have the ability
7062306a36Sopenharmony_ci *   to do a cmpxchg_double. It only protects:
7162306a36Sopenharmony_ci *
7262306a36Sopenharmony_ci *	A. slab->freelist	-> List of free objects in a slab
7362306a36Sopenharmony_ci *	B. slab->inuse		-> Number of objects in use
7462306a36Sopenharmony_ci *	C. slab->objects	-> Number of objects in slab
7562306a36Sopenharmony_ci *	D. slab->frozen		-> frozen state
7662306a36Sopenharmony_ci *
7762306a36Sopenharmony_ci *   Frozen slabs
7862306a36Sopenharmony_ci *
7962306a36Sopenharmony_ci *   If a slab is frozen then it is exempt from list management. It is not
8062306a36Sopenharmony_ci *   on any list except per cpu partial list. The processor that froze the
8162306a36Sopenharmony_ci *   slab is the one who can perform list operations on the slab. Other
8262306a36Sopenharmony_ci *   processors may put objects onto the freelist but the processor that
8362306a36Sopenharmony_ci *   froze the slab is the only one that can retrieve the objects from the
8462306a36Sopenharmony_ci *   slab's freelist.
8562306a36Sopenharmony_ci *
8662306a36Sopenharmony_ci *   list_lock
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci *   The list_lock protects the partial and full list on each node and
8962306a36Sopenharmony_ci *   the partial slab counter. If taken then no new slabs may be added or
9062306a36Sopenharmony_ci *   removed from the lists nor make the number of partial slabs be modified.
9162306a36Sopenharmony_ci *   (Note that the total number of slabs is an atomic value that may be
9262306a36Sopenharmony_ci *   modified without taking the list lock).
9362306a36Sopenharmony_ci *
9462306a36Sopenharmony_ci *   The list_lock is a centralized lock and thus we avoid taking it as
9562306a36Sopenharmony_ci *   much as possible. As long as SLUB does not have to handle partial
9662306a36Sopenharmony_ci *   slabs, operations can continue without any centralized lock. F.e.
9762306a36Sopenharmony_ci *   allocating a long series of objects that fill up slabs does not require
9862306a36Sopenharmony_ci *   the list lock.
9962306a36Sopenharmony_ci *
10062306a36Sopenharmony_ci *   For debug caches, all allocations are forced to go through a list_lock
10162306a36Sopenharmony_ci *   protected region to serialize against concurrent validation.
10262306a36Sopenharmony_ci *
10362306a36Sopenharmony_ci *   cpu_slab->lock local lock
10462306a36Sopenharmony_ci *
10562306a36Sopenharmony_ci *   This locks protect slowpath manipulation of all kmem_cache_cpu fields
10662306a36Sopenharmony_ci *   except the stat counters. This is a percpu structure manipulated only by
10762306a36Sopenharmony_ci *   the local cpu, so the lock protects against being preempted or interrupted
10862306a36Sopenharmony_ci *   by an irq. Fast path operations rely on lockless operations instead.
10962306a36Sopenharmony_ci *
11062306a36Sopenharmony_ci *   On PREEMPT_RT, the local lock neither disables interrupts nor preemption
11162306a36Sopenharmony_ci *   which means the lockless fastpath cannot be used as it might interfere with
11262306a36Sopenharmony_ci *   an in-progress slow path operations. In this case the local lock is always
11362306a36Sopenharmony_ci *   taken but it still utilizes the freelist for the common operations.
11462306a36Sopenharmony_ci *
11562306a36Sopenharmony_ci *   lockless fastpaths
11662306a36Sopenharmony_ci *
11762306a36Sopenharmony_ci *   The fast path allocation (slab_alloc_node()) and freeing (do_slab_free())
11862306a36Sopenharmony_ci *   are fully lockless when satisfied from the percpu slab (and when
11962306a36Sopenharmony_ci *   cmpxchg_double is possible to use, otherwise slab_lock is taken).
12062306a36Sopenharmony_ci *   They also don't disable preemption or migration or irqs. They rely on
12162306a36Sopenharmony_ci *   the transaction id (tid) field to detect being preempted or moved to
12262306a36Sopenharmony_ci *   another cpu.
12362306a36Sopenharmony_ci *
12462306a36Sopenharmony_ci *   irq, preemption, migration considerations
12562306a36Sopenharmony_ci *
12662306a36Sopenharmony_ci *   Interrupts are disabled as part of list_lock or local_lock operations, or
12762306a36Sopenharmony_ci *   around the slab_lock operation, in order to make the slab allocator safe
12862306a36Sopenharmony_ci *   to use in the context of an irq.
12962306a36Sopenharmony_ci *
13062306a36Sopenharmony_ci *   In addition, preemption (or migration on PREEMPT_RT) is disabled in the
13162306a36Sopenharmony_ci *   allocation slowpath, bulk allocation, and put_cpu_partial(), so that the
13262306a36Sopenharmony_ci *   local cpu doesn't change in the process and e.g. the kmem_cache_cpu pointer
13362306a36Sopenharmony_ci *   doesn't have to be revalidated in each section protected by the local lock.
13462306a36Sopenharmony_ci *
13562306a36Sopenharmony_ci * SLUB assigns one slab for allocation to each processor.
13662306a36Sopenharmony_ci * Allocations only occur from these slabs called cpu slabs.
13762306a36Sopenharmony_ci *
13862306a36Sopenharmony_ci * Slabs with free elements are kept on a partial list and during regular
13962306a36Sopenharmony_ci * operations no list for full slabs is used. If an object in a full slab is
14062306a36Sopenharmony_ci * freed then the slab will show up again on the partial lists.
14162306a36Sopenharmony_ci * We track full slabs for debugging purposes though because otherwise we
14262306a36Sopenharmony_ci * cannot scan all objects.
14362306a36Sopenharmony_ci *
14462306a36Sopenharmony_ci * Slabs are freed when they become empty. Teardown and setup is
14562306a36Sopenharmony_ci * minimal so we rely on the page allocators per cpu caches for
14662306a36Sopenharmony_ci * fast frees and allocs.
14762306a36Sopenharmony_ci *
14862306a36Sopenharmony_ci * slab->frozen		The slab is frozen and exempt from list processing.
14962306a36Sopenharmony_ci * 			This means that the slab is dedicated to a purpose
15062306a36Sopenharmony_ci * 			such as satisfying allocations for a specific
15162306a36Sopenharmony_ci * 			processor. Objects may be freed in the slab while
15262306a36Sopenharmony_ci * 			it is frozen but slab_free will then skip the usual
15362306a36Sopenharmony_ci * 			list operations. It is up to the processor holding
15462306a36Sopenharmony_ci * 			the slab to integrate the slab into the slab lists
15562306a36Sopenharmony_ci * 			when the slab is no longer needed.
15662306a36Sopenharmony_ci *
15762306a36Sopenharmony_ci * 			One use of this flag is to mark slabs that are
15862306a36Sopenharmony_ci * 			used for allocations. Then such a slab becomes a cpu
15962306a36Sopenharmony_ci * 			slab. The cpu slab may be equipped with an additional
16062306a36Sopenharmony_ci * 			freelist that allows lockless access to
16162306a36Sopenharmony_ci * 			free objects in addition to the regular freelist
16262306a36Sopenharmony_ci * 			that requires the slab lock.
16362306a36Sopenharmony_ci *
16462306a36Sopenharmony_ci * SLAB_DEBUG_FLAGS	Slab requires special handling due to debug
16562306a36Sopenharmony_ci * 			options set. This moves	slab handling out of
16662306a36Sopenharmony_ci * 			the fast path and disables lockless freelists.
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/*
17062306a36Sopenharmony_ci * We could simply use migrate_disable()/enable() but as long as it's a
17162306a36Sopenharmony_ci * function call even on !PREEMPT_RT, use inline preempt_disable() there.
17262306a36Sopenharmony_ci */
17362306a36Sopenharmony_ci#ifndef CONFIG_PREEMPT_RT
17462306a36Sopenharmony_ci#define slub_get_cpu_ptr(var)		get_cpu_ptr(var)
17562306a36Sopenharmony_ci#define slub_put_cpu_ptr(var)		put_cpu_ptr(var)
17662306a36Sopenharmony_ci#define USE_LOCKLESS_FAST_PATH()	(true)
17762306a36Sopenharmony_ci#else
17862306a36Sopenharmony_ci#define slub_get_cpu_ptr(var)		\
17962306a36Sopenharmony_ci({					\
18062306a36Sopenharmony_ci	migrate_disable();		\
18162306a36Sopenharmony_ci	this_cpu_ptr(var);		\
18262306a36Sopenharmony_ci})
18362306a36Sopenharmony_ci#define slub_put_cpu_ptr(var)		\
18462306a36Sopenharmony_cido {					\
18562306a36Sopenharmony_ci	(void)(var);			\
18662306a36Sopenharmony_ci	migrate_enable();		\
18762306a36Sopenharmony_ci} while (0)
18862306a36Sopenharmony_ci#define USE_LOCKLESS_FAST_PATH()	(false)
18962306a36Sopenharmony_ci#endif
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
19262306a36Sopenharmony_ci#define __fastpath_inline __always_inline
19362306a36Sopenharmony_ci#else
19462306a36Sopenharmony_ci#define __fastpath_inline
19562306a36Sopenharmony_ci#endif
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
19862306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG_ON
19962306a36Sopenharmony_ciDEFINE_STATIC_KEY_TRUE(slub_debug_enabled);
20062306a36Sopenharmony_ci#else
20162306a36Sopenharmony_ciDEFINE_STATIC_KEY_FALSE(slub_debug_enabled);
20262306a36Sopenharmony_ci#endif
20362306a36Sopenharmony_ci#endif		/* CONFIG_SLUB_DEBUG */
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci/* Structure holding parameters for get_partial() call chain */
20662306a36Sopenharmony_cistruct partial_context {
20762306a36Sopenharmony_ci	struct slab **slab;
20862306a36Sopenharmony_ci	gfp_t flags;
20962306a36Sopenharmony_ci	unsigned int orig_size;
21062306a36Sopenharmony_ci};
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistatic inline bool kmem_cache_debug(struct kmem_cache *s)
21362306a36Sopenharmony_ci{
21462306a36Sopenharmony_ci	return kmem_cache_debug_flags(s, SLAB_DEBUG_FLAGS);
21562306a36Sopenharmony_ci}
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_cistatic inline bool slub_debug_orig_size(struct kmem_cache *s)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	return (kmem_cache_debug_flags(s, SLAB_STORE_USER) &&
22062306a36Sopenharmony_ci			(s->flags & SLAB_KMALLOC));
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_civoid *fixup_red_left(struct kmem_cache *s, void *p)
22462306a36Sopenharmony_ci{
22562306a36Sopenharmony_ci	if (kmem_cache_debug_flags(s, SLAB_RED_ZONE))
22662306a36Sopenharmony_ci		p += s->red_left_pad;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	return p;
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_cistatic inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s)
23262306a36Sopenharmony_ci{
23362306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
23462306a36Sopenharmony_ci	return !kmem_cache_debug(s);
23562306a36Sopenharmony_ci#else
23662306a36Sopenharmony_ci	return false;
23762306a36Sopenharmony_ci#endif
23862306a36Sopenharmony_ci}
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci/*
24162306a36Sopenharmony_ci * Issues still to be resolved:
24262306a36Sopenharmony_ci *
24362306a36Sopenharmony_ci * - Support PAGE_ALLOC_DEBUG. Should be easy to do.
24462306a36Sopenharmony_ci *
24562306a36Sopenharmony_ci * - Variable sizing of the per node arrays
24662306a36Sopenharmony_ci */
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/* Enable to log cmpxchg failures */
24962306a36Sopenharmony_ci#undef SLUB_DEBUG_CMPXCHG
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
25262306a36Sopenharmony_ci/*
25362306a36Sopenharmony_ci * Minimum number of partial slabs. These will be left on the partial
25462306a36Sopenharmony_ci * lists even if they are empty. kmem_cache_shrink may reclaim them.
25562306a36Sopenharmony_ci */
25662306a36Sopenharmony_ci#define MIN_PARTIAL 5
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci/*
25962306a36Sopenharmony_ci * Maximum number of desirable partial slabs.
26062306a36Sopenharmony_ci * The existence of more partial slabs makes kmem_cache_shrink
26162306a36Sopenharmony_ci * sort the partial list by the number of objects in use.
26262306a36Sopenharmony_ci */
26362306a36Sopenharmony_ci#define MAX_PARTIAL 10
26462306a36Sopenharmony_ci#else
26562306a36Sopenharmony_ci#define MIN_PARTIAL 0
26662306a36Sopenharmony_ci#define MAX_PARTIAL 0
26762306a36Sopenharmony_ci#endif
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci#define DEBUG_DEFAULT_FLAGS (SLAB_CONSISTENCY_CHECKS | SLAB_RED_ZONE | \
27062306a36Sopenharmony_ci				SLAB_POISON | SLAB_STORE_USER)
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci/*
27362306a36Sopenharmony_ci * These debug flags cannot use CMPXCHG because there might be consistency
27462306a36Sopenharmony_ci * issues when checking or reading debug information
27562306a36Sopenharmony_ci */
27662306a36Sopenharmony_ci#define SLAB_NO_CMPXCHG (SLAB_CONSISTENCY_CHECKS | SLAB_STORE_USER | \
27762306a36Sopenharmony_ci				SLAB_TRACE)
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci/*
28162306a36Sopenharmony_ci * Debugging flags that require metadata to be stored in the slab.  These get
28262306a36Sopenharmony_ci * disabled when slub_debug=O is used and a cache's min order increases with
28362306a36Sopenharmony_ci * metadata.
28462306a36Sopenharmony_ci */
28562306a36Sopenharmony_ci#define DEBUG_METADATA_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci#define OO_SHIFT	16
28862306a36Sopenharmony_ci#define OO_MASK		((1 << OO_SHIFT) - 1)
28962306a36Sopenharmony_ci#define MAX_OBJS_PER_PAGE	32767 /* since slab.objects is u15 */
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci/* Internal SLUB flags */
29262306a36Sopenharmony_ci/* Poison object */
29362306a36Sopenharmony_ci#define __OBJECT_POISON		((slab_flags_t __force)0x80000000U)
29462306a36Sopenharmony_ci/* Use cmpxchg_double */
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci#ifdef system_has_freelist_aba
29762306a36Sopenharmony_ci#define __CMPXCHG_DOUBLE	((slab_flags_t __force)0x40000000U)
29862306a36Sopenharmony_ci#else
29962306a36Sopenharmony_ci#define __CMPXCHG_DOUBLE	((slab_flags_t __force)0U)
30062306a36Sopenharmony_ci#endif
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/*
30362306a36Sopenharmony_ci * Tracking user of a slab.
30462306a36Sopenharmony_ci */
30562306a36Sopenharmony_ci#define TRACK_ADDRS_COUNT 16
30662306a36Sopenharmony_cistruct track {
30762306a36Sopenharmony_ci	unsigned long addr;	/* Called from address */
30862306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
30962306a36Sopenharmony_ci	depot_stack_handle_t handle;
31062306a36Sopenharmony_ci#endif
31162306a36Sopenharmony_ci	int cpu;		/* Was running on cpu */
31262306a36Sopenharmony_ci	int pid;		/* Pid context */
31362306a36Sopenharmony_ci	unsigned long when;	/* When did the operation occur */
31462306a36Sopenharmony_ci};
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cienum track_item { TRACK_ALLOC, TRACK_FREE };
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci#ifdef SLAB_SUPPORTS_SYSFS
31962306a36Sopenharmony_cistatic int sysfs_slab_add(struct kmem_cache *);
32062306a36Sopenharmony_cistatic int sysfs_slab_alias(struct kmem_cache *, const char *);
32162306a36Sopenharmony_ci#else
32262306a36Sopenharmony_cistatic inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
32362306a36Sopenharmony_cistatic inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
32462306a36Sopenharmony_ci							{ return 0; }
32562306a36Sopenharmony_ci#endif
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_SLUB_DEBUG)
32862306a36Sopenharmony_cistatic void debugfs_slab_add(struct kmem_cache *);
32962306a36Sopenharmony_ci#else
33062306a36Sopenharmony_cistatic inline void debugfs_slab_add(struct kmem_cache *s) { }
33162306a36Sopenharmony_ci#endif
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic inline void stat(const struct kmem_cache *s, enum stat_item si)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci#ifdef CONFIG_SLUB_STATS
33662306a36Sopenharmony_ci	/*
33762306a36Sopenharmony_ci	 * The rmw is racy on a preemptible kernel but this is acceptable, so
33862306a36Sopenharmony_ci	 * avoid this_cpu_add()'s irq-disable overhead.
33962306a36Sopenharmony_ci	 */
34062306a36Sopenharmony_ci	raw_cpu_inc(s->cpu_slab->stat[si]);
34162306a36Sopenharmony_ci#endif
34262306a36Sopenharmony_ci}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci/*
34562306a36Sopenharmony_ci * Tracks for which NUMA nodes we have kmem_cache_nodes allocated.
34662306a36Sopenharmony_ci * Corresponds to node_state[N_NORMAL_MEMORY], but can temporarily
34762306a36Sopenharmony_ci * differ during memory hotplug/hotremove operations.
34862306a36Sopenharmony_ci * Protected by slab_mutex.
34962306a36Sopenharmony_ci */
35062306a36Sopenharmony_cistatic nodemask_t slab_nodes;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
35362306a36Sopenharmony_ci/*
35462306a36Sopenharmony_ci * Workqueue used for flush_cpu_slab().
35562306a36Sopenharmony_ci */
35662306a36Sopenharmony_cistatic struct workqueue_struct *flushwq;
35762306a36Sopenharmony_ci#endif
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci/********************************************************************
36062306a36Sopenharmony_ci * 			Core slab cache functions
36162306a36Sopenharmony_ci *******************************************************************/
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci/*
36462306a36Sopenharmony_ci * freeptr_t represents a SLUB freelist pointer, which might be encoded
36562306a36Sopenharmony_ci * and not dereferenceable if CONFIG_SLAB_FREELIST_HARDENED is enabled.
36662306a36Sopenharmony_ci */
36762306a36Sopenharmony_citypedef struct { unsigned long v; } freeptr_t;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci/*
37062306a36Sopenharmony_ci * Returns freelist pointer (ptr). With hardening, this is obfuscated
37162306a36Sopenharmony_ci * with an XOR of the address where the pointer is held and a per-cache
37262306a36Sopenharmony_ci * random number.
37362306a36Sopenharmony_ci */
37462306a36Sopenharmony_cistatic inline freeptr_t freelist_ptr_encode(const struct kmem_cache *s,
37562306a36Sopenharmony_ci					    void *ptr, unsigned long ptr_addr)
37662306a36Sopenharmony_ci{
37762306a36Sopenharmony_ci	unsigned long encoded;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_HARDENED
38062306a36Sopenharmony_ci	encoded = (unsigned long)ptr ^ s->random ^ swab(ptr_addr);
38162306a36Sopenharmony_ci#else
38262306a36Sopenharmony_ci	encoded = (unsigned long)ptr;
38362306a36Sopenharmony_ci#endif
38462306a36Sopenharmony_ci	return (freeptr_t){.v = encoded};
38562306a36Sopenharmony_ci}
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_cistatic inline void *freelist_ptr_decode(const struct kmem_cache *s,
38862306a36Sopenharmony_ci					freeptr_t ptr, unsigned long ptr_addr)
38962306a36Sopenharmony_ci{
39062306a36Sopenharmony_ci	void *decoded;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_HARDENED
39362306a36Sopenharmony_ci	decoded = (void *)(ptr.v ^ s->random ^ swab(ptr_addr));
39462306a36Sopenharmony_ci#else
39562306a36Sopenharmony_ci	decoded = (void *)ptr.v;
39662306a36Sopenharmony_ci#endif
39762306a36Sopenharmony_ci	return decoded;
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_cistatic inline void *get_freepointer(struct kmem_cache *s, void *object)
40162306a36Sopenharmony_ci{
40262306a36Sopenharmony_ci	unsigned long ptr_addr;
40362306a36Sopenharmony_ci	freeptr_t p;
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	object = kasan_reset_tag(object);
40662306a36Sopenharmony_ci	ptr_addr = (unsigned long)object + s->offset;
40762306a36Sopenharmony_ci	p = *(freeptr_t *)(ptr_addr);
40862306a36Sopenharmony_ci	return freelist_ptr_decode(s, p, ptr_addr);
40962306a36Sopenharmony_ci}
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
41262306a36Sopenharmony_cistatic void prefetch_freepointer(const struct kmem_cache *s, void *object)
41362306a36Sopenharmony_ci{
41462306a36Sopenharmony_ci	prefetchw(object + s->offset);
41562306a36Sopenharmony_ci}
41662306a36Sopenharmony_ci#endif
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci/*
41962306a36Sopenharmony_ci * When running under KMSAN, get_freepointer_safe() may return an uninitialized
42062306a36Sopenharmony_ci * pointer value in the case the current thread loses the race for the next
42162306a36Sopenharmony_ci * memory chunk in the freelist. In that case this_cpu_cmpxchg_double() in
42262306a36Sopenharmony_ci * slab_alloc_node() will fail, so the uninitialized value won't be used, but
42362306a36Sopenharmony_ci * KMSAN will still check all arguments of cmpxchg because of imperfect
42462306a36Sopenharmony_ci * handling of inline assembly.
42562306a36Sopenharmony_ci * To work around this problem, we apply __no_kmsan_checks to ensure that
42662306a36Sopenharmony_ci * get_freepointer_safe() returns initialized memory.
42762306a36Sopenharmony_ci */
42862306a36Sopenharmony_ci__no_kmsan_checks
42962306a36Sopenharmony_cistatic inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci	unsigned long freepointer_addr;
43262306a36Sopenharmony_ci	freeptr_t p;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	if (!debug_pagealloc_enabled_static())
43562306a36Sopenharmony_ci		return get_freepointer(s, object);
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	object = kasan_reset_tag(object);
43862306a36Sopenharmony_ci	freepointer_addr = (unsigned long)object + s->offset;
43962306a36Sopenharmony_ci	copy_from_kernel_nofault(&p, (freeptr_t *)freepointer_addr, sizeof(p));
44062306a36Sopenharmony_ci	return freelist_ptr_decode(s, p, freepointer_addr);
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_cistatic inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
44462306a36Sopenharmony_ci{
44562306a36Sopenharmony_ci	unsigned long freeptr_addr = (unsigned long)object + s->offset;
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_HARDENED
44862306a36Sopenharmony_ci	BUG_ON(object == fp); /* naive detection of double free or corruption */
44962306a36Sopenharmony_ci#endif
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr);
45262306a36Sopenharmony_ci	*(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr);
45362306a36Sopenharmony_ci}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci/* Loop over all objects in a slab */
45662306a36Sopenharmony_ci#define for_each_object(__p, __s, __addr, __objects) \
45762306a36Sopenharmony_ci	for (__p = fixup_red_left(__s, __addr); \
45862306a36Sopenharmony_ci		__p < (__addr) + (__objects) * (__s)->size; \
45962306a36Sopenharmony_ci		__p += (__s)->size)
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cistatic inline unsigned int order_objects(unsigned int order, unsigned int size)
46262306a36Sopenharmony_ci{
46362306a36Sopenharmony_ci	return ((unsigned int)PAGE_SIZE << order) / size;
46462306a36Sopenharmony_ci}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_cistatic inline struct kmem_cache_order_objects oo_make(unsigned int order,
46762306a36Sopenharmony_ci		unsigned int size)
46862306a36Sopenharmony_ci{
46962306a36Sopenharmony_ci	struct kmem_cache_order_objects x = {
47062306a36Sopenharmony_ci		(order << OO_SHIFT) + order_objects(order, size)
47162306a36Sopenharmony_ci	};
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	return x;
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_cistatic inline unsigned int oo_order(struct kmem_cache_order_objects x)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	return x.x >> OO_SHIFT;
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_cistatic inline unsigned int oo_objects(struct kmem_cache_order_objects x)
48262306a36Sopenharmony_ci{
48362306a36Sopenharmony_ci	return x.x & OO_MASK;
48462306a36Sopenharmony_ci}
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
48762306a36Sopenharmony_cistatic void slub_set_cpu_partial(struct kmem_cache *s, unsigned int nr_objects)
48862306a36Sopenharmony_ci{
48962306a36Sopenharmony_ci	unsigned int nr_slabs;
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	s->cpu_partial = nr_objects;
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	/*
49462306a36Sopenharmony_ci	 * We take the number of objects but actually limit the number of
49562306a36Sopenharmony_ci	 * slabs on the per cpu partial list, in order to limit excessive
49662306a36Sopenharmony_ci	 * growth of the list. For simplicity we assume that the slabs will
49762306a36Sopenharmony_ci	 * be half-full.
49862306a36Sopenharmony_ci	 */
49962306a36Sopenharmony_ci	nr_slabs = DIV_ROUND_UP(nr_objects * 2, oo_objects(s->oo));
50062306a36Sopenharmony_ci	s->cpu_partial_slabs = nr_slabs;
50162306a36Sopenharmony_ci}
50262306a36Sopenharmony_ci#else
50362306a36Sopenharmony_cistatic inline void
50462306a36Sopenharmony_cislub_set_cpu_partial(struct kmem_cache *s, unsigned int nr_objects)
50562306a36Sopenharmony_ci{
50662306a36Sopenharmony_ci}
50762306a36Sopenharmony_ci#endif /* CONFIG_SLUB_CPU_PARTIAL */
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci/*
51062306a36Sopenharmony_ci * Per slab locking using the pagelock
51162306a36Sopenharmony_ci */
51262306a36Sopenharmony_cistatic __always_inline void slab_lock(struct slab *slab)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	struct page *page = slab_page(slab);
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	VM_BUG_ON_PAGE(PageTail(page), page);
51762306a36Sopenharmony_ci	bit_spin_lock(PG_locked, &page->flags);
51862306a36Sopenharmony_ci}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_cistatic __always_inline void slab_unlock(struct slab *slab)
52162306a36Sopenharmony_ci{
52262306a36Sopenharmony_ci	struct page *page = slab_page(slab);
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	VM_BUG_ON_PAGE(PageTail(page), page);
52562306a36Sopenharmony_ci	__bit_spin_unlock(PG_locked, &page->flags);
52662306a36Sopenharmony_ci}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_cistatic inline bool
52962306a36Sopenharmony_ci__update_freelist_fast(struct slab *slab,
53062306a36Sopenharmony_ci		      void *freelist_old, unsigned long counters_old,
53162306a36Sopenharmony_ci		      void *freelist_new, unsigned long counters_new)
53262306a36Sopenharmony_ci{
53362306a36Sopenharmony_ci#ifdef system_has_freelist_aba
53462306a36Sopenharmony_ci	freelist_aba_t old = { .freelist = freelist_old, .counter = counters_old };
53562306a36Sopenharmony_ci	freelist_aba_t new = { .freelist = freelist_new, .counter = counters_new };
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	return try_cmpxchg_freelist(&slab->freelist_counter.full, &old.full, new.full);
53862306a36Sopenharmony_ci#else
53962306a36Sopenharmony_ci	return false;
54062306a36Sopenharmony_ci#endif
54162306a36Sopenharmony_ci}
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_cistatic inline bool
54462306a36Sopenharmony_ci__update_freelist_slow(struct slab *slab,
54562306a36Sopenharmony_ci		      void *freelist_old, unsigned long counters_old,
54662306a36Sopenharmony_ci		      void *freelist_new, unsigned long counters_new)
54762306a36Sopenharmony_ci{
54862306a36Sopenharmony_ci	bool ret = false;
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	slab_lock(slab);
55162306a36Sopenharmony_ci	if (slab->freelist == freelist_old &&
55262306a36Sopenharmony_ci	    slab->counters == counters_old) {
55362306a36Sopenharmony_ci		slab->freelist = freelist_new;
55462306a36Sopenharmony_ci		slab->counters = counters_new;
55562306a36Sopenharmony_ci		ret = true;
55662306a36Sopenharmony_ci	}
55762306a36Sopenharmony_ci	slab_unlock(slab);
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	return ret;
56062306a36Sopenharmony_ci}
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci/*
56362306a36Sopenharmony_ci * Interrupts must be disabled (for the fallback code to work right), typically
56462306a36Sopenharmony_ci * by an _irqsave() lock variant. On PREEMPT_RT the preempt_disable(), which is
56562306a36Sopenharmony_ci * part of bit_spin_lock(), is sufficient because the policy is not to allow any
56662306a36Sopenharmony_ci * allocation/ free operation in hardirq context. Therefore nothing can
56762306a36Sopenharmony_ci * interrupt the operation.
56862306a36Sopenharmony_ci */
56962306a36Sopenharmony_cistatic inline bool __slab_update_freelist(struct kmem_cache *s, struct slab *slab,
57062306a36Sopenharmony_ci		void *freelist_old, unsigned long counters_old,
57162306a36Sopenharmony_ci		void *freelist_new, unsigned long counters_new,
57262306a36Sopenharmony_ci		const char *n)
57362306a36Sopenharmony_ci{
57462306a36Sopenharmony_ci	bool ret;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	if (USE_LOCKLESS_FAST_PATH())
57762306a36Sopenharmony_ci		lockdep_assert_irqs_disabled();
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	if (s->flags & __CMPXCHG_DOUBLE) {
58062306a36Sopenharmony_ci		ret = __update_freelist_fast(slab, freelist_old, counters_old,
58162306a36Sopenharmony_ci				            freelist_new, counters_new);
58262306a36Sopenharmony_ci	} else {
58362306a36Sopenharmony_ci		ret = __update_freelist_slow(slab, freelist_old, counters_old,
58462306a36Sopenharmony_ci				            freelist_new, counters_new);
58562306a36Sopenharmony_ci	}
58662306a36Sopenharmony_ci	if (likely(ret))
58762306a36Sopenharmony_ci		return true;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	cpu_relax();
59062306a36Sopenharmony_ci	stat(s, CMPXCHG_DOUBLE_FAIL);
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci#ifdef SLUB_DEBUG_CMPXCHG
59362306a36Sopenharmony_ci	pr_info("%s %s: cmpxchg double redo ", n, s->name);
59462306a36Sopenharmony_ci#endif
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	return false;
59762306a36Sopenharmony_ci}
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_cistatic inline bool slab_update_freelist(struct kmem_cache *s, struct slab *slab,
60062306a36Sopenharmony_ci		void *freelist_old, unsigned long counters_old,
60162306a36Sopenharmony_ci		void *freelist_new, unsigned long counters_new,
60262306a36Sopenharmony_ci		const char *n)
60362306a36Sopenharmony_ci{
60462306a36Sopenharmony_ci	bool ret;
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	if (s->flags & __CMPXCHG_DOUBLE) {
60762306a36Sopenharmony_ci		ret = __update_freelist_fast(slab, freelist_old, counters_old,
60862306a36Sopenharmony_ci				            freelist_new, counters_new);
60962306a36Sopenharmony_ci	} else {
61062306a36Sopenharmony_ci		unsigned long flags;
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci		local_irq_save(flags);
61362306a36Sopenharmony_ci		ret = __update_freelist_slow(slab, freelist_old, counters_old,
61462306a36Sopenharmony_ci				            freelist_new, counters_new);
61562306a36Sopenharmony_ci		local_irq_restore(flags);
61662306a36Sopenharmony_ci	}
61762306a36Sopenharmony_ci	if (likely(ret))
61862306a36Sopenharmony_ci		return true;
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci	cpu_relax();
62162306a36Sopenharmony_ci	stat(s, CMPXCHG_DOUBLE_FAIL);
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci#ifdef SLUB_DEBUG_CMPXCHG
62462306a36Sopenharmony_ci	pr_info("%s %s: cmpxchg double redo ", n, s->name);
62562306a36Sopenharmony_ci#endif
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	return false;
62862306a36Sopenharmony_ci}
62962306a36Sopenharmony_ci
63062306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
63162306a36Sopenharmony_cistatic unsigned long object_map[BITS_TO_LONGS(MAX_OBJS_PER_PAGE)];
63262306a36Sopenharmony_cistatic DEFINE_SPINLOCK(object_map_lock);
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_cistatic void __fill_map(unsigned long *obj_map, struct kmem_cache *s,
63562306a36Sopenharmony_ci		       struct slab *slab)
63662306a36Sopenharmony_ci{
63762306a36Sopenharmony_ci	void *addr = slab_address(slab);
63862306a36Sopenharmony_ci	void *p;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	bitmap_zero(obj_map, slab->objects);
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	for (p = slab->freelist; p; p = get_freepointer(s, p))
64362306a36Sopenharmony_ci		set_bit(__obj_to_index(s, addr, p), obj_map);
64462306a36Sopenharmony_ci}
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_KUNIT)
64762306a36Sopenharmony_cistatic bool slab_add_kunit_errors(void)
64862306a36Sopenharmony_ci{
64962306a36Sopenharmony_ci	struct kunit_resource *resource;
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci	if (!kunit_get_current_test())
65262306a36Sopenharmony_ci		return false;
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	resource = kunit_find_named_resource(current->kunit_test, "slab_errors");
65562306a36Sopenharmony_ci	if (!resource)
65662306a36Sopenharmony_ci		return false;
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	(*(int *)resource->data)++;
65962306a36Sopenharmony_ci	kunit_put_resource(resource);
66062306a36Sopenharmony_ci	return true;
66162306a36Sopenharmony_ci}
66262306a36Sopenharmony_ci#else
66362306a36Sopenharmony_cistatic inline bool slab_add_kunit_errors(void) { return false; }
66462306a36Sopenharmony_ci#endif
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_cistatic inline unsigned int size_from_object(struct kmem_cache *s)
66762306a36Sopenharmony_ci{
66862306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE)
66962306a36Sopenharmony_ci		return s->size - s->red_left_pad;
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	return s->size;
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistatic inline void *restore_red_left(struct kmem_cache *s, void *p)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE)
67762306a36Sopenharmony_ci		p -= s->red_left_pad;
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	return p;
68062306a36Sopenharmony_ci}
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci/*
68362306a36Sopenharmony_ci * Debug settings:
68462306a36Sopenharmony_ci */
68562306a36Sopenharmony_ci#if defined(CONFIG_SLUB_DEBUG_ON)
68662306a36Sopenharmony_cistatic slab_flags_t slub_debug = DEBUG_DEFAULT_FLAGS;
68762306a36Sopenharmony_ci#else
68862306a36Sopenharmony_cistatic slab_flags_t slub_debug;
68962306a36Sopenharmony_ci#endif
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_cistatic char *slub_debug_string;
69262306a36Sopenharmony_cistatic int disable_higher_order_debug;
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci/*
69562306a36Sopenharmony_ci * slub is about to manipulate internal object metadata.  This memory lies
69662306a36Sopenharmony_ci * outside the range of the allocated object, so accessing it would normally
69762306a36Sopenharmony_ci * be reported by kasan as a bounds error.  metadata_access_enable() is used
69862306a36Sopenharmony_ci * to tell kasan that these accesses are OK.
69962306a36Sopenharmony_ci */
70062306a36Sopenharmony_cistatic inline void metadata_access_enable(void)
70162306a36Sopenharmony_ci{
70262306a36Sopenharmony_ci	kasan_disable_current();
70362306a36Sopenharmony_ci}
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_cistatic inline void metadata_access_disable(void)
70662306a36Sopenharmony_ci{
70762306a36Sopenharmony_ci	kasan_enable_current();
70862306a36Sopenharmony_ci}
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci/*
71162306a36Sopenharmony_ci * Object debugging
71262306a36Sopenharmony_ci */
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci/* Verify that a pointer has an address that is valid within a slab page */
71562306a36Sopenharmony_cistatic inline int check_valid_pointer(struct kmem_cache *s,
71662306a36Sopenharmony_ci				struct slab *slab, void *object)
71762306a36Sopenharmony_ci{
71862306a36Sopenharmony_ci	void *base;
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	if (!object)
72162306a36Sopenharmony_ci		return 1;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci	base = slab_address(slab);
72462306a36Sopenharmony_ci	object = kasan_reset_tag(object);
72562306a36Sopenharmony_ci	object = restore_red_left(s, object);
72662306a36Sopenharmony_ci	if (object < base || object >= base + slab->objects * s->size ||
72762306a36Sopenharmony_ci		(object - base) % s->size) {
72862306a36Sopenharmony_ci		return 0;
72962306a36Sopenharmony_ci	}
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci	return 1;
73262306a36Sopenharmony_ci}
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic void print_section(char *level, char *text, u8 *addr,
73562306a36Sopenharmony_ci			  unsigned int length)
73662306a36Sopenharmony_ci{
73762306a36Sopenharmony_ci	metadata_access_enable();
73862306a36Sopenharmony_ci	print_hex_dump(level, text, DUMP_PREFIX_ADDRESS,
73962306a36Sopenharmony_ci			16, 1, kasan_reset_tag((void *)addr), length, 1);
74062306a36Sopenharmony_ci	metadata_access_disable();
74162306a36Sopenharmony_ci}
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci/*
74462306a36Sopenharmony_ci * See comment in calculate_sizes().
74562306a36Sopenharmony_ci */
74662306a36Sopenharmony_cistatic inline bool freeptr_outside_object(struct kmem_cache *s)
74762306a36Sopenharmony_ci{
74862306a36Sopenharmony_ci	return s->offset >= s->inuse;
74962306a36Sopenharmony_ci}
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci/*
75262306a36Sopenharmony_ci * Return offset of the end of info block which is inuse + free pointer if
75362306a36Sopenharmony_ci * not overlapping with object.
75462306a36Sopenharmony_ci */
75562306a36Sopenharmony_cistatic inline unsigned int get_info_end(struct kmem_cache *s)
75662306a36Sopenharmony_ci{
75762306a36Sopenharmony_ci	if (freeptr_outside_object(s))
75862306a36Sopenharmony_ci		return s->inuse + sizeof(void *);
75962306a36Sopenharmony_ci	else
76062306a36Sopenharmony_ci		return s->inuse;
76162306a36Sopenharmony_ci}
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_cistatic struct track *get_track(struct kmem_cache *s, void *object,
76462306a36Sopenharmony_ci	enum track_item alloc)
76562306a36Sopenharmony_ci{
76662306a36Sopenharmony_ci	struct track *p;
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	p = object + get_info_end(s);
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci	return kasan_reset_tag(p + alloc);
77162306a36Sopenharmony_ci}
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
77462306a36Sopenharmony_cistatic noinline depot_stack_handle_t set_track_prepare(void)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	depot_stack_handle_t handle;
77762306a36Sopenharmony_ci	unsigned long entries[TRACK_ADDRS_COUNT];
77862306a36Sopenharmony_ci	unsigned int nr_entries;
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 3);
78162306a36Sopenharmony_ci	handle = stack_depot_save(entries, nr_entries, GFP_NOWAIT);
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	return handle;
78462306a36Sopenharmony_ci}
78562306a36Sopenharmony_ci#else
78662306a36Sopenharmony_cistatic inline depot_stack_handle_t set_track_prepare(void)
78762306a36Sopenharmony_ci{
78862306a36Sopenharmony_ci	return 0;
78962306a36Sopenharmony_ci}
79062306a36Sopenharmony_ci#endif
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_cistatic void set_track_update(struct kmem_cache *s, void *object,
79362306a36Sopenharmony_ci			     enum track_item alloc, unsigned long addr,
79462306a36Sopenharmony_ci			     depot_stack_handle_t handle)
79562306a36Sopenharmony_ci{
79662306a36Sopenharmony_ci	struct track *p = get_track(s, object, alloc);
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
79962306a36Sopenharmony_ci	p->handle = handle;
80062306a36Sopenharmony_ci#endif
80162306a36Sopenharmony_ci	p->addr = addr;
80262306a36Sopenharmony_ci	p->cpu = smp_processor_id();
80362306a36Sopenharmony_ci	p->pid = current->pid;
80462306a36Sopenharmony_ci	p->when = jiffies;
80562306a36Sopenharmony_ci}
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_cistatic __always_inline void set_track(struct kmem_cache *s, void *object,
80862306a36Sopenharmony_ci				      enum track_item alloc, unsigned long addr)
80962306a36Sopenharmony_ci{
81062306a36Sopenharmony_ci	depot_stack_handle_t handle = set_track_prepare();
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	set_track_update(s, object, alloc, addr, handle);
81362306a36Sopenharmony_ci}
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_cistatic void init_tracking(struct kmem_cache *s, void *object)
81662306a36Sopenharmony_ci{
81762306a36Sopenharmony_ci	struct track *p;
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_ci	if (!(s->flags & SLAB_STORE_USER))
82062306a36Sopenharmony_ci		return;
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci	p = get_track(s, object, TRACK_ALLOC);
82362306a36Sopenharmony_ci	memset(p, 0, 2*sizeof(struct track));
82462306a36Sopenharmony_ci}
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_cistatic void print_track(const char *s, struct track *t, unsigned long pr_time)
82762306a36Sopenharmony_ci{
82862306a36Sopenharmony_ci	depot_stack_handle_t handle __maybe_unused;
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	if (!t->addr)
83162306a36Sopenharmony_ci		return;
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci	pr_err("%s in %pS age=%lu cpu=%u pid=%d\n",
83462306a36Sopenharmony_ci	       s, (void *)t->addr, pr_time - t->when, t->cpu, t->pid);
83562306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
83662306a36Sopenharmony_ci	handle = READ_ONCE(t->handle);
83762306a36Sopenharmony_ci	if (handle)
83862306a36Sopenharmony_ci		stack_depot_print(handle);
83962306a36Sopenharmony_ci	else
84062306a36Sopenharmony_ci		pr_err("object allocation/free stack trace missing\n");
84162306a36Sopenharmony_ci#endif
84262306a36Sopenharmony_ci}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_civoid print_tracking(struct kmem_cache *s, void *object)
84562306a36Sopenharmony_ci{
84662306a36Sopenharmony_ci	unsigned long pr_time = jiffies;
84762306a36Sopenharmony_ci	if (!(s->flags & SLAB_STORE_USER))
84862306a36Sopenharmony_ci		return;
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci	print_track("Allocated", get_track(s, object, TRACK_ALLOC), pr_time);
85162306a36Sopenharmony_ci	print_track("Freed", get_track(s, object, TRACK_FREE), pr_time);
85262306a36Sopenharmony_ci}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic void print_slab_info(const struct slab *slab)
85562306a36Sopenharmony_ci{
85662306a36Sopenharmony_ci	struct folio *folio = (struct folio *)slab_folio(slab);
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	pr_err("Slab 0x%p objects=%u used=%u fp=0x%p flags=%pGp\n",
85962306a36Sopenharmony_ci	       slab, slab->objects, slab->inuse, slab->freelist,
86062306a36Sopenharmony_ci	       folio_flags(folio, 0));
86162306a36Sopenharmony_ci}
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci/*
86462306a36Sopenharmony_ci * kmalloc caches has fixed sizes (mostly power of 2), and kmalloc() API
86562306a36Sopenharmony_ci * family will round up the real request size to these fixed ones, so
86662306a36Sopenharmony_ci * there could be an extra area than what is requested. Save the original
86762306a36Sopenharmony_ci * request size in the meta data area, for better debug and sanity check.
86862306a36Sopenharmony_ci */
86962306a36Sopenharmony_cistatic inline void set_orig_size(struct kmem_cache *s,
87062306a36Sopenharmony_ci				void *object, unsigned int orig_size)
87162306a36Sopenharmony_ci{
87262306a36Sopenharmony_ci	void *p = kasan_reset_tag(object);
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	if (!slub_debug_orig_size(s))
87562306a36Sopenharmony_ci		return;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci#ifdef CONFIG_KASAN_GENERIC
87862306a36Sopenharmony_ci	/*
87962306a36Sopenharmony_ci	 * KASAN could save its free meta data in object's data area at
88062306a36Sopenharmony_ci	 * offset 0, if the size is larger than 'orig_size', it will
88162306a36Sopenharmony_ci	 * overlap the data redzone in [orig_size+1, object_size], and
88262306a36Sopenharmony_ci	 * the check should be skipped.
88362306a36Sopenharmony_ci	 */
88462306a36Sopenharmony_ci	if (kasan_metadata_size(s, true) > orig_size)
88562306a36Sopenharmony_ci		orig_size = s->object_size;
88662306a36Sopenharmony_ci#endif
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	p += get_info_end(s);
88962306a36Sopenharmony_ci	p += sizeof(struct track) * 2;
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	*(unsigned int *)p = orig_size;
89262306a36Sopenharmony_ci}
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_cistatic inline unsigned int get_orig_size(struct kmem_cache *s, void *object)
89562306a36Sopenharmony_ci{
89662306a36Sopenharmony_ci	void *p = kasan_reset_tag(object);
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	if (!slub_debug_orig_size(s))
89962306a36Sopenharmony_ci		return s->object_size;
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	p += get_info_end(s);
90262306a36Sopenharmony_ci	p += sizeof(struct track) * 2;
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	return *(unsigned int *)p;
90562306a36Sopenharmony_ci}
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_civoid skip_orig_size_check(struct kmem_cache *s, const void *object)
90862306a36Sopenharmony_ci{
90962306a36Sopenharmony_ci	set_orig_size(s, (void *)object, s->object_size);
91062306a36Sopenharmony_ci}
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_cistatic void slab_bug(struct kmem_cache *s, char *fmt, ...)
91362306a36Sopenharmony_ci{
91462306a36Sopenharmony_ci	struct va_format vaf;
91562306a36Sopenharmony_ci	va_list args;
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci	va_start(args, fmt);
91862306a36Sopenharmony_ci	vaf.fmt = fmt;
91962306a36Sopenharmony_ci	vaf.va = &args;
92062306a36Sopenharmony_ci	pr_err("=============================================================================\n");
92162306a36Sopenharmony_ci	pr_err("BUG %s (%s): %pV\n", s->name, print_tainted(), &vaf);
92262306a36Sopenharmony_ci	pr_err("-----------------------------------------------------------------------------\n\n");
92362306a36Sopenharmony_ci	va_end(args);
92462306a36Sopenharmony_ci}
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci__printf(2, 3)
92762306a36Sopenharmony_cistatic void slab_fix(struct kmem_cache *s, char *fmt, ...)
92862306a36Sopenharmony_ci{
92962306a36Sopenharmony_ci	struct va_format vaf;
93062306a36Sopenharmony_ci	va_list args;
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_ci	if (slab_add_kunit_errors())
93362306a36Sopenharmony_ci		return;
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	va_start(args, fmt);
93662306a36Sopenharmony_ci	vaf.fmt = fmt;
93762306a36Sopenharmony_ci	vaf.va = &args;
93862306a36Sopenharmony_ci	pr_err("FIX %s: %pV\n", s->name, &vaf);
93962306a36Sopenharmony_ci	va_end(args);
94062306a36Sopenharmony_ci}
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_cistatic void print_trailer(struct kmem_cache *s, struct slab *slab, u8 *p)
94362306a36Sopenharmony_ci{
94462306a36Sopenharmony_ci	unsigned int off;	/* Offset of last byte */
94562306a36Sopenharmony_ci	u8 *addr = slab_address(slab);
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	print_tracking(s, p);
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ci	print_slab_info(slab);
95062306a36Sopenharmony_ci
95162306a36Sopenharmony_ci	pr_err("Object 0x%p @offset=%tu fp=0x%p\n\n",
95262306a36Sopenharmony_ci	       p, p - addr, get_freepointer(s, p));
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE)
95562306a36Sopenharmony_ci		print_section(KERN_ERR, "Redzone  ", p - s->red_left_pad,
95662306a36Sopenharmony_ci			      s->red_left_pad);
95762306a36Sopenharmony_ci	else if (p > addr + 16)
95862306a36Sopenharmony_ci		print_section(KERN_ERR, "Bytes b4 ", p - 16, 16);
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	print_section(KERN_ERR,         "Object   ", p,
96162306a36Sopenharmony_ci		      min_t(unsigned int, s->object_size, PAGE_SIZE));
96262306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE)
96362306a36Sopenharmony_ci		print_section(KERN_ERR, "Redzone  ", p + s->object_size,
96462306a36Sopenharmony_ci			s->inuse - s->object_size);
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci	off = get_info_end(s);
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	if (s->flags & SLAB_STORE_USER)
96962306a36Sopenharmony_ci		off += 2 * sizeof(struct track);
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	if (slub_debug_orig_size(s))
97262306a36Sopenharmony_ci		off += sizeof(unsigned int);
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci	off += kasan_metadata_size(s, false);
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	if (off != size_from_object(s))
97762306a36Sopenharmony_ci		/* Beginning of the filler is the free pointer */
97862306a36Sopenharmony_ci		print_section(KERN_ERR, "Padding  ", p + off,
97962306a36Sopenharmony_ci			      size_from_object(s) - off);
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ci	dump_stack();
98262306a36Sopenharmony_ci}
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_cistatic void object_err(struct kmem_cache *s, struct slab *slab,
98562306a36Sopenharmony_ci			u8 *object, char *reason)
98662306a36Sopenharmony_ci{
98762306a36Sopenharmony_ci	if (slab_add_kunit_errors())
98862306a36Sopenharmony_ci		return;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	slab_bug(s, "%s", reason);
99162306a36Sopenharmony_ci	print_trailer(s, slab, object);
99262306a36Sopenharmony_ci	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
99362306a36Sopenharmony_ci}
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_cistatic bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
99662306a36Sopenharmony_ci			       void **freelist, void *nextfree)
99762306a36Sopenharmony_ci{
99862306a36Sopenharmony_ci	if ((s->flags & SLAB_CONSISTENCY_CHECKS) &&
99962306a36Sopenharmony_ci	    !check_valid_pointer(s, slab, nextfree) && freelist) {
100062306a36Sopenharmony_ci		object_err(s, slab, *freelist, "Freechain corrupt");
100162306a36Sopenharmony_ci		*freelist = NULL;
100262306a36Sopenharmony_ci		slab_fix(s, "Isolate corrupted freechain");
100362306a36Sopenharmony_ci		return true;
100462306a36Sopenharmony_ci	}
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	return false;
100762306a36Sopenharmony_ci}
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_cistatic __printf(3, 4) void slab_err(struct kmem_cache *s, struct slab *slab,
101062306a36Sopenharmony_ci			const char *fmt, ...)
101162306a36Sopenharmony_ci{
101262306a36Sopenharmony_ci	va_list args;
101362306a36Sopenharmony_ci	char buf[100];
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	if (slab_add_kunit_errors())
101662306a36Sopenharmony_ci		return;
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci	va_start(args, fmt);
101962306a36Sopenharmony_ci	vsnprintf(buf, sizeof(buf), fmt, args);
102062306a36Sopenharmony_ci	va_end(args);
102162306a36Sopenharmony_ci	slab_bug(s, "%s", buf);
102262306a36Sopenharmony_ci	print_slab_info(slab);
102362306a36Sopenharmony_ci	dump_stack();
102462306a36Sopenharmony_ci	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
102562306a36Sopenharmony_ci}
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_cistatic void init_object(struct kmem_cache *s, void *object, u8 val)
102862306a36Sopenharmony_ci{
102962306a36Sopenharmony_ci	u8 *p = kasan_reset_tag(object);
103062306a36Sopenharmony_ci	unsigned int poison_size = s->object_size;
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE) {
103362306a36Sopenharmony_ci		memset(p - s->red_left_pad, val, s->red_left_pad);
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci		if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {
103662306a36Sopenharmony_ci			/*
103762306a36Sopenharmony_ci			 * Redzone the extra allocated space by kmalloc than
103862306a36Sopenharmony_ci			 * requested, and the poison size will be limited to
103962306a36Sopenharmony_ci			 * the original request size accordingly.
104062306a36Sopenharmony_ci			 */
104162306a36Sopenharmony_ci			poison_size = get_orig_size(s, object);
104262306a36Sopenharmony_ci		}
104362306a36Sopenharmony_ci	}
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_ci	if (s->flags & __OBJECT_POISON) {
104662306a36Sopenharmony_ci		memset(p, POISON_FREE, poison_size - 1);
104762306a36Sopenharmony_ci		p[poison_size - 1] = POISON_END;
104862306a36Sopenharmony_ci	}
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE)
105162306a36Sopenharmony_ci		memset(p + poison_size, val, s->inuse - poison_size);
105262306a36Sopenharmony_ci}
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_cistatic void restore_bytes(struct kmem_cache *s, char *message, u8 data,
105562306a36Sopenharmony_ci						void *from, void *to)
105662306a36Sopenharmony_ci{
105762306a36Sopenharmony_ci	slab_fix(s, "Restoring %s 0x%p-0x%p=0x%x", message, from, to - 1, data);
105862306a36Sopenharmony_ci	memset(from, data, to - from);
105962306a36Sopenharmony_ci}
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_cistatic int check_bytes_and_report(struct kmem_cache *s, struct slab *slab,
106262306a36Sopenharmony_ci			u8 *object, char *what,
106362306a36Sopenharmony_ci			u8 *start, unsigned int value, unsigned int bytes)
106462306a36Sopenharmony_ci{
106562306a36Sopenharmony_ci	u8 *fault;
106662306a36Sopenharmony_ci	u8 *end;
106762306a36Sopenharmony_ci	u8 *addr = slab_address(slab);
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci	metadata_access_enable();
107062306a36Sopenharmony_ci	fault = memchr_inv(kasan_reset_tag(start), value, bytes);
107162306a36Sopenharmony_ci	metadata_access_disable();
107262306a36Sopenharmony_ci	if (!fault)
107362306a36Sopenharmony_ci		return 1;
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ci	end = start + bytes;
107662306a36Sopenharmony_ci	while (end > fault && end[-1] == value)
107762306a36Sopenharmony_ci		end--;
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ci	if (slab_add_kunit_errors())
108062306a36Sopenharmony_ci		goto skip_bug_print;
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	slab_bug(s, "%s overwritten", what);
108362306a36Sopenharmony_ci	pr_err("0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
108462306a36Sopenharmony_ci					fault, end - 1, fault - addr,
108562306a36Sopenharmony_ci					fault[0], value);
108662306a36Sopenharmony_ci	print_trailer(s, slab, object);
108762306a36Sopenharmony_ci	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_ciskip_bug_print:
109062306a36Sopenharmony_ci	restore_bytes(s, what, value, fault, end);
109162306a36Sopenharmony_ci	return 0;
109262306a36Sopenharmony_ci}
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci/*
109562306a36Sopenharmony_ci * Object layout:
109662306a36Sopenharmony_ci *
109762306a36Sopenharmony_ci * object address
109862306a36Sopenharmony_ci * 	Bytes of the object to be managed.
109962306a36Sopenharmony_ci * 	If the freepointer may overlay the object then the free
110062306a36Sopenharmony_ci *	pointer is at the middle of the object.
110162306a36Sopenharmony_ci *
110262306a36Sopenharmony_ci * 	Poisoning uses 0x6b (POISON_FREE) and the last byte is
110362306a36Sopenharmony_ci * 	0xa5 (POISON_END)
110462306a36Sopenharmony_ci *
110562306a36Sopenharmony_ci * object + s->object_size
110662306a36Sopenharmony_ci * 	Padding to reach word boundary. This is also used for Redzoning.
110762306a36Sopenharmony_ci * 	Padding is extended by another word if Redzoning is enabled and
110862306a36Sopenharmony_ci * 	object_size == inuse.
110962306a36Sopenharmony_ci *
111062306a36Sopenharmony_ci * 	We fill with 0xbb (RED_INACTIVE) for inactive objects and with
111162306a36Sopenharmony_ci * 	0xcc (RED_ACTIVE) for objects in use.
111262306a36Sopenharmony_ci *
111362306a36Sopenharmony_ci * object + s->inuse
111462306a36Sopenharmony_ci * 	Meta data starts here.
111562306a36Sopenharmony_ci *
111662306a36Sopenharmony_ci * 	A. Free pointer (if we cannot overwrite object on free)
111762306a36Sopenharmony_ci * 	B. Tracking data for SLAB_STORE_USER
111862306a36Sopenharmony_ci *	C. Original request size for kmalloc object (SLAB_STORE_USER enabled)
111962306a36Sopenharmony_ci *	D. Padding to reach required alignment boundary or at minimum
112062306a36Sopenharmony_ci * 		one word if debugging is on to be able to detect writes
112162306a36Sopenharmony_ci * 		before the word boundary.
112262306a36Sopenharmony_ci *
112362306a36Sopenharmony_ci *	Padding is done using 0x5a (POISON_INUSE)
112462306a36Sopenharmony_ci *
112562306a36Sopenharmony_ci * object + s->size
112662306a36Sopenharmony_ci * 	Nothing is used beyond s->size.
112762306a36Sopenharmony_ci *
112862306a36Sopenharmony_ci * If slabcaches are merged then the object_size and inuse boundaries are mostly
112962306a36Sopenharmony_ci * ignored. And therefore no slab options that rely on these boundaries
113062306a36Sopenharmony_ci * may be used with merged slabcaches.
113162306a36Sopenharmony_ci */
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_cistatic int check_pad_bytes(struct kmem_cache *s, struct slab *slab, u8 *p)
113462306a36Sopenharmony_ci{
113562306a36Sopenharmony_ci	unsigned long off = get_info_end(s);	/* The end of info */
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci	if (s->flags & SLAB_STORE_USER) {
113862306a36Sopenharmony_ci		/* We also have user information there */
113962306a36Sopenharmony_ci		off += 2 * sizeof(struct track);
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci		if (s->flags & SLAB_KMALLOC)
114262306a36Sopenharmony_ci			off += sizeof(unsigned int);
114362306a36Sopenharmony_ci	}
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci	off += kasan_metadata_size(s, false);
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_ci	if (size_from_object(s) == off)
114862306a36Sopenharmony_ci		return 1;
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci	return check_bytes_and_report(s, slab, p, "Object padding",
115162306a36Sopenharmony_ci			p + off, POISON_INUSE, size_from_object(s) - off);
115262306a36Sopenharmony_ci}
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci/* Check the pad bytes at the end of a slab page */
115562306a36Sopenharmony_cistatic void slab_pad_check(struct kmem_cache *s, struct slab *slab)
115662306a36Sopenharmony_ci{
115762306a36Sopenharmony_ci	u8 *start;
115862306a36Sopenharmony_ci	u8 *fault;
115962306a36Sopenharmony_ci	u8 *end;
116062306a36Sopenharmony_ci	u8 *pad;
116162306a36Sopenharmony_ci	int length;
116262306a36Sopenharmony_ci	int remainder;
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci	if (!(s->flags & SLAB_POISON))
116562306a36Sopenharmony_ci		return;
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci	start = slab_address(slab);
116862306a36Sopenharmony_ci	length = slab_size(slab);
116962306a36Sopenharmony_ci	end = start + length;
117062306a36Sopenharmony_ci	remainder = length % s->size;
117162306a36Sopenharmony_ci	if (!remainder)
117262306a36Sopenharmony_ci		return;
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci	pad = end - remainder;
117562306a36Sopenharmony_ci	metadata_access_enable();
117662306a36Sopenharmony_ci	fault = memchr_inv(kasan_reset_tag(pad), POISON_INUSE, remainder);
117762306a36Sopenharmony_ci	metadata_access_disable();
117862306a36Sopenharmony_ci	if (!fault)
117962306a36Sopenharmony_ci		return;
118062306a36Sopenharmony_ci	while (end > fault && end[-1] == POISON_INUSE)
118162306a36Sopenharmony_ci		end--;
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_ci	slab_err(s, slab, "Padding overwritten. 0x%p-0x%p @offset=%tu",
118462306a36Sopenharmony_ci			fault, end - 1, fault - start);
118562306a36Sopenharmony_ci	print_section(KERN_ERR, "Padding ", pad, remainder);
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_ci	restore_bytes(s, "slab padding", POISON_INUSE, fault, end);
118862306a36Sopenharmony_ci}
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_cistatic int check_object(struct kmem_cache *s, struct slab *slab,
119162306a36Sopenharmony_ci					void *object, u8 val)
119262306a36Sopenharmony_ci{
119362306a36Sopenharmony_ci	u8 *p = object;
119462306a36Sopenharmony_ci	u8 *endobject = object + s->object_size;
119562306a36Sopenharmony_ci	unsigned int orig_size;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	if (s->flags & SLAB_RED_ZONE) {
119862306a36Sopenharmony_ci		if (!check_bytes_and_report(s, slab, object, "Left Redzone",
119962306a36Sopenharmony_ci			object - s->red_left_pad, val, s->red_left_pad))
120062306a36Sopenharmony_ci			return 0;
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci		if (!check_bytes_and_report(s, slab, object, "Right Redzone",
120362306a36Sopenharmony_ci			endobject, val, s->inuse - s->object_size))
120462306a36Sopenharmony_ci			return 0;
120562306a36Sopenharmony_ci
120662306a36Sopenharmony_ci		if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {
120762306a36Sopenharmony_ci			orig_size = get_orig_size(s, object);
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ci			if (s->object_size > orig_size  &&
121062306a36Sopenharmony_ci				!check_bytes_and_report(s, slab, object,
121162306a36Sopenharmony_ci					"kmalloc Redzone", p + orig_size,
121262306a36Sopenharmony_ci					val, s->object_size - orig_size)) {
121362306a36Sopenharmony_ci				return 0;
121462306a36Sopenharmony_ci			}
121562306a36Sopenharmony_ci		}
121662306a36Sopenharmony_ci	} else {
121762306a36Sopenharmony_ci		if ((s->flags & SLAB_POISON) && s->object_size < s->inuse) {
121862306a36Sopenharmony_ci			check_bytes_and_report(s, slab, p, "Alignment padding",
121962306a36Sopenharmony_ci				endobject, POISON_INUSE,
122062306a36Sopenharmony_ci				s->inuse - s->object_size);
122162306a36Sopenharmony_ci		}
122262306a36Sopenharmony_ci	}
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci	if (s->flags & SLAB_POISON) {
122562306a36Sopenharmony_ci		if (val != SLUB_RED_ACTIVE && (s->flags & __OBJECT_POISON) &&
122662306a36Sopenharmony_ci			(!check_bytes_and_report(s, slab, p, "Poison", p,
122762306a36Sopenharmony_ci					POISON_FREE, s->object_size - 1) ||
122862306a36Sopenharmony_ci			 !check_bytes_and_report(s, slab, p, "End Poison",
122962306a36Sopenharmony_ci				p + s->object_size - 1, POISON_END, 1)))
123062306a36Sopenharmony_ci			return 0;
123162306a36Sopenharmony_ci		/*
123262306a36Sopenharmony_ci		 * check_pad_bytes cleans up on its own.
123362306a36Sopenharmony_ci		 */
123462306a36Sopenharmony_ci		check_pad_bytes(s, slab, p);
123562306a36Sopenharmony_ci	}
123662306a36Sopenharmony_ci
123762306a36Sopenharmony_ci	if (!freeptr_outside_object(s) && val == SLUB_RED_ACTIVE)
123862306a36Sopenharmony_ci		/*
123962306a36Sopenharmony_ci		 * Object and freepointer overlap. Cannot check
124062306a36Sopenharmony_ci		 * freepointer while object is allocated.
124162306a36Sopenharmony_ci		 */
124262306a36Sopenharmony_ci		return 1;
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci	/* Check free pointer validity */
124562306a36Sopenharmony_ci	if (!check_valid_pointer(s, slab, get_freepointer(s, p))) {
124662306a36Sopenharmony_ci		object_err(s, slab, p, "Freepointer corrupt");
124762306a36Sopenharmony_ci		/*
124862306a36Sopenharmony_ci		 * No choice but to zap it and thus lose the remainder
124962306a36Sopenharmony_ci		 * of the free objects in this slab. May cause
125062306a36Sopenharmony_ci		 * another error because the object count is now wrong.
125162306a36Sopenharmony_ci		 */
125262306a36Sopenharmony_ci		set_freepointer(s, p, NULL);
125362306a36Sopenharmony_ci		return 0;
125462306a36Sopenharmony_ci	}
125562306a36Sopenharmony_ci	return 1;
125662306a36Sopenharmony_ci}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_cistatic int check_slab(struct kmem_cache *s, struct slab *slab)
125962306a36Sopenharmony_ci{
126062306a36Sopenharmony_ci	int maxobj;
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci	if (!folio_test_slab(slab_folio(slab))) {
126362306a36Sopenharmony_ci		slab_err(s, slab, "Not a valid slab page");
126462306a36Sopenharmony_ci		return 0;
126562306a36Sopenharmony_ci	}
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	maxobj = order_objects(slab_order(slab), s->size);
126862306a36Sopenharmony_ci	if (slab->objects > maxobj) {
126962306a36Sopenharmony_ci		slab_err(s, slab, "objects %u > max %u",
127062306a36Sopenharmony_ci			slab->objects, maxobj);
127162306a36Sopenharmony_ci		return 0;
127262306a36Sopenharmony_ci	}
127362306a36Sopenharmony_ci	if (slab->inuse > slab->objects) {
127462306a36Sopenharmony_ci		slab_err(s, slab, "inuse %u > max %u",
127562306a36Sopenharmony_ci			slab->inuse, slab->objects);
127662306a36Sopenharmony_ci		return 0;
127762306a36Sopenharmony_ci	}
127862306a36Sopenharmony_ci	/* Slab_pad_check fixes things up after itself */
127962306a36Sopenharmony_ci	slab_pad_check(s, slab);
128062306a36Sopenharmony_ci	return 1;
128162306a36Sopenharmony_ci}
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci/*
128462306a36Sopenharmony_ci * Determine if a certain object in a slab is on the freelist. Must hold the
128562306a36Sopenharmony_ci * slab lock to guarantee that the chains are in a consistent state.
128662306a36Sopenharmony_ci */
128762306a36Sopenharmony_cistatic int on_freelist(struct kmem_cache *s, struct slab *slab, void *search)
128862306a36Sopenharmony_ci{
128962306a36Sopenharmony_ci	int nr = 0;
129062306a36Sopenharmony_ci	void *fp;
129162306a36Sopenharmony_ci	void *object = NULL;
129262306a36Sopenharmony_ci	int max_objects;
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci	fp = slab->freelist;
129562306a36Sopenharmony_ci	while (fp && nr <= slab->objects) {
129662306a36Sopenharmony_ci		if (fp == search)
129762306a36Sopenharmony_ci			return 1;
129862306a36Sopenharmony_ci		if (!check_valid_pointer(s, slab, fp)) {
129962306a36Sopenharmony_ci			if (object) {
130062306a36Sopenharmony_ci				object_err(s, slab, object,
130162306a36Sopenharmony_ci					"Freechain corrupt");
130262306a36Sopenharmony_ci				set_freepointer(s, object, NULL);
130362306a36Sopenharmony_ci			} else {
130462306a36Sopenharmony_ci				slab_err(s, slab, "Freepointer corrupt");
130562306a36Sopenharmony_ci				slab->freelist = NULL;
130662306a36Sopenharmony_ci				slab->inuse = slab->objects;
130762306a36Sopenharmony_ci				slab_fix(s, "Freelist cleared");
130862306a36Sopenharmony_ci				return 0;
130962306a36Sopenharmony_ci			}
131062306a36Sopenharmony_ci			break;
131162306a36Sopenharmony_ci		}
131262306a36Sopenharmony_ci		object = fp;
131362306a36Sopenharmony_ci		fp = get_freepointer(s, object);
131462306a36Sopenharmony_ci		nr++;
131562306a36Sopenharmony_ci	}
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_ci	max_objects = order_objects(slab_order(slab), s->size);
131862306a36Sopenharmony_ci	if (max_objects > MAX_OBJS_PER_PAGE)
131962306a36Sopenharmony_ci		max_objects = MAX_OBJS_PER_PAGE;
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	if (slab->objects != max_objects) {
132262306a36Sopenharmony_ci		slab_err(s, slab, "Wrong number of objects. Found %d but should be %d",
132362306a36Sopenharmony_ci			 slab->objects, max_objects);
132462306a36Sopenharmony_ci		slab->objects = max_objects;
132562306a36Sopenharmony_ci		slab_fix(s, "Number of objects adjusted");
132662306a36Sopenharmony_ci	}
132762306a36Sopenharmony_ci	if (slab->inuse != slab->objects - nr) {
132862306a36Sopenharmony_ci		slab_err(s, slab, "Wrong object count. Counter is %d but counted were %d",
132962306a36Sopenharmony_ci			 slab->inuse, slab->objects - nr);
133062306a36Sopenharmony_ci		slab->inuse = slab->objects - nr;
133162306a36Sopenharmony_ci		slab_fix(s, "Object count adjusted");
133262306a36Sopenharmony_ci	}
133362306a36Sopenharmony_ci	return search == NULL;
133462306a36Sopenharmony_ci}
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_cistatic void trace(struct kmem_cache *s, struct slab *slab, void *object,
133762306a36Sopenharmony_ci								int alloc)
133862306a36Sopenharmony_ci{
133962306a36Sopenharmony_ci	if (s->flags & SLAB_TRACE) {
134062306a36Sopenharmony_ci		pr_info("TRACE %s %s 0x%p inuse=%d fp=0x%p\n",
134162306a36Sopenharmony_ci			s->name,
134262306a36Sopenharmony_ci			alloc ? "alloc" : "free",
134362306a36Sopenharmony_ci			object, slab->inuse,
134462306a36Sopenharmony_ci			slab->freelist);
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci		if (!alloc)
134762306a36Sopenharmony_ci			print_section(KERN_INFO, "Object ", (void *)object,
134862306a36Sopenharmony_ci					s->object_size);
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci		dump_stack();
135162306a36Sopenharmony_ci	}
135262306a36Sopenharmony_ci}
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci/*
135562306a36Sopenharmony_ci * Tracking of fully allocated slabs for debugging purposes.
135662306a36Sopenharmony_ci */
135762306a36Sopenharmony_cistatic void add_full(struct kmem_cache *s,
135862306a36Sopenharmony_ci	struct kmem_cache_node *n, struct slab *slab)
135962306a36Sopenharmony_ci{
136062306a36Sopenharmony_ci	if (!(s->flags & SLAB_STORE_USER))
136162306a36Sopenharmony_ci		return;
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	lockdep_assert_held(&n->list_lock);
136462306a36Sopenharmony_ci	list_add(&slab->slab_list, &n->full);
136562306a36Sopenharmony_ci}
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_cistatic void remove_full(struct kmem_cache *s, struct kmem_cache_node *n, struct slab *slab)
136862306a36Sopenharmony_ci{
136962306a36Sopenharmony_ci	if (!(s->flags & SLAB_STORE_USER))
137062306a36Sopenharmony_ci		return;
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_ci	lockdep_assert_held(&n->list_lock);
137362306a36Sopenharmony_ci	list_del(&slab->slab_list);
137462306a36Sopenharmony_ci}
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_cistatic inline unsigned long node_nr_slabs(struct kmem_cache_node *n)
137762306a36Sopenharmony_ci{
137862306a36Sopenharmony_ci	return atomic_long_read(&n->nr_slabs);
137962306a36Sopenharmony_ci}
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_cistatic inline void inc_slabs_node(struct kmem_cache *s, int node, int objects)
138262306a36Sopenharmony_ci{
138362306a36Sopenharmony_ci	struct kmem_cache_node *n = get_node(s, node);
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	/*
138662306a36Sopenharmony_ci	 * May be called early in order to allocate a slab for the
138762306a36Sopenharmony_ci	 * kmem_cache_node structure. Solve the chicken-egg
138862306a36Sopenharmony_ci	 * dilemma by deferring the increment of the count during
138962306a36Sopenharmony_ci	 * bootstrap (see early_kmem_cache_node_alloc).
139062306a36Sopenharmony_ci	 */
139162306a36Sopenharmony_ci	if (likely(n)) {
139262306a36Sopenharmony_ci		atomic_long_inc(&n->nr_slabs);
139362306a36Sopenharmony_ci		atomic_long_add(objects, &n->total_objects);
139462306a36Sopenharmony_ci	}
139562306a36Sopenharmony_ci}
139662306a36Sopenharmony_cistatic inline void dec_slabs_node(struct kmem_cache *s, int node, int objects)
139762306a36Sopenharmony_ci{
139862306a36Sopenharmony_ci	struct kmem_cache_node *n = get_node(s, node);
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci	atomic_long_dec(&n->nr_slabs);
140162306a36Sopenharmony_ci	atomic_long_sub(objects, &n->total_objects);
140262306a36Sopenharmony_ci}
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci/* Object debug checks for alloc/free paths */
140562306a36Sopenharmony_cistatic void setup_object_debug(struct kmem_cache *s, void *object)
140662306a36Sopenharmony_ci{
140762306a36Sopenharmony_ci	if (!kmem_cache_debug_flags(s, SLAB_STORE_USER|SLAB_RED_ZONE|__OBJECT_POISON))
140862306a36Sopenharmony_ci		return;
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	init_object(s, object, SLUB_RED_INACTIVE);
141162306a36Sopenharmony_ci	init_tracking(s, object);
141262306a36Sopenharmony_ci}
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_cistatic
141562306a36Sopenharmony_civoid setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr)
141662306a36Sopenharmony_ci{
141762306a36Sopenharmony_ci	if (!kmem_cache_debug_flags(s, SLAB_POISON))
141862306a36Sopenharmony_ci		return;
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci	metadata_access_enable();
142162306a36Sopenharmony_ci	memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab));
142262306a36Sopenharmony_ci	metadata_access_disable();
142362306a36Sopenharmony_ci}
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_cistatic inline int alloc_consistency_checks(struct kmem_cache *s,
142662306a36Sopenharmony_ci					struct slab *slab, void *object)
142762306a36Sopenharmony_ci{
142862306a36Sopenharmony_ci	if (!check_slab(s, slab))
142962306a36Sopenharmony_ci		return 0;
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ci	if (!check_valid_pointer(s, slab, object)) {
143262306a36Sopenharmony_ci		object_err(s, slab, object, "Freelist Pointer check fails");
143362306a36Sopenharmony_ci		return 0;
143462306a36Sopenharmony_ci	}
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	if (!check_object(s, slab, object, SLUB_RED_INACTIVE))
143762306a36Sopenharmony_ci		return 0;
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_ci	return 1;
144062306a36Sopenharmony_ci}
144162306a36Sopenharmony_ci
144262306a36Sopenharmony_cistatic noinline bool alloc_debug_processing(struct kmem_cache *s,
144362306a36Sopenharmony_ci			struct slab *slab, void *object, int orig_size)
144462306a36Sopenharmony_ci{
144562306a36Sopenharmony_ci	if (s->flags & SLAB_CONSISTENCY_CHECKS) {
144662306a36Sopenharmony_ci		if (!alloc_consistency_checks(s, slab, object))
144762306a36Sopenharmony_ci			goto bad;
144862306a36Sopenharmony_ci	}
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	/* Success. Perform special debug activities for allocs */
145162306a36Sopenharmony_ci	trace(s, slab, object, 1);
145262306a36Sopenharmony_ci	set_orig_size(s, object, orig_size);
145362306a36Sopenharmony_ci	init_object(s, object, SLUB_RED_ACTIVE);
145462306a36Sopenharmony_ci	return true;
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_cibad:
145762306a36Sopenharmony_ci	if (folio_test_slab(slab_folio(slab))) {
145862306a36Sopenharmony_ci		/*
145962306a36Sopenharmony_ci		 * If this is a slab page then lets do the best we can
146062306a36Sopenharmony_ci		 * to avoid issues in the future. Marking all objects
146162306a36Sopenharmony_ci		 * as used avoids touching the remaining objects.
146262306a36Sopenharmony_ci		 */
146362306a36Sopenharmony_ci		slab_fix(s, "Marking all objects used");
146462306a36Sopenharmony_ci		slab->inuse = slab->objects;
146562306a36Sopenharmony_ci		slab->freelist = NULL;
146662306a36Sopenharmony_ci	}
146762306a36Sopenharmony_ci	return false;
146862306a36Sopenharmony_ci}
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_cistatic inline int free_consistency_checks(struct kmem_cache *s,
147162306a36Sopenharmony_ci		struct slab *slab, void *object, unsigned long addr)
147262306a36Sopenharmony_ci{
147362306a36Sopenharmony_ci	if (!check_valid_pointer(s, slab, object)) {
147462306a36Sopenharmony_ci		slab_err(s, slab, "Invalid object pointer 0x%p", object);
147562306a36Sopenharmony_ci		return 0;
147662306a36Sopenharmony_ci	}
147762306a36Sopenharmony_ci
147862306a36Sopenharmony_ci	if (on_freelist(s, slab, object)) {
147962306a36Sopenharmony_ci		object_err(s, slab, object, "Object already free");
148062306a36Sopenharmony_ci		return 0;
148162306a36Sopenharmony_ci	}
148262306a36Sopenharmony_ci
148362306a36Sopenharmony_ci	if (!check_object(s, slab, object, SLUB_RED_ACTIVE))
148462306a36Sopenharmony_ci		return 0;
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci	if (unlikely(s != slab->slab_cache)) {
148762306a36Sopenharmony_ci		if (!folio_test_slab(slab_folio(slab))) {
148862306a36Sopenharmony_ci			slab_err(s, slab, "Attempt to free object(0x%p) outside of slab",
148962306a36Sopenharmony_ci				 object);
149062306a36Sopenharmony_ci		} else if (!slab->slab_cache) {
149162306a36Sopenharmony_ci			pr_err("SLUB <none>: no slab for object 0x%p.\n",
149262306a36Sopenharmony_ci			       object);
149362306a36Sopenharmony_ci			dump_stack();
149462306a36Sopenharmony_ci		} else
149562306a36Sopenharmony_ci			object_err(s, slab, object,
149662306a36Sopenharmony_ci					"page slab pointer corrupt.");
149762306a36Sopenharmony_ci		return 0;
149862306a36Sopenharmony_ci	}
149962306a36Sopenharmony_ci	return 1;
150062306a36Sopenharmony_ci}
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci/*
150362306a36Sopenharmony_ci * Parse a block of slub_debug options. Blocks are delimited by ';'
150462306a36Sopenharmony_ci *
150562306a36Sopenharmony_ci * @str:    start of block
150662306a36Sopenharmony_ci * @flags:  returns parsed flags, or DEBUG_DEFAULT_FLAGS if none specified
150762306a36Sopenharmony_ci * @slabs:  return start of list of slabs, or NULL when there's no list
150862306a36Sopenharmony_ci * @init:   assume this is initial parsing and not per-kmem-create parsing
150962306a36Sopenharmony_ci *
151062306a36Sopenharmony_ci * returns the start of next block if there's any, or NULL
151162306a36Sopenharmony_ci */
151262306a36Sopenharmony_cistatic char *
151362306a36Sopenharmony_ciparse_slub_debug_flags(char *str, slab_flags_t *flags, char **slabs, bool init)
151462306a36Sopenharmony_ci{
151562306a36Sopenharmony_ci	bool higher_order_disable = false;
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_ci	/* Skip any completely empty blocks */
151862306a36Sopenharmony_ci	while (*str && *str == ';')
151962306a36Sopenharmony_ci		str++;
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_ci	if (*str == ',') {
152262306a36Sopenharmony_ci		/*
152362306a36Sopenharmony_ci		 * No options but restriction on slabs. This means full
152462306a36Sopenharmony_ci		 * debugging for slabs matching a pattern.
152562306a36Sopenharmony_ci		 */
152662306a36Sopenharmony_ci		*flags = DEBUG_DEFAULT_FLAGS;
152762306a36Sopenharmony_ci		goto check_slabs;
152862306a36Sopenharmony_ci	}
152962306a36Sopenharmony_ci	*flags = 0;
153062306a36Sopenharmony_ci
153162306a36Sopenharmony_ci	/* Determine which debug features should be switched on */
153262306a36Sopenharmony_ci	for (; *str && *str != ',' && *str != ';'; str++) {
153362306a36Sopenharmony_ci		switch (tolower(*str)) {
153462306a36Sopenharmony_ci		case '-':
153562306a36Sopenharmony_ci			*flags = 0;
153662306a36Sopenharmony_ci			break;
153762306a36Sopenharmony_ci		case 'f':
153862306a36Sopenharmony_ci			*flags |= SLAB_CONSISTENCY_CHECKS;
153962306a36Sopenharmony_ci			break;
154062306a36Sopenharmony_ci		case 'z':
154162306a36Sopenharmony_ci			*flags |= SLAB_RED_ZONE;
154262306a36Sopenharmony_ci			break;
154362306a36Sopenharmony_ci		case 'p':
154462306a36Sopenharmony_ci			*flags |= SLAB_POISON;
154562306a36Sopenharmony_ci			break;
154662306a36Sopenharmony_ci		case 'u':
154762306a36Sopenharmony_ci			*flags |= SLAB_STORE_USER;
154862306a36Sopenharmony_ci			break;
154962306a36Sopenharmony_ci		case 't':
155062306a36Sopenharmony_ci			*flags |= SLAB_TRACE;
155162306a36Sopenharmony_ci			break;
155262306a36Sopenharmony_ci		case 'a':
155362306a36Sopenharmony_ci			*flags |= SLAB_FAILSLAB;
155462306a36Sopenharmony_ci			break;
155562306a36Sopenharmony_ci		case 'o':
155662306a36Sopenharmony_ci			/*
155762306a36Sopenharmony_ci			 * Avoid enabling debugging on caches if its minimum
155862306a36Sopenharmony_ci			 * order would increase as a result.
155962306a36Sopenharmony_ci			 */
156062306a36Sopenharmony_ci			higher_order_disable = true;
156162306a36Sopenharmony_ci			break;
156262306a36Sopenharmony_ci		default:
156362306a36Sopenharmony_ci			if (init)
156462306a36Sopenharmony_ci				pr_err("slub_debug option '%c' unknown. skipped\n", *str);
156562306a36Sopenharmony_ci		}
156662306a36Sopenharmony_ci	}
156762306a36Sopenharmony_cicheck_slabs:
156862306a36Sopenharmony_ci	if (*str == ',')
156962306a36Sopenharmony_ci		*slabs = ++str;
157062306a36Sopenharmony_ci	else
157162306a36Sopenharmony_ci		*slabs = NULL;
157262306a36Sopenharmony_ci
157362306a36Sopenharmony_ci	/* Skip over the slab list */
157462306a36Sopenharmony_ci	while (*str && *str != ';')
157562306a36Sopenharmony_ci		str++;
157662306a36Sopenharmony_ci
157762306a36Sopenharmony_ci	/* Skip any completely empty blocks */
157862306a36Sopenharmony_ci	while (*str && *str == ';')
157962306a36Sopenharmony_ci		str++;
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_ci	if (init && higher_order_disable)
158262306a36Sopenharmony_ci		disable_higher_order_debug = 1;
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	if (*str)
158562306a36Sopenharmony_ci		return str;
158662306a36Sopenharmony_ci	else
158762306a36Sopenharmony_ci		return NULL;
158862306a36Sopenharmony_ci}
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_cistatic int __init setup_slub_debug(char *str)
159162306a36Sopenharmony_ci{
159262306a36Sopenharmony_ci	slab_flags_t flags;
159362306a36Sopenharmony_ci	slab_flags_t global_flags;
159462306a36Sopenharmony_ci	char *saved_str;
159562306a36Sopenharmony_ci	char *slab_list;
159662306a36Sopenharmony_ci	bool global_slub_debug_changed = false;
159762306a36Sopenharmony_ci	bool slab_list_specified = false;
159862306a36Sopenharmony_ci
159962306a36Sopenharmony_ci	global_flags = DEBUG_DEFAULT_FLAGS;
160062306a36Sopenharmony_ci	if (*str++ != '=' || !*str)
160162306a36Sopenharmony_ci		/*
160262306a36Sopenharmony_ci		 * No options specified. Switch on full debugging.
160362306a36Sopenharmony_ci		 */
160462306a36Sopenharmony_ci		goto out;
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_ci	saved_str = str;
160762306a36Sopenharmony_ci	while (str) {
160862306a36Sopenharmony_ci		str = parse_slub_debug_flags(str, &flags, &slab_list, true);
160962306a36Sopenharmony_ci
161062306a36Sopenharmony_ci		if (!slab_list) {
161162306a36Sopenharmony_ci			global_flags = flags;
161262306a36Sopenharmony_ci			global_slub_debug_changed = true;
161362306a36Sopenharmony_ci		} else {
161462306a36Sopenharmony_ci			slab_list_specified = true;
161562306a36Sopenharmony_ci			if (flags & SLAB_STORE_USER)
161662306a36Sopenharmony_ci				stack_depot_request_early_init();
161762306a36Sopenharmony_ci		}
161862306a36Sopenharmony_ci	}
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci	/*
162162306a36Sopenharmony_ci	 * For backwards compatibility, a single list of flags with list of
162262306a36Sopenharmony_ci	 * slabs means debugging is only changed for those slabs, so the global
162362306a36Sopenharmony_ci	 * slub_debug should be unchanged (0 or DEBUG_DEFAULT_FLAGS, depending
162462306a36Sopenharmony_ci	 * on CONFIG_SLUB_DEBUG_ON). We can extended that to multiple lists as
162562306a36Sopenharmony_ci	 * long as there is no option specifying flags without a slab list.
162662306a36Sopenharmony_ci	 */
162762306a36Sopenharmony_ci	if (slab_list_specified) {
162862306a36Sopenharmony_ci		if (!global_slub_debug_changed)
162962306a36Sopenharmony_ci			global_flags = slub_debug;
163062306a36Sopenharmony_ci		slub_debug_string = saved_str;
163162306a36Sopenharmony_ci	}
163262306a36Sopenharmony_ciout:
163362306a36Sopenharmony_ci	slub_debug = global_flags;
163462306a36Sopenharmony_ci	if (slub_debug & SLAB_STORE_USER)
163562306a36Sopenharmony_ci		stack_depot_request_early_init();
163662306a36Sopenharmony_ci	if (slub_debug != 0 || slub_debug_string)
163762306a36Sopenharmony_ci		static_branch_enable(&slub_debug_enabled);
163862306a36Sopenharmony_ci	else
163962306a36Sopenharmony_ci		static_branch_disable(&slub_debug_enabled);
164062306a36Sopenharmony_ci	if ((static_branch_unlikely(&init_on_alloc) ||
164162306a36Sopenharmony_ci	     static_branch_unlikely(&init_on_free)) &&
164262306a36Sopenharmony_ci	    (slub_debug & SLAB_POISON))
164362306a36Sopenharmony_ci		pr_info("mem auto-init: SLAB_POISON will take precedence over init_on_alloc/init_on_free\n");
164462306a36Sopenharmony_ci	return 1;
164562306a36Sopenharmony_ci}
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_ci__setup("slub_debug", setup_slub_debug);
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci/*
165062306a36Sopenharmony_ci * kmem_cache_flags - apply debugging options to the cache
165162306a36Sopenharmony_ci * @object_size:	the size of an object without meta data
165262306a36Sopenharmony_ci * @flags:		flags to set
165362306a36Sopenharmony_ci * @name:		name of the cache
165462306a36Sopenharmony_ci *
165562306a36Sopenharmony_ci * Debug option(s) are applied to @flags. In addition to the debug
165662306a36Sopenharmony_ci * option(s), if a slab name (or multiple) is specified i.e.
165762306a36Sopenharmony_ci * slub_debug=<Debug-Options>,<slab name1>,<slab name2> ...
165862306a36Sopenharmony_ci * then only the select slabs will receive the debug option(s).
165962306a36Sopenharmony_ci */
166062306a36Sopenharmony_cislab_flags_t kmem_cache_flags(unsigned int object_size,
166162306a36Sopenharmony_ci	slab_flags_t flags, const char *name)
166262306a36Sopenharmony_ci{
166362306a36Sopenharmony_ci	char *iter;
166462306a36Sopenharmony_ci	size_t len;
166562306a36Sopenharmony_ci	char *next_block;
166662306a36Sopenharmony_ci	slab_flags_t block_flags;
166762306a36Sopenharmony_ci	slab_flags_t slub_debug_local = slub_debug;
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	if (flags & SLAB_NO_USER_FLAGS)
167062306a36Sopenharmony_ci		return flags;
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_ci	/*
167362306a36Sopenharmony_ci	 * If the slab cache is for debugging (e.g. kmemleak) then
167462306a36Sopenharmony_ci	 * don't store user (stack trace) information by default,
167562306a36Sopenharmony_ci	 * but let the user enable it via the command line below.
167662306a36Sopenharmony_ci	 */
167762306a36Sopenharmony_ci	if (flags & SLAB_NOLEAKTRACE)
167862306a36Sopenharmony_ci		slub_debug_local &= ~SLAB_STORE_USER;
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	len = strlen(name);
168162306a36Sopenharmony_ci	next_block = slub_debug_string;
168262306a36Sopenharmony_ci	/* Go through all blocks of debug options, see if any matches our slab's name */
168362306a36Sopenharmony_ci	while (next_block) {
168462306a36Sopenharmony_ci		next_block = parse_slub_debug_flags(next_block, &block_flags, &iter, false);
168562306a36Sopenharmony_ci		if (!iter)
168662306a36Sopenharmony_ci			continue;
168762306a36Sopenharmony_ci		/* Found a block that has a slab list, search it */
168862306a36Sopenharmony_ci		while (*iter) {
168962306a36Sopenharmony_ci			char *end, *glob;
169062306a36Sopenharmony_ci			size_t cmplen;
169162306a36Sopenharmony_ci
169262306a36Sopenharmony_ci			end = strchrnul(iter, ',');
169362306a36Sopenharmony_ci			if (next_block && next_block < end)
169462306a36Sopenharmony_ci				end = next_block - 1;
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_ci			glob = strnchr(iter, end - iter, '*');
169762306a36Sopenharmony_ci			if (glob)
169862306a36Sopenharmony_ci				cmplen = glob - iter;
169962306a36Sopenharmony_ci			else
170062306a36Sopenharmony_ci				cmplen = max_t(size_t, len, (end - iter));
170162306a36Sopenharmony_ci
170262306a36Sopenharmony_ci			if (!strncmp(name, iter, cmplen)) {
170362306a36Sopenharmony_ci				flags |= block_flags;
170462306a36Sopenharmony_ci				return flags;
170562306a36Sopenharmony_ci			}
170662306a36Sopenharmony_ci
170762306a36Sopenharmony_ci			if (!*end || *end == ';')
170862306a36Sopenharmony_ci				break;
170962306a36Sopenharmony_ci			iter = end + 1;
171062306a36Sopenharmony_ci		}
171162306a36Sopenharmony_ci	}
171262306a36Sopenharmony_ci
171362306a36Sopenharmony_ci	return flags | slub_debug_local;
171462306a36Sopenharmony_ci}
171562306a36Sopenharmony_ci#else /* !CONFIG_SLUB_DEBUG */
171662306a36Sopenharmony_cistatic inline void setup_object_debug(struct kmem_cache *s, void *object) {}
171762306a36Sopenharmony_cistatic inline
171862306a36Sopenharmony_civoid setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr) {}
171962306a36Sopenharmony_ci
172062306a36Sopenharmony_cistatic inline bool alloc_debug_processing(struct kmem_cache *s,
172162306a36Sopenharmony_ci	struct slab *slab, void *object, int orig_size) { return true; }
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_cistatic inline bool free_debug_processing(struct kmem_cache *s,
172462306a36Sopenharmony_ci	struct slab *slab, void *head, void *tail, int *bulk_cnt,
172562306a36Sopenharmony_ci	unsigned long addr, depot_stack_handle_t handle) { return true; }
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_cistatic inline void slab_pad_check(struct kmem_cache *s, struct slab *slab) {}
172862306a36Sopenharmony_cistatic inline int check_object(struct kmem_cache *s, struct slab *slab,
172962306a36Sopenharmony_ci			void *object, u8 val) { return 1; }
173062306a36Sopenharmony_cistatic inline depot_stack_handle_t set_track_prepare(void) { return 0; }
173162306a36Sopenharmony_cistatic inline void set_track(struct kmem_cache *s, void *object,
173262306a36Sopenharmony_ci			     enum track_item alloc, unsigned long addr) {}
173362306a36Sopenharmony_cistatic inline void add_full(struct kmem_cache *s, struct kmem_cache_node *n,
173462306a36Sopenharmony_ci					struct slab *slab) {}
173562306a36Sopenharmony_cistatic inline void remove_full(struct kmem_cache *s, struct kmem_cache_node *n,
173662306a36Sopenharmony_ci					struct slab *slab) {}
173762306a36Sopenharmony_cislab_flags_t kmem_cache_flags(unsigned int object_size,
173862306a36Sopenharmony_ci	slab_flags_t flags, const char *name)
173962306a36Sopenharmony_ci{
174062306a36Sopenharmony_ci	return flags;
174162306a36Sopenharmony_ci}
174262306a36Sopenharmony_ci#define slub_debug 0
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci#define disable_higher_order_debug 0
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_cistatic inline unsigned long node_nr_slabs(struct kmem_cache_node *n)
174762306a36Sopenharmony_ci							{ return 0; }
174862306a36Sopenharmony_cistatic inline void inc_slabs_node(struct kmem_cache *s, int node,
174962306a36Sopenharmony_ci							int objects) {}
175062306a36Sopenharmony_cistatic inline void dec_slabs_node(struct kmem_cache *s, int node,
175162306a36Sopenharmony_ci							int objects) {}
175262306a36Sopenharmony_ci
175362306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
175462306a36Sopenharmony_cistatic bool freelist_corrupted(struct kmem_cache *s, struct slab *slab,
175562306a36Sopenharmony_ci			       void **freelist, void *nextfree)
175662306a36Sopenharmony_ci{
175762306a36Sopenharmony_ci	return false;
175862306a36Sopenharmony_ci}
175962306a36Sopenharmony_ci#endif
176062306a36Sopenharmony_ci#endif /* CONFIG_SLUB_DEBUG */
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci/*
176362306a36Sopenharmony_ci * Hooks for other subsystems that check memory allocations. In a typical
176462306a36Sopenharmony_ci * production configuration these hooks all should produce no code at all.
176562306a36Sopenharmony_ci */
176662306a36Sopenharmony_cistatic __always_inline bool slab_free_hook(struct kmem_cache *s,
176762306a36Sopenharmony_ci						void *x, bool init)
176862306a36Sopenharmony_ci{
176962306a36Sopenharmony_ci	kmemleak_free_recursive(x, s->flags);
177062306a36Sopenharmony_ci	kmsan_slab_free(s, x);
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci	debug_check_no_locks_freed(x, s->object_size);
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci	if (!(s->flags & SLAB_DEBUG_OBJECTS))
177562306a36Sopenharmony_ci		debug_check_no_obj_freed(x, s->object_size);
177662306a36Sopenharmony_ci
177762306a36Sopenharmony_ci	/* Use KCSAN to help debug racy use-after-free. */
177862306a36Sopenharmony_ci	if (!(s->flags & SLAB_TYPESAFE_BY_RCU))
177962306a36Sopenharmony_ci		__kcsan_check_access(x, s->object_size,
178062306a36Sopenharmony_ci				     KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT);
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci	/*
178362306a36Sopenharmony_ci	 * As memory initialization might be integrated into KASAN,
178462306a36Sopenharmony_ci	 * kasan_slab_free and initialization memset's must be
178562306a36Sopenharmony_ci	 * kept together to avoid discrepancies in behavior.
178662306a36Sopenharmony_ci	 *
178762306a36Sopenharmony_ci	 * The initialization memset's clear the object and the metadata,
178862306a36Sopenharmony_ci	 * but don't touch the SLAB redzone.
178962306a36Sopenharmony_ci	 */
179062306a36Sopenharmony_ci	if (init) {
179162306a36Sopenharmony_ci		int rsize;
179262306a36Sopenharmony_ci
179362306a36Sopenharmony_ci		if (!kasan_has_integrated_init())
179462306a36Sopenharmony_ci			memset(kasan_reset_tag(x), 0, s->object_size);
179562306a36Sopenharmony_ci		rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad : 0;
179662306a36Sopenharmony_ci		memset((char *)kasan_reset_tag(x) + s->inuse, 0,
179762306a36Sopenharmony_ci		       s->size - s->inuse - rsize);
179862306a36Sopenharmony_ci	}
179962306a36Sopenharmony_ci	/* KASAN might put x into memory quarantine, delaying its reuse. */
180062306a36Sopenharmony_ci	return kasan_slab_free(s, x, init);
180162306a36Sopenharmony_ci}
180262306a36Sopenharmony_ci
180362306a36Sopenharmony_cistatic inline bool slab_free_freelist_hook(struct kmem_cache *s,
180462306a36Sopenharmony_ci					   void **head, void **tail,
180562306a36Sopenharmony_ci					   int *cnt)
180662306a36Sopenharmony_ci{
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_ci	void *object;
180962306a36Sopenharmony_ci	void *next = *head;
181062306a36Sopenharmony_ci	void *old_tail = *tail ? *tail : *head;
181162306a36Sopenharmony_ci
181262306a36Sopenharmony_ci	if (is_kfence_address(next)) {
181362306a36Sopenharmony_ci		slab_free_hook(s, next, false);
181462306a36Sopenharmony_ci		return true;
181562306a36Sopenharmony_ci	}
181662306a36Sopenharmony_ci
181762306a36Sopenharmony_ci	/* Head and tail of the reconstructed freelist */
181862306a36Sopenharmony_ci	*head = NULL;
181962306a36Sopenharmony_ci	*tail = NULL;
182062306a36Sopenharmony_ci
182162306a36Sopenharmony_ci	do {
182262306a36Sopenharmony_ci		object = next;
182362306a36Sopenharmony_ci		next = get_freepointer(s, object);
182462306a36Sopenharmony_ci
182562306a36Sopenharmony_ci		/* If object's reuse doesn't have to be delayed */
182662306a36Sopenharmony_ci		if (!slab_free_hook(s, object, slab_want_init_on_free(s))) {
182762306a36Sopenharmony_ci			/* Move object to the new freelist */
182862306a36Sopenharmony_ci			set_freepointer(s, object, *head);
182962306a36Sopenharmony_ci			*head = object;
183062306a36Sopenharmony_ci			if (!*tail)
183162306a36Sopenharmony_ci				*tail = object;
183262306a36Sopenharmony_ci		} else {
183362306a36Sopenharmony_ci			/*
183462306a36Sopenharmony_ci			 * Adjust the reconstructed freelist depth
183562306a36Sopenharmony_ci			 * accordingly if object's reuse is delayed.
183662306a36Sopenharmony_ci			 */
183762306a36Sopenharmony_ci			--(*cnt);
183862306a36Sopenharmony_ci		}
183962306a36Sopenharmony_ci	} while (object != old_tail);
184062306a36Sopenharmony_ci
184162306a36Sopenharmony_ci	if (*head == *tail)
184262306a36Sopenharmony_ci		*tail = NULL;
184362306a36Sopenharmony_ci
184462306a36Sopenharmony_ci	return *head != NULL;
184562306a36Sopenharmony_ci}
184662306a36Sopenharmony_ci
184762306a36Sopenharmony_cistatic void *setup_object(struct kmem_cache *s, void *object)
184862306a36Sopenharmony_ci{
184962306a36Sopenharmony_ci	setup_object_debug(s, object);
185062306a36Sopenharmony_ci	object = kasan_init_slab_obj(s, object);
185162306a36Sopenharmony_ci	if (unlikely(s->ctor)) {
185262306a36Sopenharmony_ci		kasan_unpoison_object_data(s, object);
185362306a36Sopenharmony_ci		s->ctor(object);
185462306a36Sopenharmony_ci		kasan_poison_object_data(s, object);
185562306a36Sopenharmony_ci	}
185662306a36Sopenharmony_ci	return object;
185762306a36Sopenharmony_ci}
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci/*
186062306a36Sopenharmony_ci * Slab allocation and freeing
186162306a36Sopenharmony_ci */
186262306a36Sopenharmony_cistatic inline struct slab *alloc_slab_page(gfp_t flags, int node,
186362306a36Sopenharmony_ci		struct kmem_cache_order_objects oo)
186462306a36Sopenharmony_ci{
186562306a36Sopenharmony_ci	struct folio *folio;
186662306a36Sopenharmony_ci	struct slab *slab;
186762306a36Sopenharmony_ci	unsigned int order = oo_order(oo);
186862306a36Sopenharmony_ci
186962306a36Sopenharmony_ci	if (node == NUMA_NO_NODE)
187062306a36Sopenharmony_ci		folio = (struct folio *)alloc_pages(flags, order);
187162306a36Sopenharmony_ci	else
187262306a36Sopenharmony_ci		folio = (struct folio *)__alloc_pages_node(node, flags, order);
187362306a36Sopenharmony_ci
187462306a36Sopenharmony_ci	if (!folio)
187562306a36Sopenharmony_ci		return NULL;
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_ci	slab = folio_slab(folio);
187862306a36Sopenharmony_ci	__folio_set_slab(folio);
187962306a36Sopenharmony_ci	/* Make the flag visible before any changes to folio->mapping */
188062306a36Sopenharmony_ci	smp_wmb();
188162306a36Sopenharmony_ci	if (folio_is_pfmemalloc(folio))
188262306a36Sopenharmony_ci		slab_set_pfmemalloc(slab);
188362306a36Sopenharmony_ci
188462306a36Sopenharmony_ci	return slab;
188562306a36Sopenharmony_ci}
188662306a36Sopenharmony_ci
188762306a36Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_RANDOM
188862306a36Sopenharmony_ci/* Pre-initialize the random sequence cache */
188962306a36Sopenharmony_cistatic int init_cache_random_seq(struct kmem_cache *s)
189062306a36Sopenharmony_ci{
189162306a36Sopenharmony_ci	unsigned int count = oo_objects(s->oo);
189262306a36Sopenharmony_ci	int err;
189362306a36Sopenharmony_ci
189462306a36Sopenharmony_ci	/* Bailout if already initialised */
189562306a36Sopenharmony_ci	if (s->random_seq)
189662306a36Sopenharmony_ci		return 0;
189762306a36Sopenharmony_ci
189862306a36Sopenharmony_ci	err = cache_random_seq_create(s, count, GFP_KERNEL);
189962306a36Sopenharmony_ci	if (err) {
190062306a36Sopenharmony_ci		pr_err("SLUB: Unable to initialize free list for %s\n",
190162306a36Sopenharmony_ci			s->name);
190262306a36Sopenharmony_ci		return err;
190362306a36Sopenharmony_ci	}
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci	/* Transform to an offset on the set of pages */
190662306a36Sopenharmony_ci	if (s->random_seq) {
190762306a36Sopenharmony_ci		unsigned int i;
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_ci		for (i = 0; i < count; i++)
191062306a36Sopenharmony_ci			s->random_seq[i] *= s->size;
191162306a36Sopenharmony_ci	}
191262306a36Sopenharmony_ci	return 0;
191362306a36Sopenharmony_ci}
191462306a36Sopenharmony_ci
191562306a36Sopenharmony_ci/* Initialize each random sequence freelist per cache */
191662306a36Sopenharmony_cistatic void __init init_freelist_randomization(void)
191762306a36Sopenharmony_ci{
191862306a36Sopenharmony_ci	struct kmem_cache *s;
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_ci	mutex_lock(&slab_mutex);
192162306a36Sopenharmony_ci
192262306a36Sopenharmony_ci	list_for_each_entry(s, &slab_caches, list)
192362306a36Sopenharmony_ci		init_cache_random_seq(s);
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci	mutex_unlock(&slab_mutex);
192662306a36Sopenharmony_ci}
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci/* Get the next entry on the pre-computed freelist randomized */
192962306a36Sopenharmony_cistatic void *next_freelist_entry(struct kmem_cache *s, struct slab *slab,
193062306a36Sopenharmony_ci				unsigned long *pos, void *start,
193162306a36Sopenharmony_ci				unsigned long page_limit,
193262306a36Sopenharmony_ci				unsigned long freelist_count)
193362306a36Sopenharmony_ci{
193462306a36Sopenharmony_ci	unsigned int idx;
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_ci	/*
193762306a36Sopenharmony_ci	 * If the target page allocation failed, the number of objects on the
193862306a36Sopenharmony_ci	 * page might be smaller than the usual size defined by the cache.
193962306a36Sopenharmony_ci	 */
194062306a36Sopenharmony_ci	do {
194162306a36Sopenharmony_ci		idx = s->random_seq[*pos];
194262306a36Sopenharmony_ci		*pos += 1;
194362306a36Sopenharmony_ci		if (*pos >= freelist_count)
194462306a36Sopenharmony_ci			*pos = 0;
194562306a36Sopenharmony_ci	} while (unlikely(idx >= page_limit));
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_ci	return (char *)start + idx;
194862306a36Sopenharmony_ci}
194962306a36Sopenharmony_ci
195062306a36Sopenharmony_ci/* Shuffle the single linked freelist based on a random pre-computed sequence */
195162306a36Sopenharmony_cistatic bool shuffle_freelist(struct kmem_cache *s, struct slab *slab)
195262306a36Sopenharmony_ci{
195362306a36Sopenharmony_ci	void *start;
195462306a36Sopenharmony_ci	void *cur;
195562306a36Sopenharmony_ci	void *next;
195662306a36Sopenharmony_ci	unsigned long idx, pos, page_limit, freelist_count;
195762306a36Sopenharmony_ci
195862306a36Sopenharmony_ci	if (slab->objects < 2 || !s->random_seq)
195962306a36Sopenharmony_ci		return false;
196062306a36Sopenharmony_ci
196162306a36Sopenharmony_ci	freelist_count = oo_objects(s->oo);
196262306a36Sopenharmony_ci	pos = get_random_u32_below(freelist_count);
196362306a36Sopenharmony_ci
196462306a36Sopenharmony_ci	page_limit = slab->objects * s->size;
196562306a36Sopenharmony_ci	start = fixup_red_left(s, slab_address(slab));
196662306a36Sopenharmony_ci
196762306a36Sopenharmony_ci	/* First entry is used as the base of the freelist */
196862306a36Sopenharmony_ci	cur = next_freelist_entry(s, slab, &pos, start, page_limit,
196962306a36Sopenharmony_ci				freelist_count);
197062306a36Sopenharmony_ci	cur = setup_object(s, cur);
197162306a36Sopenharmony_ci	slab->freelist = cur;
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_ci	for (idx = 1; idx < slab->objects; idx++) {
197462306a36Sopenharmony_ci		next = next_freelist_entry(s, slab, &pos, start, page_limit,
197562306a36Sopenharmony_ci			freelist_count);
197662306a36Sopenharmony_ci		next = setup_object(s, next);
197762306a36Sopenharmony_ci		set_freepointer(s, cur, next);
197862306a36Sopenharmony_ci		cur = next;
197962306a36Sopenharmony_ci	}
198062306a36Sopenharmony_ci	set_freepointer(s, cur, NULL);
198162306a36Sopenharmony_ci
198262306a36Sopenharmony_ci	return true;
198362306a36Sopenharmony_ci}
198462306a36Sopenharmony_ci#else
198562306a36Sopenharmony_cistatic inline int init_cache_random_seq(struct kmem_cache *s)
198662306a36Sopenharmony_ci{
198762306a36Sopenharmony_ci	return 0;
198862306a36Sopenharmony_ci}
198962306a36Sopenharmony_cistatic inline void init_freelist_randomization(void) { }
199062306a36Sopenharmony_cistatic inline bool shuffle_freelist(struct kmem_cache *s, struct slab *slab)
199162306a36Sopenharmony_ci{
199262306a36Sopenharmony_ci	return false;
199362306a36Sopenharmony_ci}
199462306a36Sopenharmony_ci#endif /* CONFIG_SLAB_FREELIST_RANDOM */
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_cistatic struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
199762306a36Sopenharmony_ci{
199862306a36Sopenharmony_ci	struct slab *slab;
199962306a36Sopenharmony_ci	struct kmem_cache_order_objects oo = s->oo;
200062306a36Sopenharmony_ci	gfp_t alloc_gfp;
200162306a36Sopenharmony_ci	void *start, *p, *next;
200262306a36Sopenharmony_ci	int idx;
200362306a36Sopenharmony_ci	bool shuffle;
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	flags &= gfp_allowed_mask;
200662306a36Sopenharmony_ci
200762306a36Sopenharmony_ci	flags |= s->allocflags;
200862306a36Sopenharmony_ci
200962306a36Sopenharmony_ci	/*
201062306a36Sopenharmony_ci	 * Let the initial higher-order allocation fail under memory pressure
201162306a36Sopenharmony_ci	 * so we fall-back to the minimum order allocation.
201262306a36Sopenharmony_ci	 */
201362306a36Sopenharmony_ci	alloc_gfp = (flags | __GFP_NOWARN | __GFP_NORETRY) & ~__GFP_NOFAIL;
201462306a36Sopenharmony_ci	if ((alloc_gfp & __GFP_DIRECT_RECLAIM) && oo_order(oo) > oo_order(s->min))
201562306a36Sopenharmony_ci		alloc_gfp = (alloc_gfp | __GFP_NOMEMALLOC) & ~__GFP_RECLAIM;
201662306a36Sopenharmony_ci
201762306a36Sopenharmony_ci	slab = alloc_slab_page(alloc_gfp, node, oo);
201862306a36Sopenharmony_ci	if (unlikely(!slab)) {
201962306a36Sopenharmony_ci		oo = s->min;
202062306a36Sopenharmony_ci		alloc_gfp = flags;
202162306a36Sopenharmony_ci		/*
202262306a36Sopenharmony_ci		 * Allocation may have failed due to fragmentation.
202362306a36Sopenharmony_ci		 * Try a lower order alloc if possible
202462306a36Sopenharmony_ci		 */
202562306a36Sopenharmony_ci		slab = alloc_slab_page(alloc_gfp, node, oo);
202662306a36Sopenharmony_ci		if (unlikely(!slab))
202762306a36Sopenharmony_ci			return NULL;
202862306a36Sopenharmony_ci		stat(s, ORDER_FALLBACK);
202962306a36Sopenharmony_ci	}
203062306a36Sopenharmony_ci
203162306a36Sopenharmony_ci	slab->objects = oo_objects(oo);
203262306a36Sopenharmony_ci	slab->inuse = 0;
203362306a36Sopenharmony_ci	slab->frozen = 0;
203462306a36Sopenharmony_ci
203562306a36Sopenharmony_ci	account_slab(slab, oo_order(oo), s, flags);
203662306a36Sopenharmony_ci
203762306a36Sopenharmony_ci	slab->slab_cache = s;
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	kasan_poison_slab(slab);
204062306a36Sopenharmony_ci
204162306a36Sopenharmony_ci	start = slab_address(slab);
204262306a36Sopenharmony_ci
204362306a36Sopenharmony_ci	setup_slab_debug(s, slab, start);
204462306a36Sopenharmony_ci
204562306a36Sopenharmony_ci	shuffle = shuffle_freelist(s, slab);
204662306a36Sopenharmony_ci
204762306a36Sopenharmony_ci	if (!shuffle) {
204862306a36Sopenharmony_ci		start = fixup_red_left(s, start);
204962306a36Sopenharmony_ci		start = setup_object(s, start);
205062306a36Sopenharmony_ci		slab->freelist = start;
205162306a36Sopenharmony_ci		for (idx = 0, p = start; idx < slab->objects - 1; idx++) {
205262306a36Sopenharmony_ci			next = p + s->size;
205362306a36Sopenharmony_ci			next = setup_object(s, next);
205462306a36Sopenharmony_ci			set_freepointer(s, p, next);
205562306a36Sopenharmony_ci			p = next;
205662306a36Sopenharmony_ci		}
205762306a36Sopenharmony_ci		set_freepointer(s, p, NULL);
205862306a36Sopenharmony_ci	}
205962306a36Sopenharmony_ci
206062306a36Sopenharmony_ci	return slab;
206162306a36Sopenharmony_ci}
206262306a36Sopenharmony_ci
206362306a36Sopenharmony_cistatic struct slab *new_slab(struct kmem_cache *s, gfp_t flags, int node)
206462306a36Sopenharmony_ci{
206562306a36Sopenharmony_ci	if (unlikely(flags & GFP_SLAB_BUG_MASK))
206662306a36Sopenharmony_ci		flags = kmalloc_fix_flags(flags);
206762306a36Sopenharmony_ci
206862306a36Sopenharmony_ci	WARN_ON_ONCE(s->ctor && (flags & __GFP_ZERO));
206962306a36Sopenharmony_ci
207062306a36Sopenharmony_ci	return allocate_slab(s,
207162306a36Sopenharmony_ci		flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node);
207262306a36Sopenharmony_ci}
207362306a36Sopenharmony_ci
207462306a36Sopenharmony_cistatic void __free_slab(struct kmem_cache *s, struct slab *slab)
207562306a36Sopenharmony_ci{
207662306a36Sopenharmony_ci	struct folio *folio = slab_folio(slab);
207762306a36Sopenharmony_ci	int order = folio_order(folio);
207862306a36Sopenharmony_ci	int pages = 1 << order;
207962306a36Sopenharmony_ci
208062306a36Sopenharmony_ci	__slab_clear_pfmemalloc(slab);
208162306a36Sopenharmony_ci	folio->mapping = NULL;
208262306a36Sopenharmony_ci	/* Make the mapping reset visible before clearing the flag */
208362306a36Sopenharmony_ci	smp_wmb();
208462306a36Sopenharmony_ci	__folio_clear_slab(folio);
208562306a36Sopenharmony_ci	mm_account_reclaimed_pages(pages);
208662306a36Sopenharmony_ci	unaccount_slab(slab, order, s);
208762306a36Sopenharmony_ci	__free_pages(&folio->page, order);
208862306a36Sopenharmony_ci}
208962306a36Sopenharmony_ci
209062306a36Sopenharmony_cistatic void rcu_free_slab(struct rcu_head *h)
209162306a36Sopenharmony_ci{
209262306a36Sopenharmony_ci	struct slab *slab = container_of(h, struct slab, rcu_head);
209362306a36Sopenharmony_ci
209462306a36Sopenharmony_ci	__free_slab(slab->slab_cache, slab);
209562306a36Sopenharmony_ci}
209662306a36Sopenharmony_ci
209762306a36Sopenharmony_cistatic void free_slab(struct kmem_cache *s, struct slab *slab)
209862306a36Sopenharmony_ci{
209962306a36Sopenharmony_ci	if (kmem_cache_debug_flags(s, SLAB_CONSISTENCY_CHECKS)) {
210062306a36Sopenharmony_ci		void *p;
210162306a36Sopenharmony_ci
210262306a36Sopenharmony_ci		slab_pad_check(s, slab);
210362306a36Sopenharmony_ci		for_each_object(p, s, slab_address(slab), slab->objects)
210462306a36Sopenharmony_ci			check_object(s, slab, p, SLUB_RED_INACTIVE);
210562306a36Sopenharmony_ci	}
210662306a36Sopenharmony_ci
210762306a36Sopenharmony_ci	if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU))
210862306a36Sopenharmony_ci		call_rcu(&slab->rcu_head, rcu_free_slab);
210962306a36Sopenharmony_ci	else
211062306a36Sopenharmony_ci		__free_slab(s, slab);
211162306a36Sopenharmony_ci}
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_cistatic void discard_slab(struct kmem_cache *s, struct slab *slab)
211462306a36Sopenharmony_ci{
211562306a36Sopenharmony_ci	dec_slabs_node(s, slab_nid(slab), slab->objects);
211662306a36Sopenharmony_ci	free_slab(s, slab);
211762306a36Sopenharmony_ci}
211862306a36Sopenharmony_ci
211962306a36Sopenharmony_ci/*
212062306a36Sopenharmony_ci * Management of partially allocated slabs.
212162306a36Sopenharmony_ci */
212262306a36Sopenharmony_cistatic inline void
212362306a36Sopenharmony_ci__add_partial(struct kmem_cache_node *n, struct slab *slab, int tail)
212462306a36Sopenharmony_ci{
212562306a36Sopenharmony_ci	n->nr_partial++;
212662306a36Sopenharmony_ci	if (tail == DEACTIVATE_TO_TAIL)
212762306a36Sopenharmony_ci		list_add_tail(&slab->slab_list, &n->partial);
212862306a36Sopenharmony_ci	else
212962306a36Sopenharmony_ci		list_add(&slab->slab_list, &n->partial);
213062306a36Sopenharmony_ci}
213162306a36Sopenharmony_ci
213262306a36Sopenharmony_cistatic inline void add_partial(struct kmem_cache_node *n,
213362306a36Sopenharmony_ci				struct slab *slab, int tail)
213462306a36Sopenharmony_ci{
213562306a36Sopenharmony_ci	lockdep_assert_held(&n->list_lock);
213662306a36Sopenharmony_ci	__add_partial(n, slab, tail);
213762306a36Sopenharmony_ci}
213862306a36Sopenharmony_ci
213962306a36Sopenharmony_cistatic inline void remove_partial(struct kmem_cache_node *n,
214062306a36Sopenharmony_ci					struct slab *slab)
214162306a36Sopenharmony_ci{
214262306a36Sopenharmony_ci	lockdep_assert_held(&n->list_lock);
214362306a36Sopenharmony_ci	list_del(&slab->slab_list);
214462306a36Sopenharmony_ci	n->nr_partial--;
214562306a36Sopenharmony_ci}
214662306a36Sopenharmony_ci
214762306a36Sopenharmony_ci/*
214862306a36Sopenharmony_ci * Called only for kmem_cache_debug() caches instead of acquire_slab(), with a
214962306a36Sopenharmony_ci * slab from the n->partial list. Remove only a single object from the slab, do
215062306a36Sopenharmony_ci * the alloc_debug_processing() checks and leave the slab on the list, or move
215162306a36Sopenharmony_ci * it to full list if it was the last free object.
215262306a36Sopenharmony_ci */
215362306a36Sopenharmony_cistatic void *alloc_single_from_partial(struct kmem_cache *s,
215462306a36Sopenharmony_ci		struct kmem_cache_node *n, struct slab *slab, int orig_size)
215562306a36Sopenharmony_ci{
215662306a36Sopenharmony_ci	void *object;
215762306a36Sopenharmony_ci
215862306a36Sopenharmony_ci	lockdep_assert_held(&n->list_lock);
215962306a36Sopenharmony_ci
216062306a36Sopenharmony_ci	object = slab->freelist;
216162306a36Sopenharmony_ci	slab->freelist = get_freepointer(s, object);
216262306a36Sopenharmony_ci	slab->inuse++;
216362306a36Sopenharmony_ci
216462306a36Sopenharmony_ci	if (!alloc_debug_processing(s, slab, object, orig_size)) {
216562306a36Sopenharmony_ci		remove_partial(n, slab);
216662306a36Sopenharmony_ci		return NULL;
216762306a36Sopenharmony_ci	}
216862306a36Sopenharmony_ci
216962306a36Sopenharmony_ci	if (slab->inuse == slab->objects) {
217062306a36Sopenharmony_ci		remove_partial(n, slab);
217162306a36Sopenharmony_ci		add_full(s, n, slab);
217262306a36Sopenharmony_ci	}
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci	return object;
217562306a36Sopenharmony_ci}
217662306a36Sopenharmony_ci
217762306a36Sopenharmony_ci/*
217862306a36Sopenharmony_ci * Called only for kmem_cache_debug() caches to allocate from a freshly
217962306a36Sopenharmony_ci * allocated slab. Allocate a single object instead of whole freelist
218062306a36Sopenharmony_ci * and put the slab to the partial (or full) list.
218162306a36Sopenharmony_ci */
218262306a36Sopenharmony_cistatic void *alloc_single_from_new_slab(struct kmem_cache *s,
218362306a36Sopenharmony_ci					struct slab *slab, int orig_size)
218462306a36Sopenharmony_ci{
218562306a36Sopenharmony_ci	int nid = slab_nid(slab);
218662306a36Sopenharmony_ci	struct kmem_cache_node *n = get_node(s, nid);
218762306a36Sopenharmony_ci	unsigned long flags;
218862306a36Sopenharmony_ci	void *object;
218962306a36Sopenharmony_ci
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_ci	object = slab->freelist;
219262306a36Sopenharmony_ci	slab->freelist = get_freepointer(s, object);
219362306a36Sopenharmony_ci	slab->inuse = 1;
219462306a36Sopenharmony_ci
219562306a36Sopenharmony_ci	if (!alloc_debug_processing(s, slab, object, orig_size))
219662306a36Sopenharmony_ci		/*
219762306a36Sopenharmony_ci		 * It's not really expected that this would fail on a
219862306a36Sopenharmony_ci		 * freshly allocated slab, but a concurrent memory
219962306a36Sopenharmony_ci		 * corruption in theory could cause that.
220062306a36Sopenharmony_ci		 */
220162306a36Sopenharmony_ci		return NULL;
220262306a36Sopenharmony_ci
220362306a36Sopenharmony_ci	spin_lock_irqsave(&n->list_lock, flags);
220462306a36Sopenharmony_ci
220562306a36Sopenharmony_ci	if (slab->inuse == slab->objects)
220662306a36Sopenharmony_ci		add_full(s, n, slab);
220762306a36Sopenharmony_ci	else
220862306a36Sopenharmony_ci		add_partial(n, slab, DEACTIVATE_TO_HEAD);
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_ci	inc_slabs_node(s, nid, slab->objects);
221162306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	return object;
221462306a36Sopenharmony_ci}
221562306a36Sopenharmony_ci
221662306a36Sopenharmony_ci/*
221762306a36Sopenharmony_ci * Remove slab from the partial list, freeze it and
221862306a36Sopenharmony_ci * return the pointer to the freelist.
221962306a36Sopenharmony_ci *
222062306a36Sopenharmony_ci * Returns a list of objects or NULL if it fails.
222162306a36Sopenharmony_ci */
222262306a36Sopenharmony_cistatic inline void *acquire_slab(struct kmem_cache *s,
222362306a36Sopenharmony_ci		struct kmem_cache_node *n, struct slab *slab,
222462306a36Sopenharmony_ci		int mode)
222562306a36Sopenharmony_ci{
222662306a36Sopenharmony_ci	void *freelist;
222762306a36Sopenharmony_ci	unsigned long counters;
222862306a36Sopenharmony_ci	struct slab new;
222962306a36Sopenharmony_ci
223062306a36Sopenharmony_ci	lockdep_assert_held(&n->list_lock);
223162306a36Sopenharmony_ci
223262306a36Sopenharmony_ci	/*
223362306a36Sopenharmony_ci	 * Zap the freelist and set the frozen bit.
223462306a36Sopenharmony_ci	 * The old freelist is the list of objects for the
223562306a36Sopenharmony_ci	 * per cpu allocation list.
223662306a36Sopenharmony_ci	 */
223762306a36Sopenharmony_ci	freelist = slab->freelist;
223862306a36Sopenharmony_ci	counters = slab->counters;
223962306a36Sopenharmony_ci	new.counters = counters;
224062306a36Sopenharmony_ci	if (mode) {
224162306a36Sopenharmony_ci		new.inuse = slab->objects;
224262306a36Sopenharmony_ci		new.freelist = NULL;
224362306a36Sopenharmony_ci	} else {
224462306a36Sopenharmony_ci		new.freelist = freelist;
224562306a36Sopenharmony_ci	}
224662306a36Sopenharmony_ci
224762306a36Sopenharmony_ci	VM_BUG_ON(new.frozen);
224862306a36Sopenharmony_ci	new.frozen = 1;
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_ci	if (!__slab_update_freelist(s, slab,
225162306a36Sopenharmony_ci			freelist, counters,
225262306a36Sopenharmony_ci			new.freelist, new.counters,
225362306a36Sopenharmony_ci			"acquire_slab"))
225462306a36Sopenharmony_ci		return NULL;
225562306a36Sopenharmony_ci
225662306a36Sopenharmony_ci	remove_partial(n, slab);
225762306a36Sopenharmony_ci	WARN_ON(!freelist);
225862306a36Sopenharmony_ci	return freelist;
225962306a36Sopenharmony_ci}
226062306a36Sopenharmony_ci
226162306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
226262306a36Sopenharmony_cistatic void put_cpu_partial(struct kmem_cache *s, struct slab *slab, int drain);
226362306a36Sopenharmony_ci#else
226462306a36Sopenharmony_cistatic inline void put_cpu_partial(struct kmem_cache *s, struct slab *slab,
226562306a36Sopenharmony_ci				   int drain) { }
226662306a36Sopenharmony_ci#endif
226762306a36Sopenharmony_cistatic inline bool pfmemalloc_match(struct slab *slab, gfp_t gfpflags);
226862306a36Sopenharmony_ci
226962306a36Sopenharmony_ci/*
227062306a36Sopenharmony_ci * Try to allocate a partial slab from a specific node.
227162306a36Sopenharmony_ci */
227262306a36Sopenharmony_cistatic void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
227362306a36Sopenharmony_ci			      struct partial_context *pc)
227462306a36Sopenharmony_ci{
227562306a36Sopenharmony_ci	struct slab *slab, *slab2;
227662306a36Sopenharmony_ci	void *object = NULL;
227762306a36Sopenharmony_ci	unsigned long flags;
227862306a36Sopenharmony_ci	unsigned int partial_slabs = 0;
227962306a36Sopenharmony_ci
228062306a36Sopenharmony_ci	/*
228162306a36Sopenharmony_ci	 * Racy check. If we mistakenly see no partial slabs then we
228262306a36Sopenharmony_ci	 * just allocate an empty slab. If we mistakenly try to get a
228362306a36Sopenharmony_ci	 * partial slab and there is none available then get_partial()
228462306a36Sopenharmony_ci	 * will return NULL.
228562306a36Sopenharmony_ci	 */
228662306a36Sopenharmony_ci	if (!n || !n->nr_partial)
228762306a36Sopenharmony_ci		return NULL;
228862306a36Sopenharmony_ci
228962306a36Sopenharmony_ci	spin_lock_irqsave(&n->list_lock, flags);
229062306a36Sopenharmony_ci	list_for_each_entry_safe(slab, slab2, &n->partial, slab_list) {
229162306a36Sopenharmony_ci		void *t;
229262306a36Sopenharmony_ci
229362306a36Sopenharmony_ci		if (!pfmemalloc_match(slab, pc->flags))
229462306a36Sopenharmony_ci			continue;
229562306a36Sopenharmony_ci
229662306a36Sopenharmony_ci		if (IS_ENABLED(CONFIG_SLUB_TINY) || kmem_cache_debug(s)) {
229762306a36Sopenharmony_ci			object = alloc_single_from_partial(s, n, slab,
229862306a36Sopenharmony_ci							pc->orig_size);
229962306a36Sopenharmony_ci			if (object)
230062306a36Sopenharmony_ci				break;
230162306a36Sopenharmony_ci			continue;
230262306a36Sopenharmony_ci		}
230362306a36Sopenharmony_ci
230462306a36Sopenharmony_ci		t = acquire_slab(s, n, slab, object == NULL);
230562306a36Sopenharmony_ci		if (!t)
230662306a36Sopenharmony_ci			break;
230762306a36Sopenharmony_ci
230862306a36Sopenharmony_ci		if (!object) {
230962306a36Sopenharmony_ci			*pc->slab = slab;
231062306a36Sopenharmony_ci			stat(s, ALLOC_FROM_PARTIAL);
231162306a36Sopenharmony_ci			object = t;
231262306a36Sopenharmony_ci		} else {
231362306a36Sopenharmony_ci			put_cpu_partial(s, slab, 0);
231462306a36Sopenharmony_ci			stat(s, CPU_PARTIAL_NODE);
231562306a36Sopenharmony_ci			partial_slabs++;
231662306a36Sopenharmony_ci		}
231762306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
231862306a36Sopenharmony_ci		if (!kmem_cache_has_cpu_partial(s)
231962306a36Sopenharmony_ci			|| partial_slabs > s->cpu_partial_slabs / 2)
232062306a36Sopenharmony_ci			break;
232162306a36Sopenharmony_ci#else
232262306a36Sopenharmony_ci		break;
232362306a36Sopenharmony_ci#endif
232462306a36Sopenharmony_ci
232562306a36Sopenharmony_ci	}
232662306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
232762306a36Sopenharmony_ci	return object;
232862306a36Sopenharmony_ci}
232962306a36Sopenharmony_ci
233062306a36Sopenharmony_ci/*
233162306a36Sopenharmony_ci * Get a slab from somewhere. Search in increasing NUMA distances.
233262306a36Sopenharmony_ci */
233362306a36Sopenharmony_cistatic void *get_any_partial(struct kmem_cache *s, struct partial_context *pc)
233462306a36Sopenharmony_ci{
233562306a36Sopenharmony_ci#ifdef CONFIG_NUMA
233662306a36Sopenharmony_ci	struct zonelist *zonelist;
233762306a36Sopenharmony_ci	struct zoneref *z;
233862306a36Sopenharmony_ci	struct zone *zone;
233962306a36Sopenharmony_ci	enum zone_type highest_zoneidx = gfp_zone(pc->flags);
234062306a36Sopenharmony_ci	void *object;
234162306a36Sopenharmony_ci	unsigned int cpuset_mems_cookie;
234262306a36Sopenharmony_ci
234362306a36Sopenharmony_ci	/*
234462306a36Sopenharmony_ci	 * The defrag ratio allows a configuration of the tradeoffs between
234562306a36Sopenharmony_ci	 * inter node defragmentation and node local allocations. A lower
234662306a36Sopenharmony_ci	 * defrag_ratio increases the tendency to do local allocations
234762306a36Sopenharmony_ci	 * instead of attempting to obtain partial slabs from other nodes.
234862306a36Sopenharmony_ci	 *
234962306a36Sopenharmony_ci	 * If the defrag_ratio is set to 0 then kmalloc() always
235062306a36Sopenharmony_ci	 * returns node local objects. If the ratio is higher then kmalloc()
235162306a36Sopenharmony_ci	 * may return off node objects because partial slabs are obtained
235262306a36Sopenharmony_ci	 * from other nodes and filled up.
235362306a36Sopenharmony_ci	 *
235462306a36Sopenharmony_ci	 * If /sys/kernel/slab/xx/remote_node_defrag_ratio is set to 100
235562306a36Sopenharmony_ci	 * (which makes defrag_ratio = 1000) then every (well almost)
235662306a36Sopenharmony_ci	 * allocation will first attempt to defrag slab caches on other nodes.
235762306a36Sopenharmony_ci	 * This means scanning over all nodes to look for partial slabs which
235862306a36Sopenharmony_ci	 * may be expensive if we do it every time we are trying to find a slab
235962306a36Sopenharmony_ci	 * with available objects.
236062306a36Sopenharmony_ci	 */
236162306a36Sopenharmony_ci	if (!s->remote_node_defrag_ratio ||
236262306a36Sopenharmony_ci			get_cycles() % 1024 > s->remote_node_defrag_ratio)
236362306a36Sopenharmony_ci		return NULL;
236462306a36Sopenharmony_ci
236562306a36Sopenharmony_ci	do {
236662306a36Sopenharmony_ci		cpuset_mems_cookie = read_mems_allowed_begin();
236762306a36Sopenharmony_ci		zonelist = node_zonelist(mempolicy_slab_node(), pc->flags);
236862306a36Sopenharmony_ci		for_each_zone_zonelist(zone, z, zonelist, highest_zoneidx) {
236962306a36Sopenharmony_ci			struct kmem_cache_node *n;
237062306a36Sopenharmony_ci
237162306a36Sopenharmony_ci			n = get_node(s, zone_to_nid(zone));
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_ci			if (n && cpuset_zone_allowed(zone, pc->flags) &&
237462306a36Sopenharmony_ci					n->nr_partial > s->min_partial) {
237562306a36Sopenharmony_ci				object = get_partial_node(s, n, pc);
237662306a36Sopenharmony_ci				if (object) {
237762306a36Sopenharmony_ci					/*
237862306a36Sopenharmony_ci					 * Don't check read_mems_allowed_retry()
237962306a36Sopenharmony_ci					 * here - if mems_allowed was updated in
238062306a36Sopenharmony_ci					 * parallel, that was a harmless race
238162306a36Sopenharmony_ci					 * between allocation and the cpuset
238262306a36Sopenharmony_ci					 * update
238362306a36Sopenharmony_ci					 */
238462306a36Sopenharmony_ci					return object;
238562306a36Sopenharmony_ci				}
238662306a36Sopenharmony_ci			}
238762306a36Sopenharmony_ci		}
238862306a36Sopenharmony_ci	} while (read_mems_allowed_retry(cpuset_mems_cookie));
238962306a36Sopenharmony_ci#endif	/* CONFIG_NUMA */
239062306a36Sopenharmony_ci	return NULL;
239162306a36Sopenharmony_ci}
239262306a36Sopenharmony_ci
239362306a36Sopenharmony_ci/*
239462306a36Sopenharmony_ci * Get a partial slab, lock it and return it.
239562306a36Sopenharmony_ci */
239662306a36Sopenharmony_cistatic void *get_partial(struct kmem_cache *s, int node, struct partial_context *pc)
239762306a36Sopenharmony_ci{
239862306a36Sopenharmony_ci	void *object;
239962306a36Sopenharmony_ci	int searchnode = node;
240062306a36Sopenharmony_ci
240162306a36Sopenharmony_ci	if (node == NUMA_NO_NODE)
240262306a36Sopenharmony_ci		searchnode = numa_mem_id();
240362306a36Sopenharmony_ci
240462306a36Sopenharmony_ci	object = get_partial_node(s, get_node(s, searchnode), pc);
240562306a36Sopenharmony_ci	if (object || node != NUMA_NO_NODE)
240662306a36Sopenharmony_ci		return object;
240762306a36Sopenharmony_ci
240862306a36Sopenharmony_ci	return get_any_partial(s, pc);
240962306a36Sopenharmony_ci}
241062306a36Sopenharmony_ci
241162306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
241262306a36Sopenharmony_ci
241362306a36Sopenharmony_ci#ifdef CONFIG_PREEMPTION
241462306a36Sopenharmony_ci/*
241562306a36Sopenharmony_ci * Calculate the next globally unique transaction for disambiguation
241662306a36Sopenharmony_ci * during cmpxchg. The transactions start with the cpu number and are then
241762306a36Sopenharmony_ci * incremented by CONFIG_NR_CPUS.
241862306a36Sopenharmony_ci */
241962306a36Sopenharmony_ci#define TID_STEP  roundup_pow_of_two(CONFIG_NR_CPUS)
242062306a36Sopenharmony_ci#else
242162306a36Sopenharmony_ci/*
242262306a36Sopenharmony_ci * No preemption supported therefore also no need to check for
242362306a36Sopenharmony_ci * different cpus.
242462306a36Sopenharmony_ci */
242562306a36Sopenharmony_ci#define TID_STEP 1
242662306a36Sopenharmony_ci#endif /* CONFIG_PREEMPTION */
242762306a36Sopenharmony_ci
242862306a36Sopenharmony_cistatic inline unsigned long next_tid(unsigned long tid)
242962306a36Sopenharmony_ci{
243062306a36Sopenharmony_ci	return tid + TID_STEP;
243162306a36Sopenharmony_ci}
243262306a36Sopenharmony_ci
243362306a36Sopenharmony_ci#ifdef SLUB_DEBUG_CMPXCHG
243462306a36Sopenharmony_cistatic inline unsigned int tid_to_cpu(unsigned long tid)
243562306a36Sopenharmony_ci{
243662306a36Sopenharmony_ci	return tid % TID_STEP;
243762306a36Sopenharmony_ci}
243862306a36Sopenharmony_ci
243962306a36Sopenharmony_cistatic inline unsigned long tid_to_event(unsigned long tid)
244062306a36Sopenharmony_ci{
244162306a36Sopenharmony_ci	return tid / TID_STEP;
244262306a36Sopenharmony_ci}
244362306a36Sopenharmony_ci#endif
244462306a36Sopenharmony_ci
244562306a36Sopenharmony_cistatic inline unsigned int init_tid(int cpu)
244662306a36Sopenharmony_ci{
244762306a36Sopenharmony_ci	return cpu;
244862306a36Sopenharmony_ci}
244962306a36Sopenharmony_ci
245062306a36Sopenharmony_cistatic inline void note_cmpxchg_failure(const char *n,
245162306a36Sopenharmony_ci		const struct kmem_cache *s, unsigned long tid)
245262306a36Sopenharmony_ci{
245362306a36Sopenharmony_ci#ifdef SLUB_DEBUG_CMPXCHG
245462306a36Sopenharmony_ci	unsigned long actual_tid = __this_cpu_read(s->cpu_slab->tid);
245562306a36Sopenharmony_ci
245662306a36Sopenharmony_ci	pr_info("%s %s: cmpxchg redo ", n, s->name);
245762306a36Sopenharmony_ci
245862306a36Sopenharmony_ci#ifdef CONFIG_PREEMPTION
245962306a36Sopenharmony_ci	if (tid_to_cpu(tid) != tid_to_cpu(actual_tid))
246062306a36Sopenharmony_ci		pr_warn("due to cpu change %d -> %d\n",
246162306a36Sopenharmony_ci			tid_to_cpu(tid), tid_to_cpu(actual_tid));
246262306a36Sopenharmony_ci	else
246362306a36Sopenharmony_ci#endif
246462306a36Sopenharmony_ci	if (tid_to_event(tid) != tid_to_event(actual_tid))
246562306a36Sopenharmony_ci		pr_warn("due to cpu running other code. Event %ld->%ld\n",
246662306a36Sopenharmony_ci			tid_to_event(tid), tid_to_event(actual_tid));
246762306a36Sopenharmony_ci	else
246862306a36Sopenharmony_ci		pr_warn("for unknown reason: actual=%lx was=%lx target=%lx\n",
246962306a36Sopenharmony_ci			actual_tid, tid, next_tid(tid));
247062306a36Sopenharmony_ci#endif
247162306a36Sopenharmony_ci	stat(s, CMPXCHG_DOUBLE_CPU_FAIL);
247262306a36Sopenharmony_ci}
247362306a36Sopenharmony_ci
247462306a36Sopenharmony_cistatic void init_kmem_cache_cpus(struct kmem_cache *s)
247562306a36Sopenharmony_ci{
247662306a36Sopenharmony_ci	int cpu;
247762306a36Sopenharmony_ci	struct kmem_cache_cpu *c;
247862306a36Sopenharmony_ci
247962306a36Sopenharmony_ci	for_each_possible_cpu(cpu) {
248062306a36Sopenharmony_ci		c = per_cpu_ptr(s->cpu_slab, cpu);
248162306a36Sopenharmony_ci		local_lock_init(&c->lock);
248262306a36Sopenharmony_ci		c->tid = init_tid(cpu);
248362306a36Sopenharmony_ci	}
248462306a36Sopenharmony_ci}
248562306a36Sopenharmony_ci
248662306a36Sopenharmony_ci/*
248762306a36Sopenharmony_ci * Finishes removing the cpu slab. Merges cpu's freelist with slab's freelist,
248862306a36Sopenharmony_ci * unfreezes the slabs and puts it on the proper list.
248962306a36Sopenharmony_ci * Assumes the slab has been already safely taken away from kmem_cache_cpu
249062306a36Sopenharmony_ci * by the caller.
249162306a36Sopenharmony_ci */
249262306a36Sopenharmony_cistatic void deactivate_slab(struct kmem_cache *s, struct slab *slab,
249362306a36Sopenharmony_ci			    void *freelist)
249462306a36Sopenharmony_ci{
249562306a36Sopenharmony_ci	enum slab_modes { M_NONE, M_PARTIAL, M_FREE, M_FULL_NOLIST };
249662306a36Sopenharmony_ci	struct kmem_cache_node *n = get_node(s, slab_nid(slab));
249762306a36Sopenharmony_ci	int free_delta = 0;
249862306a36Sopenharmony_ci	enum slab_modes mode = M_NONE;
249962306a36Sopenharmony_ci	void *nextfree, *freelist_iter, *freelist_tail;
250062306a36Sopenharmony_ci	int tail = DEACTIVATE_TO_HEAD;
250162306a36Sopenharmony_ci	unsigned long flags = 0;
250262306a36Sopenharmony_ci	struct slab new;
250362306a36Sopenharmony_ci	struct slab old;
250462306a36Sopenharmony_ci
250562306a36Sopenharmony_ci	if (slab->freelist) {
250662306a36Sopenharmony_ci		stat(s, DEACTIVATE_REMOTE_FREES);
250762306a36Sopenharmony_ci		tail = DEACTIVATE_TO_TAIL;
250862306a36Sopenharmony_ci	}
250962306a36Sopenharmony_ci
251062306a36Sopenharmony_ci	/*
251162306a36Sopenharmony_ci	 * Stage one: Count the objects on cpu's freelist as free_delta and
251262306a36Sopenharmony_ci	 * remember the last object in freelist_tail for later splicing.
251362306a36Sopenharmony_ci	 */
251462306a36Sopenharmony_ci	freelist_tail = NULL;
251562306a36Sopenharmony_ci	freelist_iter = freelist;
251662306a36Sopenharmony_ci	while (freelist_iter) {
251762306a36Sopenharmony_ci		nextfree = get_freepointer(s, freelist_iter);
251862306a36Sopenharmony_ci
251962306a36Sopenharmony_ci		/*
252062306a36Sopenharmony_ci		 * If 'nextfree' is invalid, it is possible that the object at
252162306a36Sopenharmony_ci		 * 'freelist_iter' is already corrupted.  So isolate all objects
252262306a36Sopenharmony_ci		 * starting at 'freelist_iter' by skipping them.
252362306a36Sopenharmony_ci		 */
252462306a36Sopenharmony_ci		if (freelist_corrupted(s, slab, &freelist_iter, nextfree))
252562306a36Sopenharmony_ci			break;
252662306a36Sopenharmony_ci
252762306a36Sopenharmony_ci		freelist_tail = freelist_iter;
252862306a36Sopenharmony_ci		free_delta++;
252962306a36Sopenharmony_ci
253062306a36Sopenharmony_ci		freelist_iter = nextfree;
253162306a36Sopenharmony_ci	}
253262306a36Sopenharmony_ci
253362306a36Sopenharmony_ci	/*
253462306a36Sopenharmony_ci	 * Stage two: Unfreeze the slab while splicing the per-cpu
253562306a36Sopenharmony_ci	 * freelist to the head of slab's freelist.
253662306a36Sopenharmony_ci	 *
253762306a36Sopenharmony_ci	 * Ensure that the slab is unfrozen while the list presence
253862306a36Sopenharmony_ci	 * reflects the actual number of objects during unfreeze.
253962306a36Sopenharmony_ci	 *
254062306a36Sopenharmony_ci	 * We first perform cmpxchg holding lock and insert to list
254162306a36Sopenharmony_ci	 * when it succeed. If there is mismatch then the slab is not
254262306a36Sopenharmony_ci	 * unfrozen and number of objects in the slab may have changed.
254362306a36Sopenharmony_ci	 * Then release lock and retry cmpxchg again.
254462306a36Sopenharmony_ci	 */
254562306a36Sopenharmony_ciredo:
254662306a36Sopenharmony_ci
254762306a36Sopenharmony_ci	old.freelist = READ_ONCE(slab->freelist);
254862306a36Sopenharmony_ci	old.counters = READ_ONCE(slab->counters);
254962306a36Sopenharmony_ci	VM_BUG_ON(!old.frozen);
255062306a36Sopenharmony_ci
255162306a36Sopenharmony_ci	/* Determine target state of the slab */
255262306a36Sopenharmony_ci	new.counters = old.counters;
255362306a36Sopenharmony_ci	if (freelist_tail) {
255462306a36Sopenharmony_ci		new.inuse -= free_delta;
255562306a36Sopenharmony_ci		set_freepointer(s, freelist_tail, old.freelist);
255662306a36Sopenharmony_ci		new.freelist = freelist;
255762306a36Sopenharmony_ci	} else
255862306a36Sopenharmony_ci		new.freelist = old.freelist;
255962306a36Sopenharmony_ci
256062306a36Sopenharmony_ci	new.frozen = 0;
256162306a36Sopenharmony_ci
256262306a36Sopenharmony_ci	if (!new.inuse && n->nr_partial >= s->min_partial) {
256362306a36Sopenharmony_ci		mode = M_FREE;
256462306a36Sopenharmony_ci	} else if (new.freelist) {
256562306a36Sopenharmony_ci		mode = M_PARTIAL;
256662306a36Sopenharmony_ci		/*
256762306a36Sopenharmony_ci		 * Taking the spinlock removes the possibility that
256862306a36Sopenharmony_ci		 * acquire_slab() will see a slab that is frozen
256962306a36Sopenharmony_ci		 */
257062306a36Sopenharmony_ci		spin_lock_irqsave(&n->list_lock, flags);
257162306a36Sopenharmony_ci	} else {
257262306a36Sopenharmony_ci		mode = M_FULL_NOLIST;
257362306a36Sopenharmony_ci	}
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_ci
257662306a36Sopenharmony_ci	if (!slab_update_freelist(s, slab,
257762306a36Sopenharmony_ci				old.freelist, old.counters,
257862306a36Sopenharmony_ci				new.freelist, new.counters,
257962306a36Sopenharmony_ci				"unfreezing slab")) {
258062306a36Sopenharmony_ci		if (mode == M_PARTIAL)
258162306a36Sopenharmony_ci			spin_unlock_irqrestore(&n->list_lock, flags);
258262306a36Sopenharmony_ci		goto redo;
258362306a36Sopenharmony_ci	}
258462306a36Sopenharmony_ci
258562306a36Sopenharmony_ci
258662306a36Sopenharmony_ci	if (mode == M_PARTIAL) {
258762306a36Sopenharmony_ci		add_partial(n, slab, tail);
258862306a36Sopenharmony_ci		spin_unlock_irqrestore(&n->list_lock, flags);
258962306a36Sopenharmony_ci		stat(s, tail);
259062306a36Sopenharmony_ci	} else if (mode == M_FREE) {
259162306a36Sopenharmony_ci		stat(s, DEACTIVATE_EMPTY);
259262306a36Sopenharmony_ci		discard_slab(s, slab);
259362306a36Sopenharmony_ci		stat(s, FREE_SLAB);
259462306a36Sopenharmony_ci	} else if (mode == M_FULL_NOLIST) {
259562306a36Sopenharmony_ci		stat(s, DEACTIVATE_FULL);
259662306a36Sopenharmony_ci	}
259762306a36Sopenharmony_ci}
259862306a36Sopenharmony_ci
259962306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
260062306a36Sopenharmony_cistatic void __unfreeze_partials(struct kmem_cache *s, struct slab *partial_slab)
260162306a36Sopenharmony_ci{
260262306a36Sopenharmony_ci	struct kmem_cache_node *n = NULL, *n2 = NULL;
260362306a36Sopenharmony_ci	struct slab *slab, *slab_to_discard = NULL;
260462306a36Sopenharmony_ci	unsigned long flags = 0;
260562306a36Sopenharmony_ci
260662306a36Sopenharmony_ci	while (partial_slab) {
260762306a36Sopenharmony_ci		struct slab new;
260862306a36Sopenharmony_ci		struct slab old;
260962306a36Sopenharmony_ci
261062306a36Sopenharmony_ci		slab = partial_slab;
261162306a36Sopenharmony_ci		partial_slab = slab->next;
261262306a36Sopenharmony_ci
261362306a36Sopenharmony_ci		n2 = get_node(s, slab_nid(slab));
261462306a36Sopenharmony_ci		if (n != n2) {
261562306a36Sopenharmony_ci			if (n)
261662306a36Sopenharmony_ci				spin_unlock_irqrestore(&n->list_lock, flags);
261762306a36Sopenharmony_ci
261862306a36Sopenharmony_ci			n = n2;
261962306a36Sopenharmony_ci			spin_lock_irqsave(&n->list_lock, flags);
262062306a36Sopenharmony_ci		}
262162306a36Sopenharmony_ci
262262306a36Sopenharmony_ci		do {
262362306a36Sopenharmony_ci
262462306a36Sopenharmony_ci			old.freelist = slab->freelist;
262562306a36Sopenharmony_ci			old.counters = slab->counters;
262662306a36Sopenharmony_ci			VM_BUG_ON(!old.frozen);
262762306a36Sopenharmony_ci
262862306a36Sopenharmony_ci			new.counters = old.counters;
262962306a36Sopenharmony_ci			new.freelist = old.freelist;
263062306a36Sopenharmony_ci
263162306a36Sopenharmony_ci			new.frozen = 0;
263262306a36Sopenharmony_ci
263362306a36Sopenharmony_ci		} while (!__slab_update_freelist(s, slab,
263462306a36Sopenharmony_ci				old.freelist, old.counters,
263562306a36Sopenharmony_ci				new.freelist, new.counters,
263662306a36Sopenharmony_ci				"unfreezing slab"));
263762306a36Sopenharmony_ci
263862306a36Sopenharmony_ci		if (unlikely(!new.inuse && n->nr_partial >= s->min_partial)) {
263962306a36Sopenharmony_ci			slab->next = slab_to_discard;
264062306a36Sopenharmony_ci			slab_to_discard = slab;
264162306a36Sopenharmony_ci		} else {
264262306a36Sopenharmony_ci			add_partial(n, slab, DEACTIVATE_TO_TAIL);
264362306a36Sopenharmony_ci			stat(s, FREE_ADD_PARTIAL);
264462306a36Sopenharmony_ci		}
264562306a36Sopenharmony_ci	}
264662306a36Sopenharmony_ci
264762306a36Sopenharmony_ci	if (n)
264862306a36Sopenharmony_ci		spin_unlock_irqrestore(&n->list_lock, flags);
264962306a36Sopenharmony_ci
265062306a36Sopenharmony_ci	while (slab_to_discard) {
265162306a36Sopenharmony_ci		slab = slab_to_discard;
265262306a36Sopenharmony_ci		slab_to_discard = slab_to_discard->next;
265362306a36Sopenharmony_ci
265462306a36Sopenharmony_ci		stat(s, DEACTIVATE_EMPTY);
265562306a36Sopenharmony_ci		discard_slab(s, slab);
265662306a36Sopenharmony_ci		stat(s, FREE_SLAB);
265762306a36Sopenharmony_ci	}
265862306a36Sopenharmony_ci}
265962306a36Sopenharmony_ci
266062306a36Sopenharmony_ci/*
266162306a36Sopenharmony_ci * Unfreeze all the cpu partial slabs.
266262306a36Sopenharmony_ci */
266362306a36Sopenharmony_cistatic void unfreeze_partials(struct kmem_cache *s)
266462306a36Sopenharmony_ci{
266562306a36Sopenharmony_ci	struct slab *partial_slab;
266662306a36Sopenharmony_ci	unsigned long flags;
266762306a36Sopenharmony_ci
266862306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, flags);
266962306a36Sopenharmony_ci	partial_slab = this_cpu_read(s->cpu_slab->partial);
267062306a36Sopenharmony_ci	this_cpu_write(s->cpu_slab->partial, NULL);
267162306a36Sopenharmony_ci	local_unlock_irqrestore(&s->cpu_slab->lock, flags);
267262306a36Sopenharmony_ci
267362306a36Sopenharmony_ci	if (partial_slab)
267462306a36Sopenharmony_ci		__unfreeze_partials(s, partial_slab);
267562306a36Sopenharmony_ci}
267662306a36Sopenharmony_ci
267762306a36Sopenharmony_cistatic void unfreeze_partials_cpu(struct kmem_cache *s,
267862306a36Sopenharmony_ci				  struct kmem_cache_cpu *c)
267962306a36Sopenharmony_ci{
268062306a36Sopenharmony_ci	struct slab *partial_slab;
268162306a36Sopenharmony_ci
268262306a36Sopenharmony_ci	partial_slab = slub_percpu_partial(c);
268362306a36Sopenharmony_ci	c->partial = NULL;
268462306a36Sopenharmony_ci
268562306a36Sopenharmony_ci	if (partial_slab)
268662306a36Sopenharmony_ci		__unfreeze_partials(s, partial_slab);
268762306a36Sopenharmony_ci}
268862306a36Sopenharmony_ci
268962306a36Sopenharmony_ci/*
269062306a36Sopenharmony_ci * Put a slab that was just frozen (in __slab_free|get_partial_node) into a
269162306a36Sopenharmony_ci * partial slab slot if available.
269262306a36Sopenharmony_ci *
269362306a36Sopenharmony_ci * If we did not find a slot then simply move all the partials to the
269462306a36Sopenharmony_ci * per node partial list.
269562306a36Sopenharmony_ci */
269662306a36Sopenharmony_cistatic void put_cpu_partial(struct kmem_cache *s, struct slab *slab, int drain)
269762306a36Sopenharmony_ci{
269862306a36Sopenharmony_ci	struct slab *oldslab;
269962306a36Sopenharmony_ci	struct slab *slab_to_unfreeze = NULL;
270062306a36Sopenharmony_ci	unsigned long flags;
270162306a36Sopenharmony_ci	int slabs = 0;
270262306a36Sopenharmony_ci
270362306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, flags);
270462306a36Sopenharmony_ci
270562306a36Sopenharmony_ci	oldslab = this_cpu_read(s->cpu_slab->partial);
270662306a36Sopenharmony_ci
270762306a36Sopenharmony_ci	if (oldslab) {
270862306a36Sopenharmony_ci		if (drain && oldslab->slabs >= s->cpu_partial_slabs) {
270962306a36Sopenharmony_ci			/*
271062306a36Sopenharmony_ci			 * Partial array is full. Move the existing set to the
271162306a36Sopenharmony_ci			 * per node partial list. Postpone the actual unfreezing
271262306a36Sopenharmony_ci			 * outside of the critical section.
271362306a36Sopenharmony_ci			 */
271462306a36Sopenharmony_ci			slab_to_unfreeze = oldslab;
271562306a36Sopenharmony_ci			oldslab = NULL;
271662306a36Sopenharmony_ci		} else {
271762306a36Sopenharmony_ci			slabs = oldslab->slabs;
271862306a36Sopenharmony_ci		}
271962306a36Sopenharmony_ci	}
272062306a36Sopenharmony_ci
272162306a36Sopenharmony_ci	slabs++;
272262306a36Sopenharmony_ci
272362306a36Sopenharmony_ci	slab->slabs = slabs;
272462306a36Sopenharmony_ci	slab->next = oldslab;
272562306a36Sopenharmony_ci
272662306a36Sopenharmony_ci	this_cpu_write(s->cpu_slab->partial, slab);
272762306a36Sopenharmony_ci
272862306a36Sopenharmony_ci	local_unlock_irqrestore(&s->cpu_slab->lock, flags);
272962306a36Sopenharmony_ci
273062306a36Sopenharmony_ci	if (slab_to_unfreeze) {
273162306a36Sopenharmony_ci		__unfreeze_partials(s, slab_to_unfreeze);
273262306a36Sopenharmony_ci		stat(s, CPU_PARTIAL_DRAIN);
273362306a36Sopenharmony_ci	}
273462306a36Sopenharmony_ci}
273562306a36Sopenharmony_ci
273662306a36Sopenharmony_ci#else	/* CONFIG_SLUB_CPU_PARTIAL */
273762306a36Sopenharmony_ci
273862306a36Sopenharmony_cistatic inline void unfreeze_partials(struct kmem_cache *s) { }
273962306a36Sopenharmony_cistatic inline void unfreeze_partials_cpu(struct kmem_cache *s,
274062306a36Sopenharmony_ci				  struct kmem_cache_cpu *c) { }
274162306a36Sopenharmony_ci
274262306a36Sopenharmony_ci#endif	/* CONFIG_SLUB_CPU_PARTIAL */
274362306a36Sopenharmony_ci
274462306a36Sopenharmony_cistatic inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
274562306a36Sopenharmony_ci{
274662306a36Sopenharmony_ci	unsigned long flags;
274762306a36Sopenharmony_ci	struct slab *slab;
274862306a36Sopenharmony_ci	void *freelist;
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, flags);
275162306a36Sopenharmony_ci
275262306a36Sopenharmony_ci	slab = c->slab;
275362306a36Sopenharmony_ci	freelist = c->freelist;
275462306a36Sopenharmony_ci
275562306a36Sopenharmony_ci	c->slab = NULL;
275662306a36Sopenharmony_ci	c->freelist = NULL;
275762306a36Sopenharmony_ci	c->tid = next_tid(c->tid);
275862306a36Sopenharmony_ci
275962306a36Sopenharmony_ci	local_unlock_irqrestore(&s->cpu_slab->lock, flags);
276062306a36Sopenharmony_ci
276162306a36Sopenharmony_ci	if (slab) {
276262306a36Sopenharmony_ci		deactivate_slab(s, slab, freelist);
276362306a36Sopenharmony_ci		stat(s, CPUSLAB_FLUSH);
276462306a36Sopenharmony_ci	}
276562306a36Sopenharmony_ci}
276662306a36Sopenharmony_ci
276762306a36Sopenharmony_cistatic inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
276862306a36Sopenharmony_ci{
276962306a36Sopenharmony_ci	struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
277062306a36Sopenharmony_ci	void *freelist = c->freelist;
277162306a36Sopenharmony_ci	struct slab *slab = c->slab;
277262306a36Sopenharmony_ci
277362306a36Sopenharmony_ci	c->slab = NULL;
277462306a36Sopenharmony_ci	c->freelist = NULL;
277562306a36Sopenharmony_ci	c->tid = next_tid(c->tid);
277662306a36Sopenharmony_ci
277762306a36Sopenharmony_ci	if (slab) {
277862306a36Sopenharmony_ci		deactivate_slab(s, slab, freelist);
277962306a36Sopenharmony_ci		stat(s, CPUSLAB_FLUSH);
278062306a36Sopenharmony_ci	}
278162306a36Sopenharmony_ci
278262306a36Sopenharmony_ci	unfreeze_partials_cpu(s, c);
278362306a36Sopenharmony_ci}
278462306a36Sopenharmony_ci
278562306a36Sopenharmony_cistruct slub_flush_work {
278662306a36Sopenharmony_ci	struct work_struct work;
278762306a36Sopenharmony_ci	struct kmem_cache *s;
278862306a36Sopenharmony_ci	bool skip;
278962306a36Sopenharmony_ci};
279062306a36Sopenharmony_ci
279162306a36Sopenharmony_ci/*
279262306a36Sopenharmony_ci * Flush cpu slab.
279362306a36Sopenharmony_ci *
279462306a36Sopenharmony_ci * Called from CPU work handler with migration disabled.
279562306a36Sopenharmony_ci */
279662306a36Sopenharmony_cistatic void flush_cpu_slab(struct work_struct *w)
279762306a36Sopenharmony_ci{
279862306a36Sopenharmony_ci	struct kmem_cache *s;
279962306a36Sopenharmony_ci	struct kmem_cache_cpu *c;
280062306a36Sopenharmony_ci	struct slub_flush_work *sfw;
280162306a36Sopenharmony_ci
280262306a36Sopenharmony_ci	sfw = container_of(w, struct slub_flush_work, work);
280362306a36Sopenharmony_ci
280462306a36Sopenharmony_ci	s = sfw->s;
280562306a36Sopenharmony_ci	c = this_cpu_ptr(s->cpu_slab);
280662306a36Sopenharmony_ci
280762306a36Sopenharmony_ci	if (c->slab)
280862306a36Sopenharmony_ci		flush_slab(s, c);
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_ci	unfreeze_partials(s);
281162306a36Sopenharmony_ci}
281262306a36Sopenharmony_ci
281362306a36Sopenharmony_cistatic bool has_cpu_slab(int cpu, struct kmem_cache *s)
281462306a36Sopenharmony_ci{
281562306a36Sopenharmony_ci	struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
281662306a36Sopenharmony_ci
281762306a36Sopenharmony_ci	return c->slab || slub_percpu_partial(c);
281862306a36Sopenharmony_ci}
281962306a36Sopenharmony_ci
282062306a36Sopenharmony_cistatic DEFINE_MUTEX(flush_lock);
282162306a36Sopenharmony_cistatic DEFINE_PER_CPU(struct slub_flush_work, slub_flush);
282262306a36Sopenharmony_ci
282362306a36Sopenharmony_cistatic void flush_all_cpus_locked(struct kmem_cache *s)
282462306a36Sopenharmony_ci{
282562306a36Sopenharmony_ci	struct slub_flush_work *sfw;
282662306a36Sopenharmony_ci	unsigned int cpu;
282762306a36Sopenharmony_ci
282862306a36Sopenharmony_ci	lockdep_assert_cpus_held();
282962306a36Sopenharmony_ci	mutex_lock(&flush_lock);
283062306a36Sopenharmony_ci
283162306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
283262306a36Sopenharmony_ci		sfw = &per_cpu(slub_flush, cpu);
283362306a36Sopenharmony_ci		if (!has_cpu_slab(cpu, s)) {
283462306a36Sopenharmony_ci			sfw->skip = true;
283562306a36Sopenharmony_ci			continue;
283662306a36Sopenharmony_ci		}
283762306a36Sopenharmony_ci		INIT_WORK(&sfw->work, flush_cpu_slab);
283862306a36Sopenharmony_ci		sfw->skip = false;
283962306a36Sopenharmony_ci		sfw->s = s;
284062306a36Sopenharmony_ci		queue_work_on(cpu, flushwq, &sfw->work);
284162306a36Sopenharmony_ci	}
284262306a36Sopenharmony_ci
284362306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
284462306a36Sopenharmony_ci		sfw = &per_cpu(slub_flush, cpu);
284562306a36Sopenharmony_ci		if (sfw->skip)
284662306a36Sopenharmony_ci			continue;
284762306a36Sopenharmony_ci		flush_work(&sfw->work);
284862306a36Sopenharmony_ci	}
284962306a36Sopenharmony_ci
285062306a36Sopenharmony_ci	mutex_unlock(&flush_lock);
285162306a36Sopenharmony_ci}
285262306a36Sopenharmony_ci
285362306a36Sopenharmony_cistatic void flush_all(struct kmem_cache *s)
285462306a36Sopenharmony_ci{
285562306a36Sopenharmony_ci	cpus_read_lock();
285662306a36Sopenharmony_ci	flush_all_cpus_locked(s);
285762306a36Sopenharmony_ci	cpus_read_unlock();
285862306a36Sopenharmony_ci}
285962306a36Sopenharmony_ci
286062306a36Sopenharmony_ci/*
286162306a36Sopenharmony_ci * Use the cpu notifier to insure that the cpu slabs are flushed when
286262306a36Sopenharmony_ci * necessary.
286362306a36Sopenharmony_ci */
286462306a36Sopenharmony_cistatic int slub_cpu_dead(unsigned int cpu)
286562306a36Sopenharmony_ci{
286662306a36Sopenharmony_ci	struct kmem_cache *s;
286762306a36Sopenharmony_ci
286862306a36Sopenharmony_ci	mutex_lock(&slab_mutex);
286962306a36Sopenharmony_ci	list_for_each_entry(s, &slab_caches, list)
287062306a36Sopenharmony_ci		__flush_cpu_slab(s, cpu);
287162306a36Sopenharmony_ci	mutex_unlock(&slab_mutex);
287262306a36Sopenharmony_ci	return 0;
287362306a36Sopenharmony_ci}
287462306a36Sopenharmony_ci
287562306a36Sopenharmony_ci#else /* CONFIG_SLUB_TINY */
287662306a36Sopenharmony_cistatic inline void flush_all_cpus_locked(struct kmem_cache *s) { }
287762306a36Sopenharmony_cistatic inline void flush_all(struct kmem_cache *s) { }
287862306a36Sopenharmony_cistatic inline void __flush_cpu_slab(struct kmem_cache *s, int cpu) { }
287962306a36Sopenharmony_cistatic inline int slub_cpu_dead(unsigned int cpu) { return 0; }
288062306a36Sopenharmony_ci#endif /* CONFIG_SLUB_TINY */
288162306a36Sopenharmony_ci
288262306a36Sopenharmony_ci/*
288362306a36Sopenharmony_ci * Check if the objects in a per cpu structure fit numa
288462306a36Sopenharmony_ci * locality expectations.
288562306a36Sopenharmony_ci */
288662306a36Sopenharmony_cistatic inline int node_match(struct slab *slab, int node)
288762306a36Sopenharmony_ci{
288862306a36Sopenharmony_ci#ifdef CONFIG_NUMA
288962306a36Sopenharmony_ci	if (node != NUMA_NO_NODE && slab_nid(slab) != node)
289062306a36Sopenharmony_ci		return 0;
289162306a36Sopenharmony_ci#endif
289262306a36Sopenharmony_ci	return 1;
289362306a36Sopenharmony_ci}
289462306a36Sopenharmony_ci
289562306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
289662306a36Sopenharmony_cistatic int count_free(struct slab *slab)
289762306a36Sopenharmony_ci{
289862306a36Sopenharmony_ci	return slab->objects - slab->inuse;
289962306a36Sopenharmony_ci}
290062306a36Sopenharmony_ci
290162306a36Sopenharmony_cistatic inline unsigned long node_nr_objs(struct kmem_cache_node *n)
290262306a36Sopenharmony_ci{
290362306a36Sopenharmony_ci	return atomic_long_read(&n->total_objects);
290462306a36Sopenharmony_ci}
290562306a36Sopenharmony_ci
290662306a36Sopenharmony_ci/* Supports checking bulk free of a constructed freelist */
290762306a36Sopenharmony_cistatic inline bool free_debug_processing(struct kmem_cache *s,
290862306a36Sopenharmony_ci	struct slab *slab, void *head, void *tail, int *bulk_cnt,
290962306a36Sopenharmony_ci	unsigned long addr, depot_stack_handle_t handle)
291062306a36Sopenharmony_ci{
291162306a36Sopenharmony_ci	bool checks_ok = false;
291262306a36Sopenharmony_ci	void *object = head;
291362306a36Sopenharmony_ci	int cnt = 0;
291462306a36Sopenharmony_ci
291562306a36Sopenharmony_ci	if (s->flags & SLAB_CONSISTENCY_CHECKS) {
291662306a36Sopenharmony_ci		if (!check_slab(s, slab))
291762306a36Sopenharmony_ci			goto out;
291862306a36Sopenharmony_ci	}
291962306a36Sopenharmony_ci
292062306a36Sopenharmony_ci	if (slab->inuse < *bulk_cnt) {
292162306a36Sopenharmony_ci		slab_err(s, slab, "Slab has %d allocated objects but %d are to be freed\n",
292262306a36Sopenharmony_ci			 slab->inuse, *bulk_cnt);
292362306a36Sopenharmony_ci		goto out;
292462306a36Sopenharmony_ci	}
292562306a36Sopenharmony_ci
292662306a36Sopenharmony_cinext_object:
292762306a36Sopenharmony_ci
292862306a36Sopenharmony_ci	if (++cnt > *bulk_cnt)
292962306a36Sopenharmony_ci		goto out_cnt;
293062306a36Sopenharmony_ci
293162306a36Sopenharmony_ci	if (s->flags & SLAB_CONSISTENCY_CHECKS) {
293262306a36Sopenharmony_ci		if (!free_consistency_checks(s, slab, object, addr))
293362306a36Sopenharmony_ci			goto out;
293462306a36Sopenharmony_ci	}
293562306a36Sopenharmony_ci
293662306a36Sopenharmony_ci	if (s->flags & SLAB_STORE_USER)
293762306a36Sopenharmony_ci		set_track_update(s, object, TRACK_FREE, addr, handle);
293862306a36Sopenharmony_ci	trace(s, slab, object, 0);
293962306a36Sopenharmony_ci	/* Freepointer not overwritten by init_object(), SLAB_POISON moved it */
294062306a36Sopenharmony_ci	init_object(s, object, SLUB_RED_INACTIVE);
294162306a36Sopenharmony_ci
294262306a36Sopenharmony_ci	/* Reached end of constructed freelist yet? */
294362306a36Sopenharmony_ci	if (object != tail) {
294462306a36Sopenharmony_ci		object = get_freepointer(s, object);
294562306a36Sopenharmony_ci		goto next_object;
294662306a36Sopenharmony_ci	}
294762306a36Sopenharmony_ci	checks_ok = true;
294862306a36Sopenharmony_ci
294962306a36Sopenharmony_ciout_cnt:
295062306a36Sopenharmony_ci	if (cnt != *bulk_cnt) {
295162306a36Sopenharmony_ci		slab_err(s, slab, "Bulk free expected %d objects but found %d\n",
295262306a36Sopenharmony_ci			 *bulk_cnt, cnt);
295362306a36Sopenharmony_ci		*bulk_cnt = cnt;
295462306a36Sopenharmony_ci	}
295562306a36Sopenharmony_ci
295662306a36Sopenharmony_ciout:
295762306a36Sopenharmony_ci
295862306a36Sopenharmony_ci	if (!checks_ok)
295962306a36Sopenharmony_ci		slab_fix(s, "Object at 0x%p not freed", object);
296062306a36Sopenharmony_ci
296162306a36Sopenharmony_ci	return checks_ok;
296262306a36Sopenharmony_ci}
296362306a36Sopenharmony_ci#endif /* CONFIG_SLUB_DEBUG */
296462306a36Sopenharmony_ci
296562306a36Sopenharmony_ci#if defined(CONFIG_SLUB_DEBUG) || defined(SLAB_SUPPORTS_SYSFS)
296662306a36Sopenharmony_cistatic unsigned long count_partial(struct kmem_cache_node *n,
296762306a36Sopenharmony_ci					int (*get_count)(struct slab *))
296862306a36Sopenharmony_ci{
296962306a36Sopenharmony_ci	unsigned long flags;
297062306a36Sopenharmony_ci	unsigned long x = 0;
297162306a36Sopenharmony_ci	struct slab *slab;
297262306a36Sopenharmony_ci
297362306a36Sopenharmony_ci	spin_lock_irqsave(&n->list_lock, flags);
297462306a36Sopenharmony_ci	list_for_each_entry(slab, &n->partial, slab_list)
297562306a36Sopenharmony_ci		x += get_count(slab);
297662306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
297762306a36Sopenharmony_ci	return x;
297862306a36Sopenharmony_ci}
297962306a36Sopenharmony_ci#endif /* CONFIG_SLUB_DEBUG || SLAB_SUPPORTS_SYSFS */
298062306a36Sopenharmony_ci
298162306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
298262306a36Sopenharmony_cistatic noinline void
298362306a36Sopenharmony_cislab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
298462306a36Sopenharmony_ci{
298562306a36Sopenharmony_ci	static DEFINE_RATELIMIT_STATE(slub_oom_rs, DEFAULT_RATELIMIT_INTERVAL,
298662306a36Sopenharmony_ci				      DEFAULT_RATELIMIT_BURST);
298762306a36Sopenharmony_ci	int node;
298862306a36Sopenharmony_ci	struct kmem_cache_node *n;
298962306a36Sopenharmony_ci
299062306a36Sopenharmony_ci	if ((gfpflags & __GFP_NOWARN) || !__ratelimit(&slub_oom_rs))
299162306a36Sopenharmony_ci		return;
299262306a36Sopenharmony_ci
299362306a36Sopenharmony_ci	pr_warn("SLUB: Unable to allocate memory on node %d, gfp=%#x(%pGg)\n",
299462306a36Sopenharmony_ci		nid, gfpflags, &gfpflags);
299562306a36Sopenharmony_ci	pr_warn("  cache: %s, object size: %u, buffer size: %u, default order: %u, min order: %u\n",
299662306a36Sopenharmony_ci		s->name, s->object_size, s->size, oo_order(s->oo),
299762306a36Sopenharmony_ci		oo_order(s->min));
299862306a36Sopenharmony_ci
299962306a36Sopenharmony_ci	if (oo_order(s->min) > get_order(s->object_size))
300062306a36Sopenharmony_ci		pr_warn("  %s debugging increased min order, use slub_debug=O to disable.\n",
300162306a36Sopenharmony_ci			s->name);
300262306a36Sopenharmony_ci
300362306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
300462306a36Sopenharmony_ci		unsigned long nr_slabs;
300562306a36Sopenharmony_ci		unsigned long nr_objs;
300662306a36Sopenharmony_ci		unsigned long nr_free;
300762306a36Sopenharmony_ci
300862306a36Sopenharmony_ci		nr_free  = count_partial(n, count_free);
300962306a36Sopenharmony_ci		nr_slabs = node_nr_slabs(n);
301062306a36Sopenharmony_ci		nr_objs  = node_nr_objs(n);
301162306a36Sopenharmony_ci
301262306a36Sopenharmony_ci		pr_warn("  node %d: slabs: %ld, objs: %ld, free: %ld\n",
301362306a36Sopenharmony_ci			node, nr_slabs, nr_objs, nr_free);
301462306a36Sopenharmony_ci	}
301562306a36Sopenharmony_ci}
301662306a36Sopenharmony_ci#else /* CONFIG_SLUB_DEBUG */
301762306a36Sopenharmony_cistatic inline void
301862306a36Sopenharmony_cislab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid) { }
301962306a36Sopenharmony_ci#endif
302062306a36Sopenharmony_ci
302162306a36Sopenharmony_cistatic inline bool pfmemalloc_match(struct slab *slab, gfp_t gfpflags)
302262306a36Sopenharmony_ci{
302362306a36Sopenharmony_ci	if (unlikely(slab_test_pfmemalloc(slab)))
302462306a36Sopenharmony_ci		return gfp_pfmemalloc_allowed(gfpflags);
302562306a36Sopenharmony_ci
302662306a36Sopenharmony_ci	return true;
302762306a36Sopenharmony_ci}
302862306a36Sopenharmony_ci
302962306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
303062306a36Sopenharmony_cistatic inline bool
303162306a36Sopenharmony_ci__update_cpu_freelist_fast(struct kmem_cache *s,
303262306a36Sopenharmony_ci			   void *freelist_old, void *freelist_new,
303362306a36Sopenharmony_ci			   unsigned long tid)
303462306a36Sopenharmony_ci{
303562306a36Sopenharmony_ci	freelist_aba_t old = { .freelist = freelist_old, .counter = tid };
303662306a36Sopenharmony_ci	freelist_aba_t new = { .freelist = freelist_new, .counter = next_tid(tid) };
303762306a36Sopenharmony_ci
303862306a36Sopenharmony_ci	return this_cpu_try_cmpxchg_freelist(s->cpu_slab->freelist_tid.full,
303962306a36Sopenharmony_ci					     &old.full, new.full);
304062306a36Sopenharmony_ci}
304162306a36Sopenharmony_ci
304262306a36Sopenharmony_ci/*
304362306a36Sopenharmony_ci * Check the slab->freelist and either transfer the freelist to the
304462306a36Sopenharmony_ci * per cpu freelist or deactivate the slab.
304562306a36Sopenharmony_ci *
304662306a36Sopenharmony_ci * The slab is still frozen if the return value is not NULL.
304762306a36Sopenharmony_ci *
304862306a36Sopenharmony_ci * If this function returns NULL then the slab has been unfrozen.
304962306a36Sopenharmony_ci */
305062306a36Sopenharmony_cistatic inline void *get_freelist(struct kmem_cache *s, struct slab *slab)
305162306a36Sopenharmony_ci{
305262306a36Sopenharmony_ci	struct slab new;
305362306a36Sopenharmony_ci	unsigned long counters;
305462306a36Sopenharmony_ci	void *freelist;
305562306a36Sopenharmony_ci
305662306a36Sopenharmony_ci	lockdep_assert_held(this_cpu_ptr(&s->cpu_slab->lock));
305762306a36Sopenharmony_ci
305862306a36Sopenharmony_ci	do {
305962306a36Sopenharmony_ci		freelist = slab->freelist;
306062306a36Sopenharmony_ci		counters = slab->counters;
306162306a36Sopenharmony_ci
306262306a36Sopenharmony_ci		new.counters = counters;
306362306a36Sopenharmony_ci		VM_BUG_ON(!new.frozen);
306462306a36Sopenharmony_ci
306562306a36Sopenharmony_ci		new.inuse = slab->objects;
306662306a36Sopenharmony_ci		new.frozen = freelist != NULL;
306762306a36Sopenharmony_ci
306862306a36Sopenharmony_ci	} while (!__slab_update_freelist(s, slab,
306962306a36Sopenharmony_ci		freelist, counters,
307062306a36Sopenharmony_ci		NULL, new.counters,
307162306a36Sopenharmony_ci		"get_freelist"));
307262306a36Sopenharmony_ci
307362306a36Sopenharmony_ci	return freelist;
307462306a36Sopenharmony_ci}
307562306a36Sopenharmony_ci
307662306a36Sopenharmony_ci/*
307762306a36Sopenharmony_ci * Slow path. The lockless freelist is empty or we need to perform
307862306a36Sopenharmony_ci * debugging duties.
307962306a36Sopenharmony_ci *
308062306a36Sopenharmony_ci * Processing is still very fast if new objects have been freed to the
308162306a36Sopenharmony_ci * regular freelist. In that case we simply take over the regular freelist
308262306a36Sopenharmony_ci * as the lockless freelist and zap the regular freelist.
308362306a36Sopenharmony_ci *
308462306a36Sopenharmony_ci * If that is not working then we fall back to the partial lists. We take the
308562306a36Sopenharmony_ci * first element of the freelist as the object to allocate now and move the
308662306a36Sopenharmony_ci * rest of the freelist to the lockless freelist.
308762306a36Sopenharmony_ci *
308862306a36Sopenharmony_ci * And if we were unable to get a new slab from the partial slab lists then
308962306a36Sopenharmony_ci * we need to allocate a new slab. This is the slowest path since it involves
309062306a36Sopenharmony_ci * a call to the page allocator and the setup of a new slab.
309162306a36Sopenharmony_ci *
309262306a36Sopenharmony_ci * Version of __slab_alloc to use when we know that preemption is
309362306a36Sopenharmony_ci * already disabled (which is the case for bulk allocation).
309462306a36Sopenharmony_ci */
309562306a36Sopenharmony_cistatic void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
309662306a36Sopenharmony_ci			  unsigned long addr, struct kmem_cache_cpu *c, unsigned int orig_size)
309762306a36Sopenharmony_ci{
309862306a36Sopenharmony_ci	void *freelist;
309962306a36Sopenharmony_ci	struct slab *slab;
310062306a36Sopenharmony_ci	unsigned long flags;
310162306a36Sopenharmony_ci	struct partial_context pc;
310262306a36Sopenharmony_ci
310362306a36Sopenharmony_ci	stat(s, ALLOC_SLOWPATH);
310462306a36Sopenharmony_ci
310562306a36Sopenharmony_cireread_slab:
310662306a36Sopenharmony_ci
310762306a36Sopenharmony_ci	slab = READ_ONCE(c->slab);
310862306a36Sopenharmony_ci	if (!slab) {
310962306a36Sopenharmony_ci		/*
311062306a36Sopenharmony_ci		 * if the node is not online or has no normal memory, just
311162306a36Sopenharmony_ci		 * ignore the node constraint
311262306a36Sopenharmony_ci		 */
311362306a36Sopenharmony_ci		if (unlikely(node != NUMA_NO_NODE &&
311462306a36Sopenharmony_ci			     !node_isset(node, slab_nodes)))
311562306a36Sopenharmony_ci			node = NUMA_NO_NODE;
311662306a36Sopenharmony_ci		goto new_slab;
311762306a36Sopenharmony_ci	}
311862306a36Sopenharmony_ciredo:
311962306a36Sopenharmony_ci
312062306a36Sopenharmony_ci	if (unlikely(!node_match(slab, node))) {
312162306a36Sopenharmony_ci		/*
312262306a36Sopenharmony_ci		 * same as above but node_match() being false already
312362306a36Sopenharmony_ci		 * implies node != NUMA_NO_NODE
312462306a36Sopenharmony_ci		 */
312562306a36Sopenharmony_ci		if (!node_isset(node, slab_nodes)) {
312662306a36Sopenharmony_ci			node = NUMA_NO_NODE;
312762306a36Sopenharmony_ci		} else {
312862306a36Sopenharmony_ci			stat(s, ALLOC_NODE_MISMATCH);
312962306a36Sopenharmony_ci			goto deactivate_slab;
313062306a36Sopenharmony_ci		}
313162306a36Sopenharmony_ci	}
313262306a36Sopenharmony_ci
313362306a36Sopenharmony_ci	/*
313462306a36Sopenharmony_ci	 * By rights, we should be searching for a slab page that was
313562306a36Sopenharmony_ci	 * PFMEMALLOC but right now, we are losing the pfmemalloc
313662306a36Sopenharmony_ci	 * information when the page leaves the per-cpu allocator
313762306a36Sopenharmony_ci	 */
313862306a36Sopenharmony_ci	if (unlikely(!pfmemalloc_match(slab, gfpflags)))
313962306a36Sopenharmony_ci		goto deactivate_slab;
314062306a36Sopenharmony_ci
314162306a36Sopenharmony_ci	/* must check again c->slab in case we got preempted and it changed */
314262306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, flags);
314362306a36Sopenharmony_ci	if (unlikely(slab != c->slab)) {
314462306a36Sopenharmony_ci		local_unlock_irqrestore(&s->cpu_slab->lock, flags);
314562306a36Sopenharmony_ci		goto reread_slab;
314662306a36Sopenharmony_ci	}
314762306a36Sopenharmony_ci	freelist = c->freelist;
314862306a36Sopenharmony_ci	if (freelist)
314962306a36Sopenharmony_ci		goto load_freelist;
315062306a36Sopenharmony_ci
315162306a36Sopenharmony_ci	freelist = get_freelist(s, slab);
315262306a36Sopenharmony_ci
315362306a36Sopenharmony_ci	if (!freelist) {
315462306a36Sopenharmony_ci		c->slab = NULL;
315562306a36Sopenharmony_ci		c->tid = next_tid(c->tid);
315662306a36Sopenharmony_ci		local_unlock_irqrestore(&s->cpu_slab->lock, flags);
315762306a36Sopenharmony_ci		stat(s, DEACTIVATE_BYPASS);
315862306a36Sopenharmony_ci		goto new_slab;
315962306a36Sopenharmony_ci	}
316062306a36Sopenharmony_ci
316162306a36Sopenharmony_ci	stat(s, ALLOC_REFILL);
316262306a36Sopenharmony_ci
316362306a36Sopenharmony_ciload_freelist:
316462306a36Sopenharmony_ci
316562306a36Sopenharmony_ci	lockdep_assert_held(this_cpu_ptr(&s->cpu_slab->lock));
316662306a36Sopenharmony_ci
316762306a36Sopenharmony_ci	/*
316862306a36Sopenharmony_ci	 * freelist is pointing to the list of objects to be used.
316962306a36Sopenharmony_ci	 * slab is pointing to the slab from which the objects are obtained.
317062306a36Sopenharmony_ci	 * That slab must be frozen for per cpu allocations to work.
317162306a36Sopenharmony_ci	 */
317262306a36Sopenharmony_ci	VM_BUG_ON(!c->slab->frozen);
317362306a36Sopenharmony_ci	c->freelist = get_freepointer(s, freelist);
317462306a36Sopenharmony_ci	c->tid = next_tid(c->tid);
317562306a36Sopenharmony_ci	local_unlock_irqrestore(&s->cpu_slab->lock, flags);
317662306a36Sopenharmony_ci	return freelist;
317762306a36Sopenharmony_ci
317862306a36Sopenharmony_cideactivate_slab:
317962306a36Sopenharmony_ci
318062306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, flags);
318162306a36Sopenharmony_ci	if (slab != c->slab) {
318262306a36Sopenharmony_ci		local_unlock_irqrestore(&s->cpu_slab->lock, flags);
318362306a36Sopenharmony_ci		goto reread_slab;
318462306a36Sopenharmony_ci	}
318562306a36Sopenharmony_ci	freelist = c->freelist;
318662306a36Sopenharmony_ci	c->slab = NULL;
318762306a36Sopenharmony_ci	c->freelist = NULL;
318862306a36Sopenharmony_ci	c->tid = next_tid(c->tid);
318962306a36Sopenharmony_ci	local_unlock_irqrestore(&s->cpu_slab->lock, flags);
319062306a36Sopenharmony_ci	deactivate_slab(s, slab, freelist);
319162306a36Sopenharmony_ci
319262306a36Sopenharmony_cinew_slab:
319362306a36Sopenharmony_ci
319462306a36Sopenharmony_ci	if (slub_percpu_partial(c)) {
319562306a36Sopenharmony_ci		local_lock_irqsave(&s->cpu_slab->lock, flags);
319662306a36Sopenharmony_ci		if (unlikely(c->slab)) {
319762306a36Sopenharmony_ci			local_unlock_irqrestore(&s->cpu_slab->lock, flags);
319862306a36Sopenharmony_ci			goto reread_slab;
319962306a36Sopenharmony_ci		}
320062306a36Sopenharmony_ci		if (unlikely(!slub_percpu_partial(c))) {
320162306a36Sopenharmony_ci			local_unlock_irqrestore(&s->cpu_slab->lock, flags);
320262306a36Sopenharmony_ci			/* we were preempted and partial list got empty */
320362306a36Sopenharmony_ci			goto new_objects;
320462306a36Sopenharmony_ci		}
320562306a36Sopenharmony_ci
320662306a36Sopenharmony_ci		slab = c->slab = slub_percpu_partial(c);
320762306a36Sopenharmony_ci		slub_set_percpu_partial(c, slab);
320862306a36Sopenharmony_ci		local_unlock_irqrestore(&s->cpu_slab->lock, flags);
320962306a36Sopenharmony_ci		stat(s, CPU_PARTIAL_ALLOC);
321062306a36Sopenharmony_ci		goto redo;
321162306a36Sopenharmony_ci	}
321262306a36Sopenharmony_ci
321362306a36Sopenharmony_cinew_objects:
321462306a36Sopenharmony_ci
321562306a36Sopenharmony_ci	pc.flags = gfpflags;
321662306a36Sopenharmony_ci	pc.slab = &slab;
321762306a36Sopenharmony_ci	pc.orig_size = orig_size;
321862306a36Sopenharmony_ci	freelist = get_partial(s, node, &pc);
321962306a36Sopenharmony_ci	if (freelist)
322062306a36Sopenharmony_ci		goto check_new_slab;
322162306a36Sopenharmony_ci
322262306a36Sopenharmony_ci	slub_put_cpu_ptr(s->cpu_slab);
322362306a36Sopenharmony_ci	slab = new_slab(s, gfpflags, node);
322462306a36Sopenharmony_ci	c = slub_get_cpu_ptr(s->cpu_slab);
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_ci	if (unlikely(!slab)) {
322762306a36Sopenharmony_ci		slab_out_of_memory(s, gfpflags, node);
322862306a36Sopenharmony_ci		return NULL;
322962306a36Sopenharmony_ci	}
323062306a36Sopenharmony_ci
323162306a36Sopenharmony_ci	stat(s, ALLOC_SLAB);
323262306a36Sopenharmony_ci
323362306a36Sopenharmony_ci	if (kmem_cache_debug(s)) {
323462306a36Sopenharmony_ci		freelist = alloc_single_from_new_slab(s, slab, orig_size);
323562306a36Sopenharmony_ci
323662306a36Sopenharmony_ci		if (unlikely(!freelist))
323762306a36Sopenharmony_ci			goto new_objects;
323862306a36Sopenharmony_ci
323962306a36Sopenharmony_ci		if (s->flags & SLAB_STORE_USER)
324062306a36Sopenharmony_ci			set_track(s, freelist, TRACK_ALLOC, addr);
324162306a36Sopenharmony_ci
324262306a36Sopenharmony_ci		return freelist;
324362306a36Sopenharmony_ci	}
324462306a36Sopenharmony_ci
324562306a36Sopenharmony_ci	/*
324662306a36Sopenharmony_ci	 * No other reference to the slab yet so we can
324762306a36Sopenharmony_ci	 * muck around with it freely without cmpxchg
324862306a36Sopenharmony_ci	 */
324962306a36Sopenharmony_ci	freelist = slab->freelist;
325062306a36Sopenharmony_ci	slab->freelist = NULL;
325162306a36Sopenharmony_ci	slab->inuse = slab->objects;
325262306a36Sopenharmony_ci	slab->frozen = 1;
325362306a36Sopenharmony_ci
325462306a36Sopenharmony_ci	inc_slabs_node(s, slab_nid(slab), slab->objects);
325562306a36Sopenharmony_ci
325662306a36Sopenharmony_cicheck_new_slab:
325762306a36Sopenharmony_ci
325862306a36Sopenharmony_ci	if (kmem_cache_debug(s)) {
325962306a36Sopenharmony_ci		/*
326062306a36Sopenharmony_ci		 * For debug caches here we had to go through
326162306a36Sopenharmony_ci		 * alloc_single_from_partial() so just store the tracking info
326262306a36Sopenharmony_ci		 * and return the object
326362306a36Sopenharmony_ci		 */
326462306a36Sopenharmony_ci		if (s->flags & SLAB_STORE_USER)
326562306a36Sopenharmony_ci			set_track(s, freelist, TRACK_ALLOC, addr);
326662306a36Sopenharmony_ci
326762306a36Sopenharmony_ci		return freelist;
326862306a36Sopenharmony_ci	}
326962306a36Sopenharmony_ci
327062306a36Sopenharmony_ci	if (unlikely(!pfmemalloc_match(slab, gfpflags))) {
327162306a36Sopenharmony_ci		/*
327262306a36Sopenharmony_ci		 * For !pfmemalloc_match() case we don't load freelist so that
327362306a36Sopenharmony_ci		 * we don't make further mismatched allocations easier.
327462306a36Sopenharmony_ci		 */
327562306a36Sopenharmony_ci		deactivate_slab(s, slab, get_freepointer(s, freelist));
327662306a36Sopenharmony_ci		return freelist;
327762306a36Sopenharmony_ci	}
327862306a36Sopenharmony_ci
327962306a36Sopenharmony_ciretry_load_slab:
328062306a36Sopenharmony_ci
328162306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, flags);
328262306a36Sopenharmony_ci	if (unlikely(c->slab)) {
328362306a36Sopenharmony_ci		void *flush_freelist = c->freelist;
328462306a36Sopenharmony_ci		struct slab *flush_slab = c->slab;
328562306a36Sopenharmony_ci
328662306a36Sopenharmony_ci		c->slab = NULL;
328762306a36Sopenharmony_ci		c->freelist = NULL;
328862306a36Sopenharmony_ci		c->tid = next_tid(c->tid);
328962306a36Sopenharmony_ci
329062306a36Sopenharmony_ci		local_unlock_irqrestore(&s->cpu_slab->lock, flags);
329162306a36Sopenharmony_ci
329262306a36Sopenharmony_ci		deactivate_slab(s, flush_slab, flush_freelist);
329362306a36Sopenharmony_ci
329462306a36Sopenharmony_ci		stat(s, CPUSLAB_FLUSH);
329562306a36Sopenharmony_ci
329662306a36Sopenharmony_ci		goto retry_load_slab;
329762306a36Sopenharmony_ci	}
329862306a36Sopenharmony_ci	c->slab = slab;
329962306a36Sopenharmony_ci
330062306a36Sopenharmony_ci	goto load_freelist;
330162306a36Sopenharmony_ci}
330262306a36Sopenharmony_ci
330362306a36Sopenharmony_ci/*
330462306a36Sopenharmony_ci * A wrapper for ___slab_alloc() for contexts where preemption is not yet
330562306a36Sopenharmony_ci * disabled. Compensates for possible cpu changes by refetching the per cpu area
330662306a36Sopenharmony_ci * pointer.
330762306a36Sopenharmony_ci */
330862306a36Sopenharmony_cistatic void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
330962306a36Sopenharmony_ci			  unsigned long addr, struct kmem_cache_cpu *c, unsigned int orig_size)
331062306a36Sopenharmony_ci{
331162306a36Sopenharmony_ci	void *p;
331262306a36Sopenharmony_ci
331362306a36Sopenharmony_ci#ifdef CONFIG_PREEMPT_COUNT
331462306a36Sopenharmony_ci	/*
331562306a36Sopenharmony_ci	 * We may have been preempted and rescheduled on a different
331662306a36Sopenharmony_ci	 * cpu before disabling preemption. Need to reload cpu area
331762306a36Sopenharmony_ci	 * pointer.
331862306a36Sopenharmony_ci	 */
331962306a36Sopenharmony_ci	c = slub_get_cpu_ptr(s->cpu_slab);
332062306a36Sopenharmony_ci#endif
332162306a36Sopenharmony_ci
332262306a36Sopenharmony_ci	p = ___slab_alloc(s, gfpflags, node, addr, c, orig_size);
332362306a36Sopenharmony_ci#ifdef CONFIG_PREEMPT_COUNT
332462306a36Sopenharmony_ci	slub_put_cpu_ptr(s->cpu_slab);
332562306a36Sopenharmony_ci#endif
332662306a36Sopenharmony_ci	return p;
332762306a36Sopenharmony_ci}
332862306a36Sopenharmony_ci
332962306a36Sopenharmony_cistatic __always_inline void *__slab_alloc_node(struct kmem_cache *s,
333062306a36Sopenharmony_ci		gfp_t gfpflags, int node, unsigned long addr, size_t orig_size)
333162306a36Sopenharmony_ci{
333262306a36Sopenharmony_ci	struct kmem_cache_cpu *c;
333362306a36Sopenharmony_ci	struct slab *slab;
333462306a36Sopenharmony_ci	unsigned long tid;
333562306a36Sopenharmony_ci	void *object;
333662306a36Sopenharmony_ci
333762306a36Sopenharmony_ciredo:
333862306a36Sopenharmony_ci	/*
333962306a36Sopenharmony_ci	 * Must read kmem_cache cpu data via this cpu ptr. Preemption is
334062306a36Sopenharmony_ci	 * enabled. We may switch back and forth between cpus while
334162306a36Sopenharmony_ci	 * reading from one cpu area. That does not matter as long
334262306a36Sopenharmony_ci	 * as we end up on the original cpu again when doing the cmpxchg.
334362306a36Sopenharmony_ci	 *
334462306a36Sopenharmony_ci	 * We must guarantee that tid and kmem_cache_cpu are retrieved on the
334562306a36Sopenharmony_ci	 * same cpu. We read first the kmem_cache_cpu pointer and use it to read
334662306a36Sopenharmony_ci	 * the tid. If we are preempted and switched to another cpu between the
334762306a36Sopenharmony_ci	 * two reads, it's OK as the two are still associated with the same cpu
334862306a36Sopenharmony_ci	 * and cmpxchg later will validate the cpu.
334962306a36Sopenharmony_ci	 */
335062306a36Sopenharmony_ci	c = raw_cpu_ptr(s->cpu_slab);
335162306a36Sopenharmony_ci	tid = READ_ONCE(c->tid);
335262306a36Sopenharmony_ci
335362306a36Sopenharmony_ci	/*
335462306a36Sopenharmony_ci	 * Irqless object alloc/free algorithm used here depends on sequence
335562306a36Sopenharmony_ci	 * of fetching cpu_slab's data. tid should be fetched before anything
335662306a36Sopenharmony_ci	 * on c to guarantee that object and slab associated with previous tid
335762306a36Sopenharmony_ci	 * won't be used with current tid. If we fetch tid first, object and
335862306a36Sopenharmony_ci	 * slab could be one associated with next tid and our alloc/free
335962306a36Sopenharmony_ci	 * request will be failed. In this case, we will retry. So, no problem.
336062306a36Sopenharmony_ci	 */
336162306a36Sopenharmony_ci	barrier();
336262306a36Sopenharmony_ci
336362306a36Sopenharmony_ci	/*
336462306a36Sopenharmony_ci	 * The transaction ids are globally unique per cpu and per operation on
336562306a36Sopenharmony_ci	 * a per cpu queue. Thus they can be guarantee that the cmpxchg_double
336662306a36Sopenharmony_ci	 * occurs on the right processor and that there was no operation on the
336762306a36Sopenharmony_ci	 * linked list in between.
336862306a36Sopenharmony_ci	 */
336962306a36Sopenharmony_ci
337062306a36Sopenharmony_ci	object = c->freelist;
337162306a36Sopenharmony_ci	slab = c->slab;
337262306a36Sopenharmony_ci
337362306a36Sopenharmony_ci	if (!USE_LOCKLESS_FAST_PATH() ||
337462306a36Sopenharmony_ci	    unlikely(!object || !slab || !node_match(slab, node))) {
337562306a36Sopenharmony_ci		object = __slab_alloc(s, gfpflags, node, addr, c, orig_size);
337662306a36Sopenharmony_ci	} else {
337762306a36Sopenharmony_ci		void *next_object = get_freepointer_safe(s, object);
337862306a36Sopenharmony_ci
337962306a36Sopenharmony_ci		/*
338062306a36Sopenharmony_ci		 * The cmpxchg will only match if there was no additional
338162306a36Sopenharmony_ci		 * operation and if we are on the right processor.
338262306a36Sopenharmony_ci		 *
338362306a36Sopenharmony_ci		 * The cmpxchg does the following atomically (without lock
338462306a36Sopenharmony_ci		 * semantics!)
338562306a36Sopenharmony_ci		 * 1. Relocate first pointer to the current per cpu area.
338662306a36Sopenharmony_ci		 * 2. Verify that tid and freelist have not been changed
338762306a36Sopenharmony_ci		 * 3. If they were not changed replace tid and freelist
338862306a36Sopenharmony_ci		 *
338962306a36Sopenharmony_ci		 * Since this is without lock semantics the protection is only
339062306a36Sopenharmony_ci		 * against code executing on this cpu *not* from access by
339162306a36Sopenharmony_ci		 * other cpus.
339262306a36Sopenharmony_ci		 */
339362306a36Sopenharmony_ci		if (unlikely(!__update_cpu_freelist_fast(s, object, next_object, tid))) {
339462306a36Sopenharmony_ci			note_cmpxchg_failure("slab_alloc", s, tid);
339562306a36Sopenharmony_ci			goto redo;
339662306a36Sopenharmony_ci		}
339762306a36Sopenharmony_ci		prefetch_freepointer(s, next_object);
339862306a36Sopenharmony_ci		stat(s, ALLOC_FASTPATH);
339962306a36Sopenharmony_ci	}
340062306a36Sopenharmony_ci
340162306a36Sopenharmony_ci	return object;
340262306a36Sopenharmony_ci}
340362306a36Sopenharmony_ci#else /* CONFIG_SLUB_TINY */
340462306a36Sopenharmony_cistatic void *__slab_alloc_node(struct kmem_cache *s,
340562306a36Sopenharmony_ci		gfp_t gfpflags, int node, unsigned long addr, size_t orig_size)
340662306a36Sopenharmony_ci{
340762306a36Sopenharmony_ci	struct partial_context pc;
340862306a36Sopenharmony_ci	struct slab *slab;
340962306a36Sopenharmony_ci	void *object;
341062306a36Sopenharmony_ci
341162306a36Sopenharmony_ci	pc.flags = gfpflags;
341262306a36Sopenharmony_ci	pc.slab = &slab;
341362306a36Sopenharmony_ci	pc.orig_size = orig_size;
341462306a36Sopenharmony_ci	object = get_partial(s, node, &pc);
341562306a36Sopenharmony_ci
341662306a36Sopenharmony_ci	if (object)
341762306a36Sopenharmony_ci		return object;
341862306a36Sopenharmony_ci
341962306a36Sopenharmony_ci	slab = new_slab(s, gfpflags, node);
342062306a36Sopenharmony_ci	if (unlikely(!slab)) {
342162306a36Sopenharmony_ci		slab_out_of_memory(s, gfpflags, node);
342262306a36Sopenharmony_ci		return NULL;
342362306a36Sopenharmony_ci	}
342462306a36Sopenharmony_ci
342562306a36Sopenharmony_ci	object = alloc_single_from_new_slab(s, slab, orig_size);
342662306a36Sopenharmony_ci
342762306a36Sopenharmony_ci	return object;
342862306a36Sopenharmony_ci}
342962306a36Sopenharmony_ci#endif /* CONFIG_SLUB_TINY */
343062306a36Sopenharmony_ci
343162306a36Sopenharmony_ci/*
343262306a36Sopenharmony_ci * If the object has been wiped upon free, make sure it's fully initialized by
343362306a36Sopenharmony_ci * zeroing out freelist pointer.
343462306a36Sopenharmony_ci */
343562306a36Sopenharmony_cistatic __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s,
343662306a36Sopenharmony_ci						   void *obj)
343762306a36Sopenharmony_ci{
343862306a36Sopenharmony_ci	if (unlikely(slab_want_init_on_free(s)) && obj)
343962306a36Sopenharmony_ci		memset((void *)((char *)kasan_reset_tag(obj) + s->offset),
344062306a36Sopenharmony_ci			0, sizeof(void *));
344162306a36Sopenharmony_ci}
344262306a36Sopenharmony_ci
344362306a36Sopenharmony_ci/*
344462306a36Sopenharmony_ci * Inlined fastpath so that allocation functions (kmalloc, kmem_cache_alloc)
344562306a36Sopenharmony_ci * have the fastpath folded into their functions. So no function call
344662306a36Sopenharmony_ci * overhead for requests that can be satisfied on the fastpath.
344762306a36Sopenharmony_ci *
344862306a36Sopenharmony_ci * The fastpath works by first checking if the lockless freelist can be used.
344962306a36Sopenharmony_ci * If not then __slab_alloc is called for slow processing.
345062306a36Sopenharmony_ci *
345162306a36Sopenharmony_ci * Otherwise we can simply pick the next object from the lockless free list.
345262306a36Sopenharmony_ci */
345362306a36Sopenharmony_cistatic __fastpath_inline void *slab_alloc_node(struct kmem_cache *s, struct list_lru *lru,
345462306a36Sopenharmony_ci		gfp_t gfpflags, int node, unsigned long addr, size_t orig_size)
345562306a36Sopenharmony_ci{
345662306a36Sopenharmony_ci	void *object;
345762306a36Sopenharmony_ci	struct obj_cgroup *objcg = NULL;
345862306a36Sopenharmony_ci	bool init = false;
345962306a36Sopenharmony_ci
346062306a36Sopenharmony_ci	s = slab_pre_alloc_hook(s, lru, &objcg, 1, gfpflags);
346162306a36Sopenharmony_ci	if (!s)
346262306a36Sopenharmony_ci		return NULL;
346362306a36Sopenharmony_ci
346462306a36Sopenharmony_ci	object = kfence_alloc(s, orig_size, gfpflags);
346562306a36Sopenharmony_ci	if (unlikely(object))
346662306a36Sopenharmony_ci		goto out;
346762306a36Sopenharmony_ci
346862306a36Sopenharmony_ci	object = __slab_alloc_node(s, gfpflags, node, addr, orig_size);
346962306a36Sopenharmony_ci
347062306a36Sopenharmony_ci	maybe_wipe_obj_freeptr(s, object);
347162306a36Sopenharmony_ci	init = slab_want_init_on_alloc(gfpflags, s);
347262306a36Sopenharmony_ci
347362306a36Sopenharmony_ciout:
347462306a36Sopenharmony_ci	/*
347562306a36Sopenharmony_ci	 * When init equals 'true', like for kzalloc() family, only
347662306a36Sopenharmony_ci	 * @orig_size bytes might be zeroed instead of s->object_size
347762306a36Sopenharmony_ci	 */
347862306a36Sopenharmony_ci	slab_post_alloc_hook(s, objcg, gfpflags, 1, &object, init, orig_size);
347962306a36Sopenharmony_ci
348062306a36Sopenharmony_ci	return object;
348162306a36Sopenharmony_ci}
348262306a36Sopenharmony_ci
348362306a36Sopenharmony_cistatic __fastpath_inline void *slab_alloc(struct kmem_cache *s, struct list_lru *lru,
348462306a36Sopenharmony_ci		gfp_t gfpflags, unsigned long addr, size_t orig_size)
348562306a36Sopenharmony_ci{
348662306a36Sopenharmony_ci	return slab_alloc_node(s, lru, gfpflags, NUMA_NO_NODE, addr, orig_size);
348762306a36Sopenharmony_ci}
348862306a36Sopenharmony_ci
348962306a36Sopenharmony_cistatic __fastpath_inline
349062306a36Sopenharmony_civoid *__kmem_cache_alloc_lru(struct kmem_cache *s, struct list_lru *lru,
349162306a36Sopenharmony_ci			     gfp_t gfpflags)
349262306a36Sopenharmony_ci{
349362306a36Sopenharmony_ci	void *ret = slab_alloc(s, lru, gfpflags, _RET_IP_, s->object_size);
349462306a36Sopenharmony_ci
349562306a36Sopenharmony_ci	trace_kmem_cache_alloc(_RET_IP_, ret, s, gfpflags, NUMA_NO_NODE);
349662306a36Sopenharmony_ci
349762306a36Sopenharmony_ci	return ret;
349862306a36Sopenharmony_ci}
349962306a36Sopenharmony_ci
350062306a36Sopenharmony_civoid *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
350162306a36Sopenharmony_ci{
350262306a36Sopenharmony_ci	return __kmem_cache_alloc_lru(s, NULL, gfpflags);
350362306a36Sopenharmony_ci}
350462306a36Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_alloc);
350562306a36Sopenharmony_ci
350662306a36Sopenharmony_civoid *kmem_cache_alloc_lru(struct kmem_cache *s, struct list_lru *lru,
350762306a36Sopenharmony_ci			   gfp_t gfpflags)
350862306a36Sopenharmony_ci{
350962306a36Sopenharmony_ci	return __kmem_cache_alloc_lru(s, lru, gfpflags);
351062306a36Sopenharmony_ci}
351162306a36Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_alloc_lru);
351262306a36Sopenharmony_ci
351362306a36Sopenharmony_civoid *__kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags,
351462306a36Sopenharmony_ci			      int node, size_t orig_size,
351562306a36Sopenharmony_ci			      unsigned long caller)
351662306a36Sopenharmony_ci{
351762306a36Sopenharmony_ci	return slab_alloc_node(s, NULL, gfpflags, node,
351862306a36Sopenharmony_ci			       caller, orig_size);
351962306a36Sopenharmony_ci}
352062306a36Sopenharmony_ci
352162306a36Sopenharmony_civoid *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
352262306a36Sopenharmony_ci{
352362306a36Sopenharmony_ci	void *ret = slab_alloc_node(s, NULL, gfpflags, node, _RET_IP_, s->object_size);
352462306a36Sopenharmony_ci
352562306a36Sopenharmony_ci	trace_kmem_cache_alloc(_RET_IP_, ret, s, gfpflags, node);
352662306a36Sopenharmony_ci
352762306a36Sopenharmony_ci	return ret;
352862306a36Sopenharmony_ci}
352962306a36Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_alloc_node);
353062306a36Sopenharmony_ci
353162306a36Sopenharmony_cistatic noinline void free_to_partial_list(
353262306a36Sopenharmony_ci	struct kmem_cache *s, struct slab *slab,
353362306a36Sopenharmony_ci	void *head, void *tail, int bulk_cnt,
353462306a36Sopenharmony_ci	unsigned long addr)
353562306a36Sopenharmony_ci{
353662306a36Sopenharmony_ci	struct kmem_cache_node *n = get_node(s, slab_nid(slab));
353762306a36Sopenharmony_ci	struct slab *slab_free = NULL;
353862306a36Sopenharmony_ci	int cnt = bulk_cnt;
353962306a36Sopenharmony_ci	unsigned long flags;
354062306a36Sopenharmony_ci	depot_stack_handle_t handle = 0;
354162306a36Sopenharmony_ci
354262306a36Sopenharmony_ci	if (s->flags & SLAB_STORE_USER)
354362306a36Sopenharmony_ci		handle = set_track_prepare();
354462306a36Sopenharmony_ci
354562306a36Sopenharmony_ci	spin_lock_irqsave(&n->list_lock, flags);
354662306a36Sopenharmony_ci
354762306a36Sopenharmony_ci	if (free_debug_processing(s, slab, head, tail, &cnt, addr, handle)) {
354862306a36Sopenharmony_ci		void *prior = slab->freelist;
354962306a36Sopenharmony_ci
355062306a36Sopenharmony_ci		/* Perform the actual freeing while we still hold the locks */
355162306a36Sopenharmony_ci		slab->inuse -= cnt;
355262306a36Sopenharmony_ci		set_freepointer(s, tail, prior);
355362306a36Sopenharmony_ci		slab->freelist = head;
355462306a36Sopenharmony_ci
355562306a36Sopenharmony_ci		/*
355662306a36Sopenharmony_ci		 * If the slab is empty, and node's partial list is full,
355762306a36Sopenharmony_ci		 * it should be discarded anyway no matter it's on full or
355862306a36Sopenharmony_ci		 * partial list.
355962306a36Sopenharmony_ci		 */
356062306a36Sopenharmony_ci		if (slab->inuse == 0 && n->nr_partial >= s->min_partial)
356162306a36Sopenharmony_ci			slab_free = slab;
356262306a36Sopenharmony_ci
356362306a36Sopenharmony_ci		if (!prior) {
356462306a36Sopenharmony_ci			/* was on full list */
356562306a36Sopenharmony_ci			remove_full(s, n, slab);
356662306a36Sopenharmony_ci			if (!slab_free) {
356762306a36Sopenharmony_ci				add_partial(n, slab, DEACTIVATE_TO_TAIL);
356862306a36Sopenharmony_ci				stat(s, FREE_ADD_PARTIAL);
356962306a36Sopenharmony_ci			}
357062306a36Sopenharmony_ci		} else if (slab_free) {
357162306a36Sopenharmony_ci			remove_partial(n, slab);
357262306a36Sopenharmony_ci			stat(s, FREE_REMOVE_PARTIAL);
357362306a36Sopenharmony_ci		}
357462306a36Sopenharmony_ci	}
357562306a36Sopenharmony_ci
357662306a36Sopenharmony_ci	if (slab_free) {
357762306a36Sopenharmony_ci		/*
357862306a36Sopenharmony_ci		 * Update the counters while still holding n->list_lock to
357962306a36Sopenharmony_ci		 * prevent spurious validation warnings
358062306a36Sopenharmony_ci		 */
358162306a36Sopenharmony_ci		dec_slabs_node(s, slab_nid(slab_free), slab_free->objects);
358262306a36Sopenharmony_ci	}
358362306a36Sopenharmony_ci
358462306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
358562306a36Sopenharmony_ci
358662306a36Sopenharmony_ci	if (slab_free) {
358762306a36Sopenharmony_ci		stat(s, FREE_SLAB);
358862306a36Sopenharmony_ci		free_slab(s, slab_free);
358962306a36Sopenharmony_ci	}
359062306a36Sopenharmony_ci}
359162306a36Sopenharmony_ci
359262306a36Sopenharmony_ci/*
359362306a36Sopenharmony_ci * Slow path handling. This may still be called frequently since objects
359462306a36Sopenharmony_ci * have a longer lifetime than the cpu slabs in most processing loads.
359562306a36Sopenharmony_ci *
359662306a36Sopenharmony_ci * So we still attempt to reduce cache line usage. Just take the slab
359762306a36Sopenharmony_ci * lock and free the item. If there is no additional partial slab
359862306a36Sopenharmony_ci * handling required then we can return immediately.
359962306a36Sopenharmony_ci */
360062306a36Sopenharmony_cistatic void __slab_free(struct kmem_cache *s, struct slab *slab,
360162306a36Sopenharmony_ci			void *head, void *tail, int cnt,
360262306a36Sopenharmony_ci			unsigned long addr)
360362306a36Sopenharmony_ci
360462306a36Sopenharmony_ci{
360562306a36Sopenharmony_ci	void *prior;
360662306a36Sopenharmony_ci	int was_frozen;
360762306a36Sopenharmony_ci	struct slab new;
360862306a36Sopenharmony_ci	unsigned long counters;
360962306a36Sopenharmony_ci	struct kmem_cache_node *n = NULL;
361062306a36Sopenharmony_ci	unsigned long flags;
361162306a36Sopenharmony_ci
361262306a36Sopenharmony_ci	stat(s, FREE_SLOWPATH);
361362306a36Sopenharmony_ci
361462306a36Sopenharmony_ci	if (kfence_free(head))
361562306a36Sopenharmony_ci		return;
361662306a36Sopenharmony_ci
361762306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_SLUB_TINY) || kmem_cache_debug(s)) {
361862306a36Sopenharmony_ci		free_to_partial_list(s, slab, head, tail, cnt, addr);
361962306a36Sopenharmony_ci		return;
362062306a36Sopenharmony_ci	}
362162306a36Sopenharmony_ci
362262306a36Sopenharmony_ci	do {
362362306a36Sopenharmony_ci		if (unlikely(n)) {
362462306a36Sopenharmony_ci			spin_unlock_irqrestore(&n->list_lock, flags);
362562306a36Sopenharmony_ci			n = NULL;
362662306a36Sopenharmony_ci		}
362762306a36Sopenharmony_ci		prior = slab->freelist;
362862306a36Sopenharmony_ci		counters = slab->counters;
362962306a36Sopenharmony_ci		set_freepointer(s, tail, prior);
363062306a36Sopenharmony_ci		new.counters = counters;
363162306a36Sopenharmony_ci		was_frozen = new.frozen;
363262306a36Sopenharmony_ci		new.inuse -= cnt;
363362306a36Sopenharmony_ci		if ((!new.inuse || !prior) && !was_frozen) {
363462306a36Sopenharmony_ci
363562306a36Sopenharmony_ci			if (kmem_cache_has_cpu_partial(s) && !prior) {
363662306a36Sopenharmony_ci
363762306a36Sopenharmony_ci				/*
363862306a36Sopenharmony_ci				 * Slab was on no list before and will be
363962306a36Sopenharmony_ci				 * partially empty
364062306a36Sopenharmony_ci				 * We can defer the list move and instead
364162306a36Sopenharmony_ci				 * freeze it.
364262306a36Sopenharmony_ci				 */
364362306a36Sopenharmony_ci				new.frozen = 1;
364462306a36Sopenharmony_ci
364562306a36Sopenharmony_ci			} else { /* Needs to be taken off a list */
364662306a36Sopenharmony_ci
364762306a36Sopenharmony_ci				n = get_node(s, slab_nid(slab));
364862306a36Sopenharmony_ci				/*
364962306a36Sopenharmony_ci				 * Speculatively acquire the list_lock.
365062306a36Sopenharmony_ci				 * If the cmpxchg does not succeed then we may
365162306a36Sopenharmony_ci				 * drop the list_lock without any processing.
365262306a36Sopenharmony_ci				 *
365362306a36Sopenharmony_ci				 * Otherwise the list_lock will synchronize with
365462306a36Sopenharmony_ci				 * other processors updating the list of slabs.
365562306a36Sopenharmony_ci				 */
365662306a36Sopenharmony_ci				spin_lock_irqsave(&n->list_lock, flags);
365762306a36Sopenharmony_ci
365862306a36Sopenharmony_ci			}
365962306a36Sopenharmony_ci		}
366062306a36Sopenharmony_ci
366162306a36Sopenharmony_ci	} while (!slab_update_freelist(s, slab,
366262306a36Sopenharmony_ci		prior, counters,
366362306a36Sopenharmony_ci		head, new.counters,
366462306a36Sopenharmony_ci		"__slab_free"));
366562306a36Sopenharmony_ci
366662306a36Sopenharmony_ci	if (likely(!n)) {
366762306a36Sopenharmony_ci
366862306a36Sopenharmony_ci		if (likely(was_frozen)) {
366962306a36Sopenharmony_ci			/*
367062306a36Sopenharmony_ci			 * The list lock was not taken therefore no list
367162306a36Sopenharmony_ci			 * activity can be necessary.
367262306a36Sopenharmony_ci			 */
367362306a36Sopenharmony_ci			stat(s, FREE_FROZEN);
367462306a36Sopenharmony_ci		} else if (new.frozen) {
367562306a36Sopenharmony_ci			/*
367662306a36Sopenharmony_ci			 * If we just froze the slab then put it onto the
367762306a36Sopenharmony_ci			 * per cpu partial list.
367862306a36Sopenharmony_ci			 */
367962306a36Sopenharmony_ci			put_cpu_partial(s, slab, 1);
368062306a36Sopenharmony_ci			stat(s, CPU_PARTIAL_FREE);
368162306a36Sopenharmony_ci		}
368262306a36Sopenharmony_ci
368362306a36Sopenharmony_ci		return;
368462306a36Sopenharmony_ci	}
368562306a36Sopenharmony_ci
368662306a36Sopenharmony_ci	if (unlikely(!new.inuse && n->nr_partial >= s->min_partial))
368762306a36Sopenharmony_ci		goto slab_empty;
368862306a36Sopenharmony_ci
368962306a36Sopenharmony_ci	/*
369062306a36Sopenharmony_ci	 * Objects left in the slab. If it was not on the partial list before
369162306a36Sopenharmony_ci	 * then add it.
369262306a36Sopenharmony_ci	 */
369362306a36Sopenharmony_ci	if (!kmem_cache_has_cpu_partial(s) && unlikely(!prior)) {
369462306a36Sopenharmony_ci		remove_full(s, n, slab);
369562306a36Sopenharmony_ci		add_partial(n, slab, DEACTIVATE_TO_TAIL);
369662306a36Sopenharmony_ci		stat(s, FREE_ADD_PARTIAL);
369762306a36Sopenharmony_ci	}
369862306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
369962306a36Sopenharmony_ci	return;
370062306a36Sopenharmony_ci
370162306a36Sopenharmony_cislab_empty:
370262306a36Sopenharmony_ci	if (prior) {
370362306a36Sopenharmony_ci		/*
370462306a36Sopenharmony_ci		 * Slab on the partial list.
370562306a36Sopenharmony_ci		 */
370662306a36Sopenharmony_ci		remove_partial(n, slab);
370762306a36Sopenharmony_ci		stat(s, FREE_REMOVE_PARTIAL);
370862306a36Sopenharmony_ci	} else {
370962306a36Sopenharmony_ci		/* Slab must be on the full list */
371062306a36Sopenharmony_ci		remove_full(s, n, slab);
371162306a36Sopenharmony_ci	}
371262306a36Sopenharmony_ci
371362306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
371462306a36Sopenharmony_ci	stat(s, FREE_SLAB);
371562306a36Sopenharmony_ci	discard_slab(s, slab);
371662306a36Sopenharmony_ci}
371762306a36Sopenharmony_ci
371862306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
371962306a36Sopenharmony_ci/*
372062306a36Sopenharmony_ci * Fastpath with forced inlining to produce a kfree and kmem_cache_free that
372162306a36Sopenharmony_ci * can perform fastpath freeing without additional function calls.
372262306a36Sopenharmony_ci *
372362306a36Sopenharmony_ci * The fastpath is only possible if we are freeing to the current cpu slab
372462306a36Sopenharmony_ci * of this processor. This typically the case if we have just allocated
372562306a36Sopenharmony_ci * the item before.
372662306a36Sopenharmony_ci *
372762306a36Sopenharmony_ci * If fastpath is not possible then fall back to __slab_free where we deal
372862306a36Sopenharmony_ci * with all sorts of special processing.
372962306a36Sopenharmony_ci *
373062306a36Sopenharmony_ci * Bulk free of a freelist with several objects (all pointing to the
373162306a36Sopenharmony_ci * same slab) possible by specifying head and tail ptr, plus objects
373262306a36Sopenharmony_ci * count (cnt). Bulk free indicated by tail pointer being set.
373362306a36Sopenharmony_ci */
373462306a36Sopenharmony_cistatic __always_inline void do_slab_free(struct kmem_cache *s,
373562306a36Sopenharmony_ci				struct slab *slab, void *head, void *tail,
373662306a36Sopenharmony_ci				int cnt, unsigned long addr)
373762306a36Sopenharmony_ci{
373862306a36Sopenharmony_ci	void *tail_obj = tail ? : head;
373962306a36Sopenharmony_ci	struct kmem_cache_cpu *c;
374062306a36Sopenharmony_ci	unsigned long tid;
374162306a36Sopenharmony_ci	void **freelist;
374262306a36Sopenharmony_ci
374362306a36Sopenharmony_ciredo:
374462306a36Sopenharmony_ci	/*
374562306a36Sopenharmony_ci	 * Determine the currently cpus per cpu slab.
374662306a36Sopenharmony_ci	 * The cpu may change afterward. However that does not matter since
374762306a36Sopenharmony_ci	 * data is retrieved via this pointer. If we are on the same cpu
374862306a36Sopenharmony_ci	 * during the cmpxchg then the free will succeed.
374962306a36Sopenharmony_ci	 */
375062306a36Sopenharmony_ci	c = raw_cpu_ptr(s->cpu_slab);
375162306a36Sopenharmony_ci	tid = READ_ONCE(c->tid);
375262306a36Sopenharmony_ci
375362306a36Sopenharmony_ci	/* Same with comment on barrier() in slab_alloc_node() */
375462306a36Sopenharmony_ci	barrier();
375562306a36Sopenharmony_ci
375662306a36Sopenharmony_ci	if (unlikely(slab != c->slab)) {
375762306a36Sopenharmony_ci		__slab_free(s, slab, head, tail_obj, cnt, addr);
375862306a36Sopenharmony_ci		return;
375962306a36Sopenharmony_ci	}
376062306a36Sopenharmony_ci
376162306a36Sopenharmony_ci	if (USE_LOCKLESS_FAST_PATH()) {
376262306a36Sopenharmony_ci		freelist = READ_ONCE(c->freelist);
376362306a36Sopenharmony_ci
376462306a36Sopenharmony_ci		set_freepointer(s, tail_obj, freelist);
376562306a36Sopenharmony_ci
376662306a36Sopenharmony_ci		if (unlikely(!__update_cpu_freelist_fast(s, freelist, head, tid))) {
376762306a36Sopenharmony_ci			note_cmpxchg_failure("slab_free", s, tid);
376862306a36Sopenharmony_ci			goto redo;
376962306a36Sopenharmony_ci		}
377062306a36Sopenharmony_ci	} else {
377162306a36Sopenharmony_ci		/* Update the free list under the local lock */
377262306a36Sopenharmony_ci		local_lock(&s->cpu_slab->lock);
377362306a36Sopenharmony_ci		c = this_cpu_ptr(s->cpu_slab);
377462306a36Sopenharmony_ci		if (unlikely(slab != c->slab)) {
377562306a36Sopenharmony_ci			local_unlock(&s->cpu_slab->lock);
377662306a36Sopenharmony_ci			goto redo;
377762306a36Sopenharmony_ci		}
377862306a36Sopenharmony_ci		tid = c->tid;
377962306a36Sopenharmony_ci		freelist = c->freelist;
378062306a36Sopenharmony_ci
378162306a36Sopenharmony_ci		set_freepointer(s, tail_obj, freelist);
378262306a36Sopenharmony_ci		c->freelist = head;
378362306a36Sopenharmony_ci		c->tid = next_tid(tid);
378462306a36Sopenharmony_ci
378562306a36Sopenharmony_ci		local_unlock(&s->cpu_slab->lock);
378662306a36Sopenharmony_ci	}
378762306a36Sopenharmony_ci	stat(s, FREE_FASTPATH);
378862306a36Sopenharmony_ci}
378962306a36Sopenharmony_ci#else /* CONFIG_SLUB_TINY */
379062306a36Sopenharmony_cistatic void do_slab_free(struct kmem_cache *s,
379162306a36Sopenharmony_ci				struct slab *slab, void *head, void *tail,
379262306a36Sopenharmony_ci				int cnt, unsigned long addr)
379362306a36Sopenharmony_ci{
379462306a36Sopenharmony_ci	void *tail_obj = tail ? : head;
379562306a36Sopenharmony_ci
379662306a36Sopenharmony_ci	__slab_free(s, slab, head, tail_obj, cnt, addr);
379762306a36Sopenharmony_ci}
379862306a36Sopenharmony_ci#endif /* CONFIG_SLUB_TINY */
379962306a36Sopenharmony_ci
380062306a36Sopenharmony_cistatic __fastpath_inline void slab_free(struct kmem_cache *s, struct slab *slab,
380162306a36Sopenharmony_ci				      void *head, void *tail, void **p, int cnt,
380262306a36Sopenharmony_ci				      unsigned long addr)
380362306a36Sopenharmony_ci{
380462306a36Sopenharmony_ci	memcg_slab_free_hook(s, slab, p, cnt);
380562306a36Sopenharmony_ci	/*
380662306a36Sopenharmony_ci	 * With KASAN enabled slab_free_freelist_hook modifies the freelist
380762306a36Sopenharmony_ci	 * to remove objects, whose reuse must be delayed.
380862306a36Sopenharmony_ci	 */
380962306a36Sopenharmony_ci	if (slab_free_freelist_hook(s, &head, &tail, &cnt))
381062306a36Sopenharmony_ci		do_slab_free(s, slab, head, tail, cnt, addr);
381162306a36Sopenharmony_ci}
381262306a36Sopenharmony_ci
381362306a36Sopenharmony_ci#ifdef CONFIG_KASAN_GENERIC
381462306a36Sopenharmony_civoid ___cache_free(struct kmem_cache *cache, void *x, unsigned long addr)
381562306a36Sopenharmony_ci{
381662306a36Sopenharmony_ci	do_slab_free(cache, virt_to_slab(x), x, NULL, 1, addr);
381762306a36Sopenharmony_ci}
381862306a36Sopenharmony_ci#endif
381962306a36Sopenharmony_ci
382062306a36Sopenharmony_civoid __kmem_cache_free(struct kmem_cache *s, void *x, unsigned long caller)
382162306a36Sopenharmony_ci{
382262306a36Sopenharmony_ci	slab_free(s, virt_to_slab(x), x, NULL, &x, 1, caller);
382362306a36Sopenharmony_ci}
382462306a36Sopenharmony_ci
382562306a36Sopenharmony_civoid kmem_cache_free(struct kmem_cache *s, void *x)
382662306a36Sopenharmony_ci{
382762306a36Sopenharmony_ci	s = cache_from_obj(s, x);
382862306a36Sopenharmony_ci	if (!s)
382962306a36Sopenharmony_ci		return;
383062306a36Sopenharmony_ci	trace_kmem_cache_free(_RET_IP_, x, s);
383162306a36Sopenharmony_ci	slab_free(s, virt_to_slab(x), x, NULL, &x, 1, _RET_IP_);
383262306a36Sopenharmony_ci}
383362306a36Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_free);
383462306a36Sopenharmony_ci
383562306a36Sopenharmony_cistruct detached_freelist {
383662306a36Sopenharmony_ci	struct slab *slab;
383762306a36Sopenharmony_ci	void *tail;
383862306a36Sopenharmony_ci	void *freelist;
383962306a36Sopenharmony_ci	int cnt;
384062306a36Sopenharmony_ci	struct kmem_cache *s;
384162306a36Sopenharmony_ci};
384262306a36Sopenharmony_ci
384362306a36Sopenharmony_ci/*
384462306a36Sopenharmony_ci * This function progressively scans the array with free objects (with
384562306a36Sopenharmony_ci * a limited look ahead) and extract objects belonging to the same
384662306a36Sopenharmony_ci * slab.  It builds a detached freelist directly within the given
384762306a36Sopenharmony_ci * slab/objects.  This can happen without any need for
384862306a36Sopenharmony_ci * synchronization, because the objects are owned by running process.
384962306a36Sopenharmony_ci * The freelist is build up as a single linked list in the objects.
385062306a36Sopenharmony_ci * The idea is, that this detached freelist can then be bulk
385162306a36Sopenharmony_ci * transferred to the real freelist(s), but only requiring a single
385262306a36Sopenharmony_ci * synchronization primitive.  Look ahead in the array is limited due
385362306a36Sopenharmony_ci * to performance reasons.
385462306a36Sopenharmony_ci */
385562306a36Sopenharmony_cistatic inline
385662306a36Sopenharmony_ciint build_detached_freelist(struct kmem_cache *s, size_t size,
385762306a36Sopenharmony_ci			    void **p, struct detached_freelist *df)
385862306a36Sopenharmony_ci{
385962306a36Sopenharmony_ci	int lookahead = 3;
386062306a36Sopenharmony_ci	void *object;
386162306a36Sopenharmony_ci	struct folio *folio;
386262306a36Sopenharmony_ci	size_t same;
386362306a36Sopenharmony_ci
386462306a36Sopenharmony_ci	object = p[--size];
386562306a36Sopenharmony_ci	folio = virt_to_folio(object);
386662306a36Sopenharmony_ci	if (!s) {
386762306a36Sopenharmony_ci		/* Handle kalloc'ed objects */
386862306a36Sopenharmony_ci		if (unlikely(!folio_test_slab(folio))) {
386962306a36Sopenharmony_ci			free_large_kmalloc(folio, object);
387062306a36Sopenharmony_ci			df->slab = NULL;
387162306a36Sopenharmony_ci			return size;
387262306a36Sopenharmony_ci		}
387362306a36Sopenharmony_ci		/* Derive kmem_cache from object */
387462306a36Sopenharmony_ci		df->slab = folio_slab(folio);
387562306a36Sopenharmony_ci		df->s = df->slab->slab_cache;
387662306a36Sopenharmony_ci	} else {
387762306a36Sopenharmony_ci		df->slab = folio_slab(folio);
387862306a36Sopenharmony_ci		df->s = cache_from_obj(s, object); /* Support for memcg */
387962306a36Sopenharmony_ci	}
388062306a36Sopenharmony_ci
388162306a36Sopenharmony_ci	/* Start new detached freelist */
388262306a36Sopenharmony_ci	df->tail = object;
388362306a36Sopenharmony_ci	df->freelist = object;
388462306a36Sopenharmony_ci	df->cnt = 1;
388562306a36Sopenharmony_ci
388662306a36Sopenharmony_ci	if (is_kfence_address(object))
388762306a36Sopenharmony_ci		return size;
388862306a36Sopenharmony_ci
388962306a36Sopenharmony_ci	set_freepointer(df->s, object, NULL);
389062306a36Sopenharmony_ci
389162306a36Sopenharmony_ci	same = size;
389262306a36Sopenharmony_ci	while (size) {
389362306a36Sopenharmony_ci		object = p[--size];
389462306a36Sopenharmony_ci		/* df->slab is always set at this point */
389562306a36Sopenharmony_ci		if (df->slab == virt_to_slab(object)) {
389662306a36Sopenharmony_ci			/* Opportunity build freelist */
389762306a36Sopenharmony_ci			set_freepointer(df->s, object, df->freelist);
389862306a36Sopenharmony_ci			df->freelist = object;
389962306a36Sopenharmony_ci			df->cnt++;
390062306a36Sopenharmony_ci			same--;
390162306a36Sopenharmony_ci			if (size != same)
390262306a36Sopenharmony_ci				swap(p[size], p[same]);
390362306a36Sopenharmony_ci			continue;
390462306a36Sopenharmony_ci		}
390562306a36Sopenharmony_ci
390662306a36Sopenharmony_ci		/* Limit look ahead search */
390762306a36Sopenharmony_ci		if (!--lookahead)
390862306a36Sopenharmony_ci			break;
390962306a36Sopenharmony_ci	}
391062306a36Sopenharmony_ci
391162306a36Sopenharmony_ci	return same;
391262306a36Sopenharmony_ci}
391362306a36Sopenharmony_ci
391462306a36Sopenharmony_ci/* Note that interrupts must be enabled when calling this function. */
391562306a36Sopenharmony_civoid kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p)
391662306a36Sopenharmony_ci{
391762306a36Sopenharmony_ci	if (!size)
391862306a36Sopenharmony_ci		return;
391962306a36Sopenharmony_ci
392062306a36Sopenharmony_ci	do {
392162306a36Sopenharmony_ci		struct detached_freelist df;
392262306a36Sopenharmony_ci
392362306a36Sopenharmony_ci		size = build_detached_freelist(s, size, p, &df);
392462306a36Sopenharmony_ci		if (!df.slab)
392562306a36Sopenharmony_ci			continue;
392662306a36Sopenharmony_ci
392762306a36Sopenharmony_ci		slab_free(df.s, df.slab, df.freelist, df.tail, &p[size], df.cnt,
392862306a36Sopenharmony_ci			  _RET_IP_);
392962306a36Sopenharmony_ci	} while (likely(size));
393062306a36Sopenharmony_ci}
393162306a36Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_free_bulk);
393262306a36Sopenharmony_ci
393362306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
393462306a36Sopenharmony_cistatic inline int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags,
393562306a36Sopenharmony_ci			size_t size, void **p, struct obj_cgroup *objcg)
393662306a36Sopenharmony_ci{
393762306a36Sopenharmony_ci	struct kmem_cache_cpu *c;
393862306a36Sopenharmony_ci	unsigned long irqflags;
393962306a36Sopenharmony_ci	int i;
394062306a36Sopenharmony_ci
394162306a36Sopenharmony_ci	/*
394262306a36Sopenharmony_ci	 * Drain objects in the per cpu slab, while disabling local
394362306a36Sopenharmony_ci	 * IRQs, which protects against PREEMPT and interrupts
394462306a36Sopenharmony_ci	 * handlers invoking normal fastpath.
394562306a36Sopenharmony_ci	 */
394662306a36Sopenharmony_ci	c = slub_get_cpu_ptr(s->cpu_slab);
394762306a36Sopenharmony_ci	local_lock_irqsave(&s->cpu_slab->lock, irqflags);
394862306a36Sopenharmony_ci
394962306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
395062306a36Sopenharmony_ci		void *object = kfence_alloc(s, s->object_size, flags);
395162306a36Sopenharmony_ci
395262306a36Sopenharmony_ci		if (unlikely(object)) {
395362306a36Sopenharmony_ci			p[i] = object;
395462306a36Sopenharmony_ci			continue;
395562306a36Sopenharmony_ci		}
395662306a36Sopenharmony_ci
395762306a36Sopenharmony_ci		object = c->freelist;
395862306a36Sopenharmony_ci		if (unlikely(!object)) {
395962306a36Sopenharmony_ci			/*
396062306a36Sopenharmony_ci			 * We may have removed an object from c->freelist using
396162306a36Sopenharmony_ci			 * the fastpath in the previous iteration; in that case,
396262306a36Sopenharmony_ci			 * c->tid has not been bumped yet.
396362306a36Sopenharmony_ci			 * Since ___slab_alloc() may reenable interrupts while
396462306a36Sopenharmony_ci			 * allocating memory, we should bump c->tid now.
396562306a36Sopenharmony_ci			 */
396662306a36Sopenharmony_ci			c->tid = next_tid(c->tid);
396762306a36Sopenharmony_ci
396862306a36Sopenharmony_ci			local_unlock_irqrestore(&s->cpu_slab->lock, irqflags);
396962306a36Sopenharmony_ci
397062306a36Sopenharmony_ci			/*
397162306a36Sopenharmony_ci			 * Invoking slow path likely have side-effect
397262306a36Sopenharmony_ci			 * of re-populating per CPU c->freelist
397362306a36Sopenharmony_ci			 */
397462306a36Sopenharmony_ci			p[i] = ___slab_alloc(s, flags, NUMA_NO_NODE,
397562306a36Sopenharmony_ci					    _RET_IP_, c, s->object_size);
397662306a36Sopenharmony_ci			if (unlikely(!p[i]))
397762306a36Sopenharmony_ci				goto error;
397862306a36Sopenharmony_ci
397962306a36Sopenharmony_ci			c = this_cpu_ptr(s->cpu_slab);
398062306a36Sopenharmony_ci			maybe_wipe_obj_freeptr(s, p[i]);
398162306a36Sopenharmony_ci
398262306a36Sopenharmony_ci			local_lock_irqsave(&s->cpu_slab->lock, irqflags);
398362306a36Sopenharmony_ci
398462306a36Sopenharmony_ci			continue; /* goto for-loop */
398562306a36Sopenharmony_ci		}
398662306a36Sopenharmony_ci		c->freelist = get_freepointer(s, object);
398762306a36Sopenharmony_ci		p[i] = object;
398862306a36Sopenharmony_ci		maybe_wipe_obj_freeptr(s, p[i]);
398962306a36Sopenharmony_ci	}
399062306a36Sopenharmony_ci	c->tid = next_tid(c->tid);
399162306a36Sopenharmony_ci	local_unlock_irqrestore(&s->cpu_slab->lock, irqflags);
399262306a36Sopenharmony_ci	slub_put_cpu_ptr(s->cpu_slab);
399362306a36Sopenharmony_ci
399462306a36Sopenharmony_ci	return i;
399562306a36Sopenharmony_ci
399662306a36Sopenharmony_cierror:
399762306a36Sopenharmony_ci	slub_put_cpu_ptr(s->cpu_slab);
399862306a36Sopenharmony_ci	slab_post_alloc_hook(s, objcg, flags, i, p, false, s->object_size);
399962306a36Sopenharmony_ci	kmem_cache_free_bulk(s, i, p);
400062306a36Sopenharmony_ci	return 0;
400162306a36Sopenharmony_ci
400262306a36Sopenharmony_ci}
400362306a36Sopenharmony_ci#else /* CONFIG_SLUB_TINY */
400462306a36Sopenharmony_cistatic int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags,
400562306a36Sopenharmony_ci			size_t size, void **p, struct obj_cgroup *objcg)
400662306a36Sopenharmony_ci{
400762306a36Sopenharmony_ci	int i;
400862306a36Sopenharmony_ci
400962306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
401062306a36Sopenharmony_ci		void *object = kfence_alloc(s, s->object_size, flags);
401162306a36Sopenharmony_ci
401262306a36Sopenharmony_ci		if (unlikely(object)) {
401362306a36Sopenharmony_ci			p[i] = object;
401462306a36Sopenharmony_ci			continue;
401562306a36Sopenharmony_ci		}
401662306a36Sopenharmony_ci
401762306a36Sopenharmony_ci		p[i] = __slab_alloc_node(s, flags, NUMA_NO_NODE,
401862306a36Sopenharmony_ci					 _RET_IP_, s->object_size);
401962306a36Sopenharmony_ci		if (unlikely(!p[i]))
402062306a36Sopenharmony_ci			goto error;
402162306a36Sopenharmony_ci
402262306a36Sopenharmony_ci		maybe_wipe_obj_freeptr(s, p[i]);
402362306a36Sopenharmony_ci	}
402462306a36Sopenharmony_ci
402562306a36Sopenharmony_ci	return i;
402662306a36Sopenharmony_ci
402762306a36Sopenharmony_cierror:
402862306a36Sopenharmony_ci	slab_post_alloc_hook(s, objcg, flags, i, p, false, s->object_size);
402962306a36Sopenharmony_ci	kmem_cache_free_bulk(s, i, p);
403062306a36Sopenharmony_ci	return 0;
403162306a36Sopenharmony_ci}
403262306a36Sopenharmony_ci#endif /* CONFIG_SLUB_TINY */
403362306a36Sopenharmony_ci
403462306a36Sopenharmony_ci/* Note that interrupts must be enabled when calling this function. */
403562306a36Sopenharmony_ciint kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
403662306a36Sopenharmony_ci			  void **p)
403762306a36Sopenharmony_ci{
403862306a36Sopenharmony_ci	int i;
403962306a36Sopenharmony_ci	struct obj_cgroup *objcg = NULL;
404062306a36Sopenharmony_ci
404162306a36Sopenharmony_ci	if (!size)
404262306a36Sopenharmony_ci		return 0;
404362306a36Sopenharmony_ci
404462306a36Sopenharmony_ci	/* memcg and kmem_cache debug support */
404562306a36Sopenharmony_ci	s = slab_pre_alloc_hook(s, NULL, &objcg, size, flags);
404662306a36Sopenharmony_ci	if (unlikely(!s))
404762306a36Sopenharmony_ci		return 0;
404862306a36Sopenharmony_ci
404962306a36Sopenharmony_ci	i = __kmem_cache_alloc_bulk(s, flags, size, p, objcg);
405062306a36Sopenharmony_ci
405162306a36Sopenharmony_ci	/*
405262306a36Sopenharmony_ci	 * memcg and kmem_cache debug support and memory initialization.
405362306a36Sopenharmony_ci	 * Done outside of the IRQ disabled fastpath loop.
405462306a36Sopenharmony_ci	 */
405562306a36Sopenharmony_ci	if (i != 0)
405662306a36Sopenharmony_ci		slab_post_alloc_hook(s, objcg, flags, size, p,
405762306a36Sopenharmony_ci			slab_want_init_on_alloc(flags, s), s->object_size);
405862306a36Sopenharmony_ci	return i;
405962306a36Sopenharmony_ci}
406062306a36Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_alloc_bulk);
406162306a36Sopenharmony_ci
406262306a36Sopenharmony_ci
406362306a36Sopenharmony_ci/*
406462306a36Sopenharmony_ci * Object placement in a slab is made very easy because we always start at
406562306a36Sopenharmony_ci * offset 0. If we tune the size of the object to the alignment then we can
406662306a36Sopenharmony_ci * get the required alignment by putting one properly sized object after
406762306a36Sopenharmony_ci * another.
406862306a36Sopenharmony_ci *
406962306a36Sopenharmony_ci * Notice that the allocation order determines the sizes of the per cpu
407062306a36Sopenharmony_ci * caches. Each processor has always one slab available for allocations.
407162306a36Sopenharmony_ci * Increasing the allocation order reduces the number of times that slabs
407262306a36Sopenharmony_ci * must be moved on and off the partial lists and is therefore a factor in
407362306a36Sopenharmony_ci * locking overhead.
407462306a36Sopenharmony_ci */
407562306a36Sopenharmony_ci
407662306a36Sopenharmony_ci/*
407762306a36Sopenharmony_ci * Minimum / Maximum order of slab pages. This influences locking overhead
407862306a36Sopenharmony_ci * and slab fragmentation. A higher order reduces the number of partial slabs
407962306a36Sopenharmony_ci * and increases the number of allocations possible without having to
408062306a36Sopenharmony_ci * take the list_lock.
408162306a36Sopenharmony_ci */
408262306a36Sopenharmony_cistatic unsigned int slub_min_order;
408362306a36Sopenharmony_cistatic unsigned int slub_max_order =
408462306a36Sopenharmony_ci	IS_ENABLED(CONFIG_SLUB_TINY) ? 1 : PAGE_ALLOC_COSTLY_ORDER;
408562306a36Sopenharmony_cistatic unsigned int slub_min_objects;
408662306a36Sopenharmony_ci
408762306a36Sopenharmony_ci/*
408862306a36Sopenharmony_ci * Calculate the order of allocation given an slab object size.
408962306a36Sopenharmony_ci *
409062306a36Sopenharmony_ci * The order of allocation has significant impact on performance and other
409162306a36Sopenharmony_ci * system components. Generally order 0 allocations should be preferred since
409262306a36Sopenharmony_ci * order 0 does not cause fragmentation in the page allocator. Larger objects
409362306a36Sopenharmony_ci * be problematic to put into order 0 slabs because there may be too much
409462306a36Sopenharmony_ci * unused space left. We go to a higher order if more than 1/16th of the slab
409562306a36Sopenharmony_ci * would be wasted.
409662306a36Sopenharmony_ci *
409762306a36Sopenharmony_ci * In order to reach satisfactory performance we must ensure that a minimum
409862306a36Sopenharmony_ci * number of objects is in one slab. Otherwise we may generate too much
409962306a36Sopenharmony_ci * activity on the partial lists which requires taking the list_lock. This is
410062306a36Sopenharmony_ci * less a concern for large slabs though which are rarely used.
410162306a36Sopenharmony_ci *
410262306a36Sopenharmony_ci * slub_max_order specifies the order where we begin to stop considering the
410362306a36Sopenharmony_ci * number of objects in a slab as critical. If we reach slub_max_order then
410462306a36Sopenharmony_ci * we try to keep the page order as low as possible. So we accept more waste
410562306a36Sopenharmony_ci * of space in favor of a small page order.
410662306a36Sopenharmony_ci *
410762306a36Sopenharmony_ci * Higher order allocations also allow the placement of more objects in a
410862306a36Sopenharmony_ci * slab and thereby reduce object handling overhead. If the user has
410962306a36Sopenharmony_ci * requested a higher minimum order then we start with that one instead of
411062306a36Sopenharmony_ci * the smallest order which will fit the object.
411162306a36Sopenharmony_ci */
411262306a36Sopenharmony_cistatic inline unsigned int calc_slab_order(unsigned int size,
411362306a36Sopenharmony_ci		unsigned int min_objects, unsigned int max_order,
411462306a36Sopenharmony_ci		unsigned int fract_leftover)
411562306a36Sopenharmony_ci{
411662306a36Sopenharmony_ci	unsigned int min_order = slub_min_order;
411762306a36Sopenharmony_ci	unsigned int order;
411862306a36Sopenharmony_ci
411962306a36Sopenharmony_ci	if (order_objects(min_order, size) > MAX_OBJS_PER_PAGE)
412062306a36Sopenharmony_ci		return get_order(size * MAX_OBJS_PER_PAGE) - 1;
412162306a36Sopenharmony_ci
412262306a36Sopenharmony_ci	for (order = max(min_order, (unsigned int)get_order(min_objects * size));
412362306a36Sopenharmony_ci			order <= max_order; order++) {
412462306a36Sopenharmony_ci
412562306a36Sopenharmony_ci		unsigned int slab_size = (unsigned int)PAGE_SIZE << order;
412662306a36Sopenharmony_ci		unsigned int rem;
412762306a36Sopenharmony_ci
412862306a36Sopenharmony_ci		rem = slab_size % size;
412962306a36Sopenharmony_ci
413062306a36Sopenharmony_ci		if (rem <= slab_size / fract_leftover)
413162306a36Sopenharmony_ci			break;
413262306a36Sopenharmony_ci	}
413362306a36Sopenharmony_ci
413462306a36Sopenharmony_ci	return order;
413562306a36Sopenharmony_ci}
413662306a36Sopenharmony_ci
413762306a36Sopenharmony_cistatic inline int calculate_order(unsigned int size)
413862306a36Sopenharmony_ci{
413962306a36Sopenharmony_ci	unsigned int order;
414062306a36Sopenharmony_ci	unsigned int min_objects;
414162306a36Sopenharmony_ci	unsigned int max_objects;
414262306a36Sopenharmony_ci	unsigned int nr_cpus;
414362306a36Sopenharmony_ci
414462306a36Sopenharmony_ci	/*
414562306a36Sopenharmony_ci	 * Attempt to find best configuration for a slab. This
414662306a36Sopenharmony_ci	 * works by first attempting to generate a layout with
414762306a36Sopenharmony_ci	 * the best configuration and backing off gradually.
414862306a36Sopenharmony_ci	 *
414962306a36Sopenharmony_ci	 * First we increase the acceptable waste in a slab. Then
415062306a36Sopenharmony_ci	 * we reduce the minimum objects required in a slab.
415162306a36Sopenharmony_ci	 */
415262306a36Sopenharmony_ci	min_objects = slub_min_objects;
415362306a36Sopenharmony_ci	if (!min_objects) {
415462306a36Sopenharmony_ci		/*
415562306a36Sopenharmony_ci		 * Some architectures will only update present cpus when
415662306a36Sopenharmony_ci		 * onlining them, so don't trust the number if it's just 1. But
415762306a36Sopenharmony_ci		 * we also don't want to use nr_cpu_ids always, as on some other
415862306a36Sopenharmony_ci		 * architectures, there can be many possible cpus, but never
415962306a36Sopenharmony_ci		 * onlined. Here we compromise between trying to avoid too high
416062306a36Sopenharmony_ci		 * order on systems that appear larger than they are, and too
416162306a36Sopenharmony_ci		 * low order on systems that appear smaller than they are.
416262306a36Sopenharmony_ci		 */
416362306a36Sopenharmony_ci		nr_cpus = num_present_cpus();
416462306a36Sopenharmony_ci		if (nr_cpus <= 1)
416562306a36Sopenharmony_ci			nr_cpus = nr_cpu_ids;
416662306a36Sopenharmony_ci		min_objects = 4 * (fls(nr_cpus) + 1);
416762306a36Sopenharmony_ci	}
416862306a36Sopenharmony_ci	max_objects = order_objects(slub_max_order, size);
416962306a36Sopenharmony_ci	min_objects = min(min_objects, max_objects);
417062306a36Sopenharmony_ci
417162306a36Sopenharmony_ci	while (min_objects > 1) {
417262306a36Sopenharmony_ci		unsigned int fraction;
417362306a36Sopenharmony_ci
417462306a36Sopenharmony_ci		fraction = 16;
417562306a36Sopenharmony_ci		while (fraction >= 4) {
417662306a36Sopenharmony_ci			order = calc_slab_order(size, min_objects,
417762306a36Sopenharmony_ci					slub_max_order, fraction);
417862306a36Sopenharmony_ci			if (order <= slub_max_order)
417962306a36Sopenharmony_ci				return order;
418062306a36Sopenharmony_ci			fraction /= 2;
418162306a36Sopenharmony_ci		}
418262306a36Sopenharmony_ci		min_objects--;
418362306a36Sopenharmony_ci	}
418462306a36Sopenharmony_ci
418562306a36Sopenharmony_ci	/*
418662306a36Sopenharmony_ci	 * We were unable to place multiple objects in a slab. Now
418762306a36Sopenharmony_ci	 * lets see if we can place a single object there.
418862306a36Sopenharmony_ci	 */
418962306a36Sopenharmony_ci	order = calc_slab_order(size, 1, slub_max_order, 1);
419062306a36Sopenharmony_ci	if (order <= slub_max_order)
419162306a36Sopenharmony_ci		return order;
419262306a36Sopenharmony_ci
419362306a36Sopenharmony_ci	/*
419462306a36Sopenharmony_ci	 * Doh this slab cannot be placed using slub_max_order.
419562306a36Sopenharmony_ci	 */
419662306a36Sopenharmony_ci	order = calc_slab_order(size, 1, MAX_ORDER, 1);
419762306a36Sopenharmony_ci	if (order <= MAX_ORDER)
419862306a36Sopenharmony_ci		return order;
419962306a36Sopenharmony_ci	return -ENOSYS;
420062306a36Sopenharmony_ci}
420162306a36Sopenharmony_ci
420262306a36Sopenharmony_cistatic void
420362306a36Sopenharmony_ciinit_kmem_cache_node(struct kmem_cache_node *n)
420462306a36Sopenharmony_ci{
420562306a36Sopenharmony_ci	n->nr_partial = 0;
420662306a36Sopenharmony_ci	spin_lock_init(&n->list_lock);
420762306a36Sopenharmony_ci	INIT_LIST_HEAD(&n->partial);
420862306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
420962306a36Sopenharmony_ci	atomic_long_set(&n->nr_slabs, 0);
421062306a36Sopenharmony_ci	atomic_long_set(&n->total_objects, 0);
421162306a36Sopenharmony_ci	INIT_LIST_HEAD(&n->full);
421262306a36Sopenharmony_ci#endif
421362306a36Sopenharmony_ci}
421462306a36Sopenharmony_ci
421562306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
421662306a36Sopenharmony_cistatic inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
421762306a36Sopenharmony_ci{
421862306a36Sopenharmony_ci	BUILD_BUG_ON(PERCPU_DYNAMIC_EARLY_SIZE <
421962306a36Sopenharmony_ci			NR_KMALLOC_TYPES * KMALLOC_SHIFT_HIGH *
422062306a36Sopenharmony_ci			sizeof(struct kmem_cache_cpu));
422162306a36Sopenharmony_ci
422262306a36Sopenharmony_ci	/*
422362306a36Sopenharmony_ci	 * Must align to double word boundary for the double cmpxchg
422462306a36Sopenharmony_ci	 * instructions to work; see __pcpu_double_call_return_bool().
422562306a36Sopenharmony_ci	 */
422662306a36Sopenharmony_ci	s->cpu_slab = __alloc_percpu(sizeof(struct kmem_cache_cpu),
422762306a36Sopenharmony_ci				     2 * sizeof(void *));
422862306a36Sopenharmony_ci
422962306a36Sopenharmony_ci	if (!s->cpu_slab)
423062306a36Sopenharmony_ci		return 0;
423162306a36Sopenharmony_ci
423262306a36Sopenharmony_ci	init_kmem_cache_cpus(s);
423362306a36Sopenharmony_ci
423462306a36Sopenharmony_ci	return 1;
423562306a36Sopenharmony_ci}
423662306a36Sopenharmony_ci#else
423762306a36Sopenharmony_cistatic inline int alloc_kmem_cache_cpus(struct kmem_cache *s)
423862306a36Sopenharmony_ci{
423962306a36Sopenharmony_ci	return 1;
424062306a36Sopenharmony_ci}
424162306a36Sopenharmony_ci#endif /* CONFIG_SLUB_TINY */
424262306a36Sopenharmony_ci
424362306a36Sopenharmony_cistatic struct kmem_cache *kmem_cache_node;
424462306a36Sopenharmony_ci
424562306a36Sopenharmony_ci/*
424662306a36Sopenharmony_ci * No kmalloc_node yet so do it by hand. We know that this is the first
424762306a36Sopenharmony_ci * slab on the node for this slabcache. There are no concurrent accesses
424862306a36Sopenharmony_ci * possible.
424962306a36Sopenharmony_ci *
425062306a36Sopenharmony_ci * Note that this function only works on the kmem_cache_node
425162306a36Sopenharmony_ci * when allocating for the kmem_cache_node. This is used for bootstrapping
425262306a36Sopenharmony_ci * memory on a fresh node that has no slab structures yet.
425362306a36Sopenharmony_ci */
425462306a36Sopenharmony_cistatic void early_kmem_cache_node_alloc(int node)
425562306a36Sopenharmony_ci{
425662306a36Sopenharmony_ci	struct slab *slab;
425762306a36Sopenharmony_ci	struct kmem_cache_node *n;
425862306a36Sopenharmony_ci
425962306a36Sopenharmony_ci	BUG_ON(kmem_cache_node->size < sizeof(struct kmem_cache_node));
426062306a36Sopenharmony_ci
426162306a36Sopenharmony_ci	slab = new_slab(kmem_cache_node, GFP_NOWAIT, node);
426262306a36Sopenharmony_ci
426362306a36Sopenharmony_ci	BUG_ON(!slab);
426462306a36Sopenharmony_ci	inc_slabs_node(kmem_cache_node, slab_nid(slab), slab->objects);
426562306a36Sopenharmony_ci	if (slab_nid(slab) != node) {
426662306a36Sopenharmony_ci		pr_err("SLUB: Unable to allocate memory from node %d\n", node);
426762306a36Sopenharmony_ci		pr_err("SLUB: Allocating a useless per node structure in order to be able to continue\n");
426862306a36Sopenharmony_ci	}
426962306a36Sopenharmony_ci
427062306a36Sopenharmony_ci	n = slab->freelist;
427162306a36Sopenharmony_ci	BUG_ON(!n);
427262306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
427362306a36Sopenharmony_ci	init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
427462306a36Sopenharmony_ci	init_tracking(kmem_cache_node, n);
427562306a36Sopenharmony_ci#endif
427662306a36Sopenharmony_ci	n = kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL, false);
427762306a36Sopenharmony_ci	slab->freelist = get_freepointer(kmem_cache_node, n);
427862306a36Sopenharmony_ci	slab->inuse = 1;
427962306a36Sopenharmony_ci	kmem_cache_node->node[node] = n;
428062306a36Sopenharmony_ci	init_kmem_cache_node(n);
428162306a36Sopenharmony_ci	inc_slabs_node(kmem_cache_node, node, slab->objects);
428262306a36Sopenharmony_ci
428362306a36Sopenharmony_ci	/*
428462306a36Sopenharmony_ci	 * No locks need to be taken here as it has just been
428562306a36Sopenharmony_ci	 * initialized and there is no concurrent access.
428662306a36Sopenharmony_ci	 */
428762306a36Sopenharmony_ci	__add_partial(n, slab, DEACTIVATE_TO_HEAD);
428862306a36Sopenharmony_ci}
428962306a36Sopenharmony_ci
429062306a36Sopenharmony_cistatic void free_kmem_cache_nodes(struct kmem_cache *s)
429162306a36Sopenharmony_ci{
429262306a36Sopenharmony_ci	int node;
429362306a36Sopenharmony_ci	struct kmem_cache_node *n;
429462306a36Sopenharmony_ci
429562306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
429662306a36Sopenharmony_ci		s->node[node] = NULL;
429762306a36Sopenharmony_ci		kmem_cache_free(kmem_cache_node, n);
429862306a36Sopenharmony_ci	}
429962306a36Sopenharmony_ci}
430062306a36Sopenharmony_ci
430162306a36Sopenharmony_civoid __kmem_cache_release(struct kmem_cache *s)
430262306a36Sopenharmony_ci{
430362306a36Sopenharmony_ci	cache_random_seq_destroy(s);
430462306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
430562306a36Sopenharmony_ci	free_percpu(s->cpu_slab);
430662306a36Sopenharmony_ci#endif
430762306a36Sopenharmony_ci	free_kmem_cache_nodes(s);
430862306a36Sopenharmony_ci}
430962306a36Sopenharmony_ci
431062306a36Sopenharmony_cistatic int init_kmem_cache_nodes(struct kmem_cache *s)
431162306a36Sopenharmony_ci{
431262306a36Sopenharmony_ci	int node;
431362306a36Sopenharmony_ci
431462306a36Sopenharmony_ci	for_each_node_mask(node, slab_nodes) {
431562306a36Sopenharmony_ci		struct kmem_cache_node *n;
431662306a36Sopenharmony_ci
431762306a36Sopenharmony_ci		if (slab_state == DOWN) {
431862306a36Sopenharmony_ci			early_kmem_cache_node_alloc(node);
431962306a36Sopenharmony_ci			continue;
432062306a36Sopenharmony_ci		}
432162306a36Sopenharmony_ci		n = kmem_cache_alloc_node(kmem_cache_node,
432262306a36Sopenharmony_ci						GFP_KERNEL, node);
432362306a36Sopenharmony_ci
432462306a36Sopenharmony_ci		if (!n) {
432562306a36Sopenharmony_ci			free_kmem_cache_nodes(s);
432662306a36Sopenharmony_ci			return 0;
432762306a36Sopenharmony_ci		}
432862306a36Sopenharmony_ci
432962306a36Sopenharmony_ci		init_kmem_cache_node(n);
433062306a36Sopenharmony_ci		s->node[node] = n;
433162306a36Sopenharmony_ci	}
433262306a36Sopenharmony_ci	return 1;
433362306a36Sopenharmony_ci}
433462306a36Sopenharmony_ci
433562306a36Sopenharmony_cistatic void set_cpu_partial(struct kmem_cache *s)
433662306a36Sopenharmony_ci{
433762306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
433862306a36Sopenharmony_ci	unsigned int nr_objects;
433962306a36Sopenharmony_ci
434062306a36Sopenharmony_ci	/*
434162306a36Sopenharmony_ci	 * cpu_partial determined the maximum number of objects kept in the
434262306a36Sopenharmony_ci	 * per cpu partial lists of a processor.
434362306a36Sopenharmony_ci	 *
434462306a36Sopenharmony_ci	 * Per cpu partial lists mainly contain slabs that just have one
434562306a36Sopenharmony_ci	 * object freed. If they are used for allocation then they can be
434662306a36Sopenharmony_ci	 * filled up again with minimal effort. The slab will never hit the
434762306a36Sopenharmony_ci	 * per node partial lists and therefore no locking will be required.
434862306a36Sopenharmony_ci	 *
434962306a36Sopenharmony_ci	 * For backwards compatibility reasons, this is determined as number
435062306a36Sopenharmony_ci	 * of objects, even though we now limit maximum number of pages, see
435162306a36Sopenharmony_ci	 * slub_set_cpu_partial()
435262306a36Sopenharmony_ci	 */
435362306a36Sopenharmony_ci	if (!kmem_cache_has_cpu_partial(s))
435462306a36Sopenharmony_ci		nr_objects = 0;
435562306a36Sopenharmony_ci	else if (s->size >= PAGE_SIZE)
435662306a36Sopenharmony_ci		nr_objects = 6;
435762306a36Sopenharmony_ci	else if (s->size >= 1024)
435862306a36Sopenharmony_ci		nr_objects = 24;
435962306a36Sopenharmony_ci	else if (s->size >= 256)
436062306a36Sopenharmony_ci		nr_objects = 52;
436162306a36Sopenharmony_ci	else
436262306a36Sopenharmony_ci		nr_objects = 120;
436362306a36Sopenharmony_ci
436462306a36Sopenharmony_ci	slub_set_cpu_partial(s, nr_objects);
436562306a36Sopenharmony_ci#endif
436662306a36Sopenharmony_ci}
436762306a36Sopenharmony_ci
436862306a36Sopenharmony_ci/*
436962306a36Sopenharmony_ci * calculate_sizes() determines the order and the distribution of data within
437062306a36Sopenharmony_ci * a slab object.
437162306a36Sopenharmony_ci */
437262306a36Sopenharmony_cistatic int calculate_sizes(struct kmem_cache *s)
437362306a36Sopenharmony_ci{
437462306a36Sopenharmony_ci	slab_flags_t flags = s->flags;
437562306a36Sopenharmony_ci	unsigned int size = s->object_size;
437662306a36Sopenharmony_ci	unsigned int order;
437762306a36Sopenharmony_ci
437862306a36Sopenharmony_ci	/*
437962306a36Sopenharmony_ci	 * Round up object size to the next word boundary. We can only
438062306a36Sopenharmony_ci	 * place the free pointer at word boundaries and this determines
438162306a36Sopenharmony_ci	 * the possible location of the free pointer.
438262306a36Sopenharmony_ci	 */
438362306a36Sopenharmony_ci	size = ALIGN(size, sizeof(void *));
438462306a36Sopenharmony_ci
438562306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
438662306a36Sopenharmony_ci	/*
438762306a36Sopenharmony_ci	 * Determine if we can poison the object itself. If the user of
438862306a36Sopenharmony_ci	 * the slab may touch the object after free or before allocation
438962306a36Sopenharmony_ci	 * then we should never poison the object itself.
439062306a36Sopenharmony_ci	 */
439162306a36Sopenharmony_ci	if ((flags & SLAB_POISON) && !(flags & SLAB_TYPESAFE_BY_RCU) &&
439262306a36Sopenharmony_ci			!s->ctor)
439362306a36Sopenharmony_ci		s->flags |= __OBJECT_POISON;
439462306a36Sopenharmony_ci	else
439562306a36Sopenharmony_ci		s->flags &= ~__OBJECT_POISON;
439662306a36Sopenharmony_ci
439762306a36Sopenharmony_ci
439862306a36Sopenharmony_ci	/*
439962306a36Sopenharmony_ci	 * If we are Redzoning then check if there is some space between the
440062306a36Sopenharmony_ci	 * end of the object and the free pointer. If not then add an
440162306a36Sopenharmony_ci	 * additional word to have some bytes to store Redzone information.
440262306a36Sopenharmony_ci	 */
440362306a36Sopenharmony_ci	if ((flags & SLAB_RED_ZONE) && size == s->object_size)
440462306a36Sopenharmony_ci		size += sizeof(void *);
440562306a36Sopenharmony_ci#endif
440662306a36Sopenharmony_ci
440762306a36Sopenharmony_ci	/*
440862306a36Sopenharmony_ci	 * With that we have determined the number of bytes in actual use
440962306a36Sopenharmony_ci	 * by the object and redzoning.
441062306a36Sopenharmony_ci	 */
441162306a36Sopenharmony_ci	s->inuse = size;
441262306a36Sopenharmony_ci
441362306a36Sopenharmony_ci	if (slub_debug_orig_size(s) ||
441462306a36Sopenharmony_ci	    (flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)) ||
441562306a36Sopenharmony_ci	    ((flags & SLAB_RED_ZONE) && s->object_size < sizeof(void *)) ||
441662306a36Sopenharmony_ci	    s->ctor) {
441762306a36Sopenharmony_ci		/*
441862306a36Sopenharmony_ci		 * Relocate free pointer after the object if it is not
441962306a36Sopenharmony_ci		 * permitted to overwrite the first word of the object on
442062306a36Sopenharmony_ci		 * kmem_cache_free.
442162306a36Sopenharmony_ci		 *
442262306a36Sopenharmony_ci		 * This is the case if we do RCU, have a constructor or
442362306a36Sopenharmony_ci		 * destructor, are poisoning the objects, or are
442462306a36Sopenharmony_ci		 * redzoning an object smaller than sizeof(void *).
442562306a36Sopenharmony_ci		 *
442662306a36Sopenharmony_ci		 * The assumption that s->offset >= s->inuse means free
442762306a36Sopenharmony_ci		 * pointer is outside of the object is used in the
442862306a36Sopenharmony_ci		 * freeptr_outside_object() function. If that is no
442962306a36Sopenharmony_ci		 * longer true, the function needs to be modified.
443062306a36Sopenharmony_ci		 */
443162306a36Sopenharmony_ci		s->offset = size;
443262306a36Sopenharmony_ci		size += sizeof(void *);
443362306a36Sopenharmony_ci	} else {
443462306a36Sopenharmony_ci		/*
443562306a36Sopenharmony_ci		 * Store freelist pointer near middle of object to keep
443662306a36Sopenharmony_ci		 * it away from the edges of the object to avoid small
443762306a36Sopenharmony_ci		 * sized over/underflows from neighboring allocations.
443862306a36Sopenharmony_ci		 */
443962306a36Sopenharmony_ci		s->offset = ALIGN_DOWN(s->object_size / 2, sizeof(void *));
444062306a36Sopenharmony_ci	}
444162306a36Sopenharmony_ci
444262306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
444362306a36Sopenharmony_ci	if (flags & SLAB_STORE_USER) {
444462306a36Sopenharmony_ci		/*
444562306a36Sopenharmony_ci		 * Need to store information about allocs and frees after
444662306a36Sopenharmony_ci		 * the object.
444762306a36Sopenharmony_ci		 */
444862306a36Sopenharmony_ci		size += 2 * sizeof(struct track);
444962306a36Sopenharmony_ci
445062306a36Sopenharmony_ci		/* Save the original kmalloc request size */
445162306a36Sopenharmony_ci		if (flags & SLAB_KMALLOC)
445262306a36Sopenharmony_ci			size += sizeof(unsigned int);
445362306a36Sopenharmony_ci	}
445462306a36Sopenharmony_ci#endif
445562306a36Sopenharmony_ci
445662306a36Sopenharmony_ci	kasan_cache_create(s, &size, &s->flags);
445762306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
445862306a36Sopenharmony_ci	if (flags & SLAB_RED_ZONE) {
445962306a36Sopenharmony_ci		/*
446062306a36Sopenharmony_ci		 * Add some empty padding so that we can catch
446162306a36Sopenharmony_ci		 * overwrites from earlier objects rather than let
446262306a36Sopenharmony_ci		 * tracking information or the free pointer be
446362306a36Sopenharmony_ci		 * corrupted if a user writes before the start
446462306a36Sopenharmony_ci		 * of the object.
446562306a36Sopenharmony_ci		 */
446662306a36Sopenharmony_ci		size += sizeof(void *);
446762306a36Sopenharmony_ci
446862306a36Sopenharmony_ci		s->red_left_pad = sizeof(void *);
446962306a36Sopenharmony_ci		s->red_left_pad = ALIGN(s->red_left_pad, s->align);
447062306a36Sopenharmony_ci		size += s->red_left_pad;
447162306a36Sopenharmony_ci	}
447262306a36Sopenharmony_ci#endif
447362306a36Sopenharmony_ci
447462306a36Sopenharmony_ci	/*
447562306a36Sopenharmony_ci	 * SLUB stores one object immediately after another beginning from
447662306a36Sopenharmony_ci	 * offset 0. In order to align the objects we have to simply size
447762306a36Sopenharmony_ci	 * each object to conform to the alignment.
447862306a36Sopenharmony_ci	 */
447962306a36Sopenharmony_ci	size = ALIGN(size, s->align);
448062306a36Sopenharmony_ci	s->size = size;
448162306a36Sopenharmony_ci	s->reciprocal_size = reciprocal_value(size);
448262306a36Sopenharmony_ci	order = calculate_order(size);
448362306a36Sopenharmony_ci
448462306a36Sopenharmony_ci	if ((int)order < 0)
448562306a36Sopenharmony_ci		return 0;
448662306a36Sopenharmony_ci
448762306a36Sopenharmony_ci	s->allocflags = 0;
448862306a36Sopenharmony_ci	if (order)
448962306a36Sopenharmony_ci		s->allocflags |= __GFP_COMP;
449062306a36Sopenharmony_ci
449162306a36Sopenharmony_ci	if (s->flags & SLAB_CACHE_DMA)
449262306a36Sopenharmony_ci		s->allocflags |= GFP_DMA;
449362306a36Sopenharmony_ci
449462306a36Sopenharmony_ci	if (s->flags & SLAB_CACHE_DMA32)
449562306a36Sopenharmony_ci		s->allocflags |= GFP_DMA32;
449662306a36Sopenharmony_ci
449762306a36Sopenharmony_ci	if (s->flags & SLAB_RECLAIM_ACCOUNT)
449862306a36Sopenharmony_ci		s->allocflags |= __GFP_RECLAIMABLE;
449962306a36Sopenharmony_ci
450062306a36Sopenharmony_ci	/*
450162306a36Sopenharmony_ci	 * Determine the number of objects per slab
450262306a36Sopenharmony_ci	 */
450362306a36Sopenharmony_ci	s->oo = oo_make(order, size);
450462306a36Sopenharmony_ci	s->min = oo_make(get_order(size), size);
450562306a36Sopenharmony_ci
450662306a36Sopenharmony_ci	return !!oo_objects(s->oo);
450762306a36Sopenharmony_ci}
450862306a36Sopenharmony_ci
450962306a36Sopenharmony_cistatic int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags)
451062306a36Sopenharmony_ci{
451162306a36Sopenharmony_ci	s->flags = kmem_cache_flags(s->size, flags, s->name);
451262306a36Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_HARDENED
451362306a36Sopenharmony_ci	s->random = get_random_long();
451462306a36Sopenharmony_ci#endif
451562306a36Sopenharmony_ci
451662306a36Sopenharmony_ci	if (!calculate_sizes(s))
451762306a36Sopenharmony_ci		goto error;
451862306a36Sopenharmony_ci	if (disable_higher_order_debug) {
451962306a36Sopenharmony_ci		/*
452062306a36Sopenharmony_ci		 * Disable debugging flags that store metadata if the min slab
452162306a36Sopenharmony_ci		 * order increased.
452262306a36Sopenharmony_ci		 */
452362306a36Sopenharmony_ci		if (get_order(s->size) > get_order(s->object_size)) {
452462306a36Sopenharmony_ci			s->flags &= ~DEBUG_METADATA_FLAGS;
452562306a36Sopenharmony_ci			s->offset = 0;
452662306a36Sopenharmony_ci			if (!calculate_sizes(s))
452762306a36Sopenharmony_ci				goto error;
452862306a36Sopenharmony_ci		}
452962306a36Sopenharmony_ci	}
453062306a36Sopenharmony_ci
453162306a36Sopenharmony_ci#ifdef system_has_freelist_aba
453262306a36Sopenharmony_ci	if (system_has_freelist_aba() && !(s->flags & SLAB_NO_CMPXCHG)) {
453362306a36Sopenharmony_ci		/* Enable fast mode */
453462306a36Sopenharmony_ci		s->flags |= __CMPXCHG_DOUBLE;
453562306a36Sopenharmony_ci	}
453662306a36Sopenharmony_ci#endif
453762306a36Sopenharmony_ci
453862306a36Sopenharmony_ci	/*
453962306a36Sopenharmony_ci	 * The larger the object size is, the more slabs we want on the partial
454062306a36Sopenharmony_ci	 * list to avoid pounding the page allocator excessively.
454162306a36Sopenharmony_ci	 */
454262306a36Sopenharmony_ci	s->min_partial = min_t(unsigned long, MAX_PARTIAL, ilog2(s->size) / 2);
454362306a36Sopenharmony_ci	s->min_partial = max_t(unsigned long, MIN_PARTIAL, s->min_partial);
454462306a36Sopenharmony_ci
454562306a36Sopenharmony_ci	set_cpu_partial(s);
454662306a36Sopenharmony_ci
454762306a36Sopenharmony_ci#ifdef CONFIG_NUMA
454862306a36Sopenharmony_ci	s->remote_node_defrag_ratio = 1000;
454962306a36Sopenharmony_ci#endif
455062306a36Sopenharmony_ci
455162306a36Sopenharmony_ci	/* Initialize the pre-computed randomized freelist if slab is up */
455262306a36Sopenharmony_ci	if (slab_state >= UP) {
455362306a36Sopenharmony_ci		if (init_cache_random_seq(s))
455462306a36Sopenharmony_ci			goto error;
455562306a36Sopenharmony_ci	}
455662306a36Sopenharmony_ci
455762306a36Sopenharmony_ci	if (!init_kmem_cache_nodes(s))
455862306a36Sopenharmony_ci		goto error;
455962306a36Sopenharmony_ci
456062306a36Sopenharmony_ci	if (alloc_kmem_cache_cpus(s))
456162306a36Sopenharmony_ci		return 0;
456262306a36Sopenharmony_ci
456362306a36Sopenharmony_cierror:
456462306a36Sopenharmony_ci	__kmem_cache_release(s);
456562306a36Sopenharmony_ci	return -EINVAL;
456662306a36Sopenharmony_ci}
456762306a36Sopenharmony_ci
456862306a36Sopenharmony_cistatic void list_slab_objects(struct kmem_cache *s, struct slab *slab,
456962306a36Sopenharmony_ci			      const char *text)
457062306a36Sopenharmony_ci{
457162306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
457262306a36Sopenharmony_ci	void *addr = slab_address(slab);
457362306a36Sopenharmony_ci	void *p;
457462306a36Sopenharmony_ci
457562306a36Sopenharmony_ci	slab_err(s, slab, text, s->name);
457662306a36Sopenharmony_ci
457762306a36Sopenharmony_ci	spin_lock(&object_map_lock);
457862306a36Sopenharmony_ci	__fill_map(object_map, s, slab);
457962306a36Sopenharmony_ci
458062306a36Sopenharmony_ci	for_each_object(p, s, addr, slab->objects) {
458162306a36Sopenharmony_ci
458262306a36Sopenharmony_ci		if (!test_bit(__obj_to_index(s, addr, p), object_map)) {
458362306a36Sopenharmony_ci			pr_err("Object 0x%p @offset=%tu\n", p, p - addr);
458462306a36Sopenharmony_ci			print_tracking(s, p);
458562306a36Sopenharmony_ci		}
458662306a36Sopenharmony_ci	}
458762306a36Sopenharmony_ci	spin_unlock(&object_map_lock);
458862306a36Sopenharmony_ci#endif
458962306a36Sopenharmony_ci}
459062306a36Sopenharmony_ci
459162306a36Sopenharmony_ci/*
459262306a36Sopenharmony_ci * Attempt to free all partial slabs on a node.
459362306a36Sopenharmony_ci * This is called from __kmem_cache_shutdown(). We must take list_lock
459462306a36Sopenharmony_ci * because sysfs file might still access partial list after the shutdowning.
459562306a36Sopenharmony_ci */
459662306a36Sopenharmony_cistatic void free_partial(struct kmem_cache *s, struct kmem_cache_node *n)
459762306a36Sopenharmony_ci{
459862306a36Sopenharmony_ci	LIST_HEAD(discard);
459962306a36Sopenharmony_ci	struct slab *slab, *h;
460062306a36Sopenharmony_ci
460162306a36Sopenharmony_ci	BUG_ON(irqs_disabled());
460262306a36Sopenharmony_ci	spin_lock_irq(&n->list_lock);
460362306a36Sopenharmony_ci	list_for_each_entry_safe(slab, h, &n->partial, slab_list) {
460462306a36Sopenharmony_ci		if (!slab->inuse) {
460562306a36Sopenharmony_ci			remove_partial(n, slab);
460662306a36Sopenharmony_ci			list_add(&slab->slab_list, &discard);
460762306a36Sopenharmony_ci		} else {
460862306a36Sopenharmony_ci			list_slab_objects(s, slab,
460962306a36Sopenharmony_ci			  "Objects remaining in %s on __kmem_cache_shutdown()");
461062306a36Sopenharmony_ci		}
461162306a36Sopenharmony_ci	}
461262306a36Sopenharmony_ci	spin_unlock_irq(&n->list_lock);
461362306a36Sopenharmony_ci
461462306a36Sopenharmony_ci	list_for_each_entry_safe(slab, h, &discard, slab_list)
461562306a36Sopenharmony_ci		discard_slab(s, slab);
461662306a36Sopenharmony_ci}
461762306a36Sopenharmony_ci
461862306a36Sopenharmony_cibool __kmem_cache_empty(struct kmem_cache *s)
461962306a36Sopenharmony_ci{
462062306a36Sopenharmony_ci	int node;
462162306a36Sopenharmony_ci	struct kmem_cache_node *n;
462262306a36Sopenharmony_ci
462362306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n)
462462306a36Sopenharmony_ci		if (n->nr_partial || node_nr_slabs(n))
462562306a36Sopenharmony_ci			return false;
462662306a36Sopenharmony_ci	return true;
462762306a36Sopenharmony_ci}
462862306a36Sopenharmony_ci
462962306a36Sopenharmony_ci/*
463062306a36Sopenharmony_ci * Release all resources used by a slab cache.
463162306a36Sopenharmony_ci */
463262306a36Sopenharmony_ciint __kmem_cache_shutdown(struct kmem_cache *s)
463362306a36Sopenharmony_ci{
463462306a36Sopenharmony_ci	int node;
463562306a36Sopenharmony_ci	struct kmem_cache_node *n;
463662306a36Sopenharmony_ci
463762306a36Sopenharmony_ci	flush_all_cpus_locked(s);
463862306a36Sopenharmony_ci	/* Attempt to free all objects */
463962306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
464062306a36Sopenharmony_ci		free_partial(s, n);
464162306a36Sopenharmony_ci		if (n->nr_partial || node_nr_slabs(n))
464262306a36Sopenharmony_ci			return 1;
464362306a36Sopenharmony_ci	}
464462306a36Sopenharmony_ci	return 0;
464562306a36Sopenharmony_ci}
464662306a36Sopenharmony_ci
464762306a36Sopenharmony_ci#ifdef CONFIG_PRINTK
464862306a36Sopenharmony_civoid __kmem_obj_info(struct kmem_obj_info *kpp, void *object, struct slab *slab)
464962306a36Sopenharmony_ci{
465062306a36Sopenharmony_ci	void *base;
465162306a36Sopenharmony_ci	int __maybe_unused i;
465262306a36Sopenharmony_ci	unsigned int objnr;
465362306a36Sopenharmony_ci	void *objp;
465462306a36Sopenharmony_ci	void *objp0;
465562306a36Sopenharmony_ci	struct kmem_cache *s = slab->slab_cache;
465662306a36Sopenharmony_ci	struct track __maybe_unused *trackp;
465762306a36Sopenharmony_ci
465862306a36Sopenharmony_ci	kpp->kp_ptr = object;
465962306a36Sopenharmony_ci	kpp->kp_slab = slab;
466062306a36Sopenharmony_ci	kpp->kp_slab_cache = s;
466162306a36Sopenharmony_ci	base = slab_address(slab);
466262306a36Sopenharmony_ci	objp0 = kasan_reset_tag(object);
466362306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
466462306a36Sopenharmony_ci	objp = restore_red_left(s, objp0);
466562306a36Sopenharmony_ci#else
466662306a36Sopenharmony_ci	objp = objp0;
466762306a36Sopenharmony_ci#endif
466862306a36Sopenharmony_ci	objnr = obj_to_index(s, slab, objp);
466962306a36Sopenharmony_ci	kpp->kp_data_offset = (unsigned long)((char *)objp0 - (char *)objp);
467062306a36Sopenharmony_ci	objp = base + s->size * objnr;
467162306a36Sopenharmony_ci	kpp->kp_objp = objp;
467262306a36Sopenharmony_ci	if (WARN_ON_ONCE(objp < base || objp >= base + slab->objects * s->size
467362306a36Sopenharmony_ci			 || (objp - base) % s->size) ||
467462306a36Sopenharmony_ci	    !(s->flags & SLAB_STORE_USER))
467562306a36Sopenharmony_ci		return;
467662306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
467762306a36Sopenharmony_ci	objp = fixup_red_left(s, objp);
467862306a36Sopenharmony_ci	trackp = get_track(s, objp, TRACK_ALLOC);
467962306a36Sopenharmony_ci	kpp->kp_ret = (void *)trackp->addr;
468062306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
468162306a36Sopenharmony_ci	{
468262306a36Sopenharmony_ci		depot_stack_handle_t handle;
468362306a36Sopenharmony_ci		unsigned long *entries;
468462306a36Sopenharmony_ci		unsigned int nr_entries;
468562306a36Sopenharmony_ci
468662306a36Sopenharmony_ci		handle = READ_ONCE(trackp->handle);
468762306a36Sopenharmony_ci		if (handle) {
468862306a36Sopenharmony_ci			nr_entries = stack_depot_fetch(handle, &entries);
468962306a36Sopenharmony_ci			for (i = 0; i < KS_ADDRS_COUNT && i < nr_entries; i++)
469062306a36Sopenharmony_ci				kpp->kp_stack[i] = (void *)entries[i];
469162306a36Sopenharmony_ci		}
469262306a36Sopenharmony_ci
469362306a36Sopenharmony_ci		trackp = get_track(s, objp, TRACK_FREE);
469462306a36Sopenharmony_ci		handle = READ_ONCE(trackp->handle);
469562306a36Sopenharmony_ci		if (handle) {
469662306a36Sopenharmony_ci			nr_entries = stack_depot_fetch(handle, &entries);
469762306a36Sopenharmony_ci			for (i = 0; i < KS_ADDRS_COUNT && i < nr_entries; i++)
469862306a36Sopenharmony_ci				kpp->kp_free_stack[i] = (void *)entries[i];
469962306a36Sopenharmony_ci		}
470062306a36Sopenharmony_ci	}
470162306a36Sopenharmony_ci#endif
470262306a36Sopenharmony_ci#endif
470362306a36Sopenharmony_ci}
470462306a36Sopenharmony_ci#endif
470562306a36Sopenharmony_ci
470662306a36Sopenharmony_ci/********************************************************************
470762306a36Sopenharmony_ci *		Kmalloc subsystem
470862306a36Sopenharmony_ci *******************************************************************/
470962306a36Sopenharmony_ci
471062306a36Sopenharmony_cistatic int __init setup_slub_min_order(char *str)
471162306a36Sopenharmony_ci{
471262306a36Sopenharmony_ci	get_option(&str, (int *)&slub_min_order);
471362306a36Sopenharmony_ci
471462306a36Sopenharmony_ci	return 1;
471562306a36Sopenharmony_ci}
471662306a36Sopenharmony_ci
471762306a36Sopenharmony_ci__setup("slub_min_order=", setup_slub_min_order);
471862306a36Sopenharmony_ci
471962306a36Sopenharmony_cistatic int __init setup_slub_max_order(char *str)
472062306a36Sopenharmony_ci{
472162306a36Sopenharmony_ci	get_option(&str, (int *)&slub_max_order);
472262306a36Sopenharmony_ci	slub_max_order = min_t(unsigned int, slub_max_order, MAX_ORDER);
472362306a36Sopenharmony_ci
472462306a36Sopenharmony_ci	return 1;
472562306a36Sopenharmony_ci}
472662306a36Sopenharmony_ci
472762306a36Sopenharmony_ci__setup("slub_max_order=", setup_slub_max_order);
472862306a36Sopenharmony_ci
472962306a36Sopenharmony_cistatic int __init setup_slub_min_objects(char *str)
473062306a36Sopenharmony_ci{
473162306a36Sopenharmony_ci	get_option(&str, (int *)&slub_min_objects);
473262306a36Sopenharmony_ci
473362306a36Sopenharmony_ci	return 1;
473462306a36Sopenharmony_ci}
473562306a36Sopenharmony_ci
473662306a36Sopenharmony_ci__setup("slub_min_objects=", setup_slub_min_objects);
473762306a36Sopenharmony_ci
473862306a36Sopenharmony_ci#ifdef CONFIG_HARDENED_USERCOPY
473962306a36Sopenharmony_ci/*
474062306a36Sopenharmony_ci * Rejects incorrectly sized objects and objects that are to be copied
474162306a36Sopenharmony_ci * to/from userspace but do not fall entirely within the containing slab
474262306a36Sopenharmony_ci * cache's usercopy region.
474362306a36Sopenharmony_ci *
474462306a36Sopenharmony_ci * Returns NULL if check passes, otherwise const char * to name of cache
474562306a36Sopenharmony_ci * to indicate an error.
474662306a36Sopenharmony_ci */
474762306a36Sopenharmony_civoid __check_heap_object(const void *ptr, unsigned long n,
474862306a36Sopenharmony_ci			 const struct slab *slab, bool to_user)
474962306a36Sopenharmony_ci{
475062306a36Sopenharmony_ci	struct kmem_cache *s;
475162306a36Sopenharmony_ci	unsigned int offset;
475262306a36Sopenharmony_ci	bool is_kfence = is_kfence_address(ptr);
475362306a36Sopenharmony_ci
475462306a36Sopenharmony_ci	ptr = kasan_reset_tag(ptr);
475562306a36Sopenharmony_ci
475662306a36Sopenharmony_ci	/* Find object and usable object size. */
475762306a36Sopenharmony_ci	s = slab->slab_cache;
475862306a36Sopenharmony_ci
475962306a36Sopenharmony_ci	/* Reject impossible pointers. */
476062306a36Sopenharmony_ci	if (ptr < slab_address(slab))
476162306a36Sopenharmony_ci		usercopy_abort("SLUB object not in SLUB page?!", NULL,
476262306a36Sopenharmony_ci			       to_user, 0, n);
476362306a36Sopenharmony_ci
476462306a36Sopenharmony_ci	/* Find offset within object. */
476562306a36Sopenharmony_ci	if (is_kfence)
476662306a36Sopenharmony_ci		offset = ptr - kfence_object_start(ptr);
476762306a36Sopenharmony_ci	else
476862306a36Sopenharmony_ci		offset = (ptr - slab_address(slab)) % s->size;
476962306a36Sopenharmony_ci
477062306a36Sopenharmony_ci	/* Adjust for redzone and reject if within the redzone. */
477162306a36Sopenharmony_ci	if (!is_kfence && kmem_cache_debug_flags(s, SLAB_RED_ZONE)) {
477262306a36Sopenharmony_ci		if (offset < s->red_left_pad)
477362306a36Sopenharmony_ci			usercopy_abort("SLUB object in left red zone",
477462306a36Sopenharmony_ci				       s->name, to_user, offset, n);
477562306a36Sopenharmony_ci		offset -= s->red_left_pad;
477662306a36Sopenharmony_ci	}
477762306a36Sopenharmony_ci
477862306a36Sopenharmony_ci	/* Allow address range falling entirely within usercopy region. */
477962306a36Sopenharmony_ci	if (offset >= s->useroffset &&
478062306a36Sopenharmony_ci	    offset - s->useroffset <= s->usersize &&
478162306a36Sopenharmony_ci	    n <= s->useroffset - offset + s->usersize)
478262306a36Sopenharmony_ci		return;
478362306a36Sopenharmony_ci
478462306a36Sopenharmony_ci	usercopy_abort("SLUB object", s->name, to_user, offset, n);
478562306a36Sopenharmony_ci}
478662306a36Sopenharmony_ci#endif /* CONFIG_HARDENED_USERCOPY */
478762306a36Sopenharmony_ci
478862306a36Sopenharmony_ci#define SHRINK_PROMOTE_MAX 32
478962306a36Sopenharmony_ci
479062306a36Sopenharmony_ci/*
479162306a36Sopenharmony_ci * kmem_cache_shrink discards empty slabs and promotes the slabs filled
479262306a36Sopenharmony_ci * up most to the head of the partial lists. New allocations will then
479362306a36Sopenharmony_ci * fill those up and thus they can be removed from the partial lists.
479462306a36Sopenharmony_ci *
479562306a36Sopenharmony_ci * The slabs with the least items are placed last. This results in them
479662306a36Sopenharmony_ci * being allocated from last increasing the chance that the last objects
479762306a36Sopenharmony_ci * are freed in them.
479862306a36Sopenharmony_ci */
479962306a36Sopenharmony_cistatic int __kmem_cache_do_shrink(struct kmem_cache *s)
480062306a36Sopenharmony_ci{
480162306a36Sopenharmony_ci	int node;
480262306a36Sopenharmony_ci	int i;
480362306a36Sopenharmony_ci	struct kmem_cache_node *n;
480462306a36Sopenharmony_ci	struct slab *slab;
480562306a36Sopenharmony_ci	struct slab *t;
480662306a36Sopenharmony_ci	struct list_head discard;
480762306a36Sopenharmony_ci	struct list_head promote[SHRINK_PROMOTE_MAX];
480862306a36Sopenharmony_ci	unsigned long flags;
480962306a36Sopenharmony_ci	int ret = 0;
481062306a36Sopenharmony_ci
481162306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
481262306a36Sopenharmony_ci		INIT_LIST_HEAD(&discard);
481362306a36Sopenharmony_ci		for (i = 0; i < SHRINK_PROMOTE_MAX; i++)
481462306a36Sopenharmony_ci			INIT_LIST_HEAD(promote + i);
481562306a36Sopenharmony_ci
481662306a36Sopenharmony_ci		spin_lock_irqsave(&n->list_lock, flags);
481762306a36Sopenharmony_ci
481862306a36Sopenharmony_ci		/*
481962306a36Sopenharmony_ci		 * Build lists of slabs to discard or promote.
482062306a36Sopenharmony_ci		 *
482162306a36Sopenharmony_ci		 * Note that concurrent frees may occur while we hold the
482262306a36Sopenharmony_ci		 * list_lock. slab->inuse here is the upper limit.
482362306a36Sopenharmony_ci		 */
482462306a36Sopenharmony_ci		list_for_each_entry_safe(slab, t, &n->partial, slab_list) {
482562306a36Sopenharmony_ci			int free = slab->objects - slab->inuse;
482662306a36Sopenharmony_ci
482762306a36Sopenharmony_ci			/* Do not reread slab->inuse */
482862306a36Sopenharmony_ci			barrier();
482962306a36Sopenharmony_ci
483062306a36Sopenharmony_ci			/* We do not keep full slabs on the list */
483162306a36Sopenharmony_ci			BUG_ON(free <= 0);
483262306a36Sopenharmony_ci
483362306a36Sopenharmony_ci			if (free == slab->objects) {
483462306a36Sopenharmony_ci				list_move(&slab->slab_list, &discard);
483562306a36Sopenharmony_ci				n->nr_partial--;
483662306a36Sopenharmony_ci				dec_slabs_node(s, node, slab->objects);
483762306a36Sopenharmony_ci			} else if (free <= SHRINK_PROMOTE_MAX)
483862306a36Sopenharmony_ci				list_move(&slab->slab_list, promote + free - 1);
483962306a36Sopenharmony_ci		}
484062306a36Sopenharmony_ci
484162306a36Sopenharmony_ci		/*
484262306a36Sopenharmony_ci		 * Promote the slabs filled up most to the head of the
484362306a36Sopenharmony_ci		 * partial list.
484462306a36Sopenharmony_ci		 */
484562306a36Sopenharmony_ci		for (i = SHRINK_PROMOTE_MAX - 1; i >= 0; i--)
484662306a36Sopenharmony_ci			list_splice(promote + i, &n->partial);
484762306a36Sopenharmony_ci
484862306a36Sopenharmony_ci		spin_unlock_irqrestore(&n->list_lock, flags);
484962306a36Sopenharmony_ci
485062306a36Sopenharmony_ci		/* Release empty slabs */
485162306a36Sopenharmony_ci		list_for_each_entry_safe(slab, t, &discard, slab_list)
485262306a36Sopenharmony_ci			free_slab(s, slab);
485362306a36Sopenharmony_ci
485462306a36Sopenharmony_ci		if (node_nr_slabs(n))
485562306a36Sopenharmony_ci			ret = 1;
485662306a36Sopenharmony_ci	}
485762306a36Sopenharmony_ci
485862306a36Sopenharmony_ci	return ret;
485962306a36Sopenharmony_ci}
486062306a36Sopenharmony_ci
486162306a36Sopenharmony_ciint __kmem_cache_shrink(struct kmem_cache *s)
486262306a36Sopenharmony_ci{
486362306a36Sopenharmony_ci	flush_all(s);
486462306a36Sopenharmony_ci	return __kmem_cache_do_shrink(s);
486562306a36Sopenharmony_ci}
486662306a36Sopenharmony_ci
486762306a36Sopenharmony_cistatic int slab_mem_going_offline_callback(void *arg)
486862306a36Sopenharmony_ci{
486962306a36Sopenharmony_ci	struct kmem_cache *s;
487062306a36Sopenharmony_ci
487162306a36Sopenharmony_ci	mutex_lock(&slab_mutex);
487262306a36Sopenharmony_ci	list_for_each_entry(s, &slab_caches, list) {
487362306a36Sopenharmony_ci		flush_all_cpus_locked(s);
487462306a36Sopenharmony_ci		__kmem_cache_do_shrink(s);
487562306a36Sopenharmony_ci	}
487662306a36Sopenharmony_ci	mutex_unlock(&slab_mutex);
487762306a36Sopenharmony_ci
487862306a36Sopenharmony_ci	return 0;
487962306a36Sopenharmony_ci}
488062306a36Sopenharmony_ci
488162306a36Sopenharmony_cistatic void slab_mem_offline_callback(void *arg)
488262306a36Sopenharmony_ci{
488362306a36Sopenharmony_ci	struct memory_notify *marg = arg;
488462306a36Sopenharmony_ci	int offline_node;
488562306a36Sopenharmony_ci
488662306a36Sopenharmony_ci	offline_node = marg->status_change_nid_normal;
488762306a36Sopenharmony_ci
488862306a36Sopenharmony_ci	/*
488962306a36Sopenharmony_ci	 * If the node still has available memory. we need kmem_cache_node
489062306a36Sopenharmony_ci	 * for it yet.
489162306a36Sopenharmony_ci	 */
489262306a36Sopenharmony_ci	if (offline_node < 0)
489362306a36Sopenharmony_ci		return;
489462306a36Sopenharmony_ci
489562306a36Sopenharmony_ci	mutex_lock(&slab_mutex);
489662306a36Sopenharmony_ci	node_clear(offline_node, slab_nodes);
489762306a36Sopenharmony_ci	/*
489862306a36Sopenharmony_ci	 * We no longer free kmem_cache_node structures here, as it would be
489962306a36Sopenharmony_ci	 * racy with all get_node() users, and infeasible to protect them with
490062306a36Sopenharmony_ci	 * slab_mutex.
490162306a36Sopenharmony_ci	 */
490262306a36Sopenharmony_ci	mutex_unlock(&slab_mutex);
490362306a36Sopenharmony_ci}
490462306a36Sopenharmony_ci
490562306a36Sopenharmony_cistatic int slab_mem_going_online_callback(void *arg)
490662306a36Sopenharmony_ci{
490762306a36Sopenharmony_ci	struct kmem_cache_node *n;
490862306a36Sopenharmony_ci	struct kmem_cache *s;
490962306a36Sopenharmony_ci	struct memory_notify *marg = arg;
491062306a36Sopenharmony_ci	int nid = marg->status_change_nid_normal;
491162306a36Sopenharmony_ci	int ret = 0;
491262306a36Sopenharmony_ci
491362306a36Sopenharmony_ci	/*
491462306a36Sopenharmony_ci	 * If the node's memory is already available, then kmem_cache_node is
491562306a36Sopenharmony_ci	 * already created. Nothing to do.
491662306a36Sopenharmony_ci	 */
491762306a36Sopenharmony_ci	if (nid < 0)
491862306a36Sopenharmony_ci		return 0;
491962306a36Sopenharmony_ci
492062306a36Sopenharmony_ci	/*
492162306a36Sopenharmony_ci	 * We are bringing a node online. No memory is available yet. We must
492262306a36Sopenharmony_ci	 * allocate a kmem_cache_node structure in order to bring the node
492362306a36Sopenharmony_ci	 * online.
492462306a36Sopenharmony_ci	 */
492562306a36Sopenharmony_ci	mutex_lock(&slab_mutex);
492662306a36Sopenharmony_ci	list_for_each_entry(s, &slab_caches, list) {
492762306a36Sopenharmony_ci		/*
492862306a36Sopenharmony_ci		 * The structure may already exist if the node was previously
492962306a36Sopenharmony_ci		 * onlined and offlined.
493062306a36Sopenharmony_ci		 */
493162306a36Sopenharmony_ci		if (get_node(s, nid))
493262306a36Sopenharmony_ci			continue;
493362306a36Sopenharmony_ci		/*
493462306a36Sopenharmony_ci		 * XXX: kmem_cache_alloc_node will fallback to other nodes
493562306a36Sopenharmony_ci		 *      since memory is not yet available from the node that
493662306a36Sopenharmony_ci		 *      is brought up.
493762306a36Sopenharmony_ci		 */
493862306a36Sopenharmony_ci		n = kmem_cache_alloc(kmem_cache_node, GFP_KERNEL);
493962306a36Sopenharmony_ci		if (!n) {
494062306a36Sopenharmony_ci			ret = -ENOMEM;
494162306a36Sopenharmony_ci			goto out;
494262306a36Sopenharmony_ci		}
494362306a36Sopenharmony_ci		init_kmem_cache_node(n);
494462306a36Sopenharmony_ci		s->node[nid] = n;
494562306a36Sopenharmony_ci	}
494662306a36Sopenharmony_ci	/*
494762306a36Sopenharmony_ci	 * Any cache created after this point will also have kmem_cache_node
494862306a36Sopenharmony_ci	 * initialized for the new node.
494962306a36Sopenharmony_ci	 */
495062306a36Sopenharmony_ci	node_set(nid, slab_nodes);
495162306a36Sopenharmony_ciout:
495262306a36Sopenharmony_ci	mutex_unlock(&slab_mutex);
495362306a36Sopenharmony_ci	return ret;
495462306a36Sopenharmony_ci}
495562306a36Sopenharmony_ci
495662306a36Sopenharmony_cistatic int slab_memory_callback(struct notifier_block *self,
495762306a36Sopenharmony_ci				unsigned long action, void *arg)
495862306a36Sopenharmony_ci{
495962306a36Sopenharmony_ci	int ret = 0;
496062306a36Sopenharmony_ci
496162306a36Sopenharmony_ci	switch (action) {
496262306a36Sopenharmony_ci	case MEM_GOING_ONLINE:
496362306a36Sopenharmony_ci		ret = slab_mem_going_online_callback(arg);
496462306a36Sopenharmony_ci		break;
496562306a36Sopenharmony_ci	case MEM_GOING_OFFLINE:
496662306a36Sopenharmony_ci		ret = slab_mem_going_offline_callback(arg);
496762306a36Sopenharmony_ci		break;
496862306a36Sopenharmony_ci	case MEM_OFFLINE:
496962306a36Sopenharmony_ci	case MEM_CANCEL_ONLINE:
497062306a36Sopenharmony_ci		slab_mem_offline_callback(arg);
497162306a36Sopenharmony_ci		break;
497262306a36Sopenharmony_ci	case MEM_ONLINE:
497362306a36Sopenharmony_ci	case MEM_CANCEL_OFFLINE:
497462306a36Sopenharmony_ci		break;
497562306a36Sopenharmony_ci	}
497662306a36Sopenharmony_ci	if (ret)
497762306a36Sopenharmony_ci		ret = notifier_from_errno(ret);
497862306a36Sopenharmony_ci	else
497962306a36Sopenharmony_ci		ret = NOTIFY_OK;
498062306a36Sopenharmony_ci	return ret;
498162306a36Sopenharmony_ci}
498262306a36Sopenharmony_ci
498362306a36Sopenharmony_ci/********************************************************************
498462306a36Sopenharmony_ci *			Basic setup of slabs
498562306a36Sopenharmony_ci *******************************************************************/
498662306a36Sopenharmony_ci
498762306a36Sopenharmony_ci/*
498862306a36Sopenharmony_ci * Used for early kmem_cache structures that were allocated using
498962306a36Sopenharmony_ci * the page allocator. Allocate them properly then fix up the pointers
499062306a36Sopenharmony_ci * that may be pointing to the wrong kmem_cache structure.
499162306a36Sopenharmony_ci */
499262306a36Sopenharmony_ci
499362306a36Sopenharmony_cistatic struct kmem_cache * __init bootstrap(struct kmem_cache *static_cache)
499462306a36Sopenharmony_ci{
499562306a36Sopenharmony_ci	int node;
499662306a36Sopenharmony_ci	struct kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
499762306a36Sopenharmony_ci	struct kmem_cache_node *n;
499862306a36Sopenharmony_ci
499962306a36Sopenharmony_ci	memcpy(s, static_cache, kmem_cache->object_size);
500062306a36Sopenharmony_ci
500162306a36Sopenharmony_ci	/*
500262306a36Sopenharmony_ci	 * This runs very early, and only the boot processor is supposed to be
500362306a36Sopenharmony_ci	 * up.  Even if it weren't true, IRQs are not up so we couldn't fire
500462306a36Sopenharmony_ci	 * IPIs around.
500562306a36Sopenharmony_ci	 */
500662306a36Sopenharmony_ci	__flush_cpu_slab(s, smp_processor_id());
500762306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
500862306a36Sopenharmony_ci		struct slab *p;
500962306a36Sopenharmony_ci
501062306a36Sopenharmony_ci		list_for_each_entry(p, &n->partial, slab_list)
501162306a36Sopenharmony_ci			p->slab_cache = s;
501262306a36Sopenharmony_ci
501362306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
501462306a36Sopenharmony_ci		list_for_each_entry(p, &n->full, slab_list)
501562306a36Sopenharmony_ci			p->slab_cache = s;
501662306a36Sopenharmony_ci#endif
501762306a36Sopenharmony_ci	}
501862306a36Sopenharmony_ci	list_add(&s->list, &slab_caches);
501962306a36Sopenharmony_ci	return s;
502062306a36Sopenharmony_ci}
502162306a36Sopenharmony_ci
502262306a36Sopenharmony_civoid __init kmem_cache_init(void)
502362306a36Sopenharmony_ci{
502462306a36Sopenharmony_ci	static __initdata struct kmem_cache boot_kmem_cache,
502562306a36Sopenharmony_ci		boot_kmem_cache_node;
502662306a36Sopenharmony_ci	int node;
502762306a36Sopenharmony_ci
502862306a36Sopenharmony_ci	if (debug_guardpage_minorder())
502962306a36Sopenharmony_ci		slub_max_order = 0;
503062306a36Sopenharmony_ci
503162306a36Sopenharmony_ci	/* Print slub debugging pointers without hashing */
503262306a36Sopenharmony_ci	if (__slub_debug_enabled())
503362306a36Sopenharmony_ci		no_hash_pointers_enable(NULL);
503462306a36Sopenharmony_ci
503562306a36Sopenharmony_ci	kmem_cache_node = &boot_kmem_cache_node;
503662306a36Sopenharmony_ci	kmem_cache = &boot_kmem_cache;
503762306a36Sopenharmony_ci
503862306a36Sopenharmony_ci	/*
503962306a36Sopenharmony_ci	 * Initialize the nodemask for which we will allocate per node
504062306a36Sopenharmony_ci	 * structures. Here we don't need taking slab_mutex yet.
504162306a36Sopenharmony_ci	 */
504262306a36Sopenharmony_ci	for_each_node_state(node, N_NORMAL_MEMORY)
504362306a36Sopenharmony_ci		node_set(node, slab_nodes);
504462306a36Sopenharmony_ci
504562306a36Sopenharmony_ci	create_boot_cache(kmem_cache_node, "kmem_cache_node",
504662306a36Sopenharmony_ci		sizeof(struct kmem_cache_node), SLAB_HWCACHE_ALIGN, 0, 0);
504762306a36Sopenharmony_ci
504862306a36Sopenharmony_ci	hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
504962306a36Sopenharmony_ci
505062306a36Sopenharmony_ci	/* Able to allocate the per node structures */
505162306a36Sopenharmony_ci	slab_state = PARTIAL;
505262306a36Sopenharmony_ci
505362306a36Sopenharmony_ci	create_boot_cache(kmem_cache, "kmem_cache",
505462306a36Sopenharmony_ci			offsetof(struct kmem_cache, node) +
505562306a36Sopenharmony_ci				nr_node_ids * sizeof(struct kmem_cache_node *),
505662306a36Sopenharmony_ci		       SLAB_HWCACHE_ALIGN, 0, 0);
505762306a36Sopenharmony_ci
505862306a36Sopenharmony_ci	kmem_cache = bootstrap(&boot_kmem_cache);
505962306a36Sopenharmony_ci	kmem_cache_node = bootstrap(&boot_kmem_cache_node);
506062306a36Sopenharmony_ci
506162306a36Sopenharmony_ci	/* Now we can use the kmem_cache to allocate kmalloc slabs */
506262306a36Sopenharmony_ci	setup_kmalloc_cache_index_table();
506362306a36Sopenharmony_ci	create_kmalloc_caches(0);
506462306a36Sopenharmony_ci
506562306a36Sopenharmony_ci	/* Setup random freelists for each cache */
506662306a36Sopenharmony_ci	init_freelist_randomization();
506762306a36Sopenharmony_ci
506862306a36Sopenharmony_ci	cpuhp_setup_state_nocalls(CPUHP_SLUB_DEAD, "slub:dead", NULL,
506962306a36Sopenharmony_ci				  slub_cpu_dead);
507062306a36Sopenharmony_ci
507162306a36Sopenharmony_ci	pr_info("SLUB: HWalign=%d, Order=%u-%u, MinObjects=%u, CPUs=%u, Nodes=%u\n",
507262306a36Sopenharmony_ci		cache_line_size(),
507362306a36Sopenharmony_ci		slub_min_order, slub_max_order, slub_min_objects,
507462306a36Sopenharmony_ci		nr_cpu_ids, nr_node_ids);
507562306a36Sopenharmony_ci}
507662306a36Sopenharmony_ci
507762306a36Sopenharmony_civoid __init kmem_cache_init_late(void)
507862306a36Sopenharmony_ci{
507962306a36Sopenharmony_ci#ifndef CONFIG_SLUB_TINY
508062306a36Sopenharmony_ci	flushwq = alloc_workqueue("slub_flushwq", WQ_MEM_RECLAIM, 0);
508162306a36Sopenharmony_ci	WARN_ON(!flushwq);
508262306a36Sopenharmony_ci#endif
508362306a36Sopenharmony_ci}
508462306a36Sopenharmony_ci
508562306a36Sopenharmony_cistruct kmem_cache *
508662306a36Sopenharmony_ci__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
508762306a36Sopenharmony_ci		   slab_flags_t flags, void (*ctor)(void *))
508862306a36Sopenharmony_ci{
508962306a36Sopenharmony_ci	struct kmem_cache *s;
509062306a36Sopenharmony_ci
509162306a36Sopenharmony_ci	s = find_mergeable(size, align, flags, name, ctor);
509262306a36Sopenharmony_ci	if (s) {
509362306a36Sopenharmony_ci		if (sysfs_slab_alias(s, name))
509462306a36Sopenharmony_ci			return NULL;
509562306a36Sopenharmony_ci
509662306a36Sopenharmony_ci		s->refcount++;
509762306a36Sopenharmony_ci
509862306a36Sopenharmony_ci		/*
509962306a36Sopenharmony_ci		 * Adjust the object sizes so that we clear
510062306a36Sopenharmony_ci		 * the complete object on kzalloc.
510162306a36Sopenharmony_ci		 */
510262306a36Sopenharmony_ci		s->object_size = max(s->object_size, size);
510362306a36Sopenharmony_ci		s->inuse = max(s->inuse, ALIGN(size, sizeof(void *)));
510462306a36Sopenharmony_ci	}
510562306a36Sopenharmony_ci
510662306a36Sopenharmony_ci	return s;
510762306a36Sopenharmony_ci}
510862306a36Sopenharmony_ci
510962306a36Sopenharmony_ciint __kmem_cache_create(struct kmem_cache *s, slab_flags_t flags)
511062306a36Sopenharmony_ci{
511162306a36Sopenharmony_ci	int err;
511262306a36Sopenharmony_ci
511362306a36Sopenharmony_ci	err = kmem_cache_open(s, flags);
511462306a36Sopenharmony_ci	if (err)
511562306a36Sopenharmony_ci		return err;
511662306a36Sopenharmony_ci
511762306a36Sopenharmony_ci	/* Mutex is not taken during early boot */
511862306a36Sopenharmony_ci	if (slab_state <= UP)
511962306a36Sopenharmony_ci		return 0;
512062306a36Sopenharmony_ci
512162306a36Sopenharmony_ci	err = sysfs_slab_add(s);
512262306a36Sopenharmony_ci	if (err) {
512362306a36Sopenharmony_ci		__kmem_cache_release(s);
512462306a36Sopenharmony_ci		return err;
512562306a36Sopenharmony_ci	}
512662306a36Sopenharmony_ci
512762306a36Sopenharmony_ci	if (s->flags & SLAB_STORE_USER)
512862306a36Sopenharmony_ci		debugfs_slab_add(s);
512962306a36Sopenharmony_ci
513062306a36Sopenharmony_ci	return 0;
513162306a36Sopenharmony_ci}
513262306a36Sopenharmony_ci
513362306a36Sopenharmony_ci#ifdef SLAB_SUPPORTS_SYSFS
513462306a36Sopenharmony_cistatic int count_inuse(struct slab *slab)
513562306a36Sopenharmony_ci{
513662306a36Sopenharmony_ci	return slab->inuse;
513762306a36Sopenharmony_ci}
513862306a36Sopenharmony_ci
513962306a36Sopenharmony_cistatic int count_total(struct slab *slab)
514062306a36Sopenharmony_ci{
514162306a36Sopenharmony_ci	return slab->objects;
514262306a36Sopenharmony_ci}
514362306a36Sopenharmony_ci#endif
514462306a36Sopenharmony_ci
514562306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
514662306a36Sopenharmony_cistatic void validate_slab(struct kmem_cache *s, struct slab *slab,
514762306a36Sopenharmony_ci			  unsigned long *obj_map)
514862306a36Sopenharmony_ci{
514962306a36Sopenharmony_ci	void *p;
515062306a36Sopenharmony_ci	void *addr = slab_address(slab);
515162306a36Sopenharmony_ci
515262306a36Sopenharmony_ci	if (!check_slab(s, slab) || !on_freelist(s, slab, NULL))
515362306a36Sopenharmony_ci		return;
515462306a36Sopenharmony_ci
515562306a36Sopenharmony_ci	/* Now we know that a valid freelist exists */
515662306a36Sopenharmony_ci	__fill_map(obj_map, s, slab);
515762306a36Sopenharmony_ci	for_each_object(p, s, addr, slab->objects) {
515862306a36Sopenharmony_ci		u8 val = test_bit(__obj_to_index(s, addr, p), obj_map) ?
515962306a36Sopenharmony_ci			 SLUB_RED_INACTIVE : SLUB_RED_ACTIVE;
516062306a36Sopenharmony_ci
516162306a36Sopenharmony_ci		if (!check_object(s, slab, p, val))
516262306a36Sopenharmony_ci			break;
516362306a36Sopenharmony_ci	}
516462306a36Sopenharmony_ci}
516562306a36Sopenharmony_ci
516662306a36Sopenharmony_cistatic int validate_slab_node(struct kmem_cache *s,
516762306a36Sopenharmony_ci		struct kmem_cache_node *n, unsigned long *obj_map)
516862306a36Sopenharmony_ci{
516962306a36Sopenharmony_ci	unsigned long count = 0;
517062306a36Sopenharmony_ci	struct slab *slab;
517162306a36Sopenharmony_ci	unsigned long flags;
517262306a36Sopenharmony_ci
517362306a36Sopenharmony_ci	spin_lock_irqsave(&n->list_lock, flags);
517462306a36Sopenharmony_ci
517562306a36Sopenharmony_ci	list_for_each_entry(slab, &n->partial, slab_list) {
517662306a36Sopenharmony_ci		validate_slab(s, slab, obj_map);
517762306a36Sopenharmony_ci		count++;
517862306a36Sopenharmony_ci	}
517962306a36Sopenharmony_ci	if (count != n->nr_partial) {
518062306a36Sopenharmony_ci		pr_err("SLUB %s: %ld partial slabs counted but counter=%ld\n",
518162306a36Sopenharmony_ci		       s->name, count, n->nr_partial);
518262306a36Sopenharmony_ci		slab_add_kunit_errors();
518362306a36Sopenharmony_ci	}
518462306a36Sopenharmony_ci
518562306a36Sopenharmony_ci	if (!(s->flags & SLAB_STORE_USER))
518662306a36Sopenharmony_ci		goto out;
518762306a36Sopenharmony_ci
518862306a36Sopenharmony_ci	list_for_each_entry(slab, &n->full, slab_list) {
518962306a36Sopenharmony_ci		validate_slab(s, slab, obj_map);
519062306a36Sopenharmony_ci		count++;
519162306a36Sopenharmony_ci	}
519262306a36Sopenharmony_ci	if (count != node_nr_slabs(n)) {
519362306a36Sopenharmony_ci		pr_err("SLUB: %s %ld slabs counted but counter=%ld\n",
519462306a36Sopenharmony_ci		       s->name, count, node_nr_slabs(n));
519562306a36Sopenharmony_ci		slab_add_kunit_errors();
519662306a36Sopenharmony_ci	}
519762306a36Sopenharmony_ci
519862306a36Sopenharmony_ciout:
519962306a36Sopenharmony_ci	spin_unlock_irqrestore(&n->list_lock, flags);
520062306a36Sopenharmony_ci	return count;
520162306a36Sopenharmony_ci}
520262306a36Sopenharmony_ci
520362306a36Sopenharmony_cilong validate_slab_cache(struct kmem_cache *s)
520462306a36Sopenharmony_ci{
520562306a36Sopenharmony_ci	int node;
520662306a36Sopenharmony_ci	unsigned long count = 0;
520762306a36Sopenharmony_ci	struct kmem_cache_node *n;
520862306a36Sopenharmony_ci	unsigned long *obj_map;
520962306a36Sopenharmony_ci
521062306a36Sopenharmony_ci	obj_map = bitmap_alloc(oo_objects(s->oo), GFP_KERNEL);
521162306a36Sopenharmony_ci	if (!obj_map)
521262306a36Sopenharmony_ci		return -ENOMEM;
521362306a36Sopenharmony_ci
521462306a36Sopenharmony_ci	flush_all(s);
521562306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n)
521662306a36Sopenharmony_ci		count += validate_slab_node(s, n, obj_map);
521762306a36Sopenharmony_ci
521862306a36Sopenharmony_ci	bitmap_free(obj_map);
521962306a36Sopenharmony_ci
522062306a36Sopenharmony_ci	return count;
522162306a36Sopenharmony_ci}
522262306a36Sopenharmony_ciEXPORT_SYMBOL(validate_slab_cache);
522362306a36Sopenharmony_ci
522462306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_FS
522562306a36Sopenharmony_ci/*
522662306a36Sopenharmony_ci * Generate lists of code addresses where slabcache objects are allocated
522762306a36Sopenharmony_ci * and freed.
522862306a36Sopenharmony_ci */
522962306a36Sopenharmony_ci
523062306a36Sopenharmony_cistruct location {
523162306a36Sopenharmony_ci	depot_stack_handle_t handle;
523262306a36Sopenharmony_ci	unsigned long count;
523362306a36Sopenharmony_ci	unsigned long addr;
523462306a36Sopenharmony_ci	unsigned long waste;
523562306a36Sopenharmony_ci	long long sum_time;
523662306a36Sopenharmony_ci	long min_time;
523762306a36Sopenharmony_ci	long max_time;
523862306a36Sopenharmony_ci	long min_pid;
523962306a36Sopenharmony_ci	long max_pid;
524062306a36Sopenharmony_ci	DECLARE_BITMAP(cpus, NR_CPUS);
524162306a36Sopenharmony_ci	nodemask_t nodes;
524262306a36Sopenharmony_ci};
524362306a36Sopenharmony_ci
524462306a36Sopenharmony_cistruct loc_track {
524562306a36Sopenharmony_ci	unsigned long max;
524662306a36Sopenharmony_ci	unsigned long count;
524762306a36Sopenharmony_ci	struct location *loc;
524862306a36Sopenharmony_ci	loff_t idx;
524962306a36Sopenharmony_ci};
525062306a36Sopenharmony_ci
525162306a36Sopenharmony_cistatic struct dentry *slab_debugfs_root;
525262306a36Sopenharmony_ci
525362306a36Sopenharmony_cistatic void free_loc_track(struct loc_track *t)
525462306a36Sopenharmony_ci{
525562306a36Sopenharmony_ci	if (t->max)
525662306a36Sopenharmony_ci		free_pages((unsigned long)t->loc,
525762306a36Sopenharmony_ci			get_order(sizeof(struct location) * t->max));
525862306a36Sopenharmony_ci}
525962306a36Sopenharmony_ci
526062306a36Sopenharmony_cistatic int alloc_loc_track(struct loc_track *t, unsigned long max, gfp_t flags)
526162306a36Sopenharmony_ci{
526262306a36Sopenharmony_ci	struct location *l;
526362306a36Sopenharmony_ci	int order;
526462306a36Sopenharmony_ci
526562306a36Sopenharmony_ci	order = get_order(sizeof(struct location) * max);
526662306a36Sopenharmony_ci
526762306a36Sopenharmony_ci	l = (void *)__get_free_pages(flags, order);
526862306a36Sopenharmony_ci	if (!l)
526962306a36Sopenharmony_ci		return 0;
527062306a36Sopenharmony_ci
527162306a36Sopenharmony_ci	if (t->count) {
527262306a36Sopenharmony_ci		memcpy(l, t->loc, sizeof(struct location) * t->count);
527362306a36Sopenharmony_ci		free_loc_track(t);
527462306a36Sopenharmony_ci	}
527562306a36Sopenharmony_ci	t->max = max;
527662306a36Sopenharmony_ci	t->loc = l;
527762306a36Sopenharmony_ci	return 1;
527862306a36Sopenharmony_ci}
527962306a36Sopenharmony_ci
528062306a36Sopenharmony_cistatic int add_location(struct loc_track *t, struct kmem_cache *s,
528162306a36Sopenharmony_ci				const struct track *track,
528262306a36Sopenharmony_ci				unsigned int orig_size)
528362306a36Sopenharmony_ci{
528462306a36Sopenharmony_ci	long start, end, pos;
528562306a36Sopenharmony_ci	struct location *l;
528662306a36Sopenharmony_ci	unsigned long caddr, chandle, cwaste;
528762306a36Sopenharmony_ci	unsigned long age = jiffies - track->when;
528862306a36Sopenharmony_ci	depot_stack_handle_t handle = 0;
528962306a36Sopenharmony_ci	unsigned int waste = s->object_size - orig_size;
529062306a36Sopenharmony_ci
529162306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
529262306a36Sopenharmony_ci	handle = READ_ONCE(track->handle);
529362306a36Sopenharmony_ci#endif
529462306a36Sopenharmony_ci	start = -1;
529562306a36Sopenharmony_ci	end = t->count;
529662306a36Sopenharmony_ci
529762306a36Sopenharmony_ci	for ( ; ; ) {
529862306a36Sopenharmony_ci		pos = start + (end - start + 1) / 2;
529962306a36Sopenharmony_ci
530062306a36Sopenharmony_ci		/*
530162306a36Sopenharmony_ci		 * There is nothing at "end". If we end up there
530262306a36Sopenharmony_ci		 * we need to add something to before end.
530362306a36Sopenharmony_ci		 */
530462306a36Sopenharmony_ci		if (pos == end)
530562306a36Sopenharmony_ci			break;
530662306a36Sopenharmony_ci
530762306a36Sopenharmony_ci		l = &t->loc[pos];
530862306a36Sopenharmony_ci		caddr = l->addr;
530962306a36Sopenharmony_ci		chandle = l->handle;
531062306a36Sopenharmony_ci		cwaste = l->waste;
531162306a36Sopenharmony_ci		if ((track->addr == caddr) && (handle == chandle) &&
531262306a36Sopenharmony_ci			(waste == cwaste)) {
531362306a36Sopenharmony_ci
531462306a36Sopenharmony_ci			l->count++;
531562306a36Sopenharmony_ci			if (track->when) {
531662306a36Sopenharmony_ci				l->sum_time += age;
531762306a36Sopenharmony_ci				if (age < l->min_time)
531862306a36Sopenharmony_ci					l->min_time = age;
531962306a36Sopenharmony_ci				if (age > l->max_time)
532062306a36Sopenharmony_ci					l->max_time = age;
532162306a36Sopenharmony_ci
532262306a36Sopenharmony_ci				if (track->pid < l->min_pid)
532362306a36Sopenharmony_ci					l->min_pid = track->pid;
532462306a36Sopenharmony_ci				if (track->pid > l->max_pid)
532562306a36Sopenharmony_ci					l->max_pid = track->pid;
532662306a36Sopenharmony_ci
532762306a36Sopenharmony_ci				cpumask_set_cpu(track->cpu,
532862306a36Sopenharmony_ci						to_cpumask(l->cpus));
532962306a36Sopenharmony_ci			}
533062306a36Sopenharmony_ci			node_set(page_to_nid(virt_to_page(track)), l->nodes);
533162306a36Sopenharmony_ci			return 1;
533262306a36Sopenharmony_ci		}
533362306a36Sopenharmony_ci
533462306a36Sopenharmony_ci		if (track->addr < caddr)
533562306a36Sopenharmony_ci			end = pos;
533662306a36Sopenharmony_ci		else if (track->addr == caddr && handle < chandle)
533762306a36Sopenharmony_ci			end = pos;
533862306a36Sopenharmony_ci		else if (track->addr == caddr && handle == chandle &&
533962306a36Sopenharmony_ci				waste < cwaste)
534062306a36Sopenharmony_ci			end = pos;
534162306a36Sopenharmony_ci		else
534262306a36Sopenharmony_ci			start = pos;
534362306a36Sopenharmony_ci	}
534462306a36Sopenharmony_ci
534562306a36Sopenharmony_ci	/*
534662306a36Sopenharmony_ci	 * Not found. Insert new tracking element.
534762306a36Sopenharmony_ci	 */
534862306a36Sopenharmony_ci	if (t->count >= t->max && !alloc_loc_track(t, 2 * t->max, GFP_ATOMIC))
534962306a36Sopenharmony_ci		return 0;
535062306a36Sopenharmony_ci
535162306a36Sopenharmony_ci	l = t->loc + pos;
535262306a36Sopenharmony_ci	if (pos < t->count)
535362306a36Sopenharmony_ci		memmove(l + 1, l,
535462306a36Sopenharmony_ci			(t->count - pos) * sizeof(struct location));
535562306a36Sopenharmony_ci	t->count++;
535662306a36Sopenharmony_ci	l->count = 1;
535762306a36Sopenharmony_ci	l->addr = track->addr;
535862306a36Sopenharmony_ci	l->sum_time = age;
535962306a36Sopenharmony_ci	l->min_time = age;
536062306a36Sopenharmony_ci	l->max_time = age;
536162306a36Sopenharmony_ci	l->min_pid = track->pid;
536262306a36Sopenharmony_ci	l->max_pid = track->pid;
536362306a36Sopenharmony_ci	l->handle = handle;
536462306a36Sopenharmony_ci	l->waste = waste;
536562306a36Sopenharmony_ci	cpumask_clear(to_cpumask(l->cpus));
536662306a36Sopenharmony_ci	cpumask_set_cpu(track->cpu, to_cpumask(l->cpus));
536762306a36Sopenharmony_ci	nodes_clear(l->nodes);
536862306a36Sopenharmony_ci	node_set(page_to_nid(virt_to_page(track)), l->nodes);
536962306a36Sopenharmony_ci	return 1;
537062306a36Sopenharmony_ci}
537162306a36Sopenharmony_ci
537262306a36Sopenharmony_cistatic void process_slab(struct loc_track *t, struct kmem_cache *s,
537362306a36Sopenharmony_ci		struct slab *slab, enum track_item alloc,
537462306a36Sopenharmony_ci		unsigned long *obj_map)
537562306a36Sopenharmony_ci{
537662306a36Sopenharmony_ci	void *addr = slab_address(slab);
537762306a36Sopenharmony_ci	bool is_alloc = (alloc == TRACK_ALLOC);
537862306a36Sopenharmony_ci	void *p;
537962306a36Sopenharmony_ci
538062306a36Sopenharmony_ci	__fill_map(obj_map, s, slab);
538162306a36Sopenharmony_ci
538262306a36Sopenharmony_ci	for_each_object(p, s, addr, slab->objects)
538362306a36Sopenharmony_ci		if (!test_bit(__obj_to_index(s, addr, p), obj_map))
538462306a36Sopenharmony_ci			add_location(t, s, get_track(s, p, alloc),
538562306a36Sopenharmony_ci				     is_alloc ? get_orig_size(s, p) :
538662306a36Sopenharmony_ci						s->object_size);
538762306a36Sopenharmony_ci}
538862306a36Sopenharmony_ci#endif  /* CONFIG_DEBUG_FS   */
538962306a36Sopenharmony_ci#endif	/* CONFIG_SLUB_DEBUG */
539062306a36Sopenharmony_ci
539162306a36Sopenharmony_ci#ifdef SLAB_SUPPORTS_SYSFS
539262306a36Sopenharmony_cienum slab_stat_type {
539362306a36Sopenharmony_ci	SL_ALL,			/* All slabs */
539462306a36Sopenharmony_ci	SL_PARTIAL,		/* Only partially allocated slabs */
539562306a36Sopenharmony_ci	SL_CPU,			/* Only slabs used for cpu caches */
539662306a36Sopenharmony_ci	SL_OBJECTS,		/* Determine allocated objects not slabs */
539762306a36Sopenharmony_ci	SL_TOTAL		/* Determine object capacity not slabs */
539862306a36Sopenharmony_ci};
539962306a36Sopenharmony_ci
540062306a36Sopenharmony_ci#define SO_ALL		(1 << SL_ALL)
540162306a36Sopenharmony_ci#define SO_PARTIAL	(1 << SL_PARTIAL)
540262306a36Sopenharmony_ci#define SO_CPU		(1 << SL_CPU)
540362306a36Sopenharmony_ci#define SO_OBJECTS	(1 << SL_OBJECTS)
540462306a36Sopenharmony_ci#define SO_TOTAL	(1 << SL_TOTAL)
540562306a36Sopenharmony_ci
540662306a36Sopenharmony_cistatic ssize_t show_slab_objects(struct kmem_cache *s,
540762306a36Sopenharmony_ci				 char *buf, unsigned long flags)
540862306a36Sopenharmony_ci{
540962306a36Sopenharmony_ci	unsigned long total = 0;
541062306a36Sopenharmony_ci	int node;
541162306a36Sopenharmony_ci	int x;
541262306a36Sopenharmony_ci	unsigned long *nodes;
541362306a36Sopenharmony_ci	int len = 0;
541462306a36Sopenharmony_ci
541562306a36Sopenharmony_ci	nodes = kcalloc(nr_node_ids, sizeof(unsigned long), GFP_KERNEL);
541662306a36Sopenharmony_ci	if (!nodes)
541762306a36Sopenharmony_ci		return -ENOMEM;
541862306a36Sopenharmony_ci
541962306a36Sopenharmony_ci	if (flags & SO_CPU) {
542062306a36Sopenharmony_ci		int cpu;
542162306a36Sopenharmony_ci
542262306a36Sopenharmony_ci		for_each_possible_cpu(cpu) {
542362306a36Sopenharmony_ci			struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab,
542462306a36Sopenharmony_ci							       cpu);
542562306a36Sopenharmony_ci			int node;
542662306a36Sopenharmony_ci			struct slab *slab;
542762306a36Sopenharmony_ci
542862306a36Sopenharmony_ci			slab = READ_ONCE(c->slab);
542962306a36Sopenharmony_ci			if (!slab)
543062306a36Sopenharmony_ci				continue;
543162306a36Sopenharmony_ci
543262306a36Sopenharmony_ci			node = slab_nid(slab);
543362306a36Sopenharmony_ci			if (flags & SO_TOTAL)
543462306a36Sopenharmony_ci				x = slab->objects;
543562306a36Sopenharmony_ci			else if (flags & SO_OBJECTS)
543662306a36Sopenharmony_ci				x = slab->inuse;
543762306a36Sopenharmony_ci			else
543862306a36Sopenharmony_ci				x = 1;
543962306a36Sopenharmony_ci
544062306a36Sopenharmony_ci			total += x;
544162306a36Sopenharmony_ci			nodes[node] += x;
544262306a36Sopenharmony_ci
544362306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
544462306a36Sopenharmony_ci			slab = slub_percpu_partial_read_once(c);
544562306a36Sopenharmony_ci			if (slab) {
544662306a36Sopenharmony_ci				node = slab_nid(slab);
544762306a36Sopenharmony_ci				if (flags & SO_TOTAL)
544862306a36Sopenharmony_ci					WARN_ON_ONCE(1);
544962306a36Sopenharmony_ci				else if (flags & SO_OBJECTS)
545062306a36Sopenharmony_ci					WARN_ON_ONCE(1);
545162306a36Sopenharmony_ci				else
545262306a36Sopenharmony_ci					x = slab->slabs;
545362306a36Sopenharmony_ci				total += x;
545462306a36Sopenharmony_ci				nodes[node] += x;
545562306a36Sopenharmony_ci			}
545662306a36Sopenharmony_ci#endif
545762306a36Sopenharmony_ci		}
545862306a36Sopenharmony_ci	}
545962306a36Sopenharmony_ci
546062306a36Sopenharmony_ci	/*
546162306a36Sopenharmony_ci	 * It is impossible to take "mem_hotplug_lock" here with "kernfs_mutex"
546262306a36Sopenharmony_ci	 * already held which will conflict with an existing lock order:
546362306a36Sopenharmony_ci	 *
546462306a36Sopenharmony_ci	 * mem_hotplug_lock->slab_mutex->kernfs_mutex
546562306a36Sopenharmony_ci	 *
546662306a36Sopenharmony_ci	 * We don't really need mem_hotplug_lock (to hold off
546762306a36Sopenharmony_ci	 * slab_mem_going_offline_callback) here because slab's memory hot
546862306a36Sopenharmony_ci	 * unplug code doesn't destroy the kmem_cache->node[] data.
546962306a36Sopenharmony_ci	 */
547062306a36Sopenharmony_ci
547162306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
547262306a36Sopenharmony_ci	if (flags & SO_ALL) {
547362306a36Sopenharmony_ci		struct kmem_cache_node *n;
547462306a36Sopenharmony_ci
547562306a36Sopenharmony_ci		for_each_kmem_cache_node(s, node, n) {
547662306a36Sopenharmony_ci
547762306a36Sopenharmony_ci			if (flags & SO_TOTAL)
547862306a36Sopenharmony_ci				x = node_nr_objs(n);
547962306a36Sopenharmony_ci			else if (flags & SO_OBJECTS)
548062306a36Sopenharmony_ci				x = node_nr_objs(n) - count_partial(n, count_free);
548162306a36Sopenharmony_ci			else
548262306a36Sopenharmony_ci				x = node_nr_slabs(n);
548362306a36Sopenharmony_ci			total += x;
548462306a36Sopenharmony_ci			nodes[node] += x;
548562306a36Sopenharmony_ci		}
548662306a36Sopenharmony_ci
548762306a36Sopenharmony_ci	} else
548862306a36Sopenharmony_ci#endif
548962306a36Sopenharmony_ci	if (flags & SO_PARTIAL) {
549062306a36Sopenharmony_ci		struct kmem_cache_node *n;
549162306a36Sopenharmony_ci
549262306a36Sopenharmony_ci		for_each_kmem_cache_node(s, node, n) {
549362306a36Sopenharmony_ci			if (flags & SO_TOTAL)
549462306a36Sopenharmony_ci				x = count_partial(n, count_total);
549562306a36Sopenharmony_ci			else if (flags & SO_OBJECTS)
549662306a36Sopenharmony_ci				x = count_partial(n, count_inuse);
549762306a36Sopenharmony_ci			else
549862306a36Sopenharmony_ci				x = n->nr_partial;
549962306a36Sopenharmony_ci			total += x;
550062306a36Sopenharmony_ci			nodes[node] += x;
550162306a36Sopenharmony_ci		}
550262306a36Sopenharmony_ci	}
550362306a36Sopenharmony_ci
550462306a36Sopenharmony_ci	len += sysfs_emit_at(buf, len, "%lu", total);
550562306a36Sopenharmony_ci#ifdef CONFIG_NUMA
550662306a36Sopenharmony_ci	for (node = 0; node < nr_node_ids; node++) {
550762306a36Sopenharmony_ci		if (nodes[node])
550862306a36Sopenharmony_ci			len += sysfs_emit_at(buf, len, " N%d=%lu",
550962306a36Sopenharmony_ci					     node, nodes[node]);
551062306a36Sopenharmony_ci	}
551162306a36Sopenharmony_ci#endif
551262306a36Sopenharmony_ci	len += sysfs_emit_at(buf, len, "\n");
551362306a36Sopenharmony_ci	kfree(nodes);
551462306a36Sopenharmony_ci
551562306a36Sopenharmony_ci	return len;
551662306a36Sopenharmony_ci}
551762306a36Sopenharmony_ci
551862306a36Sopenharmony_ci#define to_slab_attr(n) container_of(n, struct slab_attribute, attr)
551962306a36Sopenharmony_ci#define to_slab(n) container_of(n, struct kmem_cache, kobj)
552062306a36Sopenharmony_ci
552162306a36Sopenharmony_cistruct slab_attribute {
552262306a36Sopenharmony_ci	struct attribute attr;
552362306a36Sopenharmony_ci	ssize_t (*show)(struct kmem_cache *s, char *buf);
552462306a36Sopenharmony_ci	ssize_t (*store)(struct kmem_cache *s, const char *x, size_t count);
552562306a36Sopenharmony_ci};
552662306a36Sopenharmony_ci
552762306a36Sopenharmony_ci#define SLAB_ATTR_RO(_name) \
552862306a36Sopenharmony_ci	static struct slab_attribute _name##_attr = __ATTR_RO_MODE(_name, 0400)
552962306a36Sopenharmony_ci
553062306a36Sopenharmony_ci#define SLAB_ATTR(_name) \
553162306a36Sopenharmony_ci	static struct slab_attribute _name##_attr = __ATTR_RW_MODE(_name, 0600)
553262306a36Sopenharmony_ci
553362306a36Sopenharmony_cistatic ssize_t slab_size_show(struct kmem_cache *s, char *buf)
553462306a36Sopenharmony_ci{
553562306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", s->size);
553662306a36Sopenharmony_ci}
553762306a36Sopenharmony_ciSLAB_ATTR_RO(slab_size);
553862306a36Sopenharmony_ci
553962306a36Sopenharmony_cistatic ssize_t align_show(struct kmem_cache *s, char *buf)
554062306a36Sopenharmony_ci{
554162306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", s->align);
554262306a36Sopenharmony_ci}
554362306a36Sopenharmony_ciSLAB_ATTR_RO(align);
554462306a36Sopenharmony_ci
554562306a36Sopenharmony_cistatic ssize_t object_size_show(struct kmem_cache *s, char *buf)
554662306a36Sopenharmony_ci{
554762306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", s->object_size);
554862306a36Sopenharmony_ci}
554962306a36Sopenharmony_ciSLAB_ATTR_RO(object_size);
555062306a36Sopenharmony_ci
555162306a36Sopenharmony_cistatic ssize_t objs_per_slab_show(struct kmem_cache *s, char *buf)
555262306a36Sopenharmony_ci{
555362306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", oo_objects(s->oo));
555462306a36Sopenharmony_ci}
555562306a36Sopenharmony_ciSLAB_ATTR_RO(objs_per_slab);
555662306a36Sopenharmony_ci
555762306a36Sopenharmony_cistatic ssize_t order_show(struct kmem_cache *s, char *buf)
555862306a36Sopenharmony_ci{
555962306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", oo_order(s->oo));
556062306a36Sopenharmony_ci}
556162306a36Sopenharmony_ciSLAB_ATTR_RO(order);
556262306a36Sopenharmony_ci
556362306a36Sopenharmony_cistatic ssize_t min_partial_show(struct kmem_cache *s, char *buf)
556462306a36Sopenharmony_ci{
556562306a36Sopenharmony_ci	return sysfs_emit(buf, "%lu\n", s->min_partial);
556662306a36Sopenharmony_ci}
556762306a36Sopenharmony_ci
556862306a36Sopenharmony_cistatic ssize_t min_partial_store(struct kmem_cache *s, const char *buf,
556962306a36Sopenharmony_ci				 size_t length)
557062306a36Sopenharmony_ci{
557162306a36Sopenharmony_ci	unsigned long min;
557262306a36Sopenharmony_ci	int err;
557362306a36Sopenharmony_ci
557462306a36Sopenharmony_ci	err = kstrtoul(buf, 10, &min);
557562306a36Sopenharmony_ci	if (err)
557662306a36Sopenharmony_ci		return err;
557762306a36Sopenharmony_ci
557862306a36Sopenharmony_ci	s->min_partial = min;
557962306a36Sopenharmony_ci	return length;
558062306a36Sopenharmony_ci}
558162306a36Sopenharmony_ciSLAB_ATTR(min_partial);
558262306a36Sopenharmony_ci
558362306a36Sopenharmony_cistatic ssize_t cpu_partial_show(struct kmem_cache *s, char *buf)
558462306a36Sopenharmony_ci{
558562306a36Sopenharmony_ci	unsigned int nr_partial = 0;
558662306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
558762306a36Sopenharmony_ci	nr_partial = s->cpu_partial;
558862306a36Sopenharmony_ci#endif
558962306a36Sopenharmony_ci
559062306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", nr_partial);
559162306a36Sopenharmony_ci}
559262306a36Sopenharmony_ci
559362306a36Sopenharmony_cistatic ssize_t cpu_partial_store(struct kmem_cache *s, const char *buf,
559462306a36Sopenharmony_ci				 size_t length)
559562306a36Sopenharmony_ci{
559662306a36Sopenharmony_ci	unsigned int objects;
559762306a36Sopenharmony_ci	int err;
559862306a36Sopenharmony_ci
559962306a36Sopenharmony_ci	err = kstrtouint(buf, 10, &objects);
560062306a36Sopenharmony_ci	if (err)
560162306a36Sopenharmony_ci		return err;
560262306a36Sopenharmony_ci	if (objects && !kmem_cache_has_cpu_partial(s))
560362306a36Sopenharmony_ci		return -EINVAL;
560462306a36Sopenharmony_ci
560562306a36Sopenharmony_ci	slub_set_cpu_partial(s, objects);
560662306a36Sopenharmony_ci	flush_all(s);
560762306a36Sopenharmony_ci	return length;
560862306a36Sopenharmony_ci}
560962306a36Sopenharmony_ciSLAB_ATTR(cpu_partial);
561062306a36Sopenharmony_ci
561162306a36Sopenharmony_cistatic ssize_t ctor_show(struct kmem_cache *s, char *buf)
561262306a36Sopenharmony_ci{
561362306a36Sopenharmony_ci	if (!s->ctor)
561462306a36Sopenharmony_ci		return 0;
561562306a36Sopenharmony_ci	return sysfs_emit(buf, "%pS\n", s->ctor);
561662306a36Sopenharmony_ci}
561762306a36Sopenharmony_ciSLAB_ATTR_RO(ctor);
561862306a36Sopenharmony_ci
561962306a36Sopenharmony_cistatic ssize_t aliases_show(struct kmem_cache *s, char *buf)
562062306a36Sopenharmony_ci{
562162306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", s->refcount < 0 ? 0 : s->refcount - 1);
562262306a36Sopenharmony_ci}
562362306a36Sopenharmony_ciSLAB_ATTR_RO(aliases);
562462306a36Sopenharmony_ci
562562306a36Sopenharmony_cistatic ssize_t partial_show(struct kmem_cache *s, char *buf)
562662306a36Sopenharmony_ci{
562762306a36Sopenharmony_ci	return show_slab_objects(s, buf, SO_PARTIAL);
562862306a36Sopenharmony_ci}
562962306a36Sopenharmony_ciSLAB_ATTR_RO(partial);
563062306a36Sopenharmony_ci
563162306a36Sopenharmony_cistatic ssize_t cpu_slabs_show(struct kmem_cache *s, char *buf)
563262306a36Sopenharmony_ci{
563362306a36Sopenharmony_ci	return show_slab_objects(s, buf, SO_CPU);
563462306a36Sopenharmony_ci}
563562306a36Sopenharmony_ciSLAB_ATTR_RO(cpu_slabs);
563662306a36Sopenharmony_ci
563762306a36Sopenharmony_cistatic ssize_t objects_partial_show(struct kmem_cache *s, char *buf)
563862306a36Sopenharmony_ci{
563962306a36Sopenharmony_ci	return show_slab_objects(s, buf, SO_PARTIAL|SO_OBJECTS);
564062306a36Sopenharmony_ci}
564162306a36Sopenharmony_ciSLAB_ATTR_RO(objects_partial);
564262306a36Sopenharmony_ci
564362306a36Sopenharmony_cistatic ssize_t slabs_cpu_partial_show(struct kmem_cache *s, char *buf)
564462306a36Sopenharmony_ci{
564562306a36Sopenharmony_ci	int objects = 0;
564662306a36Sopenharmony_ci	int slabs = 0;
564762306a36Sopenharmony_ci	int cpu __maybe_unused;
564862306a36Sopenharmony_ci	int len = 0;
564962306a36Sopenharmony_ci
565062306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
565162306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
565262306a36Sopenharmony_ci		struct slab *slab;
565362306a36Sopenharmony_ci
565462306a36Sopenharmony_ci		slab = slub_percpu_partial(per_cpu_ptr(s->cpu_slab, cpu));
565562306a36Sopenharmony_ci
565662306a36Sopenharmony_ci		if (slab)
565762306a36Sopenharmony_ci			slabs += slab->slabs;
565862306a36Sopenharmony_ci	}
565962306a36Sopenharmony_ci#endif
566062306a36Sopenharmony_ci
566162306a36Sopenharmony_ci	/* Approximate half-full slabs, see slub_set_cpu_partial() */
566262306a36Sopenharmony_ci	objects = (slabs * oo_objects(s->oo)) / 2;
566362306a36Sopenharmony_ci	len += sysfs_emit_at(buf, len, "%d(%d)", objects, slabs);
566462306a36Sopenharmony_ci
566562306a36Sopenharmony_ci#ifdef CONFIG_SLUB_CPU_PARTIAL
566662306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
566762306a36Sopenharmony_ci		struct slab *slab;
566862306a36Sopenharmony_ci
566962306a36Sopenharmony_ci		slab = slub_percpu_partial(per_cpu_ptr(s->cpu_slab, cpu));
567062306a36Sopenharmony_ci		if (slab) {
567162306a36Sopenharmony_ci			slabs = READ_ONCE(slab->slabs);
567262306a36Sopenharmony_ci			objects = (slabs * oo_objects(s->oo)) / 2;
567362306a36Sopenharmony_ci			len += sysfs_emit_at(buf, len, " C%d=%d(%d)",
567462306a36Sopenharmony_ci					     cpu, objects, slabs);
567562306a36Sopenharmony_ci		}
567662306a36Sopenharmony_ci	}
567762306a36Sopenharmony_ci#endif
567862306a36Sopenharmony_ci	len += sysfs_emit_at(buf, len, "\n");
567962306a36Sopenharmony_ci
568062306a36Sopenharmony_ci	return len;
568162306a36Sopenharmony_ci}
568262306a36Sopenharmony_ciSLAB_ATTR_RO(slabs_cpu_partial);
568362306a36Sopenharmony_ci
568462306a36Sopenharmony_cistatic ssize_t reclaim_account_show(struct kmem_cache *s, char *buf)
568562306a36Sopenharmony_ci{
568662306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT));
568762306a36Sopenharmony_ci}
568862306a36Sopenharmony_ciSLAB_ATTR_RO(reclaim_account);
568962306a36Sopenharmony_ci
569062306a36Sopenharmony_cistatic ssize_t hwcache_align_show(struct kmem_cache *s, char *buf)
569162306a36Sopenharmony_ci{
569262306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_HWCACHE_ALIGN));
569362306a36Sopenharmony_ci}
569462306a36Sopenharmony_ciSLAB_ATTR_RO(hwcache_align);
569562306a36Sopenharmony_ci
569662306a36Sopenharmony_ci#ifdef CONFIG_ZONE_DMA
569762306a36Sopenharmony_cistatic ssize_t cache_dma_show(struct kmem_cache *s, char *buf)
569862306a36Sopenharmony_ci{
569962306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_CACHE_DMA));
570062306a36Sopenharmony_ci}
570162306a36Sopenharmony_ciSLAB_ATTR_RO(cache_dma);
570262306a36Sopenharmony_ci#endif
570362306a36Sopenharmony_ci
570462306a36Sopenharmony_ci#ifdef CONFIG_HARDENED_USERCOPY
570562306a36Sopenharmony_cistatic ssize_t usersize_show(struct kmem_cache *s, char *buf)
570662306a36Sopenharmony_ci{
570762306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", s->usersize);
570862306a36Sopenharmony_ci}
570962306a36Sopenharmony_ciSLAB_ATTR_RO(usersize);
571062306a36Sopenharmony_ci#endif
571162306a36Sopenharmony_ci
571262306a36Sopenharmony_cistatic ssize_t destroy_by_rcu_show(struct kmem_cache *s, char *buf)
571362306a36Sopenharmony_ci{
571462306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_TYPESAFE_BY_RCU));
571562306a36Sopenharmony_ci}
571662306a36Sopenharmony_ciSLAB_ATTR_RO(destroy_by_rcu);
571762306a36Sopenharmony_ci
571862306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
571962306a36Sopenharmony_cistatic ssize_t slabs_show(struct kmem_cache *s, char *buf)
572062306a36Sopenharmony_ci{
572162306a36Sopenharmony_ci	return show_slab_objects(s, buf, SO_ALL);
572262306a36Sopenharmony_ci}
572362306a36Sopenharmony_ciSLAB_ATTR_RO(slabs);
572462306a36Sopenharmony_ci
572562306a36Sopenharmony_cistatic ssize_t total_objects_show(struct kmem_cache *s, char *buf)
572662306a36Sopenharmony_ci{
572762306a36Sopenharmony_ci	return show_slab_objects(s, buf, SO_ALL|SO_TOTAL);
572862306a36Sopenharmony_ci}
572962306a36Sopenharmony_ciSLAB_ATTR_RO(total_objects);
573062306a36Sopenharmony_ci
573162306a36Sopenharmony_cistatic ssize_t objects_show(struct kmem_cache *s, char *buf)
573262306a36Sopenharmony_ci{
573362306a36Sopenharmony_ci	return show_slab_objects(s, buf, SO_ALL|SO_OBJECTS);
573462306a36Sopenharmony_ci}
573562306a36Sopenharmony_ciSLAB_ATTR_RO(objects);
573662306a36Sopenharmony_ci
573762306a36Sopenharmony_cistatic ssize_t sanity_checks_show(struct kmem_cache *s, char *buf)
573862306a36Sopenharmony_ci{
573962306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_CONSISTENCY_CHECKS));
574062306a36Sopenharmony_ci}
574162306a36Sopenharmony_ciSLAB_ATTR_RO(sanity_checks);
574262306a36Sopenharmony_ci
574362306a36Sopenharmony_cistatic ssize_t trace_show(struct kmem_cache *s, char *buf)
574462306a36Sopenharmony_ci{
574562306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_TRACE));
574662306a36Sopenharmony_ci}
574762306a36Sopenharmony_ciSLAB_ATTR_RO(trace);
574862306a36Sopenharmony_ci
574962306a36Sopenharmony_cistatic ssize_t red_zone_show(struct kmem_cache *s, char *buf)
575062306a36Sopenharmony_ci{
575162306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_RED_ZONE));
575262306a36Sopenharmony_ci}
575362306a36Sopenharmony_ci
575462306a36Sopenharmony_ciSLAB_ATTR_RO(red_zone);
575562306a36Sopenharmony_ci
575662306a36Sopenharmony_cistatic ssize_t poison_show(struct kmem_cache *s, char *buf)
575762306a36Sopenharmony_ci{
575862306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_POISON));
575962306a36Sopenharmony_ci}
576062306a36Sopenharmony_ci
576162306a36Sopenharmony_ciSLAB_ATTR_RO(poison);
576262306a36Sopenharmony_ci
576362306a36Sopenharmony_cistatic ssize_t store_user_show(struct kmem_cache *s, char *buf)
576462306a36Sopenharmony_ci{
576562306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_STORE_USER));
576662306a36Sopenharmony_ci}
576762306a36Sopenharmony_ci
576862306a36Sopenharmony_ciSLAB_ATTR_RO(store_user);
576962306a36Sopenharmony_ci
577062306a36Sopenharmony_cistatic ssize_t validate_show(struct kmem_cache *s, char *buf)
577162306a36Sopenharmony_ci{
577262306a36Sopenharmony_ci	return 0;
577362306a36Sopenharmony_ci}
577462306a36Sopenharmony_ci
577562306a36Sopenharmony_cistatic ssize_t validate_store(struct kmem_cache *s,
577662306a36Sopenharmony_ci			const char *buf, size_t length)
577762306a36Sopenharmony_ci{
577862306a36Sopenharmony_ci	int ret = -EINVAL;
577962306a36Sopenharmony_ci
578062306a36Sopenharmony_ci	if (buf[0] == '1' && kmem_cache_debug(s)) {
578162306a36Sopenharmony_ci		ret = validate_slab_cache(s);
578262306a36Sopenharmony_ci		if (ret >= 0)
578362306a36Sopenharmony_ci			ret = length;
578462306a36Sopenharmony_ci	}
578562306a36Sopenharmony_ci	return ret;
578662306a36Sopenharmony_ci}
578762306a36Sopenharmony_ciSLAB_ATTR(validate);
578862306a36Sopenharmony_ci
578962306a36Sopenharmony_ci#endif /* CONFIG_SLUB_DEBUG */
579062306a36Sopenharmony_ci
579162306a36Sopenharmony_ci#ifdef CONFIG_FAILSLAB
579262306a36Sopenharmony_cistatic ssize_t failslab_show(struct kmem_cache *s, char *buf)
579362306a36Sopenharmony_ci{
579462306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_FAILSLAB));
579562306a36Sopenharmony_ci}
579662306a36Sopenharmony_ci
579762306a36Sopenharmony_cistatic ssize_t failslab_store(struct kmem_cache *s, const char *buf,
579862306a36Sopenharmony_ci				size_t length)
579962306a36Sopenharmony_ci{
580062306a36Sopenharmony_ci	if (s->refcount > 1)
580162306a36Sopenharmony_ci		return -EINVAL;
580262306a36Sopenharmony_ci
580362306a36Sopenharmony_ci	if (buf[0] == '1')
580462306a36Sopenharmony_ci		WRITE_ONCE(s->flags, s->flags | SLAB_FAILSLAB);
580562306a36Sopenharmony_ci	else
580662306a36Sopenharmony_ci		WRITE_ONCE(s->flags, s->flags & ~SLAB_FAILSLAB);
580762306a36Sopenharmony_ci
580862306a36Sopenharmony_ci	return length;
580962306a36Sopenharmony_ci}
581062306a36Sopenharmony_ciSLAB_ATTR(failslab);
581162306a36Sopenharmony_ci#endif
581262306a36Sopenharmony_ci
581362306a36Sopenharmony_cistatic ssize_t shrink_show(struct kmem_cache *s, char *buf)
581462306a36Sopenharmony_ci{
581562306a36Sopenharmony_ci	return 0;
581662306a36Sopenharmony_ci}
581762306a36Sopenharmony_ci
581862306a36Sopenharmony_cistatic ssize_t shrink_store(struct kmem_cache *s,
581962306a36Sopenharmony_ci			const char *buf, size_t length)
582062306a36Sopenharmony_ci{
582162306a36Sopenharmony_ci	if (buf[0] == '1')
582262306a36Sopenharmony_ci		kmem_cache_shrink(s);
582362306a36Sopenharmony_ci	else
582462306a36Sopenharmony_ci		return -EINVAL;
582562306a36Sopenharmony_ci	return length;
582662306a36Sopenharmony_ci}
582762306a36Sopenharmony_ciSLAB_ATTR(shrink);
582862306a36Sopenharmony_ci
582962306a36Sopenharmony_ci#ifdef CONFIG_NUMA
583062306a36Sopenharmony_cistatic ssize_t remote_node_defrag_ratio_show(struct kmem_cache *s, char *buf)
583162306a36Sopenharmony_ci{
583262306a36Sopenharmony_ci	return sysfs_emit(buf, "%u\n", s->remote_node_defrag_ratio / 10);
583362306a36Sopenharmony_ci}
583462306a36Sopenharmony_ci
583562306a36Sopenharmony_cistatic ssize_t remote_node_defrag_ratio_store(struct kmem_cache *s,
583662306a36Sopenharmony_ci				const char *buf, size_t length)
583762306a36Sopenharmony_ci{
583862306a36Sopenharmony_ci	unsigned int ratio;
583962306a36Sopenharmony_ci	int err;
584062306a36Sopenharmony_ci
584162306a36Sopenharmony_ci	err = kstrtouint(buf, 10, &ratio);
584262306a36Sopenharmony_ci	if (err)
584362306a36Sopenharmony_ci		return err;
584462306a36Sopenharmony_ci	if (ratio > 100)
584562306a36Sopenharmony_ci		return -ERANGE;
584662306a36Sopenharmony_ci
584762306a36Sopenharmony_ci	s->remote_node_defrag_ratio = ratio * 10;
584862306a36Sopenharmony_ci
584962306a36Sopenharmony_ci	return length;
585062306a36Sopenharmony_ci}
585162306a36Sopenharmony_ciSLAB_ATTR(remote_node_defrag_ratio);
585262306a36Sopenharmony_ci#endif
585362306a36Sopenharmony_ci
585462306a36Sopenharmony_ci#ifdef CONFIG_SLUB_STATS
585562306a36Sopenharmony_cistatic int show_stat(struct kmem_cache *s, char *buf, enum stat_item si)
585662306a36Sopenharmony_ci{
585762306a36Sopenharmony_ci	unsigned long sum  = 0;
585862306a36Sopenharmony_ci	int cpu;
585962306a36Sopenharmony_ci	int len = 0;
586062306a36Sopenharmony_ci	int *data = kmalloc_array(nr_cpu_ids, sizeof(int), GFP_KERNEL);
586162306a36Sopenharmony_ci
586262306a36Sopenharmony_ci	if (!data)
586362306a36Sopenharmony_ci		return -ENOMEM;
586462306a36Sopenharmony_ci
586562306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
586662306a36Sopenharmony_ci		unsigned x = per_cpu_ptr(s->cpu_slab, cpu)->stat[si];
586762306a36Sopenharmony_ci
586862306a36Sopenharmony_ci		data[cpu] = x;
586962306a36Sopenharmony_ci		sum += x;
587062306a36Sopenharmony_ci	}
587162306a36Sopenharmony_ci
587262306a36Sopenharmony_ci	len += sysfs_emit_at(buf, len, "%lu", sum);
587362306a36Sopenharmony_ci
587462306a36Sopenharmony_ci#ifdef CONFIG_SMP
587562306a36Sopenharmony_ci	for_each_online_cpu(cpu) {
587662306a36Sopenharmony_ci		if (data[cpu])
587762306a36Sopenharmony_ci			len += sysfs_emit_at(buf, len, " C%d=%u",
587862306a36Sopenharmony_ci					     cpu, data[cpu]);
587962306a36Sopenharmony_ci	}
588062306a36Sopenharmony_ci#endif
588162306a36Sopenharmony_ci	kfree(data);
588262306a36Sopenharmony_ci	len += sysfs_emit_at(buf, len, "\n");
588362306a36Sopenharmony_ci
588462306a36Sopenharmony_ci	return len;
588562306a36Sopenharmony_ci}
588662306a36Sopenharmony_ci
588762306a36Sopenharmony_cistatic void clear_stat(struct kmem_cache *s, enum stat_item si)
588862306a36Sopenharmony_ci{
588962306a36Sopenharmony_ci	int cpu;
589062306a36Sopenharmony_ci
589162306a36Sopenharmony_ci	for_each_online_cpu(cpu)
589262306a36Sopenharmony_ci		per_cpu_ptr(s->cpu_slab, cpu)->stat[si] = 0;
589362306a36Sopenharmony_ci}
589462306a36Sopenharmony_ci
589562306a36Sopenharmony_ci#define STAT_ATTR(si, text) 					\
589662306a36Sopenharmony_cistatic ssize_t text##_show(struct kmem_cache *s, char *buf)	\
589762306a36Sopenharmony_ci{								\
589862306a36Sopenharmony_ci	return show_stat(s, buf, si);				\
589962306a36Sopenharmony_ci}								\
590062306a36Sopenharmony_cistatic ssize_t text##_store(struct kmem_cache *s,		\
590162306a36Sopenharmony_ci				const char *buf, size_t length)	\
590262306a36Sopenharmony_ci{								\
590362306a36Sopenharmony_ci	if (buf[0] != '0')					\
590462306a36Sopenharmony_ci		return -EINVAL;					\
590562306a36Sopenharmony_ci	clear_stat(s, si);					\
590662306a36Sopenharmony_ci	return length;						\
590762306a36Sopenharmony_ci}								\
590862306a36Sopenharmony_ciSLAB_ATTR(text);						\
590962306a36Sopenharmony_ci
591062306a36Sopenharmony_ciSTAT_ATTR(ALLOC_FASTPATH, alloc_fastpath);
591162306a36Sopenharmony_ciSTAT_ATTR(ALLOC_SLOWPATH, alloc_slowpath);
591262306a36Sopenharmony_ciSTAT_ATTR(FREE_FASTPATH, free_fastpath);
591362306a36Sopenharmony_ciSTAT_ATTR(FREE_SLOWPATH, free_slowpath);
591462306a36Sopenharmony_ciSTAT_ATTR(FREE_FROZEN, free_frozen);
591562306a36Sopenharmony_ciSTAT_ATTR(FREE_ADD_PARTIAL, free_add_partial);
591662306a36Sopenharmony_ciSTAT_ATTR(FREE_REMOVE_PARTIAL, free_remove_partial);
591762306a36Sopenharmony_ciSTAT_ATTR(ALLOC_FROM_PARTIAL, alloc_from_partial);
591862306a36Sopenharmony_ciSTAT_ATTR(ALLOC_SLAB, alloc_slab);
591962306a36Sopenharmony_ciSTAT_ATTR(ALLOC_REFILL, alloc_refill);
592062306a36Sopenharmony_ciSTAT_ATTR(ALLOC_NODE_MISMATCH, alloc_node_mismatch);
592162306a36Sopenharmony_ciSTAT_ATTR(FREE_SLAB, free_slab);
592262306a36Sopenharmony_ciSTAT_ATTR(CPUSLAB_FLUSH, cpuslab_flush);
592362306a36Sopenharmony_ciSTAT_ATTR(DEACTIVATE_FULL, deactivate_full);
592462306a36Sopenharmony_ciSTAT_ATTR(DEACTIVATE_EMPTY, deactivate_empty);
592562306a36Sopenharmony_ciSTAT_ATTR(DEACTIVATE_TO_HEAD, deactivate_to_head);
592662306a36Sopenharmony_ciSTAT_ATTR(DEACTIVATE_TO_TAIL, deactivate_to_tail);
592762306a36Sopenharmony_ciSTAT_ATTR(DEACTIVATE_REMOTE_FREES, deactivate_remote_frees);
592862306a36Sopenharmony_ciSTAT_ATTR(DEACTIVATE_BYPASS, deactivate_bypass);
592962306a36Sopenharmony_ciSTAT_ATTR(ORDER_FALLBACK, order_fallback);
593062306a36Sopenharmony_ciSTAT_ATTR(CMPXCHG_DOUBLE_CPU_FAIL, cmpxchg_double_cpu_fail);
593162306a36Sopenharmony_ciSTAT_ATTR(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail);
593262306a36Sopenharmony_ciSTAT_ATTR(CPU_PARTIAL_ALLOC, cpu_partial_alloc);
593362306a36Sopenharmony_ciSTAT_ATTR(CPU_PARTIAL_FREE, cpu_partial_free);
593462306a36Sopenharmony_ciSTAT_ATTR(CPU_PARTIAL_NODE, cpu_partial_node);
593562306a36Sopenharmony_ciSTAT_ATTR(CPU_PARTIAL_DRAIN, cpu_partial_drain);
593662306a36Sopenharmony_ci#endif	/* CONFIG_SLUB_STATS */
593762306a36Sopenharmony_ci
593862306a36Sopenharmony_ci#ifdef CONFIG_KFENCE
593962306a36Sopenharmony_cistatic ssize_t skip_kfence_show(struct kmem_cache *s, char *buf)
594062306a36Sopenharmony_ci{
594162306a36Sopenharmony_ci	return sysfs_emit(buf, "%d\n", !!(s->flags & SLAB_SKIP_KFENCE));
594262306a36Sopenharmony_ci}
594362306a36Sopenharmony_ci
594462306a36Sopenharmony_cistatic ssize_t skip_kfence_store(struct kmem_cache *s,
594562306a36Sopenharmony_ci			const char *buf, size_t length)
594662306a36Sopenharmony_ci{
594762306a36Sopenharmony_ci	int ret = length;
594862306a36Sopenharmony_ci
594962306a36Sopenharmony_ci	if (buf[0] == '0')
595062306a36Sopenharmony_ci		s->flags &= ~SLAB_SKIP_KFENCE;
595162306a36Sopenharmony_ci	else if (buf[0] == '1')
595262306a36Sopenharmony_ci		s->flags |= SLAB_SKIP_KFENCE;
595362306a36Sopenharmony_ci	else
595462306a36Sopenharmony_ci		ret = -EINVAL;
595562306a36Sopenharmony_ci
595662306a36Sopenharmony_ci	return ret;
595762306a36Sopenharmony_ci}
595862306a36Sopenharmony_ciSLAB_ATTR(skip_kfence);
595962306a36Sopenharmony_ci#endif
596062306a36Sopenharmony_ci
596162306a36Sopenharmony_cistatic struct attribute *slab_attrs[] = {
596262306a36Sopenharmony_ci	&slab_size_attr.attr,
596362306a36Sopenharmony_ci	&object_size_attr.attr,
596462306a36Sopenharmony_ci	&objs_per_slab_attr.attr,
596562306a36Sopenharmony_ci	&order_attr.attr,
596662306a36Sopenharmony_ci	&min_partial_attr.attr,
596762306a36Sopenharmony_ci	&cpu_partial_attr.attr,
596862306a36Sopenharmony_ci	&objects_partial_attr.attr,
596962306a36Sopenharmony_ci	&partial_attr.attr,
597062306a36Sopenharmony_ci	&cpu_slabs_attr.attr,
597162306a36Sopenharmony_ci	&ctor_attr.attr,
597262306a36Sopenharmony_ci	&aliases_attr.attr,
597362306a36Sopenharmony_ci	&align_attr.attr,
597462306a36Sopenharmony_ci	&hwcache_align_attr.attr,
597562306a36Sopenharmony_ci	&reclaim_account_attr.attr,
597662306a36Sopenharmony_ci	&destroy_by_rcu_attr.attr,
597762306a36Sopenharmony_ci	&shrink_attr.attr,
597862306a36Sopenharmony_ci	&slabs_cpu_partial_attr.attr,
597962306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
598062306a36Sopenharmony_ci	&total_objects_attr.attr,
598162306a36Sopenharmony_ci	&objects_attr.attr,
598262306a36Sopenharmony_ci	&slabs_attr.attr,
598362306a36Sopenharmony_ci	&sanity_checks_attr.attr,
598462306a36Sopenharmony_ci	&trace_attr.attr,
598562306a36Sopenharmony_ci	&red_zone_attr.attr,
598662306a36Sopenharmony_ci	&poison_attr.attr,
598762306a36Sopenharmony_ci	&store_user_attr.attr,
598862306a36Sopenharmony_ci	&validate_attr.attr,
598962306a36Sopenharmony_ci#endif
599062306a36Sopenharmony_ci#ifdef CONFIG_ZONE_DMA
599162306a36Sopenharmony_ci	&cache_dma_attr.attr,
599262306a36Sopenharmony_ci#endif
599362306a36Sopenharmony_ci#ifdef CONFIG_NUMA
599462306a36Sopenharmony_ci	&remote_node_defrag_ratio_attr.attr,
599562306a36Sopenharmony_ci#endif
599662306a36Sopenharmony_ci#ifdef CONFIG_SLUB_STATS
599762306a36Sopenharmony_ci	&alloc_fastpath_attr.attr,
599862306a36Sopenharmony_ci	&alloc_slowpath_attr.attr,
599962306a36Sopenharmony_ci	&free_fastpath_attr.attr,
600062306a36Sopenharmony_ci	&free_slowpath_attr.attr,
600162306a36Sopenharmony_ci	&free_frozen_attr.attr,
600262306a36Sopenharmony_ci	&free_add_partial_attr.attr,
600362306a36Sopenharmony_ci	&free_remove_partial_attr.attr,
600462306a36Sopenharmony_ci	&alloc_from_partial_attr.attr,
600562306a36Sopenharmony_ci	&alloc_slab_attr.attr,
600662306a36Sopenharmony_ci	&alloc_refill_attr.attr,
600762306a36Sopenharmony_ci	&alloc_node_mismatch_attr.attr,
600862306a36Sopenharmony_ci	&free_slab_attr.attr,
600962306a36Sopenharmony_ci	&cpuslab_flush_attr.attr,
601062306a36Sopenharmony_ci	&deactivate_full_attr.attr,
601162306a36Sopenharmony_ci	&deactivate_empty_attr.attr,
601262306a36Sopenharmony_ci	&deactivate_to_head_attr.attr,
601362306a36Sopenharmony_ci	&deactivate_to_tail_attr.attr,
601462306a36Sopenharmony_ci	&deactivate_remote_frees_attr.attr,
601562306a36Sopenharmony_ci	&deactivate_bypass_attr.attr,
601662306a36Sopenharmony_ci	&order_fallback_attr.attr,
601762306a36Sopenharmony_ci	&cmpxchg_double_fail_attr.attr,
601862306a36Sopenharmony_ci	&cmpxchg_double_cpu_fail_attr.attr,
601962306a36Sopenharmony_ci	&cpu_partial_alloc_attr.attr,
602062306a36Sopenharmony_ci	&cpu_partial_free_attr.attr,
602162306a36Sopenharmony_ci	&cpu_partial_node_attr.attr,
602262306a36Sopenharmony_ci	&cpu_partial_drain_attr.attr,
602362306a36Sopenharmony_ci#endif
602462306a36Sopenharmony_ci#ifdef CONFIG_FAILSLAB
602562306a36Sopenharmony_ci	&failslab_attr.attr,
602662306a36Sopenharmony_ci#endif
602762306a36Sopenharmony_ci#ifdef CONFIG_HARDENED_USERCOPY
602862306a36Sopenharmony_ci	&usersize_attr.attr,
602962306a36Sopenharmony_ci#endif
603062306a36Sopenharmony_ci#ifdef CONFIG_KFENCE
603162306a36Sopenharmony_ci	&skip_kfence_attr.attr,
603262306a36Sopenharmony_ci#endif
603362306a36Sopenharmony_ci
603462306a36Sopenharmony_ci	NULL
603562306a36Sopenharmony_ci};
603662306a36Sopenharmony_ci
603762306a36Sopenharmony_cistatic const struct attribute_group slab_attr_group = {
603862306a36Sopenharmony_ci	.attrs = slab_attrs,
603962306a36Sopenharmony_ci};
604062306a36Sopenharmony_ci
604162306a36Sopenharmony_cistatic ssize_t slab_attr_show(struct kobject *kobj,
604262306a36Sopenharmony_ci				struct attribute *attr,
604362306a36Sopenharmony_ci				char *buf)
604462306a36Sopenharmony_ci{
604562306a36Sopenharmony_ci	struct slab_attribute *attribute;
604662306a36Sopenharmony_ci	struct kmem_cache *s;
604762306a36Sopenharmony_ci
604862306a36Sopenharmony_ci	attribute = to_slab_attr(attr);
604962306a36Sopenharmony_ci	s = to_slab(kobj);
605062306a36Sopenharmony_ci
605162306a36Sopenharmony_ci	if (!attribute->show)
605262306a36Sopenharmony_ci		return -EIO;
605362306a36Sopenharmony_ci
605462306a36Sopenharmony_ci	return attribute->show(s, buf);
605562306a36Sopenharmony_ci}
605662306a36Sopenharmony_ci
605762306a36Sopenharmony_cistatic ssize_t slab_attr_store(struct kobject *kobj,
605862306a36Sopenharmony_ci				struct attribute *attr,
605962306a36Sopenharmony_ci				const char *buf, size_t len)
606062306a36Sopenharmony_ci{
606162306a36Sopenharmony_ci	struct slab_attribute *attribute;
606262306a36Sopenharmony_ci	struct kmem_cache *s;
606362306a36Sopenharmony_ci
606462306a36Sopenharmony_ci	attribute = to_slab_attr(attr);
606562306a36Sopenharmony_ci	s = to_slab(kobj);
606662306a36Sopenharmony_ci
606762306a36Sopenharmony_ci	if (!attribute->store)
606862306a36Sopenharmony_ci		return -EIO;
606962306a36Sopenharmony_ci
607062306a36Sopenharmony_ci	return attribute->store(s, buf, len);
607162306a36Sopenharmony_ci}
607262306a36Sopenharmony_ci
607362306a36Sopenharmony_cistatic void kmem_cache_release(struct kobject *k)
607462306a36Sopenharmony_ci{
607562306a36Sopenharmony_ci	slab_kmem_cache_release(to_slab(k));
607662306a36Sopenharmony_ci}
607762306a36Sopenharmony_ci
607862306a36Sopenharmony_cistatic const struct sysfs_ops slab_sysfs_ops = {
607962306a36Sopenharmony_ci	.show = slab_attr_show,
608062306a36Sopenharmony_ci	.store = slab_attr_store,
608162306a36Sopenharmony_ci};
608262306a36Sopenharmony_ci
608362306a36Sopenharmony_cistatic const struct kobj_type slab_ktype = {
608462306a36Sopenharmony_ci	.sysfs_ops = &slab_sysfs_ops,
608562306a36Sopenharmony_ci	.release = kmem_cache_release,
608662306a36Sopenharmony_ci};
608762306a36Sopenharmony_ci
608862306a36Sopenharmony_cistatic struct kset *slab_kset;
608962306a36Sopenharmony_ci
609062306a36Sopenharmony_cistatic inline struct kset *cache_kset(struct kmem_cache *s)
609162306a36Sopenharmony_ci{
609262306a36Sopenharmony_ci	return slab_kset;
609362306a36Sopenharmony_ci}
609462306a36Sopenharmony_ci
609562306a36Sopenharmony_ci#define ID_STR_LENGTH 32
609662306a36Sopenharmony_ci
609762306a36Sopenharmony_ci/* Create a unique string id for a slab cache:
609862306a36Sopenharmony_ci *
609962306a36Sopenharmony_ci * Format	:[flags-]size
610062306a36Sopenharmony_ci */
610162306a36Sopenharmony_cistatic char *create_unique_id(struct kmem_cache *s)
610262306a36Sopenharmony_ci{
610362306a36Sopenharmony_ci	char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL);
610462306a36Sopenharmony_ci	char *p = name;
610562306a36Sopenharmony_ci
610662306a36Sopenharmony_ci	if (!name)
610762306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
610862306a36Sopenharmony_ci
610962306a36Sopenharmony_ci	*p++ = ':';
611062306a36Sopenharmony_ci	/*
611162306a36Sopenharmony_ci	 * First flags affecting slabcache operations. We will only
611262306a36Sopenharmony_ci	 * get here for aliasable slabs so we do not need to support
611362306a36Sopenharmony_ci	 * too many flags. The flags here must cover all flags that
611462306a36Sopenharmony_ci	 * are matched during merging to guarantee that the id is
611562306a36Sopenharmony_ci	 * unique.
611662306a36Sopenharmony_ci	 */
611762306a36Sopenharmony_ci	if (s->flags & SLAB_CACHE_DMA)
611862306a36Sopenharmony_ci		*p++ = 'd';
611962306a36Sopenharmony_ci	if (s->flags & SLAB_CACHE_DMA32)
612062306a36Sopenharmony_ci		*p++ = 'D';
612162306a36Sopenharmony_ci	if (s->flags & SLAB_RECLAIM_ACCOUNT)
612262306a36Sopenharmony_ci		*p++ = 'a';
612362306a36Sopenharmony_ci	if (s->flags & SLAB_CONSISTENCY_CHECKS)
612462306a36Sopenharmony_ci		*p++ = 'F';
612562306a36Sopenharmony_ci	if (s->flags & SLAB_ACCOUNT)
612662306a36Sopenharmony_ci		*p++ = 'A';
612762306a36Sopenharmony_ci	if (p != name + 1)
612862306a36Sopenharmony_ci		*p++ = '-';
612962306a36Sopenharmony_ci	p += snprintf(p, ID_STR_LENGTH - (p - name), "%07u", s->size);
613062306a36Sopenharmony_ci
613162306a36Sopenharmony_ci	if (WARN_ON(p > name + ID_STR_LENGTH - 1)) {
613262306a36Sopenharmony_ci		kfree(name);
613362306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
613462306a36Sopenharmony_ci	}
613562306a36Sopenharmony_ci	kmsan_unpoison_memory(name, p - name);
613662306a36Sopenharmony_ci	return name;
613762306a36Sopenharmony_ci}
613862306a36Sopenharmony_ci
613962306a36Sopenharmony_cistatic int sysfs_slab_add(struct kmem_cache *s)
614062306a36Sopenharmony_ci{
614162306a36Sopenharmony_ci	int err;
614262306a36Sopenharmony_ci	const char *name;
614362306a36Sopenharmony_ci	struct kset *kset = cache_kset(s);
614462306a36Sopenharmony_ci	int unmergeable = slab_unmergeable(s);
614562306a36Sopenharmony_ci
614662306a36Sopenharmony_ci	if (!unmergeable && disable_higher_order_debug &&
614762306a36Sopenharmony_ci			(slub_debug & DEBUG_METADATA_FLAGS))
614862306a36Sopenharmony_ci		unmergeable = 1;
614962306a36Sopenharmony_ci
615062306a36Sopenharmony_ci	if (unmergeable) {
615162306a36Sopenharmony_ci		/*
615262306a36Sopenharmony_ci		 * Slabcache can never be merged so we can use the name proper.
615362306a36Sopenharmony_ci		 * This is typically the case for debug situations. In that
615462306a36Sopenharmony_ci		 * case we can catch duplicate names easily.
615562306a36Sopenharmony_ci		 */
615662306a36Sopenharmony_ci		sysfs_remove_link(&slab_kset->kobj, s->name);
615762306a36Sopenharmony_ci		name = s->name;
615862306a36Sopenharmony_ci	} else {
615962306a36Sopenharmony_ci		/*
616062306a36Sopenharmony_ci		 * Create a unique name for the slab as a target
616162306a36Sopenharmony_ci		 * for the symlinks.
616262306a36Sopenharmony_ci		 */
616362306a36Sopenharmony_ci		name = create_unique_id(s);
616462306a36Sopenharmony_ci		if (IS_ERR(name))
616562306a36Sopenharmony_ci			return PTR_ERR(name);
616662306a36Sopenharmony_ci	}
616762306a36Sopenharmony_ci
616862306a36Sopenharmony_ci	s->kobj.kset = kset;
616962306a36Sopenharmony_ci	err = kobject_init_and_add(&s->kobj, &slab_ktype, NULL, "%s", name);
617062306a36Sopenharmony_ci	if (err)
617162306a36Sopenharmony_ci		goto out;
617262306a36Sopenharmony_ci
617362306a36Sopenharmony_ci	err = sysfs_create_group(&s->kobj, &slab_attr_group);
617462306a36Sopenharmony_ci	if (err)
617562306a36Sopenharmony_ci		goto out_del_kobj;
617662306a36Sopenharmony_ci
617762306a36Sopenharmony_ci	if (!unmergeable) {
617862306a36Sopenharmony_ci		/* Setup first alias */
617962306a36Sopenharmony_ci		sysfs_slab_alias(s, s->name);
618062306a36Sopenharmony_ci	}
618162306a36Sopenharmony_ciout:
618262306a36Sopenharmony_ci	if (!unmergeable)
618362306a36Sopenharmony_ci		kfree(name);
618462306a36Sopenharmony_ci	return err;
618562306a36Sopenharmony_ciout_del_kobj:
618662306a36Sopenharmony_ci	kobject_del(&s->kobj);
618762306a36Sopenharmony_ci	goto out;
618862306a36Sopenharmony_ci}
618962306a36Sopenharmony_ci
619062306a36Sopenharmony_civoid sysfs_slab_unlink(struct kmem_cache *s)
619162306a36Sopenharmony_ci{
619262306a36Sopenharmony_ci	if (slab_state >= FULL)
619362306a36Sopenharmony_ci		kobject_del(&s->kobj);
619462306a36Sopenharmony_ci}
619562306a36Sopenharmony_ci
619662306a36Sopenharmony_civoid sysfs_slab_release(struct kmem_cache *s)
619762306a36Sopenharmony_ci{
619862306a36Sopenharmony_ci	if (slab_state >= FULL)
619962306a36Sopenharmony_ci		kobject_put(&s->kobj);
620062306a36Sopenharmony_ci}
620162306a36Sopenharmony_ci
620262306a36Sopenharmony_ci/*
620362306a36Sopenharmony_ci * Need to buffer aliases during bootup until sysfs becomes
620462306a36Sopenharmony_ci * available lest we lose that information.
620562306a36Sopenharmony_ci */
620662306a36Sopenharmony_cistruct saved_alias {
620762306a36Sopenharmony_ci	struct kmem_cache *s;
620862306a36Sopenharmony_ci	const char *name;
620962306a36Sopenharmony_ci	struct saved_alias *next;
621062306a36Sopenharmony_ci};
621162306a36Sopenharmony_ci
621262306a36Sopenharmony_cistatic struct saved_alias *alias_list;
621362306a36Sopenharmony_ci
621462306a36Sopenharmony_cistatic int sysfs_slab_alias(struct kmem_cache *s, const char *name)
621562306a36Sopenharmony_ci{
621662306a36Sopenharmony_ci	struct saved_alias *al;
621762306a36Sopenharmony_ci
621862306a36Sopenharmony_ci	if (slab_state == FULL) {
621962306a36Sopenharmony_ci		/*
622062306a36Sopenharmony_ci		 * If we have a leftover link then remove it.
622162306a36Sopenharmony_ci		 */
622262306a36Sopenharmony_ci		sysfs_remove_link(&slab_kset->kobj, name);
622362306a36Sopenharmony_ci		return sysfs_create_link(&slab_kset->kobj, &s->kobj, name);
622462306a36Sopenharmony_ci	}
622562306a36Sopenharmony_ci
622662306a36Sopenharmony_ci	al = kmalloc(sizeof(struct saved_alias), GFP_KERNEL);
622762306a36Sopenharmony_ci	if (!al)
622862306a36Sopenharmony_ci		return -ENOMEM;
622962306a36Sopenharmony_ci
623062306a36Sopenharmony_ci	al->s = s;
623162306a36Sopenharmony_ci	al->name = name;
623262306a36Sopenharmony_ci	al->next = alias_list;
623362306a36Sopenharmony_ci	alias_list = al;
623462306a36Sopenharmony_ci	kmsan_unpoison_memory(al, sizeof(*al));
623562306a36Sopenharmony_ci	return 0;
623662306a36Sopenharmony_ci}
623762306a36Sopenharmony_ci
623862306a36Sopenharmony_cistatic int __init slab_sysfs_init(void)
623962306a36Sopenharmony_ci{
624062306a36Sopenharmony_ci	struct kmem_cache *s;
624162306a36Sopenharmony_ci	int err;
624262306a36Sopenharmony_ci
624362306a36Sopenharmony_ci	mutex_lock(&slab_mutex);
624462306a36Sopenharmony_ci
624562306a36Sopenharmony_ci	slab_kset = kset_create_and_add("slab", NULL, kernel_kobj);
624662306a36Sopenharmony_ci	if (!slab_kset) {
624762306a36Sopenharmony_ci		mutex_unlock(&slab_mutex);
624862306a36Sopenharmony_ci		pr_err("Cannot register slab subsystem.\n");
624962306a36Sopenharmony_ci		return -ENOMEM;
625062306a36Sopenharmony_ci	}
625162306a36Sopenharmony_ci
625262306a36Sopenharmony_ci	slab_state = FULL;
625362306a36Sopenharmony_ci
625462306a36Sopenharmony_ci	list_for_each_entry(s, &slab_caches, list) {
625562306a36Sopenharmony_ci		err = sysfs_slab_add(s);
625662306a36Sopenharmony_ci		if (err)
625762306a36Sopenharmony_ci			pr_err("SLUB: Unable to add boot slab %s to sysfs\n",
625862306a36Sopenharmony_ci			       s->name);
625962306a36Sopenharmony_ci	}
626062306a36Sopenharmony_ci
626162306a36Sopenharmony_ci	while (alias_list) {
626262306a36Sopenharmony_ci		struct saved_alias *al = alias_list;
626362306a36Sopenharmony_ci
626462306a36Sopenharmony_ci		alias_list = alias_list->next;
626562306a36Sopenharmony_ci		err = sysfs_slab_alias(al->s, al->name);
626662306a36Sopenharmony_ci		if (err)
626762306a36Sopenharmony_ci			pr_err("SLUB: Unable to add boot slab alias %s to sysfs\n",
626862306a36Sopenharmony_ci			       al->name);
626962306a36Sopenharmony_ci		kfree(al);
627062306a36Sopenharmony_ci	}
627162306a36Sopenharmony_ci
627262306a36Sopenharmony_ci	mutex_unlock(&slab_mutex);
627362306a36Sopenharmony_ci	return 0;
627462306a36Sopenharmony_ci}
627562306a36Sopenharmony_cilate_initcall(slab_sysfs_init);
627662306a36Sopenharmony_ci#endif /* SLAB_SUPPORTS_SYSFS */
627762306a36Sopenharmony_ci
627862306a36Sopenharmony_ci#if defined(CONFIG_SLUB_DEBUG) && defined(CONFIG_DEBUG_FS)
627962306a36Sopenharmony_cistatic int slab_debugfs_show(struct seq_file *seq, void *v)
628062306a36Sopenharmony_ci{
628162306a36Sopenharmony_ci	struct loc_track *t = seq->private;
628262306a36Sopenharmony_ci	struct location *l;
628362306a36Sopenharmony_ci	unsigned long idx;
628462306a36Sopenharmony_ci
628562306a36Sopenharmony_ci	idx = (unsigned long) t->idx;
628662306a36Sopenharmony_ci	if (idx < t->count) {
628762306a36Sopenharmony_ci		l = &t->loc[idx];
628862306a36Sopenharmony_ci
628962306a36Sopenharmony_ci		seq_printf(seq, "%7ld ", l->count);
629062306a36Sopenharmony_ci
629162306a36Sopenharmony_ci		if (l->addr)
629262306a36Sopenharmony_ci			seq_printf(seq, "%pS", (void *)l->addr);
629362306a36Sopenharmony_ci		else
629462306a36Sopenharmony_ci			seq_puts(seq, "<not-available>");
629562306a36Sopenharmony_ci
629662306a36Sopenharmony_ci		if (l->waste)
629762306a36Sopenharmony_ci			seq_printf(seq, " waste=%lu/%lu",
629862306a36Sopenharmony_ci				l->count * l->waste, l->waste);
629962306a36Sopenharmony_ci
630062306a36Sopenharmony_ci		if (l->sum_time != l->min_time) {
630162306a36Sopenharmony_ci			seq_printf(seq, " age=%ld/%llu/%ld",
630262306a36Sopenharmony_ci				l->min_time, div_u64(l->sum_time, l->count),
630362306a36Sopenharmony_ci				l->max_time);
630462306a36Sopenharmony_ci		} else
630562306a36Sopenharmony_ci			seq_printf(seq, " age=%ld", l->min_time);
630662306a36Sopenharmony_ci
630762306a36Sopenharmony_ci		if (l->min_pid != l->max_pid)
630862306a36Sopenharmony_ci			seq_printf(seq, " pid=%ld-%ld", l->min_pid, l->max_pid);
630962306a36Sopenharmony_ci		else
631062306a36Sopenharmony_ci			seq_printf(seq, " pid=%ld",
631162306a36Sopenharmony_ci				l->min_pid);
631262306a36Sopenharmony_ci
631362306a36Sopenharmony_ci		if (num_online_cpus() > 1 && !cpumask_empty(to_cpumask(l->cpus)))
631462306a36Sopenharmony_ci			seq_printf(seq, " cpus=%*pbl",
631562306a36Sopenharmony_ci				 cpumask_pr_args(to_cpumask(l->cpus)));
631662306a36Sopenharmony_ci
631762306a36Sopenharmony_ci		if (nr_online_nodes > 1 && !nodes_empty(l->nodes))
631862306a36Sopenharmony_ci			seq_printf(seq, " nodes=%*pbl",
631962306a36Sopenharmony_ci				 nodemask_pr_args(&l->nodes));
632062306a36Sopenharmony_ci
632162306a36Sopenharmony_ci#ifdef CONFIG_STACKDEPOT
632262306a36Sopenharmony_ci		{
632362306a36Sopenharmony_ci			depot_stack_handle_t handle;
632462306a36Sopenharmony_ci			unsigned long *entries;
632562306a36Sopenharmony_ci			unsigned int nr_entries, j;
632662306a36Sopenharmony_ci
632762306a36Sopenharmony_ci			handle = READ_ONCE(l->handle);
632862306a36Sopenharmony_ci			if (handle) {
632962306a36Sopenharmony_ci				nr_entries = stack_depot_fetch(handle, &entries);
633062306a36Sopenharmony_ci				seq_puts(seq, "\n");
633162306a36Sopenharmony_ci				for (j = 0; j < nr_entries; j++)
633262306a36Sopenharmony_ci					seq_printf(seq, "        %pS\n", (void *)entries[j]);
633362306a36Sopenharmony_ci			}
633462306a36Sopenharmony_ci		}
633562306a36Sopenharmony_ci#endif
633662306a36Sopenharmony_ci		seq_puts(seq, "\n");
633762306a36Sopenharmony_ci	}
633862306a36Sopenharmony_ci
633962306a36Sopenharmony_ci	if (!idx && !t->count)
634062306a36Sopenharmony_ci		seq_puts(seq, "No data\n");
634162306a36Sopenharmony_ci
634262306a36Sopenharmony_ci	return 0;
634362306a36Sopenharmony_ci}
634462306a36Sopenharmony_ci
634562306a36Sopenharmony_cistatic void slab_debugfs_stop(struct seq_file *seq, void *v)
634662306a36Sopenharmony_ci{
634762306a36Sopenharmony_ci}
634862306a36Sopenharmony_ci
634962306a36Sopenharmony_cistatic void *slab_debugfs_next(struct seq_file *seq, void *v, loff_t *ppos)
635062306a36Sopenharmony_ci{
635162306a36Sopenharmony_ci	struct loc_track *t = seq->private;
635262306a36Sopenharmony_ci
635362306a36Sopenharmony_ci	t->idx = ++(*ppos);
635462306a36Sopenharmony_ci	if (*ppos <= t->count)
635562306a36Sopenharmony_ci		return ppos;
635662306a36Sopenharmony_ci
635762306a36Sopenharmony_ci	return NULL;
635862306a36Sopenharmony_ci}
635962306a36Sopenharmony_ci
636062306a36Sopenharmony_cistatic int cmp_loc_by_count(const void *a, const void *b, const void *data)
636162306a36Sopenharmony_ci{
636262306a36Sopenharmony_ci	struct location *loc1 = (struct location *)a;
636362306a36Sopenharmony_ci	struct location *loc2 = (struct location *)b;
636462306a36Sopenharmony_ci
636562306a36Sopenharmony_ci	if (loc1->count > loc2->count)
636662306a36Sopenharmony_ci		return -1;
636762306a36Sopenharmony_ci	else
636862306a36Sopenharmony_ci		return 1;
636962306a36Sopenharmony_ci}
637062306a36Sopenharmony_ci
637162306a36Sopenharmony_cistatic void *slab_debugfs_start(struct seq_file *seq, loff_t *ppos)
637262306a36Sopenharmony_ci{
637362306a36Sopenharmony_ci	struct loc_track *t = seq->private;
637462306a36Sopenharmony_ci
637562306a36Sopenharmony_ci	t->idx = *ppos;
637662306a36Sopenharmony_ci	return ppos;
637762306a36Sopenharmony_ci}
637862306a36Sopenharmony_ci
637962306a36Sopenharmony_cistatic const struct seq_operations slab_debugfs_sops = {
638062306a36Sopenharmony_ci	.start  = slab_debugfs_start,
638162306a36Sopenharmony_ci	.next   = slab_debugfs_next,
638262306a36Sopenharmony_ci	.stop   = slab_debugfs_stop,
638362306a36Sopenharmony_ci	.show   = slab_debugfs_show,
638462306a36Sopenharmony_ci};
638562306a36Sopenharmony_ci
638662306a36Sopenharmony_cistatic int slab_debug_trace_open(struct inode *inode, struct file *filep)
638762306a36Sopenharmony_ci{
638862306a36Sopenharmony_ci
638962306a36Sopenharmony_ci	struct kmem_cache_node *n;
639062306a36Sopenharmony_ci	enum track_item alloc;
639162306a36Sopenharmony_ci	int node;
639262306a36Sopenharmony_ci	struct loc_track *t = __seq_open_private(filep, &slab_debugfs_sops,
639362306a36Sopenharmony_ci						sizeof(struct loc_track));
639462306a36Sopenharmony_ci	struct kmem_cache *s = file_inode(filep)->i_private;
639562306a36Sopenharmony_ci	unsigned long *obj_map;
639662306a36Sopenharmony_ci
639762306a36Sopenharmony_ci	if (!t)
639862306a36Sopenharmony_ci		return -ENOMEM;
639962306a36Sopenharmony_ci
640062306a36Sopenharmony_ci	obj_map = bitmap_alloc(oo_objects(s->oo), GFP_KERNEL);
640162306a36Sopenharmony_ci	if (!obj_map) {
640262306a36Sopenharmony_ci		seq_release_private(inode, filep);
640362306a36Sopenharmony_ci		return -ENOMEM;
640462306a36Sopenharmony_ci	}
640562306a36Sopenharmony_ci
640662306a36Sopenharmony_ci	if (strcmp(filep->f_path.dentry->d_name.name, "alloc_traces") == 0)
640762306a36Sopenharmony_ci		alloc = TRACK_ALLOC;
640862306a36Sopenharmony_ci	else
640962306a36Sopenharmony_ci		alloc = TRACK_FREE;
641062306a36Sopenharmony_ci
641162306a36Sopenharmony_ci	if (!alloc_loc_track(t, PAGE_SIZE / sizeof(struct location), GFP_KERNEL)) {
641262306a36Sopenharmony_ci		bitmap_free(obj_map);
641362306a36Sopenharmony_ci		seq_release_private(inode, filep);
641462306a36Sopenharmony_ci		return -ENOMEM;
641562306a36Sopenharmony_ci	}
641662306a36Sopenharmony_ci
641762306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
641862306a36Sopenharmony_ci		unsigned long flags;
641962306a36Sopenharmony_ci		struct slab *slab;
642062306a36Sopenharmony_ci
642162306a36Sopenharmony_ci		if (!node_nr_slabs(n))
642262306a36Sopenharmony_ci			continue;
642362306a36Sopenharmony_ci
642462306a36Sopenharmony_ci		spin_lock_irqsave(&n->list_lock, flags);
642562306a36Sopenharmony_ci		list_for_each_entry(slab, &n->partial, slab_list)
642662306a36Sopenharmony_ci			process_slab(t, s, slab, alloc, obj_map);
642762306a36Sopenharmony_ci		list_for_each_entry(slab, &n->full, slab_list)
642862306a36Sopenharmony_ci			process_slab(t, s, slab, alloc, obj_map);
642962306a36Sopenharmony_ci		spin_unlock_irqrestore(&n->list_lock, flags);
643062306a36Sopenharmony_ci	}
643162306a36Sopenharmony_ci
643262306a36Sopenharmony_ci	/* Sort locations by count */
643362306a36Sopenharmony_ci	sort_r(t->loc, t->count, sizeof(struct location),
643462306a36Sopenharmony_ci		cmp_loc_by_count, NULL, NULL);
643562306a36Sopenharmony_ci
643662306a36Sopenharmony_ci	bitmap_free(obj_map);
643762306a36Sopenharmony_ci	return 0;
643862306a36Sopenharmony_ci}
643962306a36Sopenharmony_ci
644062306a36Sopenharmony_cistatic int slab_debug_trace_release(struct inode *inode, struct file *file)
644162306a36Sopenharmony_ci{
644262306a36Sopenharmony_ci	struct seq_file *seq = file->private_data;
644362306a36Sopenharmony_ci	struct loc_track *t = seq->private;
644462306a36Sopenharmony_ci
644562306a36Sopenharmony_ci	free_loc_track(t);
644662306a36Sopenharmony_ci	return seq_release_private(inode, file);
644762306a36Sopenharmony_ci}
644862306a36Sopenharmony_ci
644962306a36Sopenharmony_cistatic const struct file_operations slab_debugfs_fops = {
645062306a36Sopenharmony_ci	.open    = slab_debug_trace_open,
645162306a36Sopenharmony_ci	.read    = seq_read,
645262306a36Sopenharmony_ci	.llseek  = seq_lseek,
645362306a36Sopenharmony_ci	.release = slab_debug_trace_release,
645462306a36Sopenharmony_ci};
645562306a36Sopenharmony_ci
645662306a36Sopenharmony_cistatic void debugfs_slab_add(struct kmem_cache *s)
645762306a36Sopenharmony_ci{
645862306a36Sopenharmony_ci	struct dentry *slab_cache_dir;
645962306a36Sopenharmony_ci
646062306a36Sopenharmony_ci	if (unlikely(!slab_debugfs_root))
646162306a36Sopenharmony_ci		return;
646262306a36Sopenharmony_ci
646362306a36Sopenharmony_ci	slab_cache_dir = debugfs_create_dir(s->name, slab_debugfs_root);
646462306a36Sopenharmony_ci
646562306a36Sopenharmony_ci	debugfs_create_file("alloc_traces", 0400,
646662306a36Sopenharmony_ci		slab_cache_dir, s, &slab_debugfs_fops);
646762306a36Sopenharmony_ci
646862306a36Sopenharmony_ci	debugfs_create_file("free_traces", 0400,
646962306a36Sopenharmony_ci		slab_cache_dir, s, &slab_debugfs_fops);
647062306a36Sopenharmony_ci}
647162306a36Sopenharmony_ci
647262306a36Sopenharmony_civoid debugfs_slab_release(struct kmem_cache *s)
647362306a36Sopenharmony_ci{
647462306a36Sopenharmony_ci	debugfs_lookup_and_remove(s->name, slab_debugfs_root);
647562306a36Sopenharmony_ci}
647662306a36Sopenharmony_ci
647762306a36Sopenharmony_cistatic int __init slab_debugfs_init(void)
647862306a36Sopenharmony_ci{
647962306a36Sopenharmony_ci	struct kmem_cache *s;
648062306a36Sopenharmony_ci
648162306a36Sopenharmony_ci	slab_debugfs_root = debugfs_create_dir("slab", NULL);
648262306a36Sopenharmony_ci
648362306a36Sopenharmony_ci	list_for_each_entry(s, &slab_caches, list)
648462306a36Sopenharmony_ci		if (s->flags & SLAB_STORE_USER)
648562306a36Sopenharmony_ci			debugfs_slab_add(s);
648662306a36Sopenharmony_ci
648762306a36Sopenharmony_ci	return 0;
648862306a36Sopenharmony_ci
648962306a36Sopenharmony_ci}
649062306a36Sopenharmony_ci__initcall(slab_debugfs_init);
649162306a36Sopenharmony_ci#endif
649262306a36Sopenharmony_ci/*
649362306a36Sopenharmony_ci * The /proc/slabinfo ABI
649462306a36Sopenharmony_ci */
649562306a36Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
649662306a36Sopenharmony_civoid get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo)
649762306a36Sopenharmony_ci{
649862306a36Sopenharmony_ci	unsigned long nr_slabs = 0;
649962306a36Sopenharmony_ci	unsigned long nr_objs = 0;
650062306a36Sopenharmony_ci	unsigned long nr_free = 0;
650162306a36Sopenharmony_ci	int node;
650262306a36Sopenharmony_ci	struct kmem_cache_node *n;
650362306a36Sopenharmony_ci
650462306a36Sopenharmony_ci	for_each_kmem_cache_node(s, node, n) {
650562306a36Sopenharmony_ci		nr_slabs += node_nr_slabs(n);
650662306a36Sopenharmony_ci		nr_objs += node_nr_objs(n);
650762306a36Sopenharmony_ci		nr_free += count_partial(n, count_free);
650862306a36Sopenharmony_ci	}
650962306a36Sopenharmony_ci
651062306a36Sopenharmony_ci	sinfo->active_objs = nr_objs - nr_free;
651162306a36Sopenharmony_ci	sinfo->num_objs = nr_objs;
651262306a36Sopenharmony_ci	sinfo->active_slabs = nr_slabs;
651362306a36Sopenharmony_ci	sinfo->num_slabs = nr_slabs;
651462306a36Sopenharmony_ci	sinfo->objects_per_slab = oo_objects(s->oo);
651562306a36Sopenharmony_ci	sinfo->cache_order = oo_order(s->oo);
651662306a36Sopenharmony_ci}
651762306a36Sopenharmony_ci
651862306a36Sopenharmony_civoid slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s)
651962306a36Sopenharmony_ci{
652062306a36Sopenharmony_ci}
652162306a36Sopenharmony_ci
652262306a36Sopenharmony_cissize_t slabinfo_write(struct file *file, const char __user *buffer,
652362306a36Sopenharmony_ci		       size_t count, loff_t *ppos)
652462306a36Sopenharmony_ci{
652562306a36Sopenharmony_ci	return -EIO;
652662306a36Sopenharmony_ci}
652762306a36Sopenharmony_ci#endif /* CONFIG_SLUB_DEBUG */
6528