mm: Account for a THP NUMA hinting update as one PTE update
[linux-3.10.git] / mm / slub.c
index 8b1b99d..57707f0 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include "slab.h"
 #include <linux/proc_fs.h>
+#include <linux/notifier.h>
 #include <linux/seq_file.h>
 #include <linux/kmemcheck.h>
 #include <linux/cpu.h>
@@ -562,7 +563,7 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...)
        printk(KERN_ERR "----------------------------------------"
                        "-------------------------------------\n\n");
 
-       add_taint(TAINT_BAD_PAGE);
+       add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
 }
 
 static void slab_fix(struct kmem_cache *s, char *fmt, ...)
@@ -1408,7 +1409,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
        __ClearPageSlab(page);
 
        memcg_release_pages(s, order);
-       reset_page_mapcount(page);
+       page_mapcount_reset(page);
        if (current->reclaim_state)
                current->reclaim_state->reclaimed_slab += pages;
        __free_memcg_kmem_pages(page, order);
@@ -2332,13 +2333,18 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
 
        s = memcg_kmem_get_cache(s, gfpflags);
 redo:
-
        /*
         * Must read kmem_cache cpu data via this cpu ptr. Preemption is
         * enabled. We may switch back and forth between cpus while
         * reading from one cpu area. That does not matter as long
         * as we end up on the original cpu again when doing the cmpxchg.
+        *
+        * Preemption is disabled for the retrieval of the tid because that
+        * must occur from the current processor. We cannot allow rescheduling
+        * on a different processor between the determination of the pointer
+        * and the retrieval of the tid.
         */
+       preempt_disable();
        c = __this_cpu_ptr(s->cpu_slab);
 
        /*
@@ -2348,7 +2354,7 @@ redo:
         * linked list in between.
         */
        tid = c->tid;
-       barrier();
+       preempt_enable();
 
        object = c->freelist;
        page = c->page;
@@ -2595,10 +2601,11 @@ redo:
         * data is retrieved via this pointer. If we are on the same cpu
         * during the cmpxchg then the free will succedd.
         */
+       preempt_disable();
        c = __this_cpu_ptr(s->cpu_slab);
 
        tid = c->tid;
-       barrier();
+       preempt_enable();
 
        if (likely(page == c->page)) {
                set_freepointer(s, object, c->freelist);
@@ -3419,7 +3426,6 @@ int kmem_cache_shrink(struct kmem_cache *s)
 }
 EXPORT_SYMBOL(kmem_cache_shrink);
 
-#if defined(CONFIG_MEMORY_HOTPLUG)
 static int slab_mem_going_offline_callback(void *arg)
 {
        struct kmem_cache *s;
@@ -3534,7 +3540,10 @@ static int slab_memory_callback(struct notifier_block *self,
        return ret;
 }
 
-#endif /* CONFIG_MEMORY_HOTPLUG */
+static struct notifier_block slab_memory_callback_nb = {
+       .notifier_call = slab_memory_callback,
+       .priority = SLAB_CALLBACK_PRI,
+};
 
 /********************************************************************
  *                     Basic setup of slabs
@@ -3591,7 +3600,7 @@ void __init kmem_cache_init(void)
        create_boot_cache(kmem_cache_node, "kmem_cache_node",
                sizeof(struct kmem_cache_node), SLAB_HWCACHE_ALIGN);
 
-       hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI);
+       register_hotmemory_notifier(&slab_memory_callback_nb);
 
        /* Able to allocate the per node structures */
        slab_state = PARTIAL;