]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - mm/slub.c
powerpc: Fix context switch DSCR on POWER8
[linux-imx.git] / mm / slub.c
index 54cc4d544f3cb47fbe518888ffc5abf873efc341..2b02d666bf63aee43e60e17fab4544e31730383c 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>
@@ -122,6 +123,15 @@ static inline int kmem_cache_debug(struct kmem_cache *s)
 #endif
 }
 
+static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s)
+{
+#ifdef CONFIG_SLUB_CPU_PARTIAL
+       return !kmem_cache_debug(s);
+#else
+       return false;
+#endif
+}
+
 /*
  * Issues still to be resolved:
  *
@@ -562,7 +572,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 +1418,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);
@@ -1572,7 +1582,8 @@ static void *get_partial_node(struct kmem_cache *s, struct kmem_cache_node *n,
                        put_cpu_partial(s, page, 0);
                        stat(s, CPU_PARTIAL_NODE);
                }
-               if (kmem_cache_debug(s) || available > s->cpu_partial / 2)
+               if (!kmem_cache_has_cpu_partial(s)
+                       || available > s->cpu_partial / 2)
                        break;
 
        }
@@ -1883,6 +1894,7 @@ redo:
 static void unfreeze_partials(struct kmem_cache *s,
                struct kmem_cache_cpu *c)
 {
+#ifdef CONFIG_SLUB_CPU_PARTIAL
        struct kmem_cache_node *n = NULL, *n2 = NULL;
        struct page *page, *discard_page = NULL;
 
@@ -1937,6 +1949,7 @@ static void unfreeze_partials(struct kmem_cache *s,
                discard_slab(s, page);
                stat(s, FREE_SLAB);
        }
+#endif
 }
 
 /*
@@ -1950,6 +1963,7 @@ static void unfreeze_partials(struct kmem_cache *s,
  */
 static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
 {
+#ifdef CONFIG_SLUB_CPU_PARTIAL
        struct page *oldpage;
        int pages;
        int pobjects;
@@ -1989,6 +2003,7 @@ static void put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
                page->next = oldpage;
 
        } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
+#endif
 }
 
 static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
@@ -2360,7 +2375,7 @@ redo:
 
        object = c->freelist;
        page = c->page;
-       if (unlikely(!object || !node_match(page, node)))
+       if (unlikely(!object || !page || !node_match(page, node)))
                object = __slab_alloc(s, gfpflags, node, addr, c);
 
        else {
@@ -2497,7 +2512,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
                new.inuse--;
                if ((!new.inuse || !prior) && !was_frozen) {
 
-                       if (!kmem_cache_debug(s) && !prior)
+                       if (kmem_cache_has_cpu_partial(s) && !prior)
 
                                /*
                                 * Slab was on no list before and will be partially empty
@@ -2552,8 +2567,9 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
         * Objects left in the slab. If it was not on the partial list before
         * then add it.
         */
-       if (kmem_cache_debug(s) && unlikely(!prior)) {
-               remove_full(s, page);
+       if (!kmem_cache_has_cpu_partial(s) && unlikely(!prior)) {
+               if (kmem_cache_debug(s))
+                       remove_full(s, page);
                add_partial(n, page, DEACTIVATE_TO_TAIL);
                stat(s, FREE_ADD_PARTIAL);
        }
@@ -3061,7 +3077,7 @@ static int kmem_cache_open(struct kmem_cache *s, unsigned long flags)
         *    per node list when we run out of per cpu objects. We only fetch 50%
         *    to keep some capacity around for frees.
         */
-       if (kmem_cache_debug(s))
+       if (!kmem_cache_has_cpu_partial(s))
                s->cpu_partial = 0;
        else if (s->size >= PAGE_SIZE)
                s->cpu_partial = 2;
@@ -3428,7 +3444,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;
@@ -3543,7 +3558,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
@@ -3600,7 +3618,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;
@@ -3755,7 +3773,7 @@ int __kmem_cache_create(struct kmem_cache *s, unsigned long flags)
  * Use the cpu notifier to insure that the cpu slabs are flushed when
  * necessary.
  */
-static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
+static int slab_cpuup_callback(struct notifier_block *nfb,
                unsigned long action, void *hcpu)
 {
        long cpu = (long)hcpu;
@@ -3781,7 +3799,7 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
        return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata slab_notifier = {
+static struct notifier_block slab_notifier = {
        .notifier_call = slab_cpuup_callback
 };
 
@@ -4456,7 +4474,7 @@ static ssize_t cpu_partial_store(struct kmem_cache *s, const char *buf,
        err = strict_strtoul(buf, 10, &objects);
        if (err)
                return err;
-       if (objects && kmem_cache_debug(s))
+       if (objects && !kmem_cache_has_cpu_partial(s))
                return -EINVAL;
 
        s->cpu_partial = objects;