struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
 {
-       struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
+       struct buffer_head *ret = kmem_cache_zalloc(bh_cachep,
+                               set_migrateflags(gfp_flags, __GFP_RECLAIMABLE));
        if (ret) {
                INIT_LIST_HEAD(&ret->b_assoc_buffers);
                get_cpu_var(bh_accounting).nr++;
 
        struct dentry *dentry;
        char *dname;
 
-       dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 
+       dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
        if (!dentry)
                return NULL;
 
 
        journal_head_cache = kmem_cache_create("journal_head",
                                sizeof(struct journal_head),
                                0,              /* offset */
-                               0,              /* flags */
+                               SLAB_TEMPORARY, /* flags */
                                NULL);          /* ctor */
        retval = 0;
        if (journal_head_cache == 0) {
        jbd_handle_cache = kmem_cache_create("journal_handle",
                                sizeof(handle_t),
                                0,              /* offset */
-                               0,              /* flags */
+                               SLAB_TEMPORARY, /* flags */
                                NULL);          /* ctor */
        if (jbd_handle_cache == NULL) {
                printk(KERN_EMERG "JBD: failed to create handle cache\n");
 
 {
        revoke_record_cache = kmem_cache_create("revoke_record",
                                           sizeof(struct jbd_revoke_record_s),
-                                          0, SLAB_HWCACHE_ALIGN, NULL);
+                                          0,
+                                          SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
+                                          NULL);
        if (revoke_record_cache == 0)
                return -ENOMEM;
 
        revoke_table_cache = kmem_cache_create("revoke_table",
                                           sizeof(struct jbd_revoke_table_s),
-                                          0, 0, NULL);
+                                          0, SLAB_TEMPORARY, NULL);
        if (revoke_table_cache == 0) {
                kmem_cache_destroy(revoke_record_cache);
                revoke_record_cache = NULL;
 
                count = PROC_BLOCK_SIZE;
 
        length = -ENOMEM;
-       if (!(page = __get_free_page(GFP_KERNEL)))
+       if (!(page = __get_free_page(GFP_TEMPORARY)))
                goto out;
 
        length = PROC_I(inode)->op.proc_read(task, (char*)page);
                goto out;
 
        ret = -ENOMEM;
-       page = (char *)__get_free_page(GFP_USER);
+       page = (char *)__get_free_page(GFP_TEMPORARY);
        if (!page)
                goto out;
 
                goto out;
 
        copied = -ENOMEM;
-       page = (char *)__get_free_page(GFP_USER);
+       page = (char *)__get_free_page(GFP_TEMPORARY);
        if (!page)
                goto out;
 
                /* No partial writes. */
                return -EINVAL;
        }
-       page = (char*)__get_free_page(GFP_USER);
+       page = (char*)__get_free_page(GFP_TEMPORARY);
        if (!page)
                return -ENOMEM;
        length = -EFAULT;
                            char __user *buffer, int buflen)
 {
        struct inode * inode;
-       char *tmp = (char*)__get_free_page(GFP_KERNEL), *path;
+       char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
+       char *path;
        int len;
 
        if (!tmp)
                goto out;
 
        length = -ENOMEM;
-       page = (char*)__get_free_page(GFP_USER);
+       page = (char*)__get_free_page(GFP_TEMPORARY);
        if (!page)
                goto out;
 
 
                nbytes = MAX_NON_LFS - pos;
 
        dp = PDE(inode);
-       if (!(page = (char*) __get_free_page(GFP_KERNEL)))
+       if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
                return -ENOMEM;
 
        while ((nbytes > 0) && !eof) {
 
 #define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
 #define __GFP_HARDWALL   ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */
 #define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */
-#define __GFP_MOVABLE  ((__force gfp_t)0x80000u) /* Page is movable */
+#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */
+#define __GFP_MOVABLE  ((__force gfp_t)0x100000u)  /* Page is movable */
 
-#define __GFP_BITS_SHIFT 20    /* Room for 20 __GFP_FOO bits */
+#define __GFP_BITS_SHIFT 21    /* Room for 21 __GFP_FOO bits */
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
 
 /* This equals 0, but use constants in case they ever change */
 #define GFP_NOIO       (__GFP_WAIT)
 #define GFP_NOFS       (__GFP_WAIT | __GFP_IO)
 #define GFP_KERNEL     (__GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_TEMPORARY  (__GFP_WAIT | __GFP_IO | __GFP_FS | \
+                        __GFP_RECLAIMABLE)
 #define GFP_USER       (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
 #define GFP_HIGHUSER   (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
                         __GFP_HIGHMEM)
 #endif
 
 /* This mask makes up all the page movable related flags */
-#define GFP_MOVABLE_MASK (__GFP_MOVABLE)
+#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
 
 /* Control page allocator reclaim behavior */
 #define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
        return base + ZONE_NORMAL;
 }
 
+static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
+{
+       BUG_ON((gfp & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
+       return (gfp & ~(GFP_MOVABLE_MASK)) | migrate_flags;
+}
+
 /*
  * There is only one page-allocator function, and two main namespaces to
  * it. The alloc_page*() variants return 'struct page *' and as such
 
 
 #ifdef CONFIG_PAGE_GROUP_BY_MOBILITY
 #define MIGRATE_UNMOVABLE     0
-#define MIGRATE_MOVABLE       1
-#define MIGRATE_TYPES         2
+#define MIGRATE_RECLAIMABLE   1
+#define MIGRATE_MOVABLE       2
+#define MIGRATE_TYPES         3
 #else
 #define MIGRATE_UNMOVABLE     0
+#define MIGRATE_UNRECLAIMABLE 0
 #define MIGRATE_MOVABLE       0
 #define MIGRATE_TYPES         1
 #endif
 
 
 /* Bit indices that affect a whole block of pages */
 enum pageblock_bits {
-       PB_range(PB_migrate, 1), /* 1 bit required for migrate types */
+       PB_range(PB_migrate, 2), /* 2 bits required for migrate types */
        NR_PAGEBLOCK_BITS
 };
 
 
 #define SLAB_HWCACHE_ALIGN     0x00002000UL    /* Align objs on cache lines */
 #define SLAB_CACHE_DMA         0x00004000UL    /* Use GFP_DMA memory */
 #define SLAB_STORE_USER                0x00010000UL    /* DEBUG: Store the last owner for bug hunting */
-#define SLAB_RECLAIM_ACCOUNT   0x00020000UL    /* Objects are reclaimable */
 #define SLAB_PANIC             0x00040000UL    /* Panic if kmem_cache_create() fails */
 #define SLAB_DESTROY_BY_RCU    0x00080000UL    /* Defer freeing slabs to RCU */
 #define SLAB_MEM_SPREAD                0x00100000UL    /* Spread some memory over cpuset */
 #define SLAB_TRACE             0x00200000UL    /* Trace allocations and frees */
 
+/* The following flags affect the page allocator grouping pages by mobility */
+#define SLAB_RECLAIM_ACCOUNT   0x00020000UL            /* Objects are reclaimable */
+#define SLAB_TEMPORARY         SLAB_RECLAIM_ACCOUNT    /* Objects are short-lived */
 /*
  * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
  *
 
        ssize_t retval = 0;
        char *s;
 
-       if (!(page = (char *)__get_free_page(GFP_KERNEL)))
+       if (!(page = (char *)__get_free_page(GFP_TEMPORARY)))
                return -ENOMEM;
 
        s = page;
 
        struct radix_tree_node *ret;
        gfp_t gfp_mask = root_gfp_mask(root);
 
-       ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
+       ret = kmem_cache_alloc(radix_tree_node_cachep,
+                               set_migrateflags(gfp_mask, __GFP_RECLAIMABLE));
        if (ret == NULL && !(gfp_mask & __GFP_WAIT)) {
                struct radix_tree_preload *rtp;
 
        rtp = &__get_cpu_var(radix_tree_preloads);
        while (rtp->nr < ARRAY_SIZE(rtp->nodes)) {
                preempt_enable();
-               node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
+               node = kmem_cache_alloc(radix_tree_node_cachep,
+                               set_migrateflags(gfp_mask, __GFP_RECLAIMABLE));
                if (node == NULL)
                        goto out;
                preempt_disable();
 
 
 static inline int gfpflags_to_migratetype(gfp_t gfp_flags)
 {
-       return ((gfp_flags & __GFP_MOVABLE) != 0);
+       WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
+
+       return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
+               ((gfp_flags & __GFP_RECLAIMABLE) != 0);
 }
 
 #else
  * the free lists for the desirable migrate type are depleted
  */
 static int fallbacks[MIGRATE_TYPES][MIGRATE_TYPES-1] = {
-       [MIGRATE_UNMOVABLE] = { MIGRATE_MOVABLE   },
-       [MIGRATE_MOVABLE]   = { MIGRATE_UNMOVABLE },
+       [MIGRATE_UNMOVABLE]   = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE   },
+       [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE,   MIGRATE_MOVABLE   },
+       [MIGRATE_MOVABLE]     = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE },
 };
 
 /*
 
         * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE:
         * might be reconsidered if it ever diverges from PAGE_SIZE.
         *
-        * __GFP_MOVABLE is masked out as swap vectors cannot move
+        * Mobility flags are masked out as swap vectors cannot move
         */
-       return alloc_pages((gfp_mask & ~__GFP_MOVABLE) | __GFP_ZERO,
+       return alloc_pages((gfp_mask & ~GFP_MOVABLE_MASK) | __GFP_ZERO,
                                PAGE_CACHE_SHIFT-PAGE_SHIFT);
 }
 
 
 #endif
 
        flags |= cachep->gfpflags;
+       if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
+               flags |= __GFP_RECLAIMABLE;
 
        page = alloc_pages_node(nodeid, flags, cachep->gfporder);
        if (!page)
 
        if (s->flags & SLAB_CACHE_DMA)
                flags |= SLUB_DMA;
 
+       if (s->flags & SLAB_RECLAIM_ACCOUNT)
+               flags |= __GFP_RECLAIMABLE;
+
        if (node == -1)
                page = alloc_pages(flags, s->order);
        else