]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - mm/slub.c
Merge tag 'mlx5-fixes-2019-10-18' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / mm / slub.c
index 3d63ae320d31bb07a667ead9ee90768d234c155d..b25c807a111f43fa77cd1ab3b10218f9323627e2 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2671,6 +2671,17 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
        return p;
 }
 
+/*
+ * If the object has been wiped upon free, make sure it's fully initialized by
+ * zeroing out freelist pointer.
+ */
+static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s,
+                                                  void *obj)
+{
+       if (unlikely(slab_want_init_on_free(s)) && obj)
+               memset((void *)((char *)obj + s->offset), 0, sizeof(void *));
+}
+
 /*
  * Inlined fastpath so that allocation functions (kmalloc, kmem_cache_alloc)
  * have the fastpath folded into their functions. So no function call
@@ -2759,12 +2770,8 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
                prefetch_freepointer(s, next_object);
                stat(s, ALLOC_FASTPATH);
        }
-       /*
-        * If the object has been wiped upon free, make sure it's fully
-        * initialized by zeroing out freelist pointer.
-        */
-       if (unlikely(slab_want_init_on_free(s)) && object)
-               memset(object + s->offset, 0, sizeof(void *));
+
+       maybe_wipe_obj_freeptr(s, object);
 
        if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
                memset(object, 0, s->object_size);
@@ -3178,10 +3185,13 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
                                goto error;
 
                        c = this_cpu_ptr(s->cpu_slab);
+                       maybe_wipe_obj_freeptr(s, p[i]);
+
                        continue; /* goto for-loop */
                }
                c->freelist = get_freepointer(s, object);
                p[i] = object;
+               maybe_wipe_obj_freeptr(s, p[i]);
        }
        c->tid = next_tid(c->tid);
        local_irq_enable();
@@ -4846,7 +4856,17 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                }
        }
 
-       get_online_mems();
+       /*
+        * It is impossible to take "mem_hotplug_lock" here with "kernfs_mutex"
+        * already held which will conflict with an existing lock order:
+        *
+        * mem_hotplug_lock->slab_mutex->kernfs_mutex
+        *
+        * We don't really need mem_hotplug_lock (to hold off
+        * slab_mem_going_offline_callback) here because slab's memory hot
+        * unplug code doesn't destroy the kmem_cache->node[] data.
+        */
+
 #ifdef CONFIG_SLUB_DEBUG
        if (flags & SO_ALL) {
                struct kmem_cache_node *n;
@@ -4887,7 +4907,6 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                        x += sprintf(buf + x, " N%d=%lu",
                                        node, nodes[node]);
 #endif
-       put_online_mems();
        kfree(nodes);
        return x + sprintf(buf + x, "\n");
 }