18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Slab allocator functions that are independent of the allocator strategy 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) 2012 Christoph Lameter <cl@linux.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <linux/slab.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/mm.h> 108c2ecf20Sopenharmony_ci#include <linux/poison.h> 118c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 128c2ecf20Sopenharmony_ci#include <linux/memory.h> 138c2ecf20Sopenharmony_ci#include <linux/cache.h> 148c2ecf20Sopenharmony_ci#include <linux/compiler.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci#include <linux/cpu.h> 178c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 188c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 198c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 208c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 218c2ecf20Sopenharmony_ci#include <asm/cacheflush.h> 228c2ecf20Sopenharmony_ci#include <asm/tlbflush.h> 238c2ecf20Sopenharmony_ci#include <asm/page.h> 248c2ecf20Sopenharmony_ci#include <linux/memcontrol.h> 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#define CREATE_TRACE_POINTS 278c2ecf20Sopenharmony_ci#include <trace/events/kmem.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include "internal.h" 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include "slab.h" 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cienum slab_state slab_state; 348c2ecf20Sopenharmony_ciLIST_HEAD(slab_caches); 358c2ecf20Sopenharmony_ciDEFINE_MUTEX(slab_mutex); 368c2ecf20Sopenharmony_cistruct kmem_cache *kmem_cache; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#ifdef CONFIG_HARDENED_USERCOPY 398c2ecf20Sopenharmony_cibool usercopy_fallback __ro_after_init = 408c2ecf20Sopenharmony_ci IS_ENABLED(CONFIG_HARDENED_USERCOPY_FALLBACK); 418c2ecf20Sopenharmony_cimodule_param(usercopy_fallback, bool, 0400); 428c2ecf20Sopenharmony_ciMODULE_PARM_DESC(usercopy_fallback, 438c2ecf20Sopenharmony_ci "WARN instead of reject usercopy whitelist violations"); 448c2ecf20Sopenharmony_ci#endif 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic LIST_HEAD(slab_caches_to_rcu_destroy); 478c2ecf20Sopenharmony_cistatic void slab_caches_to_rcu_destroy_workfn(struct work_struct *work); 488c2ecf20Sopenharmony_cistatic DECLARE_WORK(slab_caches_to_rcu_destroy_work, 498c2ecf20Sopenharmony_ci slab_caches_to_rcu_destroy_workfn); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* 528c2ecf20Sopenharmony_ci * Set of flags that will prevent slab merging 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_ci#define SLAB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \ 558c2ecf20Sopenharmony_ci SLAB_TRACE | SLAB_TYPESAFE_BY_RCU | SLAB_NOLEAKTRACE | \ 568c2ecf20Sopenharmony_ci SLAB_FAILSLAB | SLAB_KASAN) 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \ 598c2ecf20Sopenharmony_ci SLAB_CACHE_DMA32 | SLAB_ACCOUNT) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* 628c2ecf20Sopenharmony_ci * Merge control. If this is set then no merging of slab caches will occur. 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_cistatic bool slab_nomerge = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic int __init setup_slab_nomerge(char *str) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci slab_nomerge = true; 698c2ecf20Sopenharmony_ci return 1; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#ifdef CONFIG_SLUB 738c2ecf20Sopenharmony_ci__setup_param("slub_nomerge", slub_nomerge, setup_slab_nomerge, 0); 748c2ecf20Sopenharmony_ci#endif 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci__setup("slab_nomerge", setup_slab_nomerge); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* 798c2ecf20Sopenharmony_ci * Determine the size of a slab object 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ciunsigned int kmem_cache_size(struct kmem_cache *s) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci return s->object_size; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_size); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_VM 888c2ecf20Sopenharmony_cistatic int kmem_cache_sanity_check(const char *name, unsigned int size) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci if (!name || in_interrupt() || size > KMALLOC_MAX_SIZE) { 918c2ecf20Sopenharmony_ci pr_err("kmem_cache_create(%s) integrity check failed\n", name); 928c2ecf20Sopenharmony_ci return -EINVAL; 938c2ecf20Sopenharmony_ci } 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci WARN_ON(strchr(name, ' ')); /* It confuses parsers */ 968c2ecf20Sopenharmony_ci return 0; 978c2ecf20Sopenharmony_ci} 988c2ecf20Sopenharmony_ci#else 998c2ecf20Sopenharmony_cistatic inline int kmem_cache_sanity_check(const char *name, unsigned int size) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci return 0; 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci#endif 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_civoid __kmem_cache_free_bulk(struct kmem_cache *s, size_t nr, void **p) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci size_t i; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci for (i = 0; i < nr; i++) { 1108c2ecf20Sopenharmony_ci if (s) 1118c2ecf20Sopenharmony_ci kmem_cache_free(s, p[i]); 1128c2ecf20Sopenharmony_ci else 1138c2ecf20Sopenharmony_ci kfree(p[i]); 1148c2ecf20Sopenharmony_ci } 1158c2ecf20Sopenharmony_ci} 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ciint __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t nr, 1188c2ecf20Sopenharmony_ci void **p) 1198c2ecf20Sopenharmony_ci{ 1208c2ecf20Sopenharmony_ci size_t i; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci for (i = 0; i < nr; i++) { 1238c2ecf20Sopenharmony_ci void *x = p[i] = kmem_cache_alloc(s, flags); 1248c2ecf20Sopenharmony_ci if (!x) { 1258c2ecf20Sopenharmony_ci __kmem_cache_free_bulk(s, i, p); 1268c2ecf20Sopenharmony_ci return 0; 1278c2ecf20Sopenharmony_ci } 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci return i; 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci/* 1338c2ecf20Sopenharmony_ci * Figure out what the alignment of the objects will be given a set of 1348c2ecf20Sopenharmony_ci * flags, a user specified alignment and the size of the objects. 1358c2ecf20Sopenharmony_ci */ 1368c2ecf20Sopenharmony_cistatic unsigned int calculate_alignment(slab_flags_t flags, 1378c2ecf20Sopenharmony_ci unsigned int align, unsigned int size) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci /* 1408c2ecf20Sopenharmony_ci * If the user wants hardware cache aligned objects then follow that 1418c2ecf20Sopenharmony_ci * suggestion if the object is sufficiently large. 1428c2ecf20Sopenharmony_ci * 1438c2ecf20Sopenharmony_ci * The hardware cache alignment cannot override the specified 1448c2ecf20Sopenharmony_ci * alignment though. If that is greater then use it. 1458c2ecf20Sopenharmony_ci */ 1468c2ecf20Sopenharmony_ci if (flags & SLAB_HWCACHE_ALIGN) { 1478c2ecf20Sopenharmony_ci unsigned int ralign; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci ralign = cache_line_size(); 1508c2ecf20Sopenharmony_ci while (size <= ralign / 2) 1518c2ecf20Sopenharmony_ci ralign /= 2; 1528c2ecf20Sopenharmony_ci align = max(align, ralign); 1538c2ecf20Sopenharmony_ci } 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci if (align < ARCH_SLAB_MINALIGN) 1568c2ecf20Sopenharmony_ci align = ARCH_SLAB_MINALIGN; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci return ALIGN(align, sizeof(void *)); 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci/* 1628c2ecf20Sopenharmony_ci * Find a mergeable slab cache 1638c2ecf20Sopenharmony_ci */ 1648c2ecf20Sopenharmony_ciint slab_unmergeable(struct kmem_cache *s) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci if (slab_nomerge || (s->flags & SLAB_NEVER_MERGE)) 1678c2ecf20Sopenharmony_ci return 1; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci if (s->ctor) 1708c2ecf20Sopenharmony_ci return 1; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci if (s->usersize) 1738c2ecf20Sopenharmony_ci return 1; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci /* 1768c2ecf20Sopenharmony_ci * We may have set a slab to be unmergeable during bootstrap. 1778c2ecf20Sopenharmony_ci */ 1788c2ecf20Sopenharmony_ci if (s->refcount < 0) 1798c2ecf20Sopenharmony_ci return 1; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci return 0; 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistruct kmem_cache *find_mergeable(unsigned int size, unsigned int align, 1858c2ecf20Sopenharmony_ci slab_flags_t flags, const char *name, void (*ctor)(void *)) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci struct kmem_cache *s; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci if (slab_nomerge) 1908c2ecf20Sopenharmony_ci return NULL; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci if (ctor) 1938c2ecf20Sopenharmony_ci return NULL; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci size = ALIGN(size, sizeof(void *)); 1968c2ecf20Sopenharmony_ci align = calculate_alignment(flags, align, size); 1978c2ecf20Sopenharmony_ci size = ALIGN(size, align); 1988c2ecf20Sopenharmony_ci flags = kmem_cache_flags(size, flags, name); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci if (flags & SLAB_NEVER_MERGE) 2018c2ecf20Sopenharmony_ci return NULL; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci list_for_each_entry_reverse(s, &slab_caches, list) { 2048c2ecf20Sopenharmony_ci if (slab_unmergeable(s)) 2058c2ecf20Sopenharmony_ci continue; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci if (size > s->size) 2088c2ecf20Sopenharmony_ci continue; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci if ((flags & SLAB_MERGE_SAME) != (s->flags & SLAB_MERGE_SAME)) 2118c2ecf20Sopenharmony_ci continue; 2128c2ecf20Sopenharmony_ci /* 2138c2ecf20Sopenharmony_ci * Check if alignment is compatible. 2148c2ecf20Sopenharmony_ci * Courtesy of Adrian Drzewiecki 2158c2ecf20Sopenharmony_ci */ 2168c2ecf20Sopenharmony_ci if ((s->size & ~(align - 1)) != s->size) 2178c2ecf20Sopenharmony_ci continue; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (s->size - size >= sizeof(void *)) 2208c2ecf20Sopenharmony_ci continue; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_SLAB) && align && 2238c2ecf20Sopenharmony_ci (align > s->align || s->align % align)) 2248c2ecf20Sopenharmony_ci continue; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci return s; 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci return NULL; 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic struct kmem_cache *create_cache(const char *name, 2328c2ecf20Sopenharmony_ci unsigned int object_size, unsigned int align, 2338c2ecf20Sopenharmony_ci slab_flags_t flags, unsigned int useroffset, 2348c2ecf20Sopenharmony_ci unsigned int usersize, void (*ctor)(void *), 2358c2ecf20Sopenharmony_ci struct kmem_cache *root_cache) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci struct kmem_cache *s; 2388c2ecf20Sopenharmony_ci int err; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if (WARN_ON(useroffset + usersize > object_size)) 2418c2ecf20Sopenharmony_ci useroffset = usersize = 0; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci err = -ENOMEM; 2448c2ecf20Sopenharmony_ci s = kmem_cache_zalloc(kmem_cache, GFP_KERNEL); 2458c2ecf20Sopenharmony_ci if (!s) 2468c2ecf20Sopenharmony_ci goto out; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci s->name = name; 2498c2ecf20Sopenharmony_ci s->size = s->object_size = object_size; 2508c2ecf20Sopenharmony_ci s->align = align; 2518c2ecf20Sopenharmony_ci s->ctor = ctor; 2528c2ecf20Sopenharmony_ci s->useroffset = useroffset; 2538c2ecf20Sopenharmony_ci s->usersize = usersize; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci err = __kmem_cache_create(s, flags); 2568c2ecf20Sopenharmony_ci if (err) 2578c2ecf20Sopenharmony_ci goto out_free_cache; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci s->refcount = 1; 2608c2ecf20Sopenharmony_ci list_add(&s->list, &slab_caches); 2618c2ecf20Sopenharmony_ciout: 2628c2ecf20Sopenharmony_ci if (err) 2638c2ecf20Sopenharmony_ci return ERR_PTR(err); 2648c2ecf20Sopenharmony_ci return s; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ciout_free_cache: 2678c2ecf20Sopenharmony_ci kmem_cache_free(kmem_cache, s); 2688c2ecf20Sopenharmony_ci goto out; 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/** 2728c2ecf20Sopenharmony_ci * kmem_cache_create_usercopy - Create a cache with a region suitable 2738c2ecf20Sopenharmony_ci * for copying to userspace 2748c2ecf20Sopenharmony_ci * @name: A string which is used in /proc/slabinfo to identify this cache. 2758c2ecf20Sopenharmony_ci * @size: The size of objects to be created in this cache. 2768c2ecf20Sopenharmony_ci * @align: The required alignment for the objects. 2778c2ecf20Sopenharmony_ci * @flags: SLAB flags 2788c2ecf20Sopenharmony_ci * @useroffset: Usercopy region offset 2798c2ecf20Sopenharmony_ci * @usersize: Usercopy region size 2808c2ecf20Sopenharmony_ci * @ctor: A constructor for the objects. 2818c2ecf20Sopenharmony_ci * 2828c2ecf20Sopenharmony_ci * Cannot be called within a interrupt, but can be interrupted. 2838c2ecf20Sopenharmony_ci * The @ctor is run when new pages are allocated by the cache. 2848c2ecf20Sopenharmony_ci * 2858c2ecf20Sopenharmony_ci * The flags are 2868c2ecf20Sopenharmony_ci * 2878c2ecf20Sopenharmony_ci * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) 2888c2ecf20Sopenharmony_ci * to catch references to uninitialised memory. 2898c2ecf20Sopenharmony_ci * 2908c2ecf20Sopenharmony_ci * %SLAB_RED_ZONE - Insert `Red` zones around the allocated memory to check 2918c2ecf20Sopenharmony_ci * for buffer overruns. 2928c2ecf20Sopenharmony_ci * 2938c2ecf20Sopenharmony_ci * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware 2948c2ecf20Sopenharmony_ci * cacheline. This can be beneficial if you're counting cycles as closely 2958c2ecf20Sopenharmony_ci * as davem. 2968c2ecf20Sopenharmony_ci * 2978c2ecf20Sopenharmony_ci * Return: a pointer to the cache on success, NULL on failure. 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_cistruct kmem_cache * 3008c2ecf20Sopenharmony_cikmem_cache_create_usercopy(const char *name, 3018c2ecf20Sopenharmony_ci unsigned int size, unsigned int align, 3028c2ecf20Sopenharmony_ci slab_flags_t flags, 3038c2ecf20Sopenharmony_ci unsigned int useroffset, unsigned int usersize, 3048c2ecf20Sopenharmony_ci void (*ctor)(void *)) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci struct kmem_cache *s = NULL; 3078c2ecf20Sopenharmony_ci const char *cache_name; 3088c2ecf20Sopenharmony_ci int err; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci get_online_cpus(); 3118c2ecf20Sopenharmony_ci get_online_mems(); 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci mutex_lock(&slab_mutex); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci err = kmem_cache_sanity_check(name, size); 3168c2ecf20Sopenharmony_ci if (err) { 3178c2ecf20Sopenharmony_ci goto out_unlock; 3188c2ecf20Sopenharmony_ci } 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* Refuse requests with allocator specific flags */ 3218c2ecf20Sopenharmony_ci if (flags & ~SLAB_FLAGS_PERMITTED) { 3228c2ecf20Sopenharmony_ci err = -EINVAL; 3238c2ecf20Sopenharmony_ci goto out_unlock; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci /* 3278c2ecf20Sopenharmony_ci * Some allocators will constraint the set of valid flags to a subset 3288c2ecf20Sopenharmony_ci * of all flags. We expect them to define CACHE_CREATE_MASK in this 3298c2ecf20Sopenharmony_ci * case, and we'll just provide them with a sanitized version of the 3308c2ecf20Sopenharmony_ci * passed flags. 3318c2ecf20Sopenharmony_ci */ 3328c2ecf20Sopenharmony_ci flags &= CACHE_CREATE_MASK; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci /* Fail closed on bad usersize of useroffset values. */ 3358c2ecf20Sopenharmony_ci if (WARN_ON(!usersize && useroffset) || 3368c2ecf20Sopenharmony_ci WARN_ON(size < usersize || size - usersize < useroffset)) 3378c2ecf20Sopenharmony_ci usersize = useroffset = 0; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if (!usersize) 3408c2ecf20Sopenharmony_ci s = __kmem_cache_alias(name, size, align, flags, ctor); 3418c2ecf20Sopenharmony_ci if (s) 3428c2ecf20Sopenharmony_ci goto out_unlock; 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci cache_name = kstrdup_const(name, GFP_KERNEL); 3458c2ecf20Sopenharmony_ci if (!cache_name) { 3468c2ecf20Sopenharmony_ci err = -ENOMEM; 3478c2ecf20Sopenharmony_ci goto out_unlock; 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci s = create_cache(cache_name, size, 3518c2ecf20Sopenharmony_ci calculate_alignment(flags, align, size), 3528c2ecf20Sopenharmony_ci flags, useroffset, usersize, ctor, NULL); 3538c2ecf20Sopenharmony_ci if (IS_ERR(s)) { 3548c2ecf20Sopenharmony_ci err = PTR_ERR(s); 3558c2ecf20Sopenharmony_ci kfree_const(cache_name); 3568c2ecf20Sopenharmony_ci } 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ciout_unlock: 3598c2ecf20Sopenharmony_ci mutex_unlock(&slab_mutex); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci put_online_mems(); 3628c2ecf20Sopenharmony_ci put_online_cpus(); 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci if (err) { 3658c2ecf20Sopenharmony_ci if (flags & SLAB_PANIC) 3668c2ecf20Sopenharmony_ci panic("kmem_cache_create: Failed to create slab '%s'. Error %d\n", 3678c2ecf20Sopenharmony_ci name, err); 3688c2ecf20Sopenharmony_ci else { 3698c2ecf20Sopenharmony_ci pr_warn("kmem_cache_create(%s) failed with error %d\n", 3708c2ecf20Sopenharmony_ci name, err); 3718c2ecf20Sopenharmony_ci dump_stack(); 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci return NULL; 3748c2ecf20Sopenharmony_ci } 3758c2ecf20Sopenharmony_ci return s; 3768c2ecf20Sopenharmony_ci} 3778c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_create_usercopy); 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci/** 3808c2ecf20Sopenharmony_ci * kmem_cache_create - Create a cache. 3818c2ecf20Sopenharmony_ci * @name: A string which is used in /proc/slabinfo to identify this cache. 3828c2ecf20Sopenharmony_ci * @size: The size of objects to be created in this cache. 3838c2ecf20Sopenharmony_ci * @align: The required alignment for the objects. 3848c2ecf20Sopenharmony_ci * @flags: SLAB flags 3858c2ecf20Sopenharmony_ci * @ctor: A constructor for the objects. 3868c2ecf20Sopenharmony_ci * 3878c2ecf20Sopenharmony_ci * Cannot be called within a interrupt, but can be interrupted. 3888c2ecf20Sopenharmony_ci * The @ctor is run when new pages are allocated by the cache. 3898c2ecf20Sopenharmony_ci * 3908c2ecf20Sopenharmony_ci * The flags are 3918c2ecf20Sopenharmony_ci * 3928c2ecf20Sopenharmony_ci * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) 3938c2ecf20Sopenharmony_ci * to catch references to uninitialised memory. 3948c2ecf20Sopenharmony_ci * 3958c2ecf20Sopenharmony_ci * %SLAB_RED_ZONE - Insert `Red` zones around the allocated memory to check 3968c2ecf20Sopenharmony_ci * for buffer overruns. 3978c2ecf20Sopenharmony_ci * 3988c2ecf20Sopenharmony_ci * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware 3998c2ecf20Sopenharmony_ci * cacheline. This can be beneficial if you're counting cycles as closely 4008c2ecf20Sopenharmony_ci * as davem. 4018c2ecf20Sopenharmony_ci * 4028c2ecf20Sopenharmony_ci * Return: a pointer to the cache on success, NULL on failure. 4038c2ecf20Sopenharmony_ci */ 4048c2ecf20Sopenharmony_cistruct kmem_cache * 4058c2ecf20Sopenharmony_cikmem_cache_create(const char *name, unsigned int size, unsigned int align, 4068c2ecf20Sopenharmony_ci slab_flags_t flags, void (*ctor)(void *)) 4078c2ecf20Sopenharmony_ci{ 4088c2ecf20Sopenharmony_ci return kmem_cache_create_usercopy(name, size, align, flags, 0, 0, 4098c2ecf20Sopenharmony_ci ctor); 4108c2ecf20Sopenharmony_ci} 4118c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_create); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_cistatic void slab_caches_to_rcu_destroy_workfn(struct work_struct *work) 4148c2ecf20Sopenharmony_ci{ 4158c2ecf20Sopenharmony_ci LIST_HEAD(to_destroy); 4168c2ecf20Sopenharmony_ci struct kmem_cache *s, *s2; 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci /* 4198c2ecf20Sopenharmony_ci * On destruction, SLAB_TYPESAFE_BY_RCU kmem_caches are put on the 4208c2ecf20Sopenharmony_ci * @slab_caches_to_rcu_destroy list. The slab pages are freed 4218c2ecf20Sopenharmony_ci * through RCU and the associated kmem_cache are dereferenced 4228c2ecf20Sopenharmony_ci * while freeing the pages, so the kmem_caches should be freed only 4238c2ecf20Sopenharmony_ci * after the pending RCU operations are finished. As rcu_barrier() 4248c2ecf20Sopenharmony_ci * is a pretty slow operation, we batch all pending destructions 4258c2ecf20Sopenharmony_ci * asynchronously. 4268c2ecf20Sopenharmony_ci */ 4278c2ecf20Sopenharmony_ci mutex_lock(&slab_mutex); 4288c2ecf20Sopenharmony_ci list_splice_init(&slab_caches_to_rcu_destroy, &to_destroy); 4298c2ecf20Sopenharmony_ci mutex_unlock(&slab_mutex); 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci if (list_empty(&to_destroy)) 4328c2ecf20Sopenharmony_ci return; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci rcu_barrier(); 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci list_for_each_entry_safe(s, s2, &to_destroy, list) { 4378c2ecf20Sopenharmony_ci#ifdef SLAB_SUPPORTS_SYSFS 4388c2ecf20Sopenharmony_ci sysfs_slab_release(s); 4398c2ecf20Sopenharmony_ci#else 4408c2ecf20Sopenharmony_ci slab_kmem_cache_release(s); 4418c2ecf20Sopenharmony_ci#endif 4428c2ecf20Sopenharmony_ci } 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_cistatic int shutdown_cache(struct kmem_cache *s) 4468c2ecf20Sopenharmony_ci{ 4478c2ecf20Sopenharmony_ci /* free asan quarantined objects */ 4488c2ecf20Sopenharmony_ci kasan_cache_shutdown(s); 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci if (__kmem_cache_shutdown(s) != 0) 4518c2ecf20Sopenharmony_ci return -EBUSY; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci list_del(&s->list); 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci if (s->flags & SLAB_TYPESAFE_BY_RCU) { 4568c2ecf20Sopenharmony_ci#ifdef SLAB_SUPPORTS_SYSFS 4578c2ecf20Sopenharmony_ci sysfs_slab_unlink(s); 4588c2ecf20Sopenharmony_ci#endif 4598c2ecf20Sopenharmony_ci list_add_tail(&s->list, &slab_caches_to_rcu_destroy); 4608c2ecf20Sopenharmony_ci schedule_work(&slab_caches_to_rcu_destroy_work); 4618c2ecf20Sopenharmony_ci } else { 4628c2ecf20Sopenharmony_ci#ifdef SLAB_SUPPORTS_SYSFS 4638c2ecf20Sopenharmony_ci sysfs_slab_unlink(s); 4648c2ecf20Sopenharmony_ci sysfs_slab_release(s); 4658c2ecf20Sopenharmony_ci#else 4668c2ecf20Sopenharmony_ci slab_kmem_cache_release(s); 4678c2ecf20Sopenharmony_ci#endif 4688c2ecf20Sopenharmony_ci } 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci return 0; 4718c2ecf20Sopenharmony_ci} 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_civoid slab_kmem_cache_release(struct kmem_cache *s) 4748c2ecf20Sopenharmony_ci{ 4758c2ecf20Sopenharmony_ci __kmem_cache_release(s); 4768c2ecf20Sopenharmony_ci kfree_const(s->name); 4778c2ecf20Sopenharmony_ci kmem_cache_free(kmem_cache, s); 4788c2ecf20Sopenharmony_ci} 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_civoid kmem_cache_destroy(struct kmem_cache *s) 4818c2ecf20Sopenharmony_ci{ 4828c2ecf20Sopenharmony_ci int err; 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci if (unlikely(!s)) 4858c2ecf20Sopenharmony_ci return; 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci get_online_cpus(); 4888c2ecf20Sopenharmony_ci get_online_mems(); 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci mutex_lock(&slab_mutex); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci s->refcount--; 4938c2ecf20Sopenharmony_ci if (s->refcount) 4948c2ecf20Sopenharmony_ci goto out_unlock; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci err = shutdown_cache(s); 4978c2ecf20Sopenharmony_ci if (err) { 4988c2ecf20Sopenharmony_ci pr_err("kmem_cache_destroy %s: Slab cache still has objects\n", 4998c2ecf20Sopenharmony_ci s->name); 5008c2ecf20Sopenharmony_ci dump_stack(); 5018c2ecf20Sopenharmony_ci } 5028c2ecf20Sopenharmony_ciout_unlock: 5038c2ecf20Sopenharmony_ci mutex_unlock(&slab_mutex); 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci put_online_mems(); 5068c2ecf20Sopenharmony_ci put_online_cpus(); 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_destroy); 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci/** 5118c2ecf20Sopenharmony_ci * kmem_cache_shrink - Shrink a cache. 5128c2ecf20Sopenharmony_ci * @cachep: The cache to shrink. 5138c2ecf20Sopenharmony_ci * 5148c2ecf20Sopenharmony_ci * Releases as many slabs as possible for a cache. 5158c2ecf20Sopenharmony_ci * To help debugging, a zero exit status indicates all slabs were released. 5168c2ecf20Sopenharmony_ci * 5178c2ecf20Sopenharmony_ci * Return: %0 if all slabs were released, non-zero otherwise 5188c2ecf20Sopenharmony_ci */ 5198c2ecf20Sopenharmony_ciint kmem_cache_shrink(struct kmem_cache *cachep) 5208c2ecf20Sopenharmony_ci{ 5218c2ecf20Sopenharmony_ci int ret; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci get_online_cpus(); 5248c2ecf20Sopenharmony_ci get_online_mems(); 5258c2ecf20Sopenharmony_ci kasan_cache_shrink(cachep); 5268c2ecf20Sopenharmony_ci ret = __kmem_cache_shrink(cachep); 5278c2ecf20Sopenharmony_ci put_online_mems(); 5288c2ecf20Sopenharmony_ci put_online_cpus(); 5298c2ecf20Sopenharmony_ci return ret; 5308c2ecf20Sopenharmony_ci} 5318c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmem_cache_shrink); 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_cibool slab_is_available(void) 5348c2ecf20Sopenharmony_ci{ 5358c2ecf20Sopenharmony_ci return slab_state >= UP; 5368c2ecf20Sopenharmony_ci} 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci#ifndef CONFIG_SLOB 5398c2ecf20Sopenharmony_ci/* Create a cache during boot when no slab services are available yet */ 5408c2ecf20Sopenharmony_civoid __init create_boot_cache(struct kmem_cache *s, const char *name, 5418c2ecf20Sopenharmony_ci unsigned int size, slab_flags_t flags, 5428c2ecf20Sopenharmony_ci unsigned int useroffset, unsigned int usersize) 5438c2ecf20Sopenharmony_ci{ 5448c2ecf20Sopenharmony_ci int err; 5458c2ecf20Sopenharmony_ci unsigned int align = ARCH_KMALLOC_MINALIGN; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci s->name = name; 5488c2ecf20Sopenharmony_ci s->size = s->object_size = size; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci /* 5518c2ecf20Sopenharmony_ci * For power of two sizes, guarantee natural alignment for kmalloc 5528c2ecf20Sopenharmony_ci * caches, regardless of SL*B debugging options. 5538c2ecf20Sopenharmony_ci */ 5548c2ecf20Sopenharmony_ci if (is_power_of_2(size)) 5558c2ecf20Sopenharmony_ci align = max(align, size); 5568c2ecf20Sopenharmony_ci s->align = calculate_alignment(flags, align, size); 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci s->useroffset = useroffset; 5598c2ecf20Sopenharmony_ci s->usersize = usersize; 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci err = __kmem_cache_create(s, flags); 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci if (err) 5648c2ecf20Sopenharmony_ci panic("Creation of kmalloc slab %s size=%u failed. Reason %d\n", 5658c2ecf20Sopenharmony_ci name, size, err); 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci s->refcount = -1; /* Exempt from merging for now */ 5688c2ecf20Sopenharmony_ci} 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_cistruct kmem_cache *__init create_kmalloc_cache(const char *name, 5718c2ecf20Sopenharmony_ci unsigned int size, slab_flags_t flags, 5728c2ecf20Sopenharmony_ci unsigned int useroffset, unsigned int usersize) 5738c2ecf20Sopenharmony_ci{ 5748c2ecf20Sopenharmony_ci struct kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT); 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci if (!s) 5778c2ecf20Sopenharmony_ci panic("Out of memory when creating slab %s\n", name); 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci create_boot_cache(s, name, size, flags, useroffset, usersize); 5808c2ecf20Sopenharmony_ci list_add(&s->list, &slab_caches); 5818c2ecf20Sopenharmony_ci s->refcount = 1; 5828c2ecf20Sopenharmony_ci return s; 5838c2ecf20Sopenharmony_ci} 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_cistruct kmem_cache * 5868c2ecf20Sopenharmony_cikmalloc_caches[NR_KMALLOC_TYPES][KMALLOC_SHIFT_HIGH + 1] __ro_after_init = 5878c2ecf20Sopenharmony_ci{ /* initialization for https://bugs.llvm.org/show_bug.cgi?id=42570 */ }; 5888c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmalloc_caches); 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci/* 5918c2ecf20Sopenharmony_ci * Conversion table for small slabs sizes / 8 to the index in the 5928c2ecf20Sopenharmony_ci * kmalloc array. This is necessary for slabs < 192 since we have non power 5938c2ecf20Sopenharmony_ci * of two cache sizes there. The size of larger slabs can be determined using 5948c2ecf20Sopenharmony_ci * fls. 5958c2ecf20Sopenharmony_ci */ 5968c2ecf20Sopenharmony_cistatic u8 size_index[24] __ro_after_init = { 5978c2ecf20Sopenharmony_ci 3, /* 8 */ 5988c2ecf20Sopenharmony_ci 4, /* 16 */ 5998c2ecf20Sopenharmony_ci 5, /* 24 */ 6008c2ecf20Sopenharmony_ci 5, /* 32 */ 6018c2ecf20Sopenharmony_ci 6, /* 40 */ 6028c2ecf20Sopenharmony_ci 6, /* 48 */ 6038c2ecf20Sopenharmony_ci 6, /* 56 */ 6048c2ecf20Sopenharmony_ci 6, /* 64 */ 6058c2ecf20Sopenharmony_ci 1, /* 72 */ 6068c2ecf20Sopenharmony_ci 1, /* 80 */ 6078c2ecf20Sopenharmony_ci 1, /* 88 */ 6088c2ecf20Sopenharmony_ci 1, /* 96 */ 6098c2ecf20Sopenharmony_ci 7, /* 104 */ 6108c2ecf20Sopenharmony_ci 7, /* 112 */ 6118c2ecf20Sopenharmony_ci 7, /* 120 */ 6128c2ecf20Sopenharmony_ci 7, /* 128 */ 6138c2ecf20Sopenharmony_ci 2, /* 136 */ 6148c2ecf20Sopenharmony_ci 2, /* 144 */ 6158c2ecf20Sopenharmony_ci 2, /* 152 */ 6168c2ecf20Sopenharmony_ci 2, /* 160 */ 6178c2ecf20Sopenharmony_ci 2, /* 168 */ 6188c2ecf20Sopenharmony_ci 2, /* 176 */ 6198c2ecf20Sopenharmony_ci 2, /* 184 */ 6208c2ecf20Sopenharmony_ci 2 /* 192 */ 6218c2ecf20Sopenharmony_ci}; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistatic inline unsigned int size_index_elem(unsigned int bytes) 6248c2ecf20Sopenharmony_ci{ 6258c2ecf20Sopenharmony_ci return (bytes - 1) / 8; 6268c2ecf20Sopenharmony_ci} 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci/* 6298c2ecf20Sopenharmony_ci * Find the kmem_cache structure that serves a given size of 6308c2ecf20Sopenharmony_ci * allocation 6318c2ecf20Sopenharmony_ci */ 6328c2ecf20Sopenharmony_cistruct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) 6338c2ecf20Sopenharmony_ci{ 6348c2ecf20Sopenharmony_ci unsigned int index; 6358c2ecf20Sopenharmony_ci 6368c2ecf20Sopenharmony_ci if (size <= 192) { 6378c2ecf20Sopenharmony_ci if (!size) 6388c2ecf20Sopenharmony_ci return ZERO_SIZE_PTR; 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci index = size_index[size_index_elem(size)]; 6418c2ecf20Sopenharmony_ci } else { 6428c2ecf20Sopenharmony_ci if (WARN_ON_ONCE(size > KMALLOC_MAX_CACHE_SIZE)) 6438c2ecf20Sopenharmony_ci return NULL; 6448c2ecf20Sopenharmony_ci index = fls(size - 1); 6458c2ecf20Sopenharmony_ci } 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci return kmalloc_caches[kmalloc_type(flags)][index]; 6488c2ecf20Sopenharmony_ci} 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci#ifdef CONFIG_ZONE_DMA 6518c2ecf20Sopenharmony_ci#define INIT_KMALLOC_INFO(__size, __short_size) \ 6528c2ecf20Sopenharmony_ci{ \ 6538c2ecf20Sopenharmony_ci .name[KMALLOC_NORMAL] = "kmalloc-" #__short_size, \ 6548c2ecf20Sopenharmony_ci .name[KMALLOC_RECLAIM] = "kmalloc-rcl-" #__short_size, \ 6558c2ecf20Sopenharmony_ci .name[KMALLOC_DMA] = "dma-kmalloc-" #__short_size, \ 6568c2ecf20Sopenharmony_ci .size = __size, \ 6578c2ecf20Sopenharmony_ci} 6588c2ecf20Sopenharmony_ci#else 6598c2ecf20Sopenharmony_ci#define INIT_KMALLOC_INFO(__size, __short_size) \ 6608c2ecf20Sopenharmony_ci{ \ 6618c2ecf20Sopenharmony_ci .name[KMALLOC_NORMAL] = "kmalloc-" #__short_size, \ 6628c2ecf20Sopenharmony_ci .name[KMALLOC_RECLAIM] = "kmalloc-rcl-" #__short_size, \ 6638c2ecf20Sopenharmony_ci .size = __size, \ 6648c2ecf20Sopenharmony_ci} 6658c2ecf20Sopenharmony_ci#endif 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci/* 6688c2ecf20Sopenharmony_ci * kmalloc_info[] is to make slub_debug=,kmalloc-xx option work at boot time. 6698c2ecf20Sopenharmony_ci * kmalloc_index() supports up to 2^26=64MB, so the final entry of the table is 6708c2ecf20Sopenharmony_ci * kmalloc-67108864. 6718c2ecf20Sopenharmony_ci */ 6728c2ecf20Sopenharmony_ciconst struct kmalloc_info_struct kmalloc_info[] __initconst = { 6738c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(0, 0), 6748c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(96, 96), 6758c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(192, 192), 6768c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(8, 8), 6778c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(16, 16), 6788c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(32, 32), 6798c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(64, 64), 6808c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(128, 128), 6818c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(256, 256), 6828c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(512, 512), 6838c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(1024, 1k), 6848c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(2048, 2k), 6858c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(4096, 4k), 6868c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(8192, 8k), 6878c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(16384, 16k), 6888c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(32768, 32k), 6898c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(65536, 64k), 6908c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(131072, 128k), 6918c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(262144, 256k), 6928c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(524288, 512k), 6938c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(1048576, 1M), 6948c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(2097152, 2M), 6958c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(4194304, 4M), 6968c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(8388608, 8M), 6978c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(16777216, 16M), 6988c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(33554432, 32M), 6998c2ecf20Sopenharmony_ci INIT_KMALLOC_INFO(67108864, 64M) 7008c2ecf20Sopenharmony_ci}; 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci/* 7038c2ecf20Sopenharmony_ci * Patch up the size_index table if we have strange large alignment 7048c2ecf20Sopenharmony_ci * requirements for the kmalloc array. This is only the case for 7058c2ecf20Sopenharmony_ci * MIPS it seems. The standard arches will not generate any code here. 7068c2ecf20Sopenharmony_ci * 7078c2ecf20Sopenharmony_ci * Largest permitted alignment is 256 bytes due to the way we 7088c2ecf20Sopenharmony_ci * handle the index determination for the smaller caches. 7098c2ecf20Sopenharmony_ci * 7108c2ecf20Sopenharmony_ci * Make sure that nothing crazy happens if someone starts tinkering 7118c2ecf20Sopenharmony_ci * around with ARCH_KMALLOC_MINALIGN 7128c2ecf20Sopenharmony_ci */ 7138c2ecf20Sopenharmony_civoid __init setup_kmalloc_cache_index_table(void) 7148c2ecf20Sopenharmony_ci{ 7158c2ecf20Sopenharmony_ci unsigned int i; 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci BUILD_BUG_ON(KMALLOC_MIN_SIZE > 256 || 7188c2ecf20Sopenharmony_ci (KMALLOC_MIN_SIZE & (KMALLOC_MIN_SIZE - 1))); 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci for (i = 8; i < KMALLOC_MIN_SIZE; i += 8) { 7218c2ecf20Sopenharmony_ci unsigned int elem = size_index_elem(i); 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci if (elem >= ARRAY_SIZE(size_index)) 7248c2ecf20Sopenharmony_ci break; 7258c2ecf20Sopenharmony_ci size_index[elem] = KMALLOC_SHIFT_LOW; 7268c2ecf20Sopenharmony_ci } 7278c2ecf20Sopenharmony_ci 7288c2ecf20Sopenharmony_ci if (KMALLOC_MIN_SIZE >= 64) { 7298c2ecf20Sopenharmony_ci /* 7308c2ecf20Sopenharmony_ci * The 96 byte size cache is not used if the alignment 7318c2ecf20Sopenharmony_ci * is 64 byte. 7328c2ecf20Sopenharmony_ci */ 7338c2ecf20Sopenharmony_ci for (i = 64 + 8; i <= 96; i += 8) 7348c2ecf20Sopenharmony_ci size_index[size_index_elem(i)] = 7; 7358c2ecf20Sopenharmony_ci 7368c2ecf20Sopenharmony_ci } 7378c2ecf20Sopenharmony_ci 7388c2ecf20Sopenharmony_ci if (KMALLOC_MIN_SIZE >= 128) { 7398c2ecf20Sopenharmony_ci /* 7408c2ecf20Sopenharmony_ci * The 192 byte sized cache is not used if the alignment 7418c2ecf20Sopenharmony_ci * is 128 byte. Redirect kmalloc to use the 256 byte cache 7428c2ecf20Sopenharmony_ci * instead. 7438c2ecf20Sopenharmony_ci */ 7448c2ecf20Sopenharmony_ci for (i = 128 + 8; i <= 192; i += 8) 7458c2ecf20Sopenharmony_ci size_index[size_index_elem(i)] = 8; 7468c2ecf20Sopenharmony_ci } 7478c2ecf20Sopenharmony_ci} 7488c2ecf20Sopenharmony_ci 7498c2ecf20Sopenharmony_cistatic void __init 7508c2ecf20Sopenharmony_cinew_kmalloc_cache(int idx, enum kmalloc_cache_type type, slab_flags_t flags) 7518c2ecf20Sopenharmony_ci{ 7528c2ecf20Sopenharmony_ci if (type == KMALLOC_RECLAIM) 7538c2ecf20Sopenharmony_ci flags |= SLAB_RECLAIM_ACCOUNT; 7548c2ecf20Sopenharmony_ci 7558c2ecf20Sopenharmony_ci kmalloc_caches[type][idx] = create_kmalloc_cache( 7568c2ecf20Sopenharmony_ci kmalloc_info[idx].name[type], 7578c2ecf20Sopenharmony_ci kmalloc_info[idx].size, flags, 0, 7588c2ecf20Sopenharmony_ci kmalloc_info[idx].size); 7598c2ecf20Sopenharmony_ci} 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci/* 7628c2ecf20Sopenharmony_ci * Create the kmalloc array. Some of the regular kmalloc arrays 7638c2ecf20Sopenharmony_ci * may already have been created because they were needed to 7648c2ecf20Sopenharmony_ci * enable allocations for slab creation. 7658c2ecf20Sopenharmony_ci */ 7668c2ecf20Sopenharmony_civoid __init create_kmalloc_caches(slab_flags_t flags) 7678c2ecf20Sopenharmony_ci{ 7688c2ecf20Sopenharmony_ci int i; 7698c2ecf20Sopenharmony_ci enum kmalloc_cache_type type; 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci for (type = KMALLOC_NORMAL; type <= KMALLOC_RECLAIM; type++) { 7728c2ecf20Sopenharmony_ci for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) { 7738c2ecf20Sopenharmony_ci if (!kmalloc_caches[type][i]) 7748c2ecf20Sopenharmony_ci new_kmalloc_cache(i, type, flags); 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci /* 7778c2ecf20Sopenharmony_ci * Caches that are not of the two-to-the-power-of size. 7788c2ecf20Sopenharmony_ci * These have to be created immediately after the 7798c2ecf20Sopenharmony_ci * earlier power of two caches 7808c2ecf20Sopenharmony_ci */ 7818c2ecf20Sopenharmony_ci if (KMALLOC_MIN_SIZE <= 32 && i == 6 && 7828c2ecf20Sopenharmony_ci !kmalloc_caches[type][1]) 7838c2ecf20Sopenharmony_ci new_kmalloc_cache(1, type, flags); 7848c2ecf20Sopenharmony_ci if (KMALLOC_MIN_SIZE <= 64 && i == 7 && 7858c2ecf20Sopenharmony_ci !kmalloc_caches[type][2]) 7868c2ecf20Sopenharmony_ci new_kmalloc_cache(2, type, flags); 7878c2ecf20Sopenharmony_ci } 7888c2ecf20Sopenharmony_ci } 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci /* Kmalloc array is now usable */ 7918c2ecf20Sopenharmony_ci slab_state = UP; 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci#ifdef CONFIG_ZONE_DMA 7948c2ecf20Sopenharmony_ci for (i = 0; i <= KMALLOC_SHIFT_HIGH; i++) { 7958c2ecf20Sopenharmony_ci struct kmem_cache *s = kmalloc_caches[KMALLOC_NORMAL][i]; 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci if (s) { 7988c2ecf20Sopenharmony_ci kmalloc_caches[KMALLOC_DMA][i] = create_kmalloc_cache( 7998c2ecf20Sopenharmony_ci kmalloc_info[i].name[KMALLOC_DMA], 8008c2ecf20Sopenharmony_ci kmalloc_info[i].size, 8018c2ecf20Sopenharmony_ci SLAB_CACHE_DMA | flags, 0, 8028c2ecf20Sopenharmony_ci kmalloc_info[i].size); 8038c2ecf20Sopenharmony_ci } 8048c2ecf20Sopenharmony_ci } 8058c2ecf20Sopenharmony_ci#endif 8068c2ecf20Sopenharmony_ci} 8078c2ecf20Sopenharmony_ci#endif /* !CONFIG_SLOB */ 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_cigfp_t kmalloc_fix_flags(gfp_t flags) 8108c2ecf20Sopenharmony_ci{ 8118c2ecf20Sopenharmony_ci gfp_t invalid_mask = flags & GFP_SLAB_BUG_MASK; 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci flags &= ~GFP_SLAB_BUG_MASK; 8148c2ecf20Sopenharmony_ci pr_warn("Unexpected gfp: %#x (%pGg). Fixing up to gfp: %#x (%pGg). Fix your code!\n", 8158c2ecf20Sopenharmony_ci invalid_mask, &invalid_mask, flags, &flags); 8168c2ecf20Sopenharmony_ci dump_stack(); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci return flags; 8198c2ecf20Sopenharmony_ci} 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci/* 8228c2ecf20Sopenharmony_ci * To avoid unnecessary overhead, we pass through large allocation requests 8238c2ecf20Sopenharmony_ci * directly to the page allocator. We use __GFP_COMP, because we will need to 8248c2ecf20Sopenharmony_ci * know the allocation order to free the pages properly in kfree. 8258c2ecf20Sopenharmony_ci */ 8268c2ecf20Sopenharmony_civoid *kmalloc_order(size_t size, gfp_t flags, unsigned int order) 8278c2ecf20Sopenharmony_ci{ 8288c2ecf20Sopenharmony_ci void *ret = NULL; 8298c2ecf20Sopenharmony_ci struct page *page; 8308c2ecf20Sopenharmony_ci 8318c2ecf20Sopenharmony_ci if (unlikely(flags & GFP_SLAB_BUG_MASK)) 8328c2ecf20Sopenharmony_ci flags = kmalloc_fix_flags(flags); 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_ci flags |= __GFP_COMP; 8358c2ecf20Sopenharmony_ci page = alloc_pages(flags, order); 8368c2ecf20Sopenharmony_ci if (likely(page)) { 8378c2ecf20Sopenharmony_ci ret = page_address(page); 8388c2ecf20Sopenharmony_ci mod_lruvec_page_state(page, NR_SLAB_UNRECLAIMABLE_B, 8398c2ecf20Sopenharmony_ci PAGE_SIZE << order); 8408c2ecf20Sopenharmony_ci } 8418c2ecf20Sopenharmony_ci ret = kasan_kmalloc_large(ret, size, flags); 8428c2ecf20Sopenharmony_ci /* As ret might get tagged, call kmemleak hook after KASAN. */ 8438c2ecf20Sopenharmony_ci kmemleak_alloc(ret, size, 1, flags); 8448c2ecf20Sopenharmony_ci return ret; 8458c2ecf20Sopenharmony_ci} 8468c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmalloc_order); 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci#ifdef CONFIG_TRACING 8498c2ecf20Sopenharmony_civoid *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) 8508c2ecf20Sopenharmony_ci{ 8518c2ecf20Sopenharmony_ci void *ret = kmalloc_order(size, flags, order); 8528c2ecf20Sopenharmony_ci trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << order, flags); 8538c2ecf20Sopenharmony_ci return ret; 8548c2ecf20Sopenharmony_ci} 8558c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmalloc_order_trace); 8568c2ecf20Sopenharmony_ci#endif 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci#ifdef CONFIG_SLAB_FREELIST_RANDOM 8598c2ecf20Sopenharmony_ci/* Randomize a generic freelist */ 8608c2ecf20Sopenharmony_cistatic void freelist_randomize(struct rnd_state *state, unsigned int *list, 8618c2ecf20Sopenharmony_ci unsigned int count) 8628c2ecf20Sopenharmony_ci{ 8638c2ecf20Sopenharmony_ci unsigned int rand; 8648c2ecf20Sopenharmony_ci unsigned int i; 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) 8678c2ecf20Sopenharmony_ci list[i] = i; 8688c2ecf20Sopenharmony_ci 8698c2ecf20Sopenharmony_ci /* Fisher-Yates shuffle */ 8708c2ecf20Sopenharmony_ci for (i = count - 1; i > 0; i--) { 8718c2ecf20Sopenharmony_ci rand = prandom_u32_state(state); 8728c2ecf20Sopenharmony_ci rand %= (i + 1); 8738c2ecf20Sopenharmony_ci swap(list[i], list[rand]); 8748c2ecf20Sopenharmony_ci } 8758c2ecf20Sopenharmony_ci} 8768c2ecf20Sopenharmony_ci 8778c2ecf20Sopenharmony_ci/* Create a random sequence per cache */ 8788c2ecf20Sopenharmony_ciint cache_random_seq_create(struct kmem_cache *cachep, unsigned int count, 8798c2ecf20Sopenharmony_ci gfp_t gfp) 8808c2ecf20Sopenharmony_ci{ 8818c2ecf20Sopenharmony_ci struct rnd_state state; 8828c2ecf20Sopenharmony_ci 8838c2ecf20Sopenharmony_ci if (count < 2 || cachep->random_seq) 8848c2ecf20Sopenharmony_ci return 0; 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci cachep->random_seq = kcalloc(count, sizeof(unsigned int), gfp); 8878c2ecf20Sopenharmony_ci if (!cachep->random_seq) 8888c2ecf20Sopenharmony_ci return -ENOMEM; 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ci /* Get best entropy at this stage of boot */ 8918c2ecf20Sopenharmony_ci prandom_seed_state(&state, get_random_long()); 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci freelist_randomize(&state, cachep->random_seq, count); 8948c2ecf20Sopenharmony_ci return 0; 8958c2ecf20Sopenharmony_ci} 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci/* Destroy the per-cache random freelist sequence */ 8988c2ecf20Sopenharmony_civoid cache_random_seq_destroy(struct kmem_cache *cachep) 8998c2ecf20Sopenharmony_ci{ 9008c2ecf20Sopenharmony_ci kfree(cachep->random_seq); 9018c2ecf20Sopenharmony_ci cachep->random_seq = NULL; 9028c2ecf20Sopenharmony_ci} 9038c2ecf20Sopenharmony_ci#endif /* CONFIG_SLAB_FREELIST_RANDOM */ 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB_DEBUG) 9068c2ecf20Sopenharmony_ci#ifdef CONFIG_SLAB 9078c2ecf20Sopenharmony_ci#define SLABINFO_RIGHTS (0600) 9088c2ecf20Sopenharmony_ci#else 9098c2ecf20Sopenharmony_ci#define SLABINFO_RIGHTS (0400) 9108c2ecf20Sopenharmony_ci#endif 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_cistatic void print_slabinfo_header(struct seq_file *m) 9138c2ecf20Sopenharmony_ci{ 9148c2ecf20Sopenharmony_ci /* 9158c2ecf20Sopenharmony_ci * Output format version, so at least we can change it 9168c2ecf20Sopenharmony_ci * without _too_ many complaints. 9178c2ecf20Sopenharmony_ci */ 9188c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_SLAB 9198c2ecf20Sopenharmony_ci seq_puts(m, "slabinfo - version: 2.1 (statistics)\n"); 9208c2ecf20Sopenharmony_ci#else 9218c2ecf20Sopenharmony_ci seq_puts(m, "slabinfo - version: 2.1\n"); 9228c2ecf20Sopenharmony_ci#endif 9238c2ecf20Sopenharmony_ci seq_puts(m, "# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>"); 9248c2ecf20Sopenharmony_ci seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>"); 9258c2ecf20Sopenharmony_ci seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); 9268c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_SLAB 9278c2ecf20Sopenharmony_ci seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> <error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow>"); 9288c2ecf20Sopenharmony_ci seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>"); 9298c2ecf20Sopenharmony_ci#endif 9308c2ecf20Sopenharmony_ci seq_putc(m, '\n'); 9318c2ecf20Sopenharmony_ci} 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_civoid *slab_start(struct seq_file *m, loff_t *pos) 9348c2ecf20Sopenharmony_ci{ 9358c2ecf20Sopenharmony_ci mutex_lock(&slab_mutex); 9368c2ecf20Sopenharmony_ci return seq_list_start(&slab_caches, *pos); 9378c2ecf20Sopenharmony_ci} 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_civoid *slab_next(struct seq_file *m, void *p, loff_t *pos) 9408c2ecf20Sopenharmony_ci{ 9418c2ecf20Sopenharmony_ci return seq_list_next(p, &slab_caches, pos); 9428c2ecf20Sopenharmony_ci} 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_civoid slab_stop(struct seq_file *m, void *p) 9458c2ecf20Sopenharmony_ci{ 9468c2ecf20Sopenharmony_ci mutex_unlock(&slab_mutex); 9478c2ecf20Sopenharmony_ci} 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_cistatic void cache_show(struct kmem_cache *s, struct seq_file *m) 9508c2ecf20Sopenharmony_ci{ 9518c2ecf20Sopenharmony_ci struct slabinfo sinfo; 9528c2ecf20Sopenharmony_ci 9538c2ecf20Sopenharmony_ci memset(&sinfo, 0, sizeof(sinfo)); 9548c2ecf20Sopenharmony_ci get_slabinfo(s, &sinfo); 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d", 9578c2ecf20Sopenharmony_ci s->name, sinfo.active_objs, sinfo.num_objs, s->size, 9588c2ecf20Sopenharmony_ci sinfo.objects_per_slab, (1 << sinfo.cache_order)); 9598c2ecf20Sopenharmony_ci 9608c2ecf20Sopenharmony_ci seq_printf(m, " : tunables %4u %4u %4u", 9618c2ecf20Sopenharmony_ci sinfo.limit, sinfo.batchcount, sinfo.shared); 9628c2ecf20Sopenharmony_ci seq_printf(m, " : slabdata %6lu %6lu %6lu", 9638c2ecf20Sopenharmony_ci sinfo.active_slabs, sinfo.num_slabs, sinfo.shared_avail); 9648c2ecf20Sopenharmony_ci slabinfo_show_stats(m, s); 9658c2ecf20Sopenharmony_ci seq_putc(m, '\n'); 9668c2ecf20Sopenharmony_ci} 9678c2ecf20Sopenharmony_ci 9688c2ecf20Sopenharmony_cistatic int slab_show(struct seq_file *m, void *p) 9698c2ecf20Sopenharmony_ci{ 9708c2ecf20Sopenharmony_ci struct kmem_cache *s = list_entry(p, struct kmem_cache, list); 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci if (p == slab_caches.next) 9738c2ecf20Sopenharmony_ci print_slabinfo_header(m); 9748c2ecf20Sopenharmony_ci cache_show(s, m); 9758c2ecf20Sopenharmony_ci return 0; 9768c2ecf20Sopenharmony_ci} 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_civoid dump_unreclaimable_slab(void) 9798c2ecf20Sopenharmony_ci{ 9808c2ecf20Sopenharmony_ci struct kmem_cache *s, *s2; 9818c2ecf20Sopenharmony_ci struct slabinfo sinfo; 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci /* 9848c2ecf20Sopenharmony_ci * Here acquiring slab_mutex is risky since we don't prefer to get 9858c2ecf20Sopenharmony_ci * sleep in oom path. But, without mutex hold, it may introduce a 9868c2ecf20Sopenharmony_ci * risk of crash. 9878c2ecf20Sopenharmony_ci * Use mutex_trylock to protect the list traverse, dump nothing 9888c2ecf20Sopenharmony_ci * without acquiring the mutex. 9898c2ecf20Sopenharmony_ci */ 9908c2ecf20Sopenharmony_ci if (!mutex_trylock(&slab_mutex)) { 9918c2ecf20Sopenharmony_ci pr_warn("excessive unreclaimable slab but cannot dump stats\n"); 9928c2ecf20Sopenharmony_ci return; 9938c2ecf20Sopenharmony_ci } 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci pr_info("Unreclaimable slab info:\n"); 9968c2ecf20Sopenharmony_ci pr_info("Name Used Total\n"); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci list_for_each_entry_safe(s, s2, &slab_caches, list) { 9998c2ecf20Sopenharmony_ci if (s->flags & SLAB_RECLAIM_ACCOUNT) 10008c2ecf20Sopenharmony_ci continue; 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci get_slabinfo(s, &sinfo); 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci if (sinfo.num_objs > 0) 10058c2ecf20Sopenharmony_ci pr_info("%-17s %10luKB %10luKB\n", s->name, 10068c2ecf20Sopenharmony_ci (sinfo.active_objs * s->size) / 1024, 10078c2ecf20Sopenharmony_ci (sinfo.num_objs * s->size) / 1024); 10088c2ecf20Sopenharmony_ci } 10098c2ecf20Sopenharmony_ci mutex_unlock(&slab_mutex); 10108c2ecf20Sopenharmony_ci} 10118c2ecf20Sopenharmony_ci 10128c2ecf20Sopenharmony_ci#if defined(CONFIG_MEMCG_KMEM) 10138c2ecf20Sopenharmony_ciint memcg_slab_show(struct seq_file *m, void *p) 10148c2ecf20Sopenharmony_ci{ 10158c2ecf20Sopenharmony_ci /* 10168c2ecf20Sopenharmony_ci * Deprecated. 10178c2ecf20Sopenharmony_ci * Please, take a look at tools/cgroup/slabinfo.py . 10188c2ecf20Sopenharmony_ci */ 10198c2ecf20Sopenharmony_ci return 0; 10208c2ecf20Sopenharmony_ci} 10218c2ecf20Sopenharmony_ci#endif 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci/* 10248c2ecf20Sopenharmony_ci * slabinfo_op - iterator that generates /proc/slabinfo 10258c2ecf20Sopenharmony_ci * 10268c2ecf20Sopenharmony_ci * Output layout: 10278c2ecf20Sopenharmony_ci * cache-name 10288c2ecf20Sopenharmony_ci * num-active-objs 10298c2ecf20Sopenharmony_ci * total-objs 10308c2ecf20Sopenharmony_ci * object size 10318c2ecf20Sopenharmony_ci * num-active-slabs 10328c2ecf20Sopenharmony_ci * total-slabs 10338c2ecf20Sopenharmony_ci * num-pages-per-slab 10348c2ecf20Sopenharmony_ci * + further values on SMP and with statistics enabled 10358c2ecf20Sopenharmony_ci */ 10368c2ecf20Sopenharmony_cistatic const struct seq_operations slabinfo_op = { 10378c2ecf20Sopenharmony_ci .start = slab_start, 10388c2ecf20Sopenharmony_ci .next = slab_next, 10398c2ecf20Sopenharmony_ci .stop = slab_stop, 10408c2ecf20Sopenharmony_ci .show = slab_show, 10418c2ecf20Sopenharmony_ci}; 10428c2ecf20Sopenharmony_ci 10438c2ecf20Sopenharmony_cistatic int slabinfo_open(struct inode *inode, struct file *file) 10448c2ecf20Sopenharmony_ci{ 10458c2ecf20Sopenharmony_ci return seq_open(file, &slabinfo_op); 10468c2ecf20Sopenharmony_ci} 10478c2ecf20Sopenharmony_ci 10488c2ecf20Sopenharmony_cistatic const struct proc_ops slabinfo_proc_ops = { 10498c2ecf20Sopenharmony_ci .proc_flags = PROC_ENTRY_PERMANENT, 10508c2ecf20Sopenharmony_ci .proc_open = slabinfo_open, 10518c2ecf20Sopenharmony_ci .proc_read = seq_read, 10528c2ecf20Sopenharmony_ci .proc_write = slabinfo_write, 10538c2ecf20Sopenharmony_ci .proc_lseek = seq_lseek, 10548c2ecf20Sopenharmony_ci .proc_release = seq_release, 10558c2ecf20Sopenharmony_ci}; 10568c2ecf20Sopenharmony_ci 10578c2ecf20Sopenharmony_cistatic int __init slab_proc_init(void) 10588c2ecf20Sopenharmony_ci{ 10598c2ecf20Sopenharmony_ci proc_create("slabinfo", SLABINFO_RIGHTS, NULL, &slabinfo_proc_ops); 10608c2ecf20Sopenharmony_ci return 0; 10618c2ecf20Sopenharmony_ci} 10628c2ecf20Sopenharmony_cimodule_init(slab_proc_init); 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_ci#endif /* CONFIG_SLAB || CONFIG_SLUB_DEBUG */ 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_cistatic __always_inline void *__do_krealloc(const void *p, size_t new_size, 10678c2ecf20Sopenharmony_ci gfp_t flags) 10688c2ecf20Sopenharmony_ci{ 10698c2ecf20Sopenharmony_ci void *ret; 10708c2ecf20Sopenharmony_ci size_t ks; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_ci ks = ksize(p); 10738c2ecf20Sopenharmony_ci 10748c2ecf20Sopenharmony_ci if (ks >= new_size) { 10758c2ecf20Sopenharmony_ci p = kasan_krealloc((void *)p, new_size, flags); 10768c2ecf20Sopenharmony_ci return (void *)p; 10778c2ecf20Sopenharmony_ci } 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci ret = kmalloc_track_caller(new_size, flags); 10808c2ecf20Sopenharmony_ci if (ret && p) 10818c2ecf20Sopenharmony_ci memcpy(ret, p, ks); 10828c2ecf20Sopenharmony_ci 10838c2ecf20Sopenharmony_ci return ret; 10848c2ecf20Sopenharmony_ci} 10858c2ecf20Sopenharmony_ci 10868c2ecf20Sopenharmony_ci/** 10878c2ecf20Sopenharmony_ci * krealloc - reallocate memory. The contents will remain unchanged. 10888c2ecf20Sopenharmony_ci * @p: object to reallocate memory for. 10898c2ecf20Sopenharmony_ci * @new_size: how many bytes of memory are required. 10908c2ecf20Sopenharmony_ci * @flags: the type of memory to allocate. 10918c2ecf20Sopenharmony_ci * 10928c2ecf20Sopenharmony_ci * The contents of the object pointed to are preserved up to the 10938c2ecf20Sopenharmony_ci * lesser of the new and old sizes. If @p is %NULL, krealloc() 10948c2ecf20Sopenharmony_ci * behaves exactly like kmalloc(). If @new_size is 0 and @p is not a 10958c2ecf20Sopenharmony_ci * %NULL pointer, the object pointed to is freed. 10968c2ecf20Sopenharmony_ci * 10978c2ecf20Sopenharmony_ci * Return: pointer to the allocated memory or %NULL in case of error 10988c2ecf20Sopenharmony_ci */ 10998c2ecf20Sopenharmony_civoid *krealloc(const void *p, size_t new_size, gfp_t flags) 11008c2ecf20Sopenharmony_ci{ 11018c2ecf20Sopenharmony_ci void *ret; 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_ci if (unlikely(!new_size)) { 11048c2ecf20Sopenharmony_ci kfree(p); 11058c2ecf20Sopenharmony_ci return ZERO_SIZE_PTR; 11068c2ecf20Sopenharmony_ci } 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_ci ret = __do_krealloc(p, new_size, flags); 11098c2ecf20Sopenharmony_ci if (ret && kasan_reset_tag(p) != kasan_reset_tag(ret)) 11108c2ecf20Sopenharmony_ci kfree(p); 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_ci return ret; 11138c2ecf20Sopenharmony_ci} 11148c2ecf20Sopenharmony_ciEXPORT_SYMBOL(krealloc); 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_ci/** 11178c2ecf20Sopenharmony_ci * kfree_sensitive - Clear sensitive information in memory before freeing 11188c2ecf20Sopenharmony_ci * @p: object to free memory of 11198c2ecf20Sopenharmony_ci * 11208c2ecf20Sopenharmony_ci * The memory of the object @p points to is zeroed before freed. 11218c2ecf20Sopenharmony_ci * If @p is %NULL, kfree_sensitive() does nothing. 11228c2ecf20Sopenharmony_ci * 11238c2ecf20Sopenharmony_ci * Note: this function zeroes the whole allocated buffer which can be a good 11248c2ecf20Sopenharmony_ci * deal bigger than the requested buffer size passed to kmalloc(). So be 11258c2ecf20Sopenharmony_ci * careful when using this function in performance sensitive code. 11268c2ecf20Sopenharmony_ci */ 11278c2ecf20Sopenharmony_civoid kfree_sensitive(const void *p) 11288c2ecf20Sopenharmony_ci{ 11298c2ecf20Sopenharmony_ci size_t ks; 11308c2ecf20Sopenharmony_ci void *mem = (void *)p; 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_ci ks = ksize(mem); 11338c2ecf20Sopenharmony_ci if (ks) 11348c2ecf20Sopenharmony_ci memzero_explicit(mem, ks); 11358c2ecf20Sopenharmony_ci kfree(mem); 11368c2ecf20Sopenharmony_ci} 11378c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kfree_sensitive); 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_ci/** 11408c2ecf20Sopenharmony_ci * ksize - get the actual amount of memory allocated for a given object 11418c2ecf20Sopenharmony_ci * @objp: Pointer to the object 11428c2ecf20Sopenharmony_ci * 11438c2ecf20Sopenharmony_ci * kmalloc may internally round up allocations and return more memory 11448c2ecf20Sopenharmony_ci * than requested. ksize() can be used to determine the actual amount of 11458c2ecf20Sopenharmony_ci * memory allocated. The caller may use this additional memory, even though 11468c2ecf20Sopenharmony_ci * a smaller amount of memory was initially specified with the kmalloc call. 11478c2ecf20Sopenharmony_ci * The caller must guarantee that objp points to a valid object previously 11488c2ecf20Sopenharmony_ci * allocated with either kmalloc() or kmem_cache_alloc(). The object 11498c2ecf20Sopenharmony_ci * must not be freed during the duration of the call. 11508c2ecf20Sopenharmony_ci * 11518c2ecf20Sopenharmony_ci * Return: size of the actual memory used by @objp in bytes 11528c2ecf20Sopenharmony_ci */ 11538c2ecf20Sopenharmony_cisize_t ksize(const void *objp) 11548c2ecf20Sopenharmony_ci{ 11558c2ecf20Sopenharmony_ci size_t size; 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci /* 11588c2ecf20Sopenharmony_ci * We need to check that the pointed to object is valid, and only then 11598c2ecf20Sopenharmony_ci * unpoison the shadow memory below. We use __kasan_check_read(), to 11608c2ecf20Sopenharmony_ci * generate a more useful report at the time ksize() is called (rather 11618c2ecf20Sopenharmony_ci * than later where behaviour is undefined due to potential 11628c2ecf20Sopenharmony_ci * use-after-free or double-free). 11638c2ecf20Sopenharmony_ci * 11648c2ecf20Sopenharmony_ci * If the pointed to memory is invalid we return 0, to avoid users of 11658c2ecf20Sopenharmony_ci * ksize() writing to and potentially corrupting the memory region. 11668c2ecf20Sopenharmony_ci * 11678c2ecf20Sopenharmony_ci * We want to perform the check before __ksize(), to avoid potentially 11688c2ecf20Sopenharmony_ci * crashing in __ksize() due to accessing invalid metadata. 11698c2ecf20Sopenharmony_ci */ 11708c2ecf20Sopenharmony_ci if (unlikely(ZERO_OR_NULL_PTR(objp)) || !__kasan_check_read(objp, 1)) 11718c2ecf20Sopenharmony_ci return 0; 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_ci size = __ksize(objp); 11748c2ecf20Sopenharmony_ci /* 11758c2ecf20Sopenharmony_ci * We assume that ksize callers could use whole allocated area, 11768c2ecf20Sopenharmony_ci * so we need to unpoison this area. 11778c2ecf20Sopenharmony_ci */ 11788c2ecf20Sopenharmony_ci kasan_unpoison_shadow(objp, size); 11798c2ecf20Sopenharmony_ci return size; 11808c2ecf20Sopenharmony_ci} 11818c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ksize); 11828c2ecf20Sopenharmony_ci 11838c2ecf20Sopenharmony_ci/* Tracepoints definitions. */ 11848c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(kmalloc); 11858c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc); 11868c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(kmalloc_node); 11878c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(kmem_cache_alloc_node); 11888c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(kfree); 11898c2ecf20Sopenharmony_ciEXPORT_TRACEPOINT_SYMBOL(kmem_cache_free); 11908c2ecf20Sopenharmony_ci 11918c2ecf20Sopenharmony_ciint should_failslab(struct kmem_cache *s, gfp_t gfpflags) 11928c2ecf20Sopenharmony_ci{ 11938c2ecf20Sopenharmony_ci if (__should_failslab(s, gfpflags)) 11948c2ecf20Sopenharmony_ci return -ENOMEM; 11958c2ecf20Sopenharmony_ci return 0; 11968c2ecf20Sopenharmony_ci} 11978c2ecf20Sopenharmony_ciALLOW_ERROR_INJECTION(should_failslab, ERRNO); 1198