18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef MM_SLAB_H
38c2ecf20Sopenharmony_ci#define MM_SLAB_H
48c2ecf20Sopenharmony_ci/*
58c2ecf20Sopenharmony_ci * Internal slab definitions
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifdef CONFIG_SLOB
98c2ecf20Sopenharmony_ci/*
108c2ecf20Sopenharmony_ci * Common fields provided in kmem_cache by all slab allocators
118c2ecf20Sopenharmony_ci * This struct is either used directly by the allocator (SLOB)
128c2ecf20Sopenharmony_ci * or the allocator must include definitions for all fields
138c2ecf20Sopenharmony_ci * provided in kmem_cache_common in their definition of kmem_cache.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * Once we can do anonymous structs (C11 standard) we could put a
168c2ecf20Sopenharmony_ci * anonymous struct definition in these allocators so that the
178c2ecf20Sopenharmony_ci * separate allocations in the kmem_cache structure of SLAB and
188c2ecf20Sopenharmony_ci * SLUB is no longer needed.
198c2ecf20Sopenharmony_ci */
208c2ecf20Sopenharmony_cistruct kmem_cache {
218c2ecf20Sopenharmony_ci	unsigned int object_size;/* The original size of the object */
228c2ecf20Sopenharmony_ci	unsigned int size;	/* The aligned/padded/added on size  */
238c2ecf20Sopenharmony_ci	unsigned int align;	/* Alignment as calculated */
248c2ecf20Sopenharmony_ci	slab_flags_t flags;	/* Active flags on the slab */
258c2ecf20Sopenharmony_ci	unsigned int useroffset;/* Usercopy region offset */
268c2ecf20Sopenharmony_ci	unsigned int usersize;	/* Usercopy region size */
278c2ecf20Sopenharmony_ci	const char *name;	/* Slab name for sysfs */
288c2ecf20Sopenharmony_ci	int refcount;		/* Use counter */
298c2ecf20Sopenharmony_ci	void (*ctor)(void *);	/* Called on object slot creation */
308c2ecf20Sopenharmony_ci	struct list_head list;	/* List of all slab caches on the system */
318c2ecf20Sopenharmony_ci};
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#endif /* CONFIG_SLOB */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#ifdef CONFIG_SLAB
368c2ecf20Sopenharmony_ci#include <linux/slab_def.h>
378c2ecf20Sopenharmony_ci#endif
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB
408c2ecf20Sopenharmony_ci#include <linux/slub_def.h>
418c2ecf20Sopenharmony_ci#endif
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#include <linux/memcontrol.h>
448c2ecf20Sopenharmony_ci#include <linux/fault-inject.h>
458c2ecf20Sopenharmony_ci#include <linux/kasan.h>
468c2ecf20Sopenharmony_ci#include <linux/kmemleak.h>
478c2ecf20Sopenharmony_ci#include <linux/random.h>
488c2ecf20Sopenharmony_ci#include <linux/sched/mm.h>
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/*
518c2ecf20Sopenharmony_ci * State of the slab allocator.
528c2ecf20Sopenharmony_ci *
538c2ecf20Sopenharmony_ci * This is used to describe the states of the allocator during bootup.
548c2ecf20Sopenharmony_ci * Allocators use this to gradually bootstrap themselves. Most allocators
558c2ecf20Sopenharmony_ci * have the problem that the structures used for managing slab caches are
568c2ecf20Sopenharmony_ci * allocated from slab caches themselves.
578c2ecf20Sopenharmony_ci */
588c2ecf20Sopenharmony_cienum slab_state {
598c2ecf20Sopenharmony_ci	DOWN,			/* No slab functionality yet */
608c2ecf20Sopenharmony_ci	PARTIAL,		/* SLUB: kmem_cache_node available */
618c2ecf20Sopenharmony_ci	PARTIAL_NODE,		/* SLAB: kmalloc size for node struct available */
628c2ecf20Sopenharmony_ci	UP,			/* Slab caches usable but not all extras yet */
638c2ecf20Sopenharmony_ci	FULL			/* Everything is working */
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciextern enum slab_state slab_state;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci/* The slab cache mutex protects the management structures during changes */
698c2ecf20Sopenharmony_ciextern struct mutex slab_mutex;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci/* The list of all slab caches on the system */
728c2ecf20Sopenharmony_ciextern struct list_head slab_caches;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/* The slab cache that manages slab cache information */
758c2ecf20Sopenharmony_ciextern struct kmem_cache *kmem_cache;
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci/* A table of kmalloc cache names and sizes */
788c2ecf20Sopenharmony_ciextern const struct kmalloc_info_struct {
798c2ecf20Sopenharmony_ci	const char *name[NR_KMALLOC_TYPES];
808c2ecf20Sopenharmony_ci	unsigned int size;
818c2ecf20Sopenharmony_ci} kmalloc_info[];
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#ifndef CONFIG_SLOB
848c2ecf20Sopenharmony_ci/* Kmalloc array related functions */
858c2ecf20Sopenharmony_civoid setup_kmalloc_cache_index_table(void);
868c2ecf20Sopenharmony_civoid create_kmalloc_caches(slab_flags_t);
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/* Find the kmalloc slab corresponding for a certain size */
898c2ecf20Sopenharmony_cistruct kmem_cache *kmalloc_slab(size_t, gfp_t);
908c2ecf20Sopenharmony_ci#endif
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cigfp_t kmalloc_fix_flags(gfp_t flags);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci/* Functions provided by the slab allocators */
958c2ecf20Sopenharmony_ciint __kmem_cache_create(struct kmem_cache *, slab_flags_t flags);
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistruct kmem_cache *create_kmalloc_cache(const char *name, unsigned int size,
988c2ecf20Sopenharmony_ci			slab_flags_t flags, unsigned int useroffset,
998c2ecf20Sopenharmony_ci			unsigned int usersize);
1008c2ecf20Sopenharmony_ciextern void create_boot_cache(struct kmem_cache *, const char *name,
1018c2ecf20Sopenharmony_ci			unsigned int size, slab_flags_t flags,
1028c2ecf20Sopenharmony_ci			unsigned int useroffset, unsigned int usersize);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ciint slab_unmergeable(struct kmem_cache *s);
1058c2ecf20Sopenharmony_cistruct kmem_cache *find_mergeable(unsigned size, unsigned align,
1068c2ecf20Sopenharmony_ci		slab_flags_t flags, const char *name, void (*ctor)(void *));
1078c2ecf20Sopenharmony_ci#ifndef CONFIG_SLOB
1088c2ecf20Sopenharmony_cistruct kmem_cache *
1098c2ecf20Sopenharmony_ci__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
1108c2ecf20Sopenharmony_ci		   slab_flags_t flags, void (*ctor)(void *));
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_cislab_flags_t kmem_cache_flags(unsigned int object_size,
1138c2ecf20Sopenharmony_ci	slab_flags_t flags, const char *name);
1148c2ecf20Sopenharmony_ci#else
1158c2ecf20Sopenharmony_cistatic inline struct kmem_cache *
1168c2ecf20Sopenharmony_ci__kmem_cache_alias(const char *name, unsigned int size, unsigned int align,
1178c2ecf20Sopenharmony_ci		   slab_flags_t flags, void (*ctor)(void *))
1188c2ecf20Sopenharmony_ci{ return NULL; }
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistatic inline slab_flags_t kmem_cache_flags(unsigned int object_size,
1218c2ecf20Sopenharmony_ci	slab_flags_t flags, const char *name)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci	return flags;
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci#endif
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci/* Legal flag mask for kmem_cache_create(), for various configurations */
1298c2ecf20Sopenharmony_ci#define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | \
1308c2ecf20Sopenharmony_ci			 SLAB_CACHE_DMA32 | SLAB_PANIC | \
1318c2ecf20Sopenharmony_ci			 SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS )
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#if defined(CONFIG_DEBUG_SLAB)
1348c2ecf20Sopenharmony_ci#define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
1358c2ecf20Sopenharmony_ci#elif defined(CONFIG_SLUB_DEBUG)
1368c2ecf20Sopenharmony_ci#define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
1378c2ecf20Sopenharmony_ci			  SLAB_TRACE | SLAB_CONSISTENCY_CHECKS)
1388c2ecf20Sopenharmony_ci#else
1398c2ecf20Sopenharmony_ci#define SLAB_DEBUG_FLAGS (0)
1408c2ecf20Sopenharmony_ci#endif
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci#if defined(CONFIG_SLAB)
1438c2ecf20Sopenharmony_ci#define SLAB_CACHE_FLAGS (SLAB_MEM_SPREAD | SLAB_NOLEAKTRACE | \
1448c2ecf20Sopenharmony_ci			  SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | \
1458c2ecf20Sopenharmony_ci			  SLAB_ACCOUNT)
1468c2ecf20Sopenharmony_ci#elif defined(CONFIG_SLUB)
1478c2ecf20Sopenharmony_ci#define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE | SLAB_RECLAIM_ACCOUNT | \
1488c2ecf20Sopenharmony_ci			  SLAB_TEMPORARY | SLAB_ACCOUNT)
1498c2ecf20Sopenharmony_ci#else
1508c2ecf20Sopenharmony_ci#define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE)
1518c2ecf20Sopenharmony_ci#endif
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci/* Common flags available with current configuration */
1548c2ecf20Sopenharmony_ci#define CACHE_CREATE_MASK (SLAB_CORE_FLAGS | SLAB_DEBUG_FLAGS | SLAB_CACHE_FLAGS)
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/* Common flags permitted for kmem_cache_create */
1578c2ecf20Sopenharmony_ci#define SLAB_FLAGS_PERMITTED (SLAB_CORE_FLAGS | \
1588c2ecf20Sopenharmony_ci			      SLAB_RED_ZONE | \
1598c2ecf20Sopenharmony_ci			      SLAB_POISON | \
1608c2ecf20Sopenharmony_ci			      SLAB_STORE_USER | \
1618c2ecf20Sopenharmony_ci			      SLAB_TRACE | \
1628c2ecf20Sopenharmony_ci			      SLAB_CONSISTENCY_CHECKS | \
1638c2ecf20Sopenharmony_ci			      SLAB_MEM_SPREAD | \
1648c2ecf20Sopenharmony_ci			      SLAB_NOLEAKTRACE | \
1658c2ecf20Sopenharmony_ci			      SLAB_RECLAIM_ACCOUNT | \
1668c2ecf20Sopenharmony_ci			      SLAB_TEMPORARY | \
1678c2ecf20Sopenharmony_ci			      SLAB_ACCOUNT)
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_cibool __kmem_cache_empty(struct kmem_cache *);
1708c2ecf20Sopenharmony_ciint __kmem_cache_shutdown(struct kmem_cache *);
1718c2ecf20Sopenharmony_civoid __kmem_cache_release(struct kmem_cache *);
1728c2ecf20Sopenharmony_ciint __kmem_cache_shrink(struct kmem_cache *);
1738c2ecf20Sopenharmony_civoid slab_kmem_cache_release(struct kmem_cache *);
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cistruct seq_file;
1768c2ecf20Sopenharmony_cistruct file;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_cistruct slabinfo {
1798c2ecf20Sopenharmony_ci	unsigned long active_objs;
1808c2ecf20Sopenharmony_ci	unsigned long num_objs;
1818c2ecf20Sopenharmony_ci	unsigned long active_slabs;
1828c2ecf20Sopenharmony_ci	unsigned long num_slabs;
1838c2ecf20Sopenharmony_ci	unsigned long shared_avail;
1848c2ecf20Sopenharmony_ci	unsigned int limit;
1858c2ecf20Sopenharmony_ci	unsigned int batchcount;
1868c2ecf20Sopenharmony_ci	unsigned int shared;
1878c2ecf20Sopenharmony_ci	unsigned int objects_per_slab;
1888c2ecf20Sopenharmony_ci	unsigned int cache_order;
1898c2ecf20Sopenharmony_ci};
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_civoid get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo);
1928c2ecf20Sopenharmony_civoid slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s);
1938c2ecf20Sopenharmony_cissize_t slabinfo_write(struct file *file, const char __user *buffer,
1948c2ecf20Sopenharmony_ci		       size_t count, loff_t *ppos);
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci/*
1978c2ecf20Sopenharmony_ci * Generic implementation of bulk operations
1988c2ecf20Sopenharmony_ci * These are useful for situations in which the allocator cannot
1998c2ecf20Sopenharmony_ci * perform optimizations. In that case segments of the object listed
2008c2ecf20Sopenharmony_ci * may be allocated or freed using these operations.
2018c2ecf20Sopenharmony_ci */
2028c2ecf20Sopenharmony_civoid __kmem_cache_free_bulk(struct kmem_cache *, size_t, void **);
2038c2ecf20Sopenharmony_ciint __kmem_cache_alloc_bulk(struct kmem_cache *, gfp_t, size_t, void **);
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_cistatic inline int cache_vmstat_idx(struct kmem_cache *s)
2068c2ecf20Sopenharmony_ci{
2078c2ecf20Sopenharmony_ci	return (s->flags & SLAB_RECLAIM_ACCOUNT) ?
2088c2ecf20Sopenharmony_ci		NR_SLAB_RECLAIMABLE_B : NR_SLAB_UNRECLAIMABLE_B;
2098c2ecf20Sopenharmony_ci}
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
2128c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG_ON
2138c2ecf20Sopenharmony_ciDECLARE_STATIC_KEY_TRUE(slub_debug_enabled);
2148c2ecf20Sopenharmony_ci#else
2158c2ecf20Sopenharmony_ciDECLARE_STATIC_KEY_FALSE(slub_debug_enabled);
2168c2ecf20Sopenharmony_ci#endif
2178c2ecf20Sopenharmony_ciextern void print_tracking(struct kmem_cache *s, void *object);
2188c2ecf20Sopenharmony_ci#else
2198c2ecf20Sopenharmony_cistatic inline void print_tracking(struct kmem_cache *s, void *object)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci}
2228c2ecf20Sopenharmony_ci#endif
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci/*
2258c2ecf20Sopenharmony_ci * Returns true if any of the specified slub_debug flags is enabled for the
2268c2ecf20Sopenharmony_ci * cache. Use only for flags parsed by setup_slub_debug() as it also enables
2278c2ecf20Sopenharmony_ci * the static key.
2288c2ecf20Sopenharmony_ci */
2298c2ecf20Sopenharmony_cistatic inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t flags)
2308c2ecf20Sopenharmony_ci{
2318c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
2328c2ecf20Sopenharmony_ci	VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS));
2338c2ecf20Sopenharmony_ci	if (static_branch_unlikely(&slub_debug_enabled))
2348c2ecf20Sopenharmony_ci		return s->flags & flags;
2358c2ecf20Sopenharmony_ci#endif
2368c2ecf20Sopenharmony_ci	return false;
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci#ifdef CONFIG_MEMCG_KMEM
2408c2ecf20Sopenharmony_cistatic inline struct obj_cgroup **page_obj_cgroups(struct page *page)
2418c2ecf20Sopenharmony_ci{
2428c2ecf20Sopenharmony_ci	/*
2438c2ecf20Sopenharmony_ci	 * page->mem_cgroup and page->obj_cgroups are sharing the same
2448c2ecf20Sopenharmony_ci	 * space. To distinguish between them in case we don't know for sure
2458c2ecf20Sopenharmony_ci	 * that the page is a slab page (e.g. page_cgroup_ino()), let's
2468c2ecf20Sopenharmony_ci	 * always set the lowest bit of obj_cgroups.
2478c2ecf20Sopenharmony_ci	 */
2488c2ecf20Sopenharmony_ci	return (struct obj_cgroup **)
2498c2ecf20Sopenharmony_ci		((unsigned long)page->obj_cgroups & ~0x1UL);
2508c2ecf20Sopenharmony_ci}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_cistatic inline bool page_has_obj_cgroups(struct page *page)
2538c2ecf20Sopenharmony_ci{
2548c2ecf20Sopenharmony_ci	return ((unsigned long)page->obj_cgroups & 0x1UL);
2558c2ecf20Sopenharmony_ci}
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ciint memcg_alloc_page_obj_cgroups(struct page *page, struct kmem_cache *s,
2588c2ecf20Sopenharmony_ci				 gfp_t gfp);
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_cistatic inline void memcg_free_page_obj_cgroups(struct page *page)
2618c2ecf20Sopenharmony_ci{
2628c2ecf20Sopenharmony_ci	kfree(page_obj_cgroups(page));
2638c2ecf20Sopenharmony_ci	page->obj_cgroups = NULL;
2648c2ecf20Sopenharmony_ci}
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_cistatic inline size_t obj_full_size(struct kmem_cache *s)
2678c2ecf20Sopenharmony_ci{
2688c2ecf20Sopenharmony_ci	/*
2698c2ecf20Sopenharmony_ci	 * For each accounted object there is an extra space which is used
2708c2ecf20Sopenharmony_ci	 * to store obj_cgroup membership. Charge it too.
2718c2ecf20Sopenharmony_ci	 */
2728c2ecf20Sopenharmony_ci	return s->size + sizeof(struct obj_cgroup *);
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci/*
2768c2ecf20Sopenharmony_ci * Returns false if the allocation should fail.
2778c2ecf20Sopenharmony_ci */
2788c2ecf20Sopenharmony_cistatic inline bool memcg_slab_pre_alloc_hook(struct kmem_cache *s,
2798c2ecf20Sopenharmony_ci					     struct obj_cgroup **objcgp,
2808c2ecf20Sopenharmony_ci					     size_t objects, gfp_t flags)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	struct obj_cgroup *objcg;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	if (!memcg_kmem_enabled())
2858c2ecf20Sopenharmony_ci		return true;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	if (!(flags & __GFP_ACCOUNT) && !(s->flags & SLAB_ACCOUNT))
2888c2ecf20Sopenharmony_ci		return true;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	objcg = get_obj_cgroup_from_current();
2918c2ecf20Sopenharmony_ci	if (!objcg)
2928c2ecf20Sopenharmony_ci		return true;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci	if (obj_cgroup_charge(objcg, flags, objects * obj_full_size(s))) {
2958c2ecf20Sopenharmony_ci		obj_cgroup_put(objcg);
2968c2ecf20Sopenharmony_ci		return false;
2978c2ecf20Sopenharmony_ci	}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ci	*objcgp = objcg;
3008c2ecf20Sopenharmony_ci	return true;
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_cistatic inline void mod_objcg_state(struct obj_cgroup *objcg,
3048c2ecf20Sopenharmony_ci				   struct pglist_data *pgdat,
3058c2ecf20Sopenharmony_ci				   int idx, int nr)
3068c2ecf20Sopenharmony_ci{
3078c2ecf20Sopenharmony_ci	struct mem_cgroup *memcg;
3088c2ecf20Sopenharmony_ci	struct lruvec *lruvec;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	rcu_read_lock();
3118c2ecf20Sopenharmony_ci	memcg = obj_cgroup_memcg(objcg);
3128c2ecf20Sopenharmony_ci	lruvec = mem_cgroup_lruvec(memcg, pgdat);
3138c2ecf20Sopenharmony_ci	mod_memcg_lruvec_state(lruvec, idx, nr);
3148c2ecf20Sopenharmony_ci	rcu_read_unlock();
3158c2ecf20Sopenharmony_ci}
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_cistatic inline void memcg_slab_post_alloc_hook(struct kmem_cache *s,
3188c2ecf20Sopenharmony_ci					      struct obj_cgroup *objcg,
3198c2ecf20Sopenharmony_ci					      gfp_t flags, size_t size,
3208c2ecf20Sopenharmony_ci					      void **p)
3218c2ecf20Sopenharmony_ci{
3228c2ecf20Sopenharmony_ci	struct page *page;
3238c2ecf20Sopenharmony_ci	unsigned long off;
3248c2ecf20Sopenharmony_ci	size_t i;
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	if (!memcg_kmem_enabled() || !objcg)
3278c2ecf20Sopenharmony_ci		return;
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	for (i = 0; i < size; i++) {
3308c2ecf20Sopenharmony_ci		if (likely(p[i])) {
3318c2ecf20Sopenharmony_ci			page = virt_to_head_page(p[i]);
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci			if (!page_has_obj_cgroups(page) &&
3348c2ecf20Sopenharmony_ci			    memcg_alloc_page_obj_cgroups(page, s, flags)) {
3358c2ecf20Sopenharmony_ci				obj_cgroup_uncharge(objcg, obj_full_size(s));
3368c2ecf20Sopenharmony_ci				continue;
3378c2ecf20Sopenharmony_ci			}
3388c2ecf20Sopenharmony_ci
3398c2ecf20Sopenharmony_ci			off = obj_to_index(s, page, p[i]);
3408c2ecf20Sopenharmony_ci			obj_cgroup_get(objcg);
3418c2ecf20Sopenharmony_ci			page_obj_cgroups(page)[off] = objcg;
3428c2ecf20Sopenharmony_ci			mod_objcg_state(objcg, page_pgdat(page),
3438c2ecf20Sopenharmony_ci					cache_vmstat_idx(s), obj_full_size(s));
3448c2ecf20Sopenharmony_ci		} else {
3458c2ecf20Sopenharmony_ci			obj_cgroup_uncharge(objcg, obj_full_size(s));
3468c2ecf20Sopenharmony_ci		}
3478c2ecf20Sopenharmony_ci	}
3488c2ecf20Sopenharmony_ci	obj_cgroup_put(objcg);
3498c2ecf20Sopenharmony_ci}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_cistatic inline void memcg_slab_free_hook(struct kmem_cache *s_orig,
3528c2ecf20Sopenharmony_ci					void **p, int objects)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	struct kmem_cache *s;
3558c2ecf20Sopenharmony_ci	struct obj_cgroup *objcg;
3568c2ecf20Sopenharmony_ci	struct page *page;
3578c2ecf20Sopenharmony_ci	unsigned int off;
3588c2ecf20Sopenharmony_ci	int i;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	if (!memcg_kmem_enabled())
3618c2ecf20Sopenharmony_ci		return;
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci	for (i = 0; i < objects; i++) {
3648c2ecf20Sopenharmony_ci		if (unlikely(!p[i]))
3658c2ecf20Sopenharmony_ci			continue;
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci		page = virt_to_head_page(p[i]);
3688c2ecf20Sopenharmony_ci		if (!page_has_obj_cgroups(page))
3698c2ecf20Sopenharmony_ci			continue;
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci		if (!s_orig)
3728c2ecf20Sopenharmony_ci			s = page->slab_cache;
3738c2ecf20Sopenharmony_ci		else
3748c2ecf20Sopenharmony_ci			s = s_orig;
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci		off = obj_to_index(s, page, p[i]);
3778c2ecf20Sopenharmony_ci		objcg = page_obj_cgroups(page)[off];
3788c2ecf20Sopenharmony_ci		if (!objcg)
3798c2ecf20Sopenharmony_ci			continue;
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci		page_obj_cgroups(page)[off] = NULL;
3828c2ecf20Sopenharmony_ci		obj_cgroup_uncharge(objcg, obj_full_size(s));
3838c2ecf20Sopenharmony_ci		mod_objcg_state(objcg, page_pgdat(page), cache_vmstat_idx(s),
3848c2ecf20Sopenharmony_ci				-obj_full_size(s));
3858c2ecf20Sopenharmony_ci		obj_cgroup_put(objcg);
3868c2ecf20Sopenharmony_ci	}
3878c2ecf20Sopenharmony_ci}
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci#else /* CONFIG_MEMCG_KMEM */
3908c2ecf20Sopenharmony_cistatic inline bool page_has_obj_cgroups(struct page *page)
3918c2ecf20Sopenharmony_ci{
3928c2ecf20Sopenharmony_ci	return false;
3938c2ecf20Sopenharmony_ci}
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_cistatic inline struct mem_cgroup *memcg_from_slab_obj(void *ptr)
3968c2ecf20Sopenharmony_ci{
3978c2ecf20Sopenharmony_ci	return NULL;
3988c2ecf20Sopenharmony_ci}
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_cistatic inline int memcg_alloc_page_obj_cgroups(struct page *page,
4018c2ecf20Sopenharmony_ci					       struct kmem_cache *s, gfp_t gfp)
4028c2ecf20Sopenharmony_ci{
4038c2ecf20Sopenharmony_ci	return 0;
4048c2ecf20Sopenharmony_ci}
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_cistatic inline void memcg_free_page_obj_cgroups(struct page *page)
4078c2ecf20Sopenharmony_ci{
4088c2ecf20Sopenharmony_ci}
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_cistatic inline bool memcg_slab_pre_alloc_hook(struct kmem_cache *s,
4118c2ecf20Sopenharmony_ci					     struct obj_cgroup **objcgp,
4128c2ecf20Sopenharmony_ci					     size_t objects, gfp_t flags)
4138c2ecf20Sopenharmony_ci{
4148c2ecf20Sopenharmony_ci	return true;
4158c2ecf20Sopenharmony_ci}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_cistatic inline void memcg_slab_post_alloc_hook(struct kmem_cache *s,
4188c2ecf20Sopenharmony_ci					      struct obj_cgroup *objcg,
4198c2ecf20Sopenharmony_ci					      gfp_t flags, size_t size,
4208c2ecf20Sopenharmony_ci					      void **p)
4218c2ecf20Sopenharmony_ci{
4228c2ecf20Sopenharmony_ci}
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_cistatic inline void memcg_slab_free_hook(struct kmem_cache *s,
4258c2ecf20Sopenharmony_ci					void **p, int objects)
4268c2ecf20Sopenharmony_ci{
4278c2ecf20Sopenharmony_ci}
4288c2ecf20Sopenharmony_ci#endif /* CONFIG_MEMCG_KMEM */
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_cistatic inline struct kmem_cache *virt_to_cache(const void *obj)
4318c2ecf20Sopenharmony_ci{
4328c2ecf20Sopenharmony_ci	struct page *page;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	page = virt_to_head_page(obj);
4358c2ecf20Sopenharmony_ci	if (WARN_ONCE(!PageSlab(page), "%s: Object is not a Slab page!\n",
4368c2ecf20Sopenharmony_ci					__func__))
4378c2ecf20Sopenharmony_ci		return NULL;
4388c2ecf20Sopenharmony_ci	return page->slab_cache;
4398c2ecf20Sopenharmony_ci}
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_cistatic __always_inline void account_slab_page(struct page *page, int order,
4428c2ecf20Sopenharmony_ci					      struct kmem_cache *s)
4438c2ecf20Sopenharmony_ci{
4448c2ecf20Sopenharmony_ci	mod_node_page_state(page_pgdat(page), cache_vmstat_idx(s),
4458c2ecf20Sopenharmony_ci			    PAGE_SIZE << order);
4468c2ecf20Sopenharmony_ci}
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_cistatic __always_inline void unaccount_slab_page(struct page *page, int order,
4498c2ecf20Sopenharmony_ci						struct kmem_cache *s)
4508c2ecf20Sopenharmony_ci{
4518c2ecf20Sopenharmony_ci	if (memcg_kmem_enabled())
4528c2ecf20Sopenharmony_ci		memcg_free_page_obj_cgroups(page);
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	mod_node_page_state(page_pgdat(page), cache_vmstat_idx(s),
4558c2ecf20Sopenharmony_ci			    -(PAGE_SIZE << order));
4568c2ecf20Sopenharmony_ci}
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_cistatic inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
4598c2ecf20Sopenharmony_ci{
4608c2ecf20Sopenharmony_ci	struct kmem_cache *cachep;
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	if (!IS_ENABLED(CONFIG_SLAB_FREELIST_HARDENED) &&
4638c2ecf20Sopenharmony_ci	    !kmem_cache_debug_flags(s, SLAB_CONSISTENCY_CHECKS))
4648c2ecf20Sopenharmony_ci		return s;
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	cachep = virt_to_cache(x);
4678c2ecf20Sopenharmony_ci	if (WARN(cachep && cachep != s,
4688c2ecf20Sopenharmony_ci		  "%s: Wrong slab cache. %s but object is from %s\n",
4698c2ecf20Sopenharmony_ci		  __func__, s->name, cachep->name))
4708c2ecf20Sopenharmony_ci		print_tracking(cachep, x);
4718c2ecf20Sopenharmony_ci	return cachep;
4728c2ecf20Sopenharmony_ci}
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_cistatic inline size_t slab_ksize(const struct kmem_cache *s)
4758c2ecf20Sopenharmony_ci{
4768c2ecf20Sopenharmony_ci#ifndef CONFIG_SLUB
4778c2ecf20Sopenharmony_ci	return s->object_size;
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci#else /* CONFIG_SLUB */
4808c2ecf20Sopenharmony_ci# ifdef CONFIG_SLUB_DEBUG
4818c2ecf20Sopenharmony_ci	/*
4828c2ecf20Sopenharmony_ci	 * Debugging requires use of the padding between object
4838c2ecf20Sopenharmony_ci	 * and whatever may come after it.
4848c2ecf20Sopenharmony_ci	 */
4858c2ecf20Sopenharmony_ci	if (s->flags & (SLAB_RED_ZONE | SLAB_POISON))
4868c2ecf20Sopenharmony_ci		return s->object_size;
4878c2ecf20Sopenharmony_ci# endif
4888c2ecf20Sopenharmony_ci	if (s->flags & SLAB_KASAN)
4898c2ecf20Sopenharmony_ci		return s->object_size;
4908c2ecf20Sopenharmony_ci	/*
4918c2ecf20Sopenharmony_ci	 * If we have the need to store the freelist pointer
4928c2ecf20Sopenharmony_ci	 * back there or track user information then we can
4938c2ecf20Sopenharmony_ci	 * only use the space before that information.
4948c2ecf20Sopenharmony_ci	 */
4958c2ecf20Sopenharmony_ci	if (s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_STORE_USER))
4968c2ecf20Sopenharmony_ci		return s->inuse;
4978c2ecf20Sopenharmony_ci	/*
4988c2ecf20Sopenharmony_ci	 * Else we can use all the padding etc for the allocation
4998c2ecf20Sopenharmony_ci	 */
5008c2ecf20Sopenharmony_ci	return s->size;
5018c2ecf20Sopenharmony_ci#endif
5028c2ecf20Sopenharmony_ci}
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_cistatic inline struct kmem_cache *slab_pre_alloc_hook(struct kmem_cache *s,
5058c2ecf20Sopenharmony_ci						     struct obj_cgroup **objcgp,
5068c2ecf20Sopenharmony_ci						     size_t size, gfp_t flags)
5078c2ecf20Sopenharmony_ci{
5088c2ecf20Sopenharmony_ci	flags &= gfp_allowed_mask;
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci	fs_reclaim_acquire(flags);
5118c2ecf20Sopenharmony_ci	fs_reclaim_release(flags);
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	might_sleep_if(gfpflags_allow_blocking(flags));
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ci	if (should_failslab(s, flags))
5168c2ecf20Sopenharmony_ci		return NULL;
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci	if (!memcg_slab_pre_alloc_hook(s, objcgp, size, flags))
5198c2ecf20Sopenharmony_ci		return NULL;
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci	return s;
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_cistatic inline void slab_post_alloc_hook(struct kmem_cache *s,
5258c2ecf20Sopenharmony_ci					struct obj_cgroup *objcg,
5268c2ecf20Sopenharmony_ci					gfp_t flags, size_t size, void **p)
5278c2ecf20Sopenharmony_ci{
5288c2ecf20Sopenharmony_ci	size_t i;
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	flags &= gfp_allowed_mask;
5318c2ecf20Sopenharmony_ci	for (i = 0; i < size; i++) {
5328c2ecf20Sopenharmony_ci		p[i] = kasan_slab_alloc(s, p[i], flags);
5338c2ecf20Sopenharmony_ci		/* As p[i] might get tagged, call kmemleak hook after KASAN. */
5348c2ecf20Sopenharmony_ci		kmemleak_alloc_recursive(p[i], s->object_size, 1,
5358c2ecf20Sopenharmony_ci					 s->flags, flags);
5368c2ecf20Sopenharmony_ci	}
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	memcg_slab_post_alloc_hook(s, objcg, flags, size, p);
5398c2ecf20Sopenharmony_ci}
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci#ifndef CONFIG_SLOB
5428c2ecf20Sopenharmony_ci/*
5438c2ecf20Sopenharmony_ci * The slab lists for all objects.
5448c2ecf20Sopenharmony_ci */
5458c2ecf20Sopenharmony_cistruct kmem_cache_node {
5468c2ecf20Sopenharmony_ci	spinlock_t list_lock;
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci#ifdef CONFIG_SLAB
5498c2ecf20Sopenharmony_ci	struct list_head slabs_partial;	/* partial list first, better asm code */
5508c2ecf20Sopenharmony_ci	struct list_head slabs_full;
5518c2ecf20Sopenharmony_ci	struct list_head slabs_free;
5528c2ecf20Sopenharmony_ci	unsigned long total_slabs;	/* length of all slab lists */
5538c2ecf20Sopenharmony_ci	unsigned long free_slabs;	/* length of free slab list only */
5548c2ecf20Sopenharmony_ci	unsigned long free_objects;
5558c2ecf20Sopenharmony_ci	unsigned int free_limit;
5568c2ecf20Sopenharmony_ci	unsigned int colour_next;	/* Per-node cache coloring */
5578c2ecf20Sopenharmony_ci	struct array_cache *shared;	/* shared per node */
5588c2ecf20Sopenharmony_ci	struct alien_cache **alien;	/* on other nodes */
5598c2ecf20Sopenharmony_ci	unsigned long next_reap;	/* updated without locking */
5608c2ecf20Sopenharmony_ci	int free_touched;		/* updated without locking */
5618c2ecf20Sopenharmony_ci#endif
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB
5648c2ecf20Sopenharmony_ci	unsigned long nr_partial;
5658c2ecf20Sopenharmony_ci	struct list_head partial;
5668c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB_DEBUG
5678c2ecf20Sopenharmony_ci	atomic_long_t nr_slabs;
5688c2ecf20Sopenharmony_ci	atomic_long_t total_objects;
5698c2ecf20Sopenharmony_ci	struct list_head full;
5708c2ecf20Sopenharmony_ci#endif
5718c2ecf20Sopenharmony_ci#endif
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci};
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_cistatic inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
5768c2ecf20Sopenharmony_ci{
5778c2ecf20Sopenharmony_ci	return s->node[node];
5788c2ecf20Sopenharmony_ci}
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci/*
5818c2ecf20Sopenharmony_ci * Iterator over all nodes. The body will be executed for each node that has
5828c2ecf20Sopenharmony_ci * a kmem_cache_node structure allocated (which is true for all online nodes)
5838c2ecf20Sopenharmony_ci */
5848c2ecf20Sopenharmony_ci#define for_each_kmem_cache_node(__s, __node, __n) \
5858c2ecf20Sopenharmony_ci	for (__node = 0; __node < nr_node_ids; __node++) \
5868c2ecf20Sopenharmony_ci		 if ((__n = get_node(__s, __node)))
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci#endif
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_civoid *slab_start(struct seq_file *m, loff_t *pos);
5918c2ecf20Sopenharmony_civoid *slab_next(struct seq_file *m, void *p, loff_t *pos);
5928c2ecf20Sopenharmony_civoid slab_stop(struct seq_file *m, void *p);
5938c2ecf20Sopenharmony_ciint memcg_slab_show(struct seq_file *m, void *p);
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB_DEBUG)
5968c2ecf20Sopenharmony_civoid dump_unreclaimable_slab(void);
5978c2ecf20Sopenharmony_ci#else
5988c2ecf20Sopenharmony_cistatic inline void dump_unreclaimable_slab(void)
5998c2ecf20Sopenharmony_ci{
6008c2ecf20Sopenharmony_ci}
6018c2ecf20Sopenharmony_ci#endif
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_civoid ___cache_free(struct kmem_cache *cache, void *x, unsigned long addr);
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_RANDOM
6068c2ecf20Sopenharmony_ciint cache_random_seq_create(struct kmem_cache *cachep, unsigned int count,
6078c2ecf20Sopenharmony_ci			gfp_t gfp);
6088c2ecf20Sopenharmony_civoid cache_random_seq_destroy(struct kmem_cache *cachep);
6098c2ecf20Sopenharmony_ci#else
6108c2ecf20Sopenharmony_cistatic inline int cache_random_seq_create(struct kmem_cache *cachep,
6118c2ecf20Sopenharmony_ci					unsigned int count, gfp_t gfp)
6128c2ecf20Sopenharmony_ci{
6138c2ecf20Sopenharmony_ci	return 0;
6148c2ecf20Sopenharmony_ci}
6158c2ecf20Sopenharmony_cistatic inline void cache_random_seq_destroy(struct kmem_cache *cachep) { }
6168c2ecf20Sopenharmony_ci#endif /* CONFIG_SLAB_FREELIST_RANDOM */
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_cistatic inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c)
6198c2ecf20Sopenharmony_ci{
6208c2ecf20Sopenharmony_ci	if (static_branch_unlikely(&init_on_alloc)) {
6218c2ecf20Sopenharmony_ci		if (c->ctor)
6228c2ecf20Sopenharmony_ci			return false;
6238c2ecf20Sopenharmony_ci		if (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))
6248c2ecf20Sopenharmony_ci			return flags & __GFP_ZERO;
6258c2ecf20Sopenharmony_ci		return true;
6268c2ecf20Sopenharmony_ci	}
6278c2ecf20Sopenharmony_ci	return flags & __GFP_ZERO;
6288c2ecf20Sopenharmony_ci}
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_cistatic inline bool slab_want_init_on_free(struct kmem_cache *c)
6318c2ecf20Sopenharmony_ci{
6328c2ecf20Sopenharmony_ci	if (static_branch_unlikely(&init_on_free))
6338c2ecf20Sopenharmony_ci		return !(c->ctor ||
6348c2ecf20Sopenharmony_ci			 (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)));
6358c2ecf20Sopenharmony_ci	return false;
6368c2ecf20Sopenharmony_ci}
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci#endif /* MM_SLAB_H */
639