]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/slab_common.c
UBUNTU: link-to-tracker: update tracking bug
[mirror_ubuntu-bionic-kernel.git] / mm / slab_common.c
index 80164599ca5d1921d2c4b8f773f2a7c8b019cce7..c8cb36774ba1802c925c0b65609a15d7241d5aee 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Slab allocator functions that are independent of the allocator strategy
  *
@@ -43,7 +44,7 @@ static DECLARE_WORK(slab_caches_to_rcu_destroy_work,
                SLAB_FAILSLAB | SLAB_KASAN)
 
 #define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \
-                        SLAB_NOTRACK | SLAB_ACCOUNT)
+                        SLAB_ACCOUNT)
 
 /*
  * Merge control. If this is set then no merging of slab caches will occur.
@@ -290,7 +291,7 @@ int slab_unmergeable(struct kmem_cache *s)
 }
 
 struct kmem_cache *find_mergeable(size_t size, size_t align,
-               unsigned long flags, const char *name, void (*ctor)(void *))
+               slab_flags_t flags, const char *name, void (*ctor)(void *))
 {
        struct kmem_cache *s;
 
@@ -340,7 +341,7 @@ struct kmem_cache *find_mergeable(size_t size, size_t align,
  * Figure out what the alignment of the objects will be given a set of
  * flags, a user specified alignment and the size of the objects.
  */
-unsigned long calculate_alignment(unsigned long flags,
+unsigned long calculate_alignment(slab_flags_t flags,
                unsigned long align, unsigned long size)
 {
        /*
@@ -365,7 +366,7 @@ unsigned long calculate_alignment(unsigned long flags,
 
 static struct kmem_cache *create_cache(const char *name,
                size_t object_size, size_t size, size_t align,
-               unsigned long flags, void (*ctor)(void *),
+               slab_flags_t flags, void (*ctor)(void *),
                struct mem_cgroup *memcg, struct kmem_cache *root_cache)
 {
        struct kmem_cache *s;
@@ -430,7 +431,7 @@ out_free_cache:
  */
 struct kmem_cache *
 kmem_cache_create(const char *name, size_t size, size_t align,
-                 unsigned long flags, void (*ctor)(void *))
+                 slab_flags_t flags, void (*ctor)(void *))
 {
        struct kmem_cache *s = NULL;
        const char *cache_name;
@@ -878,7 +879,7 @@ bool slab_is_available(void)
 #ifndef CONFIG_SLOB
 /* Create a cache during boot when no slab services are available yet */
 void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t size,
-               unsigned long flags)
+               slab_flags_t flags)
 {
        int err;
 
@@ -898,7 +899,7 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name, size_t siz
 }
 
 struct kmem_cache *__init create_kmalloc_cache(const char *name, size_t size,
-                               unsigned long flags)
+                               slab_flags_t flags)
 {
        struct kmem_cache *s = kmem_cache_zalloc(kmem_cache, GFP_NOWAIT);
 
@@ -1056,7 +1057,7 @@ void __init setup_kmalloc_cache_index_table(void)
        }
 }
 
-static void __init new_kmalloc_cache(int idx, unsigned long flags)
+static void __init new_kmalloc_cache(int idx, slab_flags_t flags)
 {
        kmalloc_caches[idx] = create_kmalloc_cache(kmalloc_info[idx].name,
                                        kmalloc_info[idx].size, flags);
@@ -1067,7 +1068,7 @@ static void __init new_kmalloc_cache(int idx, unsigned long flags)
  * may already have been created because they were needed to
  * enable allocations for slab creation.
  */
-void __init create_kmalloc_caches(unsigned long flags)
+void __init create_kmalloc_caches(slab_flags_t flags)
 {
        int i;
 
@@ -1183,8 +1184,7 @@ void cache_random_seq_destroy(struct kmem_cache *cachep)
 }
 #endif /* CONFIG_SLAB_FREELIST_RANDOM */
 
-#ifdef CONFIG_SLABINFO
-
+#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB_DEBUG)
 #ifdef CONFIG_SLAB
 #define SLABINFO_RIGHTS (S_IWUSR | S_IRUSR)
 #else
@@ -1280,7 +1280,41 @@ static int slab_show(struct seq_file *m, void *p)
        return 0;
 }
 
-#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
+void dump_unreclaimable_slab(void)
+{
+       struct kmem_cache *s, *s2;
+       struct slabinfo sinfo;
+
+       /*
+        * Here acquiring slab_mutex is risky since we don't prefer to get
+        * sleep in oom path. But, without mutex hold, it may introduce a
+        * risk of crash.
+        * Use mutex_trylock to protect the list traverse, dump nothing
+        * without acquiring the mutex.
+        */
+       if (!mutex_trylock(&slab_mutex)) {
+               pr_warn("excessive unreclaimable slab but cannot dump stats\n");
+               return;
+       }
+
+       pr_info("Unreclaimable slab info:\n");
+       pr_info("Name                      Used          Total\n");
+
+       list_for_each_entry_safe(s, s2, &slab_caches, list) {
+               if (!is_root_cache(s) || (s->flags & SLAB_RECLAIM_ACCOUNT))
+                       continue;
+
+               get_slabinfo(s, &sinfo);
+
+               if (sinfo.num_objs > 0)
+                       pr_info("%-17s %10luKB %10luKB\n", cache_name(s),
+                               (sinfo.active_objs * s->size) / 1024,
+                               (sinfo.num_objs * s->size) / 1024);
+       }
+       mutex_unlock(&slab_mutex);
+}
+
+#if defined(CONFIG_MEMCG)
 void *memcg_slab_start(struct seq_file *m, loff_t *pos)
 {
        struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
@@ -1354,7 +1388,7 @@ static int __init slab_proc_init(void)
        return 0;
 }
 module_init(slab_proc_init);
-#endif /* CONFIG_SLABINFO */
+#endif /* CONFIG_SLAB || CONFIG_SLUB_DEBUG */
 
 static __always_inline void *__do_krealloc(const void *p, size_t new_size,
                                           gfp_t flags)