]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/slab.c
mm/vmscan.c: fix trying to reclaim unevictable LRU page
[mirror_ubuntu-bionic-kernel.git] / mm / slab.c
index 4e51ef954026bd15e5bef41167459970976faab0..3faf3f217fae9dbaa49348d785bd6f573bcfbef1 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -563,14 +563,6 @@ static void start_cpu_timer(int cpu)
 
 static void init_arraycache(struct array_cache *ac, int limit, int batch)
 {
-       /*
-        * The array_cache structures contain pointers to free object.
-        * However, when such objects are allocated or transferred to another
-        * cache the pointers are not cleared and they could be counted as
-        * valid references during a kmemleak scan. Therefore, kmemleak must
-        * not scan such objects.
-        */
-       kmemleak_no_scan(ac);
        if (ac) {
                ac->avail = 0;
                ac->limit = limit;
@@ -586,6 +578,14 @@ static struct array_cache *alloc_arraycache(int node, int entries,
        struct array_cache *ac = NULL;
 
        ac = kmalloc_node(memsize, gfp, node);
+       /*
+        * The array_cache structures contain pointers to free object.
+        * However, when such objects are allocated or transferred to another
+        * cache the pointers are not cleared and they could be counted as
+        * valid references during a kmemleak scan. Therefore, kmemleak must
+        * not scan such objects.
+        */
+       kmemleak_no_scan(ac);
        init_arraycache(ac, entries, batchcount);
        return ac;
 }
@@ -679,8 +679,11 @@ static struct alien_cache *__alloc_alien_cache(int node, int entries,
        struct alien_cache *alc = NULL;
 
        alc = kmalloc_node(memsize, gfp, node);
-       init_arraycache(&alc->ac, entries, batch);
-       spin_lock_init(&alc->lock);
+       if (alc) {
+               kmemleak_no_scan(alc);
+               init_arraycache(&alc->ac, entries, batch);
+               spin_lock_init(&alc->lock);
+       }
        return alc;
 }
 
@@ -1283,6 +1286,7 @@ void __init kmem_cache_init(void)
                                  nr_node_ids * sizeof(struct kmem_cache_node *),
                                  SLAB_HWCACHE_ALIGN);
        list_add(&kmem_cache->list, &slab_caches);
+       memcg_link_cache(kmem_cache);
        slab_state = PARTIAL;
 
        /*
@@ -2126,6 +2130,8 @@ done:
        cachep->allocflags = __GFP_COMP;
        if (flags & SLAB_CACHE_DMA)
                cachep->allocflags |= GFP_DMA;
+       if (flags & SLAB_CACHE_DMA32)
+               cachep->allocflags |= GFP_DMA32;
        if (flags & SLAB_RECLAIM_ACCOUNT)
                cachep->allocflags |= __GFP_RECLAIMABLE;
        cachep->size = size;
@@ -3665,6 +3671,8 @@ __do_kmalloc_node(size_t size, gfp_t flags, int node, unsigned long caller)
        struct kmem_cache *cachep;
        void *ret;
 
+       if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
+               return NULL;
        cachep = kmalloc_slab(size, flags);
        if (unlikely(ZERO_OR_NULL_PTR(cachep)))
                return cachep;
@@ -3700,6 +3708,8 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
        struct kmem_cache *cachep;
        void *ret;
 
+       if (unlikely(size > KMALLOC_MAX_CACHE_SIZE))
+               return NULL;
        cachep = kmalloc_slab(size, flags);
        if (unlikely(ZERO_OR_NULL_PTR(cachep)))
                return cachep;
@@ -4076,7 +4086,8 @@ next:
        next_reap_node();
 out:
        /* Set up the next iteration */
-       schedule_delayed_work(work, round_jiffies_relative(REAPTIMEOUT_AC));
+       schedule_delayed_work_on(smp_processor_id(), work,
+                               round_jiffies_relative(REAPTIMEOUT_AC));
 }
 
 void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
@@ -4285,7 +4296,8 @@ static void show_symbol(struct seq_file *m, unsigned long address)
 
 static int leaks_show(struct seq_file *m, void *p)
 {
-       struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list);
+       struct kmem_cache *cachep = list_entry(p, struct kmem_cache,
+                                              root_caches_node);
        struct page *page;
        struct kmem_cache_node *n;
        const char *name;
@@ -4305,8 +4317,12 @@ static int leaks_show(struct seq_file *m, void *p)
         * whole processing.
         */
        do {
-               set_store_user_clean(cachep);
                drain_cpu_caches(cachep);
+               /*
+                * drain_cpu_caches() could make kmemleak_object and
+                * debug_objects_cache dirty, so reset afterwards.
+                */
+               set_store_user_clean(cachep);
 
                x[1] = 0;