]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/slub.c
page allocator: get the pageblock migratetype without disabling interrupts
[karo-tx-linux.git] / mm / slub.c
index c1815a63807a3dcf2651ae01d5173714d7a7a9cb..30354bfeb43d5b093669fb0ef62b213e0c3991f2 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -20,6 +20,7 @@
 #include <linux/kmemtrace.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
+#include <linux/kmemleak.h>
 #include <linux/mempolicy.h>
 #include <linux/ctype.h>
 #include <linux/debugobjects.h>
  * Set of flags that will prevent slab merging
  */
 #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
-               SLAB_TRACE | SLAB_DESTROY_BY_RCU)
+               SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE)
 
 #define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
                SLAB_CACHE_DMA)
@@ -177,6 +178,12 @@ static enum {
        SYSFS           /* Sysfs up */
 } slab_state = DOWN;
 
+/*
+ * The slab allocator is initialized with interrupts disabled. Therefore, make
+ * sure early boot allocations don't accidentally enable interrupts.
+ */
+static gfp_t slab_gfp_mask __read_mostly = SLAB_GFP_BOOT_MASK;
+
 /* A list of all slab caches on the system */
 static DECLARE_RWSEM(slub_lock);
 static LIST_HEAD(slab_caches);
@@ -1594,6 +1601,8 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        unsigned long flags;
        unsigned int objsize;
 
+       gfpflags &= slab_gfp_mask;
+
        lockdep_trace_alloc(gfpflags);
        might_sleep_if(gfpflags & __GFP_WAIT);
 
@@ -1617,6 +1626,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
        if (unlikely((gfpflags & __GFP_ZERO) && object))
                memset(object, 0, objsize);
 
+       kmemleak_alloc_recursive(object, objsize, 1, s->flags, gfpflags);
        return object;
 }
 
@@ -1746,6 +1756,7 @@ static __always_inline void slab_free(struct kmem_cache *s,
        struct kmem_cache_cpu *c;
        unsigned long flags;
 
+       kmemleak_free_recursive(x, s->flags);
        local_irq_save(flags);
        c = get_cpu_slab(s, smp_processor_id());
        debug_check_no_locks_freed(object, c->objsize);
@@ -3101,6 +3112,14 @@ void __init kmem_cache_init(void)
                nr_cpu_ids, nr_node_ids);
 }
 
+void __init kmem_cache_init_late(void)
+{
+       /*
+        * Interrupts are enabled now so all GFP allocations are safe.
+        */
+       slab_gfp_mask = __GFP_BITS_MASK;
+}
+
 /*
  * Find a mergeable slab cache
  */