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