From: Mel Gorman A number of slab caches are reclaimable and some of their allocation callsites were updated to use the __GFP_RECLAIMABLE flag. However, slabs that are reclaimable specify the SLAB_ACCOUNT_RECLAIM flag at creation time and this information is available at the time of page allocation. This patch uses the SLAB_ACCOUNT_RECLAIM flag in the SLAB and SLUB allocators to determine if __GFP_RECLAIMABLE should be used when allocating pages. The SLOB allocator is not updated as it is unlikely to be used on a system where grouping pages by mobility is worthwhile and now SLUB is recommended over SLOB for smaller systems. The callsites for reclaimable cache allocations no longer specify __GFP_RECLAIMABLE as the information is redundant. This can be considered as fix to group-short-lived-and-reclaimable-kernel-allocations.patch. Credit goes to Christoph Lameter for identifying this problem during review and suggesting this fix. Signed-off-by: Mel Gorman Acked-by: Andy Whitcroft Acked-by: Christoph Lameter Signed-off-by: Andrew Morton --- fs/dcache.c | 2 +- fs/ext2/super.c | 3 +-- fs/ext3/super.c | 2 +- fs/ntfs/inode.c | 4 ++-- fs/reiserfs/super.c | 3 +-- mm/slab.c | 2 ++ mm/slub.c | 3 +++ 7 files changed, 11 insertions(+), 8 deletions(-) diff -puN fs/dcache.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used fs/dcache.c --- a/fs/dcache.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/fs/dcache.c @@ -898,7 +898,7 @@ struct dentry *d_alloc(struct dentry * p struct dentry *dentry; char *dname; - dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL|__GFP_RECLAIMABLE); + dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); if (!dentry) return NULL; diff -puN fs/ext2/super.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used fs/ext2/super.c --- a/fs/ext2/super.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/fs/ext2/super.c @@ -140,8 +140,7 @@ static struct kmem_cache * ext2_inode_ca static struct inode *ext2_alloc_inode(struct super_block *sb) { struct ext2_inode_info *ei; - ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, - GFP_KERNEL|__GFP_RECLAIMABLE); + ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL); if (!ei) return NULL; #ifdef CONFIG_EXT2_FS_POSIX_ACL diff -puN fs/ext3/super.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used fs/ext3/super.c --- a/fs/ext3/super.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/fs/ext3/super.c @@ -445,7 +445,7 @@ static struct inode *ext3_alloc_inode(st { struct ext3_inode_info *ei; - ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS|__GFP_RECLAIMABLE); + ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); if (!ei) return NULL; #ifdef CONFIG_EXT3_FS_POSIX_ACL diff -puN fs/ntfs/inode.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used fs/ntfs/inode.c --- a/fs/ntfs/inode.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/fs/ntfs/inode.c @@ -323,7 +323,7 @@ struct inode *ntfs_alloc_big_inode(struc ntfs_inode *ni; ntfs_debug("Entering."); - ni = kmem_cache_alloc(ntfs_big_inode_cache, GFP_NOFS|__GFP_RECLAIMABLE); + ni = kmem_cache_alloc(ntfs_big_inode_cache, GFP_NOFS); if (likely(ni != NULL)) { ni->state = 0; return VFS_I(ni); @@ -348,7 +348,7 @@ static inline ntfs_inode *ntfs_alloc_ext ntfs_inode *ni; ntfs_debug("Entering."); - ni = kmem_cache_alloc(ntfs_inode_cache, GFP_NOFS|__GFP_RECLAIMABLE); + ni = kmem_cache_alloc(ntfs_inode_cache, GFP_NOFS); if (likely(ni != NULL)) { ni->state = 0; return ni; diff -puN fs/reiserfs/super.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used fs/reiserfs/super.c --- a/fs/reiserfs/super.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/fs/reiserfs/super.c @@ -496,8 +496,7 @@ static struct inode *reiserfs_alloc_inod { struct reiserfs_inode_info *ei; ei = (struct reiserfs_inode_info *) - kmem_cache_alloc(reiserfs_inode_cachep, - GFP_KERNEL|__GFP_RECLAIMABLE); + kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL); if (!ei) return NULL; return &ei->vfs_inode; diff -puN mm/slab.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used mm/slab.c --- a/mm/slab.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/mm/slab.c @@ -1651,6 +1651,8 @@ static void *kmem_getpages(struct kmem_c #endif flags |= cachep->gfpflags; + if (cachep->flags & SLAB_RECLAIM_ACCOUNT) + flags |= __GFP_RECLAIMABLE; page = alloc_pages_node(nodeid, flags, cachep->gfporder); if (!page) diff -puN mm/slub.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used mm/slub.c --- a/mm/slub.c~group-short-lived-and-reclaimable-kernel-allocations-use-slab_account_reclaim-to-determine-when-__gfp_reclaimable-should-be-used +++ a/mm/slub.c @@ -969,6 +969,9 @@ static struct page *allocate_slab(struct if (s->flags & SLAB_CACHE_DMA) flags |= SLUB_DMA; + if (s->flags & SLAB_ACCOUNT_RECLAIM) + gfpflags |= __GFP_RECLAIMABLE; + if (node == -1) page = alloc_pages(flags, s->order); else _