powerpc: update comments for generic idle conversion
[deliverable/linux.git] / mm / slub.c
index de99d500af6cdf6de6881ea8d809669c5994ec34..b2b047327d761a46802377b407d992ace14358bc 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1312,17 +1312,26 @@ static inline void slab_free_hook(struct kmem_cache *s, void *x)
 /*
  * Slab allocation and freeing
  */
-static inline struct page *alloc_slab_page(gfp_t flags, int node,
-                                       struct kmem_cache_order_objects oo)
+static inline struct page *alloc_slab_page(struct kmem_cache *s,
+               gfp_t flags, int node, struct kmem_cache_order_objects oo)
 {
+       struct page *page;
        int order = oo_order(oo);
 
        flags |= __GFP_NOTRACK;
 
+       if (memcg_charge_slab(s, flags, order))
+               return NULL;
+
        if (node == NUMA_NO_NODE)
-               return alloc_pages(flags, order);
+               page = alloc_pages(flags, order);
        else
-               return alloc_pages_exact_node(node, flags, order);
+               page = alloc_pages_exact_node(node, flags, order);
+
+       if (!page)
+               memcg_uncharge_slab(s, order);
+
+       return page;
 }
 
 static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
@@ -1344,7 +1353,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
         */
        alloc_gfp = (flags | __GFP_NOWARN | __GFP_NORETRY) & ~__GFP_NOFAIL;
 
-       page = alloc_slab_page(alloc_gfp, node, oo);
+       page = alloc_slab_page(s, alloc_gfp, node, oo);
        if (unlikely(!page)) {
                oo = s->min;
                alloc_gfp = flags;
@@ -1352,7 +1361,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
                 * Allocation may have failed due to fragmentation.
                 * Try a lower order alloc if possible
                 */
-               page = alloc_slab_page(alloc_gfp, node, oo);
+               page = alloc_slab_page(s, alloc_gfp, node, oo);
 
                if (page)
                        stat(s, ORDER_FALLBACK);
@@ -1413,7 +1422,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
 
        order = compound_order(page);
        inc_slabs_node(s, page_to_nid(page), page->objects);
-       memcg_bind_pages(s, order);
        page->slab_cache = s;
        __SetPageSlab(page);
        if (page->pfmemalloc)
@@ -1464,11 +1472,11 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
        __ClearPageSlabPfmemalloc(page);
        __ClearPageSlab(page);
 
-       memcg_release_pages(s, order);
        page_mapcount_reset(page);
        if (current->reclaim_state)
                current->reclaim_state->reclaimed_slab += pages;
-       __free_memcg_kmem_pages(page, order);
+       __free_pages(page, order);
+       memcg_uncharge_slab(s, order);
 }
 
 #define need_reserve_slab_rcu                                          \
@@ -1718,7 +1726,7 @@ static void *get_partial(struct kmem_cache *s, gfp_t flags, int node,
                struct kmem_cache_cpu *c)
 {
        void *object;
-       int searchnode = (node == NUMA_NO_NODE) ? numa_node_id() : node;
+       int searchnode = (node == NUMA_NO_NODE) ? numa_mem_id() : node;
 
        object = get_partial_node(s, get_node(s, searchnode), c, flags);
        if (object || node != NUMA_NO_NODE)
@@ -2119,11 +2127,19 @@ static inline int node_match(struct page *page, int node)
        return 1;
 }
 
+#ifdef CONFIG_SLUB_DEBUG
 static int count_free(struct page *page)
 {
        return page->objects - page->inuse;
 }
 
+static inline unsigned long node_nr_objs(struct kmem_cache_node *n)
+{
+       return atomic_long_read(&n->total_objects);
+}
+#endif /* CONFIG_SLUB_DEBUG */
+
+#if defined(CONFIG_SLUB_DEBUG) || defined(CONFIG_SYSFS)
 static unsigned long count_partial(struct kmem_cache_node *n,
                                        int (*get_count)(struct page *))
 {
@@ -2137,21 +2153,19 @@ static unsigned long count_partial(struct kmem_cache_node *n,
        spin_unlock_irqrestore(&n->list_lock, flags);
        return x;
 }
-
-static inline unsigned long node_nr_objs(struct kmem_cache_node *n)
-{
-#ifdef CONFIG_SLUB_DEBUG
-       return atomic_long_read(&n->total_objects);
-#else
-       return 0;
-#endif
-}
+#endif /* CONFIG_SLUB_DEBUG || CONFIG_SYSFS */
 
 static noinline void
 slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
 {
+#ifdef CONFIG_SLUB_DEBUG
+       static DEFINE_RATELIMIT_STATE(slub_oom_rs, DEFAULT_RATELIMIT_INTERVAL,
+                                     DEFAULT_RATELIMIT_BURST);
        int node;
 
+       if ((gfpflags & __GFP_NOWARN) || !__ratelimit(&slub_oom_rs))
+               return;
+
        pr_warn("SLUB: Unable to allocate memory on node %d (gfp=0x%x)\n",
                nid, gfpflags);
        pr_warn("  cache: %s, object size: %d, buffer size: %d, default order: %d, min order: %d\n",
@@ -2178,6 +2192,7 @@ slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
                pr_warn("  node %d: slabs: %ld, objs: %ld, free: %ld\n",
                        node, nr_slabs, nr_objs, nr_free);
        }
+#endif
 }
 
 static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
@@ -2194,7 +2209,7 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
 
        page = new_slab(s, flags, node);
        if (page) {
-               c = __this_cpu_ptr(s->cpu_slab);
+               c = raw_cpu_ptr(s->cpu_slab);
                if (c->page)
                        flush_slab(s, c);
 
@@ -2319,8 +2334,6 @@ redo:
        if (freelist)
                goto load_freelist;
 
-       stat(s, ALLOC_SLOWPATH);
-
        freelist = get_freelist(s, page);
 
        if (!freelist) {
@@ -2356,9 +2369,7 @@ new_slab:
        freelist = new_slab_objects(s, gfpflags, node, &c);
 
        if (unlikely(!freelist)) {
-               if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
-                       slab_out_of_memory(s, gfpflags, node);
-
+               slab_out_of_memory(s, gfpflags, node);
                local_irq_restore(flags);
                return NULL;
        }
@@ -2414,7 +2425,7 @@ redo:
         * and the retrieval of the tid.
         */
        preempt_disable();
-       c = __this_cpu_ptr(s->cpu_slab);
+       c = this_cpu_ptr(s->cpu_slab);
 
        /*
         * The transaction ids are globally unique per cpu and per operation on
@@ -2427,10 +2438,10 @@ redo:
 
        object = c->freelist;
        page = c->page;
-       if (unlikely(!object || !node_match(page, node)))
+       if (unlikely(!object || !node_match(page, node))) {
                object = __slab_alloc(s, gfpflags, node, addr, c);
-
-       else {
+               stat(s, ALLOC_SLOWPATH);
+       else {
                void *next_object = get_freepointer_safe(s, object);
 
                /*
@@ -2670,7 +2681,7 @@ redo:
         * during the cmpxchg then the free will succedd.
         */
        preempt_disable();
-       c = __this_cpu_ptr(s->cpu_slab);
+       c = this_cpu_ptr(s->cpu_slab);
 
        tid = c->tid;
        preempt_enable();
@@ -3298,8 +3309,8 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
        struct page *page;
        void *ptr = NULL;
 
-       flags |= __GFP_COMP | __GFP_NOTRACK | __GFP_KMEMCG;
-       page = alloc_pages_node(node, flags, get_order(size));
+       flags |= __GFP_COMP | __GFP_NOTRACK;
+       page = alloc_kmem_pages_node(node, flags, get_order(size));
        if (page)
                ptr = page_address(page);
 
@@ -3368,7 +3379,7 @@ void kfree(const void *x)
        if (unlikely(!PageSlab(page))) {
                BUG_ON(!PageCompound(page));
                kfree_hook(x);
-               __free_memcg_kmem_pages(page, compound_order(page));
+               __free_kmem_pages(page, compound_order(page));
                return;
        }
        slab_free(page->slab_cache, page, object, _RET_IP_);
@@ -3385,7 +3396,7 @@ EXPORT_SYMBOL(kfree);
  * being allocated from last increasing the chance that the last objects
  * are freed in them.
  */
-int kmem_cache_shrink(struct kmem_cache *s)
+int __kmem_cache_shrink(struct kmem_cache *s)
 {
        int node;
        int i;
@@ -3441,7 +3452,6 @@ int kmem_cache_shrink(struct kmem_cache *s)
        kfree(slabs_by_inuse);
        return 0;
 }
-EXPORT_SYMBOL(kmem_cache_shrink);
 
 static int slab_mem_going_offline_callback(void *arg)
 {
@@ -3449,7 +3459,7 @@ static int slab_mem_going_offline_callback(void *arg)
 
        mutex_lock(&slab_mutex);
        list_for_each_entry(s, &slab_caches, list)
-               kmem_cache_shrink(s);
+               __kmem_cache_shrink(s);
        mutex_unlock(&slab_mutex);
 
        return 0;
@@ -4319,7 +4329,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                }
        }
 
-       lock_memory_hotplug();
+       get_online_mems();
 #ifdef CONFIG_SLUB_DEBUG
        if (flags & SO_ALL) {
                for_each_node_state(node, N_NORMAL_MEMORY) {
@@ -4359,7 +4369,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                        x += sprintf(buf + x, " N%d=%lu",
                                        node, nodes[node]);
 #endif
-       unlock_memory_hotplug();
+       put_online_mems();
        kfree(nodes);
        return x + sprintf(buf + x, "\n");
 }
This page took 0.033355 seconds and 5 git commands to generate.