tools headers UAPI: Sync linux/prctl.h with the kernel sources
[linux-2.6-microblaze.git] / mm / slub.c
index e26c274..feda53a 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3,7 +3,7 @@
  * SLUB: A slab allocator that limits cache line use instead of queuing
  * objects in per cpu and per node lists.
  *
- * The allocator synchronizes using per slab locks or atomic operatios
+ * The allocator synchronizes using per slab locks or atomic operations
  * and only uses a centralized lock to manage a pool of partial slabs.
  *
  * (C) 2007 SGI, Christoph Lameter
@@ -160,7 +160,7 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s)
 #undef SLUB_DEBUG_CMPXCHG
 
 /*
- * Mininum number of partial slabs. These will be left on the partial
+ * Minimum number of partial slabs. These will be left on the partial
  * lists even if they are empty. kmem_cache_shrink may reclaim them.
  */
 #define MIN_PARTIAL 5
@@ -624,7 +624,7 @@ static void print_track(const char *s, struct track *t, unsigned long pr_time)
        if (!t->addr)
                return;
 
-       pr_err("INFO: %s in %pS age=%lu cpu=%u pid=%d\n",
+       pr_err("%s in %pS age=%lu cpu=%u pid=%d\n",
               s, (void *)t->addr, pr_time - t->when, t->cpu, t->pid);
 #ifdef CONFIG_STACKTRACE
        {
@@ -650,8 +650,9 @@ void print_tracking(struct kmem_cache *s, void *object)
 
 static void print_page_info(struct page *page)
 {
-       pr_err("INFO: Slab 0x%p objects=%u used=%u fp=0x%p flags=0x%04lx\n",
-              page, page->objects, page->inuse, page->freelist, page->flags);
+       pr_err("Slab 0x%p objects=%u used=%u fp=0x%p flags=%#lx(%pGp)\n",
+              page, page->objects, page->inuse, page->freelist,
+              page->flags, &page->flags);
 
 }
 
@@ -706,7 +707,7 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
 
        print_page_info(page);
 
-       pr_err("INFO: Object 0x%p @offset=%tu fp=0x%p\n\n",
+       pr_err("Object 0x%p @offset=%tu fp=0x%p\n\n",
               p, p - addr, get_freepointer(s, p));
 
        if (s->flags & SLAB_RED_ZONE)
@@ -799,7 +800,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
                end--;
 
        slab_bug(s, "%s overwritten", what);
-       pr_err("INFO: 0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
+       pr_err("0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
                                        fault, end - 1, fault - addr,
                                        fault[0], value);
        print_trailer(s, page, object);
@@ -832,7 +833,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
  *
  *     A. Free pointer (if we cannot overwrite object on free)
  *     B. Tracking data for SLAB_STORE_USER
- *     C. Padding to reach required alignment boundary or at mininum
+ *     C. Padding to reach required alignment boundary or at minimum
  *             one word if debugging is on to be able to detect writes
  *             before the word boundary.
  *
@@ -1532,7 +1533,8 @@ static __always_inline void kfree_hook(void *x)
        kasan_kfree_large(x);
 }
 
-static __always_inline bool slab_free_hook(struct kmem_cache *s, void *x)
+static __always_inline bool slab_free_hook(struct kmem_cache *s,
+                                               void *x, bool init)
 {
        kmemleak_free_recursive(x, s->flags);
 
@@ -1558,8 +1560,25 @@ static __always_inline bool slab_free_hook(struct kmem_cache *s, void *x)
                __kcsan_check_access(x, s->object_size,
                                     KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT);
 
-       /* KASAN might put x into memory quarantine, delaying its reuse */
-       return kasan_slab_free(s, x);
+       /*
+        * As memory initialization might be integrated into KASAN,
+        * kasan_slab_free and initialization memset's must be
+        * kept together to avoid discrepancies in behavior.
+        *
+        * The initialization memset's clear the object and the metadata,
+        * but don't touch the SLAB redzone.
+        */
+       if (init) {
+               int rsize;
+
+               if (!kasan_has_integrated_init())
+                       memset(kasan_reset_tag(x), 0, s->object_size);
+               rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad : 0;
+               memset((char *)kasan_reset_tag(x) + s->inuse, 0,
+                      s->size - s->inuse - rsize);
+       }
+       /* KASAN might put x into memory quarantine, delaying its reuse. */
+       return kasan_slab_free(s, x, init);
 }
 
 static inline bool slab_free_freelist_hook(struct kmem_cache *s,
@@ -1569,10 +1588,9 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
        void *object;
        void *next = *head;
        void *old_tail = *tail ? *tail : *head;
-       int rsize;
 
        if (is_kfence_address(next)) {
-               slab_free_hook(s, next);
+               slab_free_hook(s, next, false);
                return true;
        }
 
@@ -1584,20 +1602,8 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
                object = next;
                next = get_freepointer(s, object);
 
-               if (slab_want_init_on_free(s)) {
-                       /*
-                        * Clear the object and the metadata, but don't touch
-                        * the redzone.
-                        */
-                       memset(kasan_reset_tag(object), 0, s->object_size);
-                       rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad
-                                                          : 0;
-                       memset((char *)kasan_reset_tag(object) + s->inuse, 0,
-                              s->size - s->inuse - rsize);
-
-               }
                /* If object's reuse doesn't have to be delayed */
-               if (!slab_free_hook(s, object)) {
+               if (!slab_free_hook(s, object, slab_want_init_on_free(s))) {
                        /* Move object to the new freelist */
                        set_freepointer(s, object, *head);
                        *head = object;
@@ -1993,7 +1999,7 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
 
                t = acquire_slab(s, n, page, object == NULL, &objects);
                if (!t)
-                       continue; /* cmpxchg raced */
+                       break;
 
                available += objects;
                if (!object) {
@@ -2822,6 +2828,7 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
        struct page *page;
        unsigned long tid;
        struct obj_cgroup *objcg = NULL;
+       bool init = false;
 
        s = slab_pre_alloc_hook(s, &objcg, 1, gfpflags);
        if (!s)
@@ -2899,12 +2906,10 @@ redo:
        }
 
        maybe_wipe_obj_freeptr(s, object);
-
-       if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
-               memset(kasan_reset_tag(object), 0, s->object_size);
+       init = slab_want_init_on_alloc(gfpflags, s);
 
 out:
-       slab_post_alloc_hook(s, objcg, gfpflags, 1, &object);
+       slab_post_alloc_hook(s, objcg, gfpflags, 1, &object, init);
 
        return object;
 }
@@ -3236,7 +3241,7 @@ int build_detached_freelist(struct kmem_cache *s, size_t size,
        }
 
        if (is_kfence_address(object)) {
-               slab_free_hook(df->s, object);
+               slab_free_hook(df->s, object, false);
                __kfence_free(object);
                p[size] = NULL; /* mark object processed */
                return size;
@@ -3356,20 +3361,16 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
        c->tid = next_tid(c->tid);
        local_irq_enable();
 
-       /* Clear memory outside IRQ disabled fastpath loop */
-       if (unlikely(slab_want_init_on_alloc(flags, s))) {
-               int j;
-
-               for (j = 0; j < i; j++)
-                       memset(kasan_reset_tag(p[j]), 0, s->object_size);
-       }
-
-       /* memcg and kmem_cache debug support */
-       slab_post_alloc_hook(s, objcg, flags, size, p);
+       /*
+        * memcg and kmem_cache debug support and memory initialization.
+        * Done outside of the IRQ disabled fastpath loop.
+        */
+       slab_post_alloc_hook(s, objcg, flags, size, p,
+                               slab_want_init_on_alloc(flags, s));
        return i;
 error:
        local_irq_enable();
-       slab_post_alloc_hook(s, objcg, flags, i, p);
+       slab_post_alloc_hook(s, objcg, flags, i, p, false);
        __kmem_cache_free_bulk(s, i, p);
        return 0;
 }
@@ -3390,7 +3391,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_bulk);
  */
 
 /*
- * Mininum / Maximum order of slab pages. This influences locking overhead
+ * Minimum / Maximum order of slab pages. This influences locking overhead
  * and slab fragmentation. A higher order reduces the number of partial slabs
  * and increases the number of allocations possible without having to
  * take the list_lock.
@@ -3421,7 +3422,7 @@ static unsigned int slub_min_objects;
  *
  * Higher order allocations also allow the placement of more objects in a
  * slab and thereby reduce object handling overhead. If the user has
- * requested a higher mininum order then we start with that one instead of
+ * requested a higher minimum order then we start with that one instead of
  * the smallest order which will fit the object.
  */
 static inline unsigned int slab_order(unsigned int size,
@@ -3579,7 +3580,7 @@ static void early_kmem_cache_node_alloc(int node)
        init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
        init_tracking(kmem_cache_node, n);
 #endif
-       n = kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL);
+       n = kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL, false);
        page->freelist = get_freepointer(kmem_cache_node, n);
        page->inuse = 1;
        page->frozen = 0;
@@ -3827,6 +3828,15 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 
 static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags)
 {
+#ifdef CONFIG_SLUB_DEBUG
+       /*
+        * If no slub_debug was enabled globally, the static key is not yet
+        * enabled by setup_slub_debug(). Enable it if the cache is being
+        * created with any of the debugging flags passed explicitly.
+        */
+       if (flags & SLAB_DEBUG_FLAGS)
+               static_branch_enable(&slub_debug_enabled);
+#endif
        s->flags = kmem_cache_flags(s->size, flags, s->name);
 #ifdef CONFIG_SLAB_FREELIST_HARDENED
        s->random = get_random_long();
@@ -3898,7 +3908,7 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page,
        for_each_object(p, s, addr, page->objects) {
 
                if (!test_bit(__obj_to_index(s, addr, p), map)) {
-                       pr_err("INFO: Object 0x%p @offset=%tu\n", p, p - addr);
+                       pr_err("Object 0x%p @offset=%tu\n", p, p - addr);
                        print_tracking(s, p);
                }
        }
@@ -3963,6 +3973,7 @@ int __kmem_cache_shutdown(struct kmem_cache *s)
        return 0;
 }
 
+#ifdef CONFIG_PRINTK
 void kmem_obj_info(struct kmem_obj_info *kpp, void *object, struct page *page)
 {
        void *base;
@@ -4002,6 +4013,7 @@ void kmem_obj_info(struct kmem_obj_info *kpp, void *object, struct page *page)
 #endif
 #endif
 }
+#endif
 
 /********************************************************************
  *             Kmalloc subsystem