page_poison: play nicely with KASAN
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / mm / slab.c
index 04dec48c3ed7a12af3fef4958e928d0ddc31b64e..f4658468b23e11a37a001d8b9d41ffc83946c823 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * linux/mm/slab.c
  * Written by Mark Hemment, 1996/97.
 #include       <linux/rtmutex.h>
 #include       <linux/reciprocal_div.h>
 #include       <linux/debugobjects.h>
-#include       <linux/kmemcheck.h>
 #include       <linux/memory.h>
 #include       <linux/prefetch.h>
 #include       <linux/sched/task_stack.h>
@@ -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;
 
        /*
@@ -1412,7 +1416,7 @@ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
                flags |= __GFP_RECLAIMABLE;
 
-       page = __alloc_pages_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder);
+       page = __alloc_pages_node(nodeid, flags, cachep->gfporder);
        if (!page) {
                slab_out_of_memory(cachep, flags, nodeid);
                return NULL;
@@ -1434,15 +1438,6 @@ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
        if (sk_memalloc_socks() && page_is_pfmemalloc(page))
                SetPageSlabPfmemalloc(page);
 
-       if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
-               kmemcheck_alloc_shadow(page, cachep->gfporder, flags, nodeid);
-
-               if (cachep->ctor)
-                       kmemcheck_mark_uninitialized_pages(page, nr_pages);
-               else
-                       kmemcheck_mark_unallocated_pages(page, nr_pages);
-       }
-
        return page;
 }
 
@@ -1454,8 +1449,6 @@ static void kmem_freepages(struct kmem_cache *cachep, struct page *page)
        int order = cachep->gfporder;
        unsigned long nr_freed = (1 << order);
 
-       kmemcheck_free_shadow(page, order);
-
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
                mod_lruvec_page_state(page, NR_SLAB_RECLAIMABLE, -nr_freed);
        else
@@ -3515,8 +3508,6 @@ void ___cache_free(struct kmem_cache *cachep, void *objp,
        kmemleak_free_recursive(objp, cachep->flags);
        objp = cache_free_debugcheck(cachep, objp, caller);
 
-       kmemcheck_slab_free(cachep, objp, cachep->object_size);
-
        /*
         * Skip calling cache_free_alien() when the platform is not numa.
         * This will avoid cache misses that happen while accessing slabp (which
@@ -3682,6 +3673,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;
@@ -3717,6 +3710,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;
@@ -4093,7 +4088,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));
 }
 
 #ifdef CONFIG_SLABINFO