DEACTIVATE_TO_HEAD,     /* Cpu slab was moved to the head of partials */
        DEACTIVATE_TO_TAIL,     /* Cpu slab was moved to the tail of partials */
        DEACTIVATE_REMOTE_FREES,/* Slab contained remotely freed objects */
+       ORDER_FALLBACK,         /* Number of times fallback was necessary */
        NR_SLUB_STAT_ITEMS };
 
 struct kmem_cache_cpu {
 
        /* Allocation and freeing of slabs */
        struct kmem_cache_order_objects max;
+       struct kmem_cache_order_objects min;
        gfp_t allocflags;       /* gfp flags to use on each alloc */
        int refcount;           /* Refcount for slab cache destroy */
        void (*ctor)(struct kmem_cache *, void *);
 
 /*
  * Slab allocation and freeing
  */
+static inline struct page *alloc_slab_page(gfp_t flags, int node,
+                                       struct kmem_cache_order_objects oo)
+{
+       int order = oo_order(oo);
+
+       if (node == -1)
+               return alloc_pages(flags, order);
+       else
+               return alloc_pages_node(node, flags, order);
+}
+
 static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
 {
        struct page *page;
        struct kmem_cache_order_objects oo = s->oo;
-       int order = oo_order(oo);
-       int pages = 1 << order;
 
        flags |= s->allocflags;
 
-       if (node == -1)
-               page = alloc_pages(flags, order);
-       else
-               page = alloc_pages_node(node, flags, order);
-
-       if (!page)
-               return NULL;
+       page = alloc_slab_page(flags | __GFP_NOWARN | __GFP_NORETRY, node,
+                                                                       oo);
+       if (unlikely(!page)) {
+               oo = s->min;
+               /*
+                * Allocation may have failed due to fragmentation.
+                * Try a lower order alloc if possible
+                */
+               page = alloc_slab_page(flags, node, oo);
+               if (!page)
+                       return NULL;
 
+               stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK);
+       }
        page->objects = oo_objects(oo);
        mod_zone_page_state(page_zone(page),
                (s->flags & SLAB_RECLAIM_ACCOUNT) ?
                NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
-               pages);
+               1 << oo_order(oo));
 
        return page;
 }
         * Determine the number of objects per slab
         */
        s->oo = oo_make(order, size);
+       s->min = oo_make(get_order(size), size);
        if (oo_objects(s->oo) > oo_objects(s->max))
                s->max = s->oo;
 
 STAT_ATTR(DEACTIVATE_TO_HEAD, deactivate_to_head);
 STAT_ATTR(DEACTIVATE_TO_TAIL, deactivate_to_tail);
 STAT_ATTR(DEACTIVATE_REMOTE_FREES, deactivate_remote_frees);
-
+STAT_ATTR(ORDER_FALLBACK, order_fallback);
 #endif
 
 static struct attribute *slab_attrs[] = {
        &deactivate_to_head_attr.attr,
        &deactivate_to_tail_attr.attr,
        &deactivate_remote_frees_attr.attr,
+       &order_fallback_attr.attr,
 #endif
        NULL
 };