libceph: introduce and switch to reopen_session()
[linux-2.6-block.git] / mm / slab.c
index ab43d9fcdb81e1662c66128f96a129dbe89299a7..e719a5cb33963be4b23ff6cd3d9d8cfb65fb1008 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -168,12 +168,6 @@ typedef unsigned short freelist_idx_t;
 
 #define SLAB_OBJ_MAX_NUM ((1 << sizeof(freelist_idx_t) * BITS_PER_BYTE) - 1)
 
-/*
- * true if a page was allocated from pfmemalloc reserves for network-based
- * swap
- */
-static bool pfmemalloc_active __read_mostly;
-
 /*
  * struct array_cache
  *
@@ -195,10 +189,6 @@ struct array_cache {
                         * Must have this definition in here for the proper
                         * alignment of array_cache. Also simplifies accessing
                         * the entries.
-                        *
-                        * Entries should not be directly dereferenced as
-                        * entries belonging to slabs marked pfmemalloc will
-                        * have the lower bits set SLAB_OBJ_PFMEMALLOC
                         */
 };
 
@@ -207,23 +197,6 @@ struct alien_cache {
        struct array_cache ac;
 };
 
-#define SLAB_OBJ_PFMEMALLOC    1
-static inline bool is_obj_pfmemalloc(void *objp)
-{
-       return (unsigned long)objp & SLAB_OBJ_PFMEMALLOC;
-}
-
-static inline void set_obj_pfmemalloc(void **objp)
-{
-       *objp = (void *)((unsigned long)*objp | SLAB_OBJ_PFMEMALLOC);
-       return;
-}
-
-static inline void clear_obj_pfmemalloc(void **objp)
-{
-       *objp = (void *)((unsigned long)*objp & ~SLAB_OBJ_PFMEMALLOC);
-}
-
 /*
  * Need this for bootstrapping a per node allocator.
  */
@@ -270,7 +243,9 @@ static void kmem_cache_node_init(struct kmem_cache_node *parent)
        MAKE_LIST((cachep), (&(ptr)->slabs_free), slabs_free, nodeid);  \
        } while (0)
 
+#define CFLGS_OBJFREELIST_SLAB (0x40000000UL)
 #define CFLGS_OFF_SLAB         (0x80000000UL)
+#define        OBJFREELIST_SLAB(x)     ((x)->flags & CFLGS_OBJFREELIST_SLAB)
 #define        OFF_SLAB(x)     ((x)->flags & CFLGS_OFF_SLAB)
 
 #define BATCHREFILL_LIMIT      16
@@ -458,9 +433,10 @@ static inline struct array_cache *cpu_cache_get(struct kmem_cache *cachep)
 /*
  * Calculate the number of objects and left-over bytes for a given buffer size.
  */
-static void cache_estimate(unsigned long gfporder, size_t buffer_size,
-               unsigned long flags, size_t *left_over, unsigned int *num)
+static unsigned int cache_estimate(unsigned long gfporder, size_t buffer_size,
+               unsigned long flags, size_t *left_over)
 {
+       unsigned int num;
        size_t slab_size = PAGE_SIZE << gfporder;
 
        /*
@@ -480,14 +456,16 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size,
         * the slabs are all pages aligned, the objects will be at the
         * correct alignment when allocated.
         */
-       if (flags & CFLGS_OFF_SLAB) {
-               *num = slab_size / buffer_size;
+       if (flags & (CFLGS_OBJFREELIST_SLAB | CFLGS_OFF_SLAB)) {
+               num = slab_size / buffer_size;
                *left_over = slab_size % buffer_size;
        } else {
-               *num = slab_size / (buffer_size + sizeof(freelist_idx_t));
+               num = slab_size / (buffer_size + sizeof(freelist_idx_t));
                *left_over = slab_size %
                        (buffer_size + sizeof(freelist_idx_t));
        }
+
+       return num;
 }
 
 #if DEBUG
@@ -496,7 +474,7 @@ static void cache_estimate(unsigned long gfporder, size_t buffer_size,
 static void __slab_error(const char *function, struct kmem_cache *cachep,
                        char *msg)
 {
-       printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
+       pr_err("slab error in %s(): cache `%s': %s\n",
               function, cachep->name, msg);
        dump_stack();
        add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
@@ -618,120 +596,21 @@ static struct array_cache *alloc_arraycache(int node, int entries,
        return ac;
 }
 
-static inline bool is_slab_pfmemalloc(struct page *page)
-{
-       return PageSlabPfmemalloc(page);
-}
-
-/* Clears pfmemalloc_active if no slabs have pfmalloc set */
-static void recheck_pfmemalloc_active(struct kmem_cache *cachep,
-                                               struct array_cache *ac)
-{
-       struct kmem_cache_node *n = get_node(cachep, numa_mem_id());
-       struct page *page;
-       unsigned long flags;
-
-       if (!pfmemalloc_active)
-               return;
-
-       spin_lock_irqsave(&n->list_lock, flags);
-       list_for_each_entry(page, &n->slabs_full, lru)
-               if (is_slab_pfmemalloc(page))
-                       goto out;
-
-       list_for_each_entry(page, &n->slabs_partial, lru)
-               if (is_slab_pfmemalloc(page))
-                       goto out;
-
-       list_for_each_entry(page, &n->slabs_free, lru)
-               if (is_slab_pfmemalloc(page))
-                       goto out;
-
-       pfmemalloc_active = false;
-out:
-       spin_unlock_irqrestore(&n->list_lock, flags);
-}
-
-static void *__ac_get_obj(struct kmem_cache *cachep, struct array_cache *ac,
-                                               gfp_t flags, bool force_refill)
-{
-       int i;
-       void *objp = ac->entry[--ac->avail];
-
-       /* Ensure the caller is allowed to use objects from PFMEMALLOC slab */
-       if (unlikely(is_obj_pfmemalloc(objp))) {
-               struct kmem_cache_node *n;
-
-               if (gfp_pfmemalloc_allowed(flags)) {
-                       clear_obj_pfmemalloc(&objp);
-                       return objp;
-               }
-
-               /* The caller cannot use PFMEMALLOC objects, find another one */
-               for (i = 0; i < ac->avail; i++) {
-                       /* If a !PFMEMALLOC object is found, swap them */
-                       if (!is_obj_pfmemalloc(ac->entry[i])) {
-                               objp = ac->entry[i];
-                               ac->entry[i] = ac->entry[ac->avail];
-                               ac->entry[ac->avail] = objp;
-                               return objp;
-                       }
-               }
-
-               /*
-                * If there are empty slabs on the slabs_free list and we are
-                * being forced to refill the cache, mark this one !pfmemalloc.
-                */
-               n = get_node(cachep, numa_mem_id());
-               if (!list_empty(&n->slabs_free) && force_refill) {
-                       struct page *page = virt_to_head_page(objp);
-                       ClearPageSlabPfmemalloc(page);
-                       clear_obj_pfmemalloc(&objp);
-                       recheck_pfmemalloc_active(cachep, ac);
-                       return objp;
-               }
-
-               /* No !PFMEMALLOC objects available */
-               ac->avail++;
-               objp = NULL;
-       }
-
-       return objp;
-}
-
-static inline void *ac_get_obj(struct kmem_cache *cachep,
-                       struct array_cache *ac, gfp_t flags, bool force_refill)
-{
-       void *objp;
-
-       if (unlikely(sk_memalloc_socks()))
-               objp = __ac_get_obj(cachep, ac, flags, force_refill);
-       else
-               objp = ac->entry[--ac->avail];
-
-       return objp;
-}
-
-static noinline void *__ac_put_obj(struct kmem_cache *cachep,
-                       struct array_cache *ac, void *objp)
+static noinline void cache_free_pfmemalloc(struct kmem_cache *cachep,
+                                       struct page *page, void *objp)
 {
-       if (unlikely(pfmemalloc_active)) {
-               /* Some pfmemalloc slabs exist, check if this is one */
-               struct page *page = virt_to_head_page(objp);
-               if (PageSlabPfmemalloc(page))
-                       set_obj_pfmemalloc(&objp);
-       }
+       struct kmem_cache_node *n;
+       int page_node;
+       LIST_HEAD(list);
 
-       return objp;
-}
+       page_node = page_to_nid(page);
+       n = get_node(cachep, page_node);
 
-static inline void ac_put_obj(struct kmem_cache *cachep, struct array_cache *ac,
-                                                               void *objp)
-{
-       if (unlikely(sk_memalloc_socks()))
-               objp = __ac_put_obj(cachep, ac, objp);
+       spin_lock(&n->list_lock);
+       free_block(cachep, &objp, 1, page_node, &list);
+       spin_unlock(&n->list_lock);
 
-       ac->entry[ac->avail++] = objp;
+       slabs_destroy(cachep, &list);
 }
 
 /*
@@ -791,7 +670,7 @@ static inline void *____cache_alloc_node(struct kmem_cache *cachep,
 
 static inline gfp_t gfp_exact_node(gfp_t flags)
 {
-       return flags;
+       return flags & ~__GFP_NOFAIL;
 }
 
 #else  /* CONFIG_NUMA */
@@ -934,7 +813,7 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp,
                        STATS_INC_ACOVERFLOW(cachep);
                        __drain_alien_cache(cachep, ac, page_node, &list);
                }
-               ac_put_obj(cachep, ac, objp);
+               ac->entry[ac->avail++] = objp;
                spin_unlock(&alien->lock);
                slabs_destroy(cachep, &list);
        } else {
@@ -962,12 +841,12 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
 }
 
 /*
- * Construct gfp mask to allocate from a specific node but do not direct reclaim
- * or warn about failures. kswapd may still wake to reclaim in the background.
+ * Construct gfp mask to allocate from a specific node but do not reclaim or
+ * warn about failures.
  */
 static inline gfp_t gfp_exact_node(gfp_t flags)
 {
-       return (flags | __GFP_THISNODE | __GFP_NOWARN) & ~__GFP_DIRECT_RECLAIM;
+       return (flags | __GFP_THISNODE | __GFP_NOWARN) & ~(__GFP_RECLAIM|__GFP_NOFAIL);
 }
 #endif
 
@@ -1471,10 +1350,9 @@ slab_out_of_memory(struct kmem_cache *cachep, gfp_t gfpflags, int nodeid)
        if ((gfpflags & __GFP_NOWARN) || !__ratelimit(&slab_oom_rs))
                return;
 
-       printk(KERN_WARNING
-               "SLAB: Unable to allocate memory on node %d (gfp=0x%x)\n",
-               nodeid, gfpflags);
-       printk(KERN_WARNING "  cache: %s, object size: %d, order: %d\n",
+       pr_warn("SLAB: Unable to allocate memory on node %d, gfp=%#x(%pGg)\n",
+               nodeid, gfpflags, &gfpflags);
+       pr_warn("  cache: %s, object size: %d, order: %d\n",
                cachep->name, cachep->size, cachep->gfporder);
 
        for_each_kmem_cache_node(cachep, node, n) {
@@ -1498,8 +1376,7 @@ slab_out_of_memory(struct kmem_cache *cachep, gfp_t gfpflags, int nodeid)
 
                num_slabs += active_slabs;
                num_objs = num_slabs * cachep->num;
-               printk(KERN_WARNING
-                       "  node %d: slabs: %ld/%ld, objs: %ld/%ld, free: %ld\n",
+               pr_warn("  node %d: slabs: %ld/%ld, objs: %ld/%ld, free: %ld\n",
                        node, active_slabs, num_slabs, active_objs, num_objs,
                        free_objects);
        }
@@ -1535,10 +1412,6 @@ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
                return NULL;
        }
 
-       /* Record if ALLOC_NO_WATERMARKS was set when allocating the slab */
-       if (page_is_pfmemalloc(page))
-               pfmemalloc_active = true;
-
        nr_pages = (1 << cachep->gfporder);
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
                add_zone_page_state(page_zone(page),
@@ -1546,8 +1419,10 @@ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
        else
                add_zone_page_state(page_zone(page),
                        NR_SLAB_UNRECLAIMABLE, nr_pages);
+
        __SetPageSlab(page);
-       if (page_is_pfmemalloc(page))
+       /* Record if ALLOC_NO_WATERMARKS was set when allocating the slab */
+       if (sk_memalloc_socks() && page_is_pfmemalloc(page))
                SetPageSlabPfmemalloc(page);
 
        if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
@@ -1567,9 +1442,10 @@ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
  */
 static void kmem_freepages(struct kmem_cache *cachep, struct page *page)
 {
-       const unsigned long nr_freed = (1 << cachep->gfporder);
+       int order = cachep->gfporder;
+       unsigned long nr_freed = (1 << order);
 
-       kmemcheck_free_shadow(page, cachep->gfporder);
+       kmemcheck_free_shadow(page, order);
 
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
                sub_zone_page_state(page_zone(page),
@@ -1586,7 +1462,8 @@ static void kmem_freepages(struct kmem_cache *cachep, struct page *page)
 
        if (current->reclaim_state)
                current->reclaim_state->reclaimed_slab += nr_freed;
-       __free_kmem_pages(page, cachep->gfporder);
+       memcg_uncharge_slab(page, order, cachep);
+       __free_pages(page, order);
 }
 
 static void kmem_rcu_free(struct rcu_head *head)
@@ -1676,7 +1553,7 @@ static void dump_line(char *data, int offset, int limit)
        unsigned char error = 0;
        int bad_count = 0;
 
-       printk(KERN_ERR "%03x: ", offset);
+       pr_err("%03x: ", offset);
        for (i = 0; i < limit; i++) {
                if (data[offset + i] != POISON_FREE) {
                        error = data[offset + i];
@@ -1689,13 +1566,11 @@ static void dump_line(char *data, int offset, int limit)
        if (bad_count == 1) {
                error ^= POISON_FREE;
                if (!(error & (error - 1))) {
-                       printk(KERN_ERR "Single bit error detected. Probably "
-                                       "bad RAM.\n");
+                       pr_err("Single bit error detected. Probably bad RAM.\n");
 #ifdef CONFIG_X86
-                       printk(KERN_ERR "Run memtest86+ or a similar memory "
-                                       "test tool.\n");
+                       pr_err("Run memtest86+ or a similar memory test tool.\n");
 #else
-                       printk(KERN_ERR "Run a memory test tool.\n");
+                       pr_err("Run a memory test tool.\n");
 #endif
                }
        }
@@ -1710,13 +1585,13 @@ static void print_objinfo(struct kmem_cache *cachep, void *objp, int lines)
        char *realobj;
 
        if (cachep->flags & SLAB_RED_ZONE) {
-               printk(KERN_ERR "Redzone: 0x%llx/0x%llx.\n",
-                       *dbg_redzone1(cachep, objp),
-                       *dbg_redzone2(cachep, objp));
+               pr_err("Redzone: 0x%llx/0x%llx\n",
+                      *dbg_redzone1(cachep, objp),
+                      *dbg_redzone2(cachep, objp));
        }
 
        if (cachep->flags & SLAB_STORE_USER) {
-               printk(KERN_ERR "Last user: [<%p>](%pSR)\n",
+               pr_err("Last user: [<%p>](%pSR)\n",
                       *dbg_userword(cachep, objp),
                       *dbg_userword(cachep, objp));
        }
@@ -1752,9 +1627,9 @@ static void check_poison_obj(struct kmem_cache *cachep, void *objp)
                        /* Mismatch ! */
                        /* Print header */
                        if (lines == 0) {
-                               printk(KERN_ERR
-                                       "Slab corruption (%s): %s start=%p, len=%d\n",
-                                       print_tainted(), cachep->name, realobj, size);
+                               pr_err("Slab corruption (%s): %s start=%p, len=%d\n",
+                                      print_tainted(), cachep->name,
+                                      realobj, size);
                                print_objinfo(cachep, objp, 0);
                        }
                        /* Hexdump the affected line */
@@ -1781,15 +1656,13 @@ static void check_poison_obj(struct kmem_cache *cachep, void *objp)
                if (objnr) {
                        objp = index_to_obj(cachep, page, objnr - 1);
                        realobj = (char *)objp + obj_offset(cachep);
-                       printk(KERN_ERR "Prev obj: start=%p, len=%d\n",
-                              realobj, size);
+                       pr_err("Prev obj: start=%p, len=%d\n", realobj, size);
                        print_objinfo(cachep, objp, 2);
                }
                if (objnr + 1 < cachep->num) {
                        objp = index_to_obj(cachep, page, objnr + 1);
                        realobj = (char *)objp + obj_offset(cachep);
-                       printk(KERN_ERR "Next obj: start=%p, len=%d\n",
-                              realobj, size);
+                       pr_err("Next obj: start=%p, len=%d\n", realobj, size);
                        print_objinfo(cachep, objp, 2);
                }
        }
@@ -1801,6 +1674,12 @@ static void slab_destroy_debugcheck(struct kmem_cache *cachep,
                                                struct page *page)
 {
        int i;
+
+       if (OBJFREELIST_SLAB(cachep) && cachep->flags & SLAB_POISON) {
+               poison_obj(cachep, page->freelist - obj_offset(cachep),
+                       POISON_FREE);
+       }
+
        for (i = 0; i < cachep->num; i++) {
                void *objp = index_to_obj(cachep, page, i);
 
@@ -1810,11 +1689,9 @@ static void slab_destroy_debugcheck(struct kmem_cache *cachep,
                }
                if (cachep->flags & SLAB_RED_ZONE) {
                        if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
-                               slab_error(cachep, "start of a freed object "
-                                          "was overwritten");
+                               slab_error(cachep, "start of a freed object was overwritten");
                        if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
-                               slab_error(cachep, "end of a freed object "
-                                          "was overwritten");
+                               slab_error(cachep, "end of a freed object was overwritten");
                }
        }
 }
@@ -1885,7 +1762,7 @@ static size_t calculate_slab_order(struct kmem_cache *cachep,
                unsigned int num;
                size_t remainder;
 
-               cache_estimate(gfporder, size, flags, &remainder, &num);
+               num = cache_estimate(gfporder, size, flags, &remainder);
                if (!num)
                        continue;
 
@@ -2029,6 +1906,29 @@ __kmem_cache_alias(const char *name, size_t size, size_t align,
        return cachep;
 }
 
+static bool set_objfreelist_slab_cache(struct kmem_cache *cachep,
+                       size_t size, unsigned long flags)
+{
+       size_t left;
+
+       cachep->num = 0;
+
+       if (cachep->ctor || flags & SLAB_DESTROY_BY_RCU)
+               return false;
+
+       left = calculate_slab_order(cachep, size,
+                       flags | CFLGS_OBJFREELIST_SLAB);
+       if (!cachep->num)
+               return false;
+
+       if (cachep->num * sizeof(freelist_idx_t) > cachep->object_size)
+               return false;
+
+       cachep->colour = left / cachep->colour_off;
+
+       return true;
+}
+
 static bool set_off_slab_cache(struct kmem_cache *cachep,
                        size_t size, unsigned long flags)
 {
@@ -2217,6 +2117,11 @@ __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
        }
 #endif
 
+       if (set_objfreelist_slab_cache(cachep, size, flags)) {
+               flags |= CFLGS_OBJFREELIST_SLAB;
+               goto done;
+       }
+
        if (set_off_slab_cache(cachep, size, flags)) {
                flags |= CFLGS_OFF_SLAB;
                goto done;
@@ -2434,7 +2339,9 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
        page->s_mem = addr + colour_off;
        page->active = 0;
 
-       if (OFF_SLAB(cachep)) {
+       if (OBJFREELIST_SLAB(cachep))
+               freelist = NULL;
+       else if (OFF_SLAB(cachep)) {
                /* Slab management obj is off-slab. */
                freelist = kmem_cache_alloc_node(cachep->freelist_cache,
                                              local_flags, nodeid);
@@ -2460,14 +2367,14 @@ static inline void set_free_obj(struct page *page,
        ((freelist_idx_t *)(page->freelist))[idx] = val;
 }
 
-static void cache_init_objs(struct kmem_cache *cachep,
-                           struct page *page)
+static void cache_init_objs_debug(struct kmem_cache *cachep, struct page *page)
 {
+#if DEBUG
        int i;
 
        for (i = 0; i < cachep->num; i++) {
                void *objp = index_to_obj(cachep, page, i);
-#if DEBUG
+
                if (cachep->flags & SLAB_STORE_USER)
                        *dbg_userword(cachep, objp) = NULL;
 
@@ -2485,21 +2392,36 @@ static void cache_init_objs(struct kmem_cache *cachep,
 
                if (cachep->flags & SLAB_RED_ZONE) {
                        if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
-                               slab_error(cachep, "constructor overwrote the"
-                                          " end of an object");
+                               slab_error(cachep, "constructor overwrote the end of an object");
                        if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
-                               slab_error(cachep, "constructor overwrote the"
-                                          " start of an object");
+                               slab_error(cachep, "constructor overwrote the start of an object");
                }
                /* need to poison the objs? */
                if (cachep->flags & SLAB_POISON) {
                        poison_obj(cachep, objp, POISON_FREE);
                        slab_kernel_map(cachep, objp, 0, 0);
                }
-#else
-               if (cachep->ctor)
-                       cachep->ctor(objp);
+       }
 #endif
+}
+
+static void cache_init_objs(struct kmem_cache *cachep,
+                           struct page *page)
+{
+       int i;
+
+       cache_init_objs_debug(cachep, page);
+
+       if (OBJFREELIST_SLAB(cachep)) {
+               page->freelist = index_to_obj(cachep, page, cachep->num - 1) +
+                                               obj_offset(cachep);
+       }
+
+       for (i = 0; i < cachep->num; i++) {
+               /* constructor could break poison info */
+               if (DEBUG == 0 && cachep->ctor)
+                       cachep->ctor(index_to_obj(cachep, page, i));
+
                set_free_obj(page, i, i);
        }
 }
@@ -2539,13 +2461,16 @@ static void slab_put_obj(struct kmem_cache *cachep,
        /* Verify double free bug */
        for (i = page->active; i < cachep->num; i++) {
                if (get_free_obj(page, i) == objnr) {
-                       printk(KERN_ERR "slab: double free detected in cache "
-                                       "'%s', objp %p\n", cachep->name, objp);
+                       pr_err("slab: double free detected in cache '%s', objp %p\n",
+                              cachep->name, objp);
                        BUG();
                }
        }
 #endif
        page->active--;
+       if (!page->freelist)
+               page->freelist = objp + obj_offset(cachep);
+
        set_free_obj(page, page->active, objnr);
 }
 
@@ -2620,7 +2545,7 @@ static int cache_grow(struct kmem_cache *cachep,
        /* Get slab management. */
        freelist = alloc_slabmgmt(cachep, page, offset,
                        local_flags & ~GFP_CONSTRAINT_MASK, nodeid);
-       if (!freelist)
+       if (OFF_SLAB(cachep) && !freelist)
                goto opps1;
 
        slab_map_pages(cachep, page, freelist);
@@ -2656,7 +2581,7 @@ failed:
 static void kfree_debugcheck(const void *objp)
 {
        if (!virt_addr_valid(objp)) {
-               printk(KERN_ERR "kfree_debugcheck: out of range ptr %lxh.\n",
+               pr_err("kfree_debugcheck: out of range ptr %lxh\n",
                       (unsigned long)objp);
                BUG();
        }
@@ -2680,8 +2605,8 @@ static inline void verify_redzone_free(struct kmem_cache *cache, void *obj)
        else
                slab_error(cache, "memory outside object was overwritten");
 
-       printk(KERN_ERR "%p: redzone 1:0x%llx, redzone 2:0x%llx.\n",
-                       obj, redzone1, redzone2);
+       pr_err("%p: redzone 1:0x%llx, redzone 2:0x%llx\n",
+              obj, redzone1, redzone2);
 }
 
 static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
@@ -2723,7 +2648,85 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
 #define cache_free_debugcheck(x,objp,z) (objp)
 #endif
 
-static struct page *get_first_slab(struct kmem_cache_node *n)
+static inline void fixup_objfreelist_debug(struct kmem_cache *cachep,
+                                               void **list)
+{
+#if DEBUG
+       void *next = *list;
+       void *objp;
+
+       while (next) {
+               objp = next - obj_offset(cachep);
+               next = *(void **)next;
+               poison_obj(cachep, objp, POISON_FREE);
+       }
+#endif
+}
+
+static inline void fixup_slab_list(struct kmem_cache *cachep,
+                               struct kmem_cache_node *n, struct page *page,
+                               void **list)
+{
+       /* move slabp to correct slabp list: */
+       list_del(&page->lru);
+       if (page->active == cachep->num) {
+               list_add(&page->lru, &n->slabs_full);
+               if (OBJFREELIST_SLAB(cachep)) {
+#if DEBUG
+                       /* Poisoning will be done without holding the lock */
+                       if (cachep->flags & SLAB_POISON) {
+                               void **objp = page->freelist;
+
+                               *objp = *list;
+                               *list = objp;
+                       }
+#endif
+                       page->freelist = NULL;
+               }
+       } else
+               list_add(&page->lru, &n->slabs_partial);
+}
+
+/* Try to find non-pfmemalloc slab if needed */
+static noinline struct page *get_valid_first_slab(struct kmem_cache_node *n,
+                                       struct page *page, bool pfmemalloc)
+{
+       if (!page)
+               return NULL;
+
+       if (pfmemalloc)
+               return page;
+
+       if (!PageSlabPfmemalloc(page))
+               return page;
+
+       /* No need to keep pfmemalloc slab if we have enough free objects */
+       if (n->free_objects > n->free_limit) {
+               ClearPageSlabPfmemalloc(page);
+               return page;
+       }
+
+       /* Move pfmemalloc slab to the end of list to speed up next search */
+       list_del(&page->lru);
+       if (!page->active)
+               list_add_tail(&page->lru, &n->slabs_free);
+       else
+               list_add_tail(&page->lru, &n->slabs_partial);
+
+       list_for_each_entry(page, &n->slabs_partial, lru) {
+               if (!PageSlabPfmemalloc(page))
+                       return page;
+       }
+
+       list_for_each_entry(page, &n->slabs_free, lru) {
+               if (!PageSlabPfmemalloc(page))
+                       return page;
+       }
+
+       return NULL;
+}
+
+static struct page *get_first_slab(struct kmem_cache_node *n, bool pfmemalloc)
 {
        struct page *page;
 
@@ -2735,21 +2738,51 @@ static struct page *get_first_slab(struct kmem_cache_node *n)
                                struct page, lru);
        }
 
+       if (sk_memalloc_socks())
+               return get_valid_first_slab(n, page, pfmemalloc);
+
        return page;
 }
 
-static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags,
-                                                       bool force_refill)
+static noinline void *cache_alloc_pfmemalloc(struct kmem_cache *cachep,
+                               struct kmem_cache_node *n, gfp_t flags)
+{
+       struct page *page;
+       void *obj;
+       void *list = NULL;
+
+       if (!gfp_pfmemalloc_allowed(flags))
+               return NULL;
+
+       spin_lock(&n->list_lock);
+       page = get_first_slab(n, true);
+       if (!page) {
+               spin_unlock(&n->list_lock);
+               return NULL;
+       }
+
+       obj = slab_get_obj(cachep, page);
+       n->free_objects--;
+
+       fixup_slab_list(cachep, n, page, &list);
+
+       spin_unlock(&n->list_lock);
+       fixup_objfreelist_debug(cachep, &list);
+
+       return obj;
+}
+
+static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags)
 {
        int batchcount;
        struct kmem_cache_node *n;
        struct array_cache *ac;
        int node;
+       void *list = NULL;
 
        check_irq_off();
        node = numa_mem_id();
-       if (unlikely(force_refill))
-               goto force_grow;
+
 retry:
        ac = cpu_cache_get(cachep);
        batchcount = ac->batchcount;
@@ -2775,7 +2808,7 @@ retry:
        while (batchcount > 0) {
                struct page *page;
                /* Get slab alloc is to come from. */
-               page = get_first_slab(n);
+               page = get_first_slab(n, false);
                if (!page)
                        goto must_grow;
 
@@ -2793,25 +2826,29 @@ retry:
                        STATS_INC_ACTIVE(cachep);
                        STATS_SET_HIGH(cachep);
 
-                       ac_put_obj(cachep, ac, slab_get_obj(cachep, page));
+                       ac->entry[ac->avail++] = slab_get_obj(cachep, page);
                }
 
-               /* move slabp to correct slabp list: */
-               list_del(&page->lru);
-               if (page->active == cachep->num)
-                       list_add(&page->lru, &n->slabs_full);
-               else
-                       list_add(&page->lru, &n->slabs_partial);
+               fixup_slab_list(cachep, n, page, &list);
        }
 
 must_grow:
        n->free_objects -= ac->avail;
 alloc_done:
        spin_unlock(&n->list_lock);
+       fixup_objfreelist_debug(cachep, &list);
 
        if (unlikely(!ac->avail)) {
                int x;
-force_grow:
+
+               /* Check if we can use obj in pfmemalloc slab */
+               if (sk_memalloc_socks()) {
+                       void *obj = cache_alloc_pfmemalloc(cachep, n, flags);
+
+                       if (obj)
+                               return obj;
+               }
+
                x = cache_grow(cachep, gfp_exact_node(flags), node, NULL);
 
                /* cache_grow can reenable interrupts, then ac could change. */
@@ -2819,7 +2856,7 @@ force_grow:
                node = numa_mem_id();
 
                /* no objects in sight? abort */
-               if (!x && (ac->avail == 0 || force_refill))
+               if (!x && ac->avail == 0)
                        return NULL;
 
                if (!ac->avail)         /* objects refilled by interrupt? */
@@ -2827,7 +2864,7 @@ force_grow:
        }
        ac->touched = 1;
 
-       return ac_get_obj(cachep, ac, flags, force_refill);
+       return ac->entry[--ac->avail];
 }
 
 static inline void cache_alloc_debugcheck_before(struct kmem_cache *cachep,
@@ -2856,12 +2893,10 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
        if (cachep->flags & SLAB_RED_ZONE) {
                if (*dbg_redzone1(cachep, objp) != RED_INACTIVE ||
                                *dbg_redzone2(cachep, objp) != RED_INACTIVE) {
-                       slab_error(cachep, "double free, or memory outside"
-                                               " object was overwritten");
-                       printk(KERN_ERR
-                               "%p: redzone 1:0x%llx, redzone 2:0x%llx\n",
-                               objp, *dbg_redzone1(cachep, objp),
-                               *dbg_redzone2(cachep, objp));
+                       slab_error(cachep, "double free, or memory outside object was overwritten");
+                       pr_err("%p: redzone 1:0x%llx, redzone 2:0x%llx\n",
+                              objp, *dbg_redzone1(cachep, objp),
+                              *dbg_redzone2(cachep, objp));
                }
                *dbg_redzone1(cachep, objp) = RED_ACTIVE;
                *dbg_redzone2(cachep, objp) = RED_ACTIVE;
@@ -2872,7 +2907,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
                cachep->ctor(objp);
        if (ARCH_SLAB_MINALIGN &&
            ((unsigned long)objp & (ARCH_SLAB_MINALIGN-1))) {
-               printk(KERN_ERR "0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n",
+               pr_err("0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n",
                       objp, (int)ARCH_SLAB_MINALIGN);
        }
        return objp;
@@ -2885,28 +2920,20 @@ static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
        void *objp;
        struct array_cache *ac;
-       bool force_refill = false;
 
        check_irq_off();
 
        ac = cpu_cache_get(cachep);
        if (likely(ac->avail)) {
                ac->touched = 1;
-               objp = ac_get_obj(cachep, ac, flags, false);
+               objp = ac->entry[--ac->avail];
 
-               /*
-                * Allow for the possibility all avail objects are not allowed
-                * by the current flags
-                */
-               if (objp) {
-                       STATS_INC_ALLOCHIT(cachep);
-                       goto out;
-               }
-               force_refill = true;
+               STATS_INC_ALLOCHIT(cachep);
+               goto out;
        }
 
        STATS_INC_ALLOCMISS(cachep);
-       objp = cache_alloc_refill(cachep, flags, force_refill);
+       objp = cache_alloc_refill(cachep, flags);
        /*
         * the 'ac' may be updated by cache_alloc_refill(),
         * and kmemleak_erase() requires its correct value.
@@ -3044,6 +3071,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
        struct page *page;
        struct kmem_cache_node *n;
        void *obj;
+       void *list = NULL;
        int x;
 
        VM_BUG_ON(nodeid < 0 || nodeid >= MAX_NUMNODES);
@@ -3053,7 +3081,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
 retry:
        check_irq_off();
        spin_lock(&n->list_lock);
-       page = get_first_slab(n);
+       page = get_first_slab(n, false);
        if (!page)
                goto must_grow;
 
@@ -3067,15 +3095,11 @@ retry:
 
        obj = slab_get_obj(cachep, page);
        n->free_objects--;
-       /* move slabp to correct slabp list: */
-       list_del(&page->lru);
 
-       if (page->active == cachep->num)
-               list_add(&page->lru, &n->slabs_full);
-       else
-               list_add(&page->lru, &n->slabs_partial);
+       fixup_slab_list(cachep, n, page, &list);
 
        spin_unlock(&n->list_lock);
+       fixup_objfreelist_debug(cachep, &list);
        goto done;
 
 must_grow:
@@ -3210,7 +3234,6 @@ static void free_block(struct kmem_cache *cachep, void **objpp,
                void *objp;
                struct page *page;
 
-               clear_obj_pfmemalloc(&objpp[i]);
                objp = objpp[i];
 
                page = virt_to_head_page(objp);
@@ -3316,7 +3339,16 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp,
                cache_flusharray(cachep, ac);
        }
 
-       ac_put_obj(cachep, ac, objp);
+       if (sk_memalloc_socks()) {
+               struct page *page = virt_to_head_page(objp);
+
+               if (unlikely(PageSlabPfmemalloc(page))) {
+                       cache_free_pfmemalloc(cachep, page, objp);
+                       return;
+               }
+       }
+
+       ac->entry[ac->avail++] = objp;
 }
 
 /**
@@ -3802,7 +3834,7 @@ static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp)
 skip_setup:
        err = do_tune_cpucache(cachep, limit, batchcount, shared, gfp);
        if (err)
-               printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
+               pr_err("enable_cpucache failed for %s, error %d\n",
                       cachep->name, -err);
        return err;
 }
@@ -3958,7 +3990,7 @@ void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
 
        name = cachep->name;
        if (error)
-               printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
+               pr_err("slab: cache %s error: %s\n", name, error);
 
        sinfo->active_objs = active_objs;
        sinfo->num_objs = num_objs;
@@ -3986,8 +4018,7 @@ void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *cachep)
                unsigned long node_frees = cachep->node_frees;
                unsigned long overflows = cachep->node_overflow;
 
-               seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu "
-                          "%4lu %4lu %4lu %4lu %4lu",
+               seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu %4lu %4lu %4lu %4lu %4lu",
                           allocs, high, grown,
                           reaped, errors, max_freeable, node_allocs,
                           node_frees, overflows);