memcg/kmem: switch to white list policy
Subsystems (57)
v2 cover memcg/kmem: switch to white list policy
Hi,
Currently, all kmem allocations (namely every kmem_cache_alloc, kmalloc, alloc_kmem_pages call) are accounted to memory cgroup automatically. Callers have to explicitly opt out if they don't want/need accounting for some reason. Such a design decision leads to several problems:
- kmalloc users are highly sensitive to failures, many of them implicitly rely on the fact that kmalloc never fails, while memcg makes failures quite plausible.
- A lot of objects are shared among different containers by design. Accounting such objects to one of containers is just unfair. Moreover, it might lead to pinning a dead memcg along with its kmem caches, which aren't tiny, which might result in noticeable increase in memory consumption for no apparent reason in the long run.
- There are tons of short-lived objects. Accounting them to memcg will only result in slight noise and won't change the overall picture, but we still have to pay accounting overhead.
For more info, see
- http://lkml.kernel.org/r/20151105144002.GB15111%40dhcp22.suse.cz
- http://lkml.kernel.org/r/20151106090555.GK29259@esperanza
Therefore this patch switches to the white list policy. Now kmalloc users have to explicitly opt in by passing __GFP_ACCOUNT flag.
Currently, the list of accounted objects is quite limited and only includes those allocations that (1) are known to be easily triggered from userspace and (2) can fail gracefully (for the full list see patch no. 6) and it still misses many object types. However, accounting only those objects should be a satisfactory approximation of the behavior we used to have for most sane workloads.
Changes in v2:
- add and use SLAB_ACCOUNT flag (Tejun)
v1: http://marc.info/?l=linux-mm&m=144692684713032&w=2
Thanks,
Vladimir Davydov (6):
Revert "kernfs: do not account ino_ida allocations to memcg" Revert "gfp: add __GFP_NOACCOUNT"
memcg: only account kmem allocations marked as __GFP_ACCOUNT
slab: add SLAB_ACCOUNT flag
vmalloc: allow to account vmalloc to memcg
Account certain kmem allocations to memcg
arch/powerpc/platforms/cell/spufs/inode.c | 2 +- drivers/staging/lustre/lustre/llite/super25.c | 3 ++- fs/9p/v9fs.c | 2 +- fs/adfs/super.c | 2 +- fs/affs/super.c | 2 +- fs/afs/super.c | 2 +- fs/befs/linuxvfs.c | 2 +- fs/bfs/inode.c | 2 +- fs/block_dev.c | 2 +- fs/btrfs/inode.c | 3 ++- fs/ceph/super.c | 4 ++-- fs/cifs/cifsfs.c | 2 +- fs/coda/inode.c | 6 +++--- fs/dcache.c | 5 +++-- fs/ecryptfs/main.c | 6 ++++-- fs/efs/super.c | 6 +++--- fs/exofs/super.c | 4 ++-- fs/ext2/super.c | 2 +- fs/ext4/super.c | 2 +- fs/f2fs/super.c | 5 +++-- fs/fat/inode.c | 2 +- fs/file.c | 7 ++++--- fs/fuse/inode.c | 4 ++-- fs/gfs2/main.c | 3 ++- fs/hfs/super.c | 4 ++-- fs/hfsplus/super.c | 2 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hpfs/super.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 2 +- fs/isofs/inode.c | 2 +- fs/jffs2/super.c | 2 +- fs/jfs/super.c | 2 +- fs/kernfs/dir.c | 9 +-------- fs/logfs/inode.c | 3 ++- fs/minix/inode.c | 2 +- fs/ncpfs/inode.c | 2 +- fs/nfs/inode.c | 2 +- fs/nilfs2/super.c | 3 ++- fs/ntfs/super.c | 4 ++-- fs/ocfs2/dlmfs/dlmfs.c | 2 +- fs/ocfs2/super.c | 2 +- fs/openpromfs/inode.c | 2 +- fs/proc/inode.c | 3 ++- fs/qnx4/inode.c | 2 +- fs/qnx6/inode.c | 2 +- fs/reiserfs/super.c | 3 ++- fs/romfs/super.c | 4 ++-- fs/squashfs/super.c | 3 ++- fs/sysv/inode.c | 2 +- fs/ubifs/super.c | 4 ++-- fs/udf/super.c | 3 ++- fs/ufs/super.c | 2 +- fs/xfs/kmem.h | 1 + fs/xfs/xfs_super.c | 4 ++-- include/linux/gfp.h | 6 ++++-- include/linux/memcontrol.h | 15 +++++++-------- include/linux/slab.h | 5 +++++ include/linux/thread_info.h | 5 +++-- ipc/mqueue.c | 2 +- kernel/cred.c | 4 ++-- kernel/delayacct.c | 2 +- kernel/fork.c | 22 +++++++++++++--------- kernel/pid.c | 2 +- mm/kmemleak.c | 3 +-- mm/memcontrol.c | 8 +++++++- mm/nommu.c | 2 +- mm/page_alloc.c | 3 ++- mm/rmap.c | 6 ++++-- mm/shmem.c | 2 +- mm/slab.h | 5 +++-- mm/slab_common.c | 3 ++- mm/slub.c | 2 ++ mm/vmalloc.c | 6 +++--- net/socket.c | 2 +- net/sunrpc/rpc_pipe.c | 2 +- 76 files changed, 151 insertions(+), 120 deletions(-)
Signature · 1 line
2.1.4
PATCH v2 1/6 Revert "kernfs: do not account ino_ida allocations to memcg"
This reverts commit 499611ed451508a42d1d7d1faff10177827755d5.
Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series.
--- fs/kernfs/dir.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
fs/kernfs/dir.c +1 -8
@@ -541,14 +541,7 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,if (!kn) goto err_out1; -/* -* If the ino of the sysfs entry created for a kmem cache gets -* allocated from an ida layer, which is accounted to the memcg that -* owns the cache, the memcg will get pinned forever. So do not account -* ino ida allocations. -*/ - ret =ida_simple_get (&root->ino_ida,1 ,0 , -GFP_KERNEL | __GFP_NOACCOUNT); + ret =ida_simple_get (&root->ino_ida,1 ,0 ,GFP_KERNEL );if (ret <0 ) goto err_out2; kn->ino = ret;
Signature · 7 lines
2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v2 1/6] Revert "kernfs: do not account ino_ida allocations to memcg"
Quoted 9 lines · Vladimir Davydov
This reverts commit
499611ed451508a42d1d7d1faff10177827755d5.Black-list kmem accounting policy (aka
__GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
Quoted 5 lines
So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series.
Signed-off-by Vladimir Davydov <[email protected]>
PATCH v2 2/6 Revert "gfp: add __GFP_NOACCOUNT"
In reply to Vladimir DavydovThis reverts commit 8f4fc071b1926d0b20336e2b3f8ab85c94c734c5.
Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series.
Conflicts:
include/linux/memcontrol.h
--- include/linux/gfp.h | 2 -- include/linux/memcontrol.h | 2 -- mm/kmemleak.c | 3 +-- 3 files changed, 1 insertion(+), 6 deletions(-)
include/linux/gfp.h +0 -2
@@ -30,7 +30,6 @@ struct vm_area_struct;#define ___GFP_HARDWALL 0x20000u#define ___GFP_THISNODE 0x40000u#define ___GFP_RECLAIMABLE 0x80000u -#define ___GFP_NOACCOUNT 0x100000u#define ___GFP_NOTRACK 0x200000u#define ___GFP_NO_KSWAPD 0x400000u#define ___GFP_OTHER_NODE 0x800000u
@@ -91,7 +90,6 @@ struct vm_area_struct;#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL)/* Enforce hardwall cpuset memory allocs */ #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)/* Page is reclaimable */ -#define __GFP_NOACCOUNT ((__force gfp_t)___GFP_NOACCOUNT)/* Don't account to kmemcg */ #define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK)/* Don't track with kmemcheck */ #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)
include/linux/memcontrol.h +0 -2
@@ -773,8 +773,6 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) {if (!memcg_kmem_enabled ())return true; -if (gfp & __GFP_NOACCOUNT) -return true;if (in_interrupt () || (!current->mm) || (current->flags &PF_KTHREAD ))return true;return false;
mm/kmemleak.c +1 -2
@@ -122,8 +122,7 @@#define BYTES_PER_POINTER sizeof(void *)/* GFP bitmask for kmemleak internal allocations */ -#define gfp_kmemleak_mask (gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \ - __GFP_NOACCOUNT)) | \ +#define gfp_kmemleak_mask (gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \ __GFP_NORETRY | __GFP_NOMEMALLOC | \ __GFP_NOWARN)
Signature · 7 lines
2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v2 2/6] Revert "gfp: add __GFP_NOACCOUNT"
Quoted 9 lines · Vladimir Davydov
This reverts commit
8f4fc071b1926d0b20336e2b3f8ab85c94c734c5.Black-list kmem accounting policy (aka
__GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
Quoted 5 lines
So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series.
Signed-off-by Vladimir Davydov <[email protected]>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v2 3/6 memcg: only account kmem allocations marked as __GFP_ACCOUNT
In reply to Vladimir DavydovBlack-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
So this patch switches kmem accounting to the white-policy: now only those kmem allocations that are marked as __GFP_ACCOUNT are accounted to memcg. Currently, no kmem allocations are marked like this. The following patches will mark several kmem allocations that are known to be easily triggered from userspace and therefore should be accounted to memcg.
--- include/linux/gfp.h | 4 ++++ include/linux/memcontrol.h | 2 ++ mm/page_alloc.c | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-)
include/linux/gfp.h +4 -0
@@ -30,6 +30,7 @@ struct vm_area_struct;#define ___GFP_HARDWALL 0x20000u#define ___GFP_THISNODE 0x40000u#define ___GFP_RECLAIMABLE 0x80000u +#define ___GFP_ACCOUNT 0x100000u#define ___GFP_NOTRACK 0x200000u#define ___GFP_NO_KSWAPD 0x400000u#define ___GFP_OTHER_NODE 0x800000u
@@ -90,6 +91,8 @@ struct vm_area_struct;#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL)/* Enforce hardwall cpuset memory allocs */ #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)/* Page is reclaimable */ +#define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT)/* Account to memcg (only relevant +* to kmem allocations) */ #define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK)/* Don't track with kmemcheck */ #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)
@@ -112,6 +115,7 @@ struct vm_area_struct;#define GFP_NOIO (__GFP_WAIT)#define GFP_NOFS (__GFP_WAIT | __GFP_IO)#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT)#define GFP_TEMPORARY (__GFP_WAIT | __GFP_IO | __GFP_FS | \ __GFP_RECLAIMABLE)#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
include/linux/memcontrol.h +2 -0
@@ -773,6 +773,8 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) {if (!memcg_kmem_enabled ())return true; +if (!(gfp & __GFP_ACCOUNT)) +return true;if (in_interrupt () || (!current->mm) || (current->flags &PF_KTHREAD ))return true;return false;
mm/page_alloc.c +2 -1
@@ -3420,7 +3420,8 @@ EXPORT_SYMBOL(__free_page_frag);/* * alloc_kmem_pages charges newly allocated pages to the kmem resource counter -* of the current memory cgroup. +* of the current memory cgroup if __GFP_ACCOUNT is set, other than that it is +* equivalent to alloc_pages. * * It should be used when the caller would like to use kmalloc, but since the * allocation is large, it has to fall back to the page allocator.
Signature · 7 lines
2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v2 3/6] memcg: only account kmem allocations marked as __GFP_ACCOUNT
Quoted 7 lines · Vladimir Davydov
Black-list kmem accounting policy (aka
__GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
Quoted 8 lines
So this patch switches kmem accounting to the white-policy: now only those kmem allocations that are marked as
__GFP_ACCOUNTare accounted to memcg. Currently, no kmem allocations are marked like this. The following patches will mark several kmem allocations that are known to be easily triggered from userspace and therefore should be accounted to memcg.Signed-off-by Vladimir Davydov <[email protected]>
As mentioned previously I would simply squash 1-3 into a single patch. Anyway
Quoted 64 lines
--- include/linux/gfp.h | 4 ++++ include/linux/memcontrol.h | 2 ++ mm/page_alloc.c | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-)include/linux/gfp.h +4
-0@@ -30,6 +30,7 @@ struct vm_area_struct;#define ___GFP_HARDWALL 0x20000u#define ___GFP_THISNODE 0x40000u#define ___GFP_RECLAIMABLE 0x80000u +#define ___GFP_ACCOUNT 0x100000u#define ___GFP_NOTRACK 0x200000u#define ___GFP_NO_KSWAPD 0x400000u#define ___GFP_OTHER_NODE 0x800000u@@ -90,6 +91,8 @@ struct vm_area_struct;#define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL)/* Enforce hardwall cpuset memory allocs */ #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)/* Page is reclaimable */ +#define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT)/* Account to memcg (only relevant +* to kmem allocations) */ #define __GFP_NOTRACK ((__force gfp_t)___GFP_NOTRACK)/* Don't track with kmemcheck */ #define __GFP_NO_KSWAPD ((__force gfp_t)___GFP_NO_KSWAPD)@@ -112,6 +115,7 @@ struct vm_area_struct;#define GFP_NOIO (__GFP_WAIT)#define GFP_NOFS (__GFP_WAIT | __GFP_IO)#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT)#define GFP_TEMPORARY (__GFP_WAIT | __GFP_IO | __GFP_FS | \ __GFP_RECLAIMABLE)#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)include/linux/memcontrol.h +2
-0@@ -773,6 +773,8 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) {if (!memcg_kmem_enabled ())return true; +if (!(gfp & __GFP_ACCOUNT)) +return true;if (in_interrupt () || (!current->mm) || (current->flags &PF_KTHREAD ))return true;return false;mm/page_alloc.c +2
-1@@ -3420,7 +3420,8 @@ EXPORT_SYMBOL(__free_page_frag);/* * alloc_kmem_pages charges newly allocated pages to the kmem resource counter -* of the current memory cgroup. +* of the current memory cgroup if __GFP_ACCOUNT is set, other than that it is +* equivalent to alloc_pages. * * It should be used when the caller would like to use kmalloc, but since the * allocation is large, it has to fall back to the page allocator. Signature · 1 line
2.1.4
Signature · 2 lines
Michal Hocko SUSE Labs
Re: [PATCH v2 3/6] memcg: only account kmem allocations marked as __GFP_ACCOUNT
In reply to Vladimir DavydovQuoted 7 lines · Vladimir Davydov
Black-list kmem accounting policy (aka
__GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches.
Quoted 8 lines
So this patch switches kmem accounting to the white-policy: now only those kmem allocations that are marked as
__GFP_ACCOUNTare accounted to memcg. Currently, no kmem allocations are marked like this. The following patches will mark several kmem allocations that are known to be easily triggered from userspace and therefore should be accounted to memcg.Signed-off-by Vladimir Davydov <[email protected]>
PATCH v2 4/6 slab: add SLAB_ACCOUNT flag
In reply to Vladimir DavydovCurrently, if we want to account all objects of a particular kmem cache, we have to pass __GFP_ACCOUNT to each kmem_cache_alloc call, which is inconvenient. This patch introduces SLAB_ACCOUNT flag which if passed to kmem_cache_create will force accounting for every allocation from this cache even if __GFP_ACCOUNT is not passed.
This patch does not make any of the existing caches use this flag - it will be done later in the series.
Note, a cache with SLAB_ACCOUNT cannot be merged with a cache w/o SLAB_ACCOUNT, i.e. using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).
--- include/linux/memcontrol.h | 15 +++++++-------- include/linux/slab.h | 5 +++++ mm/memcontrol.c | 8 +++++++- mm/slab.h | 5 +++-- mm/slab_common.c | 3 ++- mm/slub.c | 2 ++ 6 files changed, 26 insertions(+), 12 deletions(-)
include/linux/memcontrol.h +7 -8
@@ -766,15 +766,13 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg)return memcg ? memcg->kmemcg_id :-1 ; } -struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep); +struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep,gfp_t gfp);void __memcg_kmem_put_cache (struct kmem_cache *cachep); -static inline bool __memcg_kmem_bypass (gfp_t gfp) +static inline bool __memcg_kmem_bypass (void ) {if (!memcg_kmem_enabled ())return true; -if (!(gfp & __GFP_ACCOUNT)) -return true;if (in_interrupt () || (!current->mm) || (current->flags &PF_KTHREAD ))return true;return false;
@@ -791,7 +789,9 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) static __always_inline int memcg_kmem_charge(struct page *page,gfp_t gfp,int order) { -if (__memcg_kmem_bypass (gfp)) +if (__memcg_kmem_bypass ()) +return 0 ; +if (!(gfp & __GFP_ACCOUNT))return 0 ;return __memcg_kmem_charge (page, gfp, order); }
@@ -810,16 +810,15 @@ static __always_inline void memcg_kmem_uncharge(struct page *page, int order)/** * memcg_kmem_get_cache: selects the correct per-memcg cache for allocation * @cachep: the original global kmem cache -* @gfp: allocation flags. * * All memory allocated from a per-memcg cache is charged to the owner memcg. */ static __always_inline struct kmem_cache *memcg_kmem_get_cache (struct kmem_cache *cachep,gfp_t gfp) { -if (__memcg_kmem_bypass (gfp)) +if (__memcg_kmem_bypass ())return cachep; -return __memcg_kmem_get_cache (cachep); +return __memcg_kmem_get_cache (cachep, gfp); } static __always_inline void memcg_kmem_put_cache(struct kmem_cache *cachep)
include/linux/slab.h +5 -0
@@ -86,6 +86,11 @@#else # define SLAB_FAILSLAB 0x00000000UL#endif +#ifdef CONFIG_MEMCG_KMEM +# define SLAB_ACCOUNT 0x04000000UL/* Account to memcg */ +#else +# define SLAB_ACCOUNT 0x00000000UL +#endif /* The following flags affect the page allocator grouping pages by mobility */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL/* Objects are reclaimable */
mm/memcontrol.c +7 -1
@@ -2332,7 +2332,7 @@ static void memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg,* Can't be called in interrupt context or from kernel threads. * This function needs to be called with rcu_read_lock() held. */ -struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep) +struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep,gfp_t gfp) {struct mem_cgroup *memcg;struct kmem_cache *memcg_cachep;
@@ -2340,6 +2340,12 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep)VM_BUG_ON (!is_root_cache (cachep)); +if (cachep->flags &SLAB_ACCOUNT ) + gfp |= __GFP_ACCOUNT; + +if (!(gfp & __GFP_ACCOUNT)) +return cachep; +if (current->memcg_kmem_skip_account)return cachep;
mm/slab.h +3 -2
@@ -128,10 +128,11 @@ static inline unsigned long kmem_cache_flags(unsigned long object_size,#if defined(CONFIG_SLAB )#define SLAB_CACHE_FLAGS (SLAB_MEM_SPREAD | SLAB_NOLEAKTRACE | \ - SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | SLAB_NOTRACK) + SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | \ + SLAB_NOTRACK | SLAB_ACCOUNT)#elif defined(CONFIG_SLUB )#define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE | SLAB_RECLAIM_ACCOUNT | \ - SLAB_TEMPORARY | SLAB_NOTRACK) + SLAB_TEMPORARY | SLAB_NOTRACK | SLAB_ACCOUNT)#else #define SLAB_CACHE_FLAGS (0)#endif
mm/slab_common.c +2 -1
@@ -37,7 +37,8 @@ struct kmem_cache *kmem_cache; SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \ SLAB_FAILSLAB) -#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | SLAB_NOTRACK) +#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \ + SLAB_NOTRACK | SLAB_ACCOUNT)/* * Merge control. If this is set then no merging of slab caches will occur.
mm/slub.c +2 -0
@@ -5247,6 +5247,8 @@ static char *create_unique_id(struct kmem_cache *s) *p++ ='F' ;if (!(s->flags &SLAB_NOTRACK )) *p++ ='t' ; +if (s->flags &SLAB_ACCOUNT ) + *p++ ='A' ;if (p != name +1 ) *p++ ='-' ; p +=sprintf (p,"%07d" , s->size);
Signature · 7 lines
2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Tejun Heo
maintainerRe: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
Quoted 6 lines · Vladimir Davydov
Currently, if we want to account all objects of a particular kmem cache, we have to pass
__GFP_ACCOUNTto eachkmem_cache_alloccall, which is inconvenient. This patch introducesSLAB_ACCOUNTflag which if passed tokmem_cache_createwill force accounting for every allocation from this cache even if__GFP_ACCOUNTis not passed.
Quoted 6 lines
This patch does not make any of the existing caches use this flag - it will be done later in the series.
Note, a cache with
SLAB_ACCOUNTcannot be merged with a cache w/oSLAB_ACCOUNT, i.e. using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).
Am I correct in thinking that we should eventually be able to removed __GFP_ACCOUNT and that only caches explicitly marked with SLAB_ACCOUNT would need to be handled by kmemcg?
Thanks a lot for doing this!
Signature · 1 line
tejun
Re: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
Quoted 10 lines · Tejun Heo
Quoted 9 lines · Vladimir Davydov
Currently, if we want to account all objects of a particular kmem cache, we have to pass
__GFP_ACCOUNTto eachkmem_cache_alloccall, which is inconvenient. This patch introducesSLAB_ACCOUNTflag which if passed tokmem_cache_createwill force accounting for every allocation from this cache even if__GFP_ACCOUNTis not passed.This patch does not make any of the existing caches use this flag - it will be done later in the series.
Quoted 7 lines
Quoted 3 lines
Note, a cache with
SLAB_ACCOUNTcannot be merged with a cache w/oSLAB_ACCOUNT, i.e. using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).Am I correct in thinking that we should eventually be able to removed
__GFP_ACCOUNTand that only caches explicitly marked withSLAB_ACCOUNTwould need to be handled by kmemcg?
Don't think so, because sometimes we want to account kmalloc.
Thanks,
Vladimir
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Tejun Heo
maintainerRe: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
Hello,
Quoted 5 lines · Vladimir Davydov
Quoted 3 lines
Am I correct in thinking that we should eventually be able to removed
__GFP_ACCOUNTand that only caches explicitly marked withSLAB_ACCOUNTwould need to be handled by kmemcg?Don't think so, because sometimes we want to account kmalloc.
I'm kinda skeptical about that because if those allocations are occassional by nature, we don't care and if there can be a huge number of them, splitting them into a separate cache makes sense. I think it makes sense to pin down exactly which caches are memcg managed. That has the potential to simplify the involved code path and shave off a small bit of hot path overhead.
Thanks.
Signature · 1 line
tejun
Re: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
Quoted 7 lines · Tejun Heo
Hello,
Quoted 4 lines · Vladimir Davydov
Quoted 3 lines
Am I correct in thinking that we should eventually be able to removed
__GFP_ACCOUNTand that only caches explicitly marked withSLAB_ACCOUNTwould need to be handled by kmemcg?
Quoted 8 lines
Quoted 1 line
Don't think so, because sometimes we want to account kmalloc.
I'm kinda skeptical about that because if those allocations are occassional by nature, we don't care and if there can be a huge number of them, splitting them into a separate cache makes sense. I think it makes sense to pin down exactly which caches are memcg managed. That has the potential to simplify the involved code path and shave off a small bit of hot path overhead.
What about external_name allocation in __d_alloc? Is it occasional? Depends on the workload I guess. Can we create a separate cache for it? No, because its size is variable. There are other things like that, e.g. pipe_buffer array.
Thanks,
Vladimir
Tejun Heo
maintainerRe: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
Hello, Vladimir.
Quoted 4 lines · Vladimir Davydov
What about
external_nameallocation in__d_alloc? Is it occasional? Depends on the workload I guess. Can we create a separate cache for it? No, because its size is variable. There are other things like that, e.g.pipe_bufferarray.
You're right. Ah, it was so close. :(
Signature · 1 line
tejun
Re: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
In reply to Vladimir DavydovQuoted 5 lines · Vladimir Davydov
Currently, if we want to account all objects of a particular kmem cache, we have to pass
__GFP_ACCOUNTto eachkmem_cache_alloccall, which is inconvenient. This patch introducesSLAB_ACCOUNTflag which if passed tokmem_cache_createwill force accounting for every allocation from this cache even if__GFP_ACCOUNTis not passed.
Yes this is much better and less error prone for dedicated caches.
Quoted 6 lines
This patch does not make any of the existing caches use this flag - it will be done later in the series.
Note, a cache with
SLAB_ACCOUNTcannot be merged with a cache w/oSLAB_ACCOUNT, i.e. using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).
I would expect some reasoning why this is the case. Why cannot caches of the same memcg be merged? I remember you have mentioned something in the previous discussion with Tejun but it should be in the changelog as well IMO.
Quoted 2 lines
Suggested-by Tejun Heo <[email protected]>Signed-off-by Vladimir Davydov <[email protected]>
I am not sufficiently qualified to judge the slab implementation specifics but for the overal approach
Quoted 150 lines
--- include/linux/memcontrol.h | 15 +++++++-------- include/linux/slab.h | 5 +++++ mm/memcontrol.c | 8 +++++++- mm/slab.h | 5 +++-- mm/slab_common.c | 3 ++- mm/slub.c | 2 ++ 6 files changed, 26 insertions(+), 12 deletions(-)include/linux/memcontrol.h +7
-8@@ -766,15 +766,13 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg)return memcg ? memcg->kmemcg_id :-1 ; } -struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep); +struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep,gfp_t gfp);void __memcg_kmem_put_cache (struct kmem_cache *cachep); -static inline bool __memcg_kmem_bypass (gfp_t gfp) +static inline bool __memcg_kmem_bypass (void ) {if (!memcg_kmem_enabled ())return true; -if (!(gfp & __GFP_ACCOUNT)) -return true;if (in_interrupt () || (!current->mm) || (current->flags &PF_KTHREAD ))return true;return false;@@ -791,7 +789,9 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) static __always_inline int memcg_kmem_charge(struct page *page,gfp_t gfp,int order) { -if (__memcg_kmem_bypass (gfp)) +if (__memcg_kmem_bypass ()) +return 0 ; +if (!(gfp & __GFP_ACCOUNT))return 0 ;return __memcg_kmem_charge (page, gfp, order); }@@ -810,16 +810,15 @@ static __always_inline void memcg_kmem_uncharge(struct page *page, int order)/** * memcg_kmem_get_cache: selects the correct per-memcg cache for allocation * @cachep: the original global kmem cache -* @gfp: allocation flags. * * All memory allocated from a per-memcg cache is charged to the owner memcg. */ static __always_inline struct kmem_cache *memcg_kmem_get_cache (struct kmem_cache *cachep,gfp_t gfp) { -if (__memcg_kmem_bypass (gfp)) +if (__memcg_kmem_bypass ())return cachep; -return __memcg_kmem_get_cache (cachep); +return __memcg_kmem_get_cache (cachep, gfp); } static __always_inline void memcg_kmem_put_cache(struct kmem_cache *cachep)include/linux/slab.h +5
-0@@ -86,6 +86,11 @@#else # define SLAB_FAILSLAB 0x00000000UL#endif +#ifdef CONFIG_MEMCG_KMEM +# define SLAB_ACCOUNT 0x04000000UL/* Account to memcg */ +#else +# define SLAB_ACCOUNT 0x00000000UL +#endif /* The following flags affect the page allocator grouping pages by mobility */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL/* Objects are reclaimable */ mm/memcontrol.c +7
-1@@ -2332,7 +2332,7 @@ static void memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg,* Can't be called in interrupt context or from kernel threads. * This function needs to be called with rcu_read_lock() held. */ -struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep) +struct kmem_cache *__memcg_kmem_get_cache (struct kmem_cache *cachep,gfp_t gfp) {struct mem_cgroup *memcg;struct kmem_cache *memcg_cachep;@@ -2340,6 +2340,12 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep)VM_BUG_ON (!is_root_cache (cachep)); +if (cachep->flags &SLAB_ACCOUNT ) + gfp |= __GFP_ACCOUNT; + +if (!(gfp & __GFP_ACCOUNT)) +return cachep; +if (current->memcg_kmem_skip_account)return cachep;mm/slab.h +3
-2@@ -128,10 +128,11 @@ static inline unsigned long kmem_cache_flags(unsigned long object_size,#if defined(CONFIG_SLAB )#define SLAB_CACHE_FLAGS (SLAB_MEM_SPREAD | SLAB_NOLEAKTRACE | \ - SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | SLAB_NOTRACK) + SLAB_RECLAIM_ACCOUNT | SLAB_TEMPORARY | \ + SLAB_NOTRACK | SLAB_ACCOUNT)#elif defined(CONFIG_SLUB )#define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE | SLAB_RECLAIM_ACCOUNT | \ - SLAB_TEMPORARY | SLAB_NOTRACK) + SLAB_TEMPORARY | SLAB_NOTRACK | SLAB_ACCOUNT)#else #define SLAB_CACHE_FLAGS (0)#endif mm/slab_common.c +2
-1@@ -37,7 +37,8 @@ struct kmem_cache *kmem_cache; SLAB_TRACE | SLAB_DESTROY_BY_RCU | SLAB_NOLEAKTRACE | \ SLAB_FAILSLAB) -#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | SLAB_NOTRACK) +#define SLAB_MERGE_SAME (SLAB_RECLAIM_ACCOUNT | SLAB_CACHE_DMA | \ + SLAB_NOTRACK | SLAB_ACCOUNT)/* * Merge control. If this is set then no merging of slab caches will occur. mm/slub.c +2
-0@@ -5247,6 +5247,8 @@ static char *create_unique_id(struct kmem_cache *s) *p++ ='F' ;if (!(s->flags &SLAB_NOTRACK )) *p++ ='t' ; +if (s->flags &SLAB_ACCOUNT ) + *p++ ='A' ;if (p != name +1 ) *p++ ='-' ; p +=sprintf (p,"%07d" , s->size);Signature · 1 line
2.1.4
Signature · 2 lines
Michal Hocko SUSE Labs
Re: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
Quoted 12 lines · Michal Hocko
Quoted 5 lines · Vladimir Davydov
Currently, if we want to account all objects of a particular kmem cache, we have to pass
__GFP_ACCOUNTto eachkmem_cache_alloccall, which is inconvenient. This patch introducesSLAB_ACCOUNTflag which if passed tokmem_cache_createwill force accounting for every allocation from this cache even if__GFP_ACCOUNTis not passed.Yes this is much better and less error prone for dedicated caches.
Quoted 3 lines
This patch does not make any of the existing caches use this flag - it will be done later in the series.
Quoted 8 lines
Quoted 3 lines
Note, a cache with
SLAB_ACCOUNTcannot be merged with a cache w/oSLAB_ACCOUNT, i.e. using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).I would expect some reasoning why this is the case. Why cannot caches of the same memcg be merged? I remember you have mentioned something in the previous discussion with Tejun but it should be in the changelog as well IMO.
Here goes an extended version of the last paragraph, hope it makes everything clear:
"""
Note, a cache with SLAB_ACCOUNT cannot be merged with a cache w/o SLAB_ACCOUNT, because merged caches share the same kmem_cache struct and hence cannot have different sets of SLAB_* flags. Thus using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).
"""
Andrew, could you please update the commit message?
Quoted 8 lines
Quoted 3 lines
Suggested-by Tejun Heo <[email protected]>Signed-off-by Vladimir Davydov <[email protected]>I am not sufficiently qualified to judge the slab implementation specifics but for the overal approach
Acked-by Michal Hocko <[email protected]>
Thanks!
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v2 4/6] slab: add SLAB_ACCOUNT flag
In reply to Vladimir DavydovQuoted 9 lines · Vladimir Davydov
Currently, if we want to account all objects of a particular kmem cache, we have to pass
__GFP_ACCOUNTto eachkmem_cache_alloccall, which is inconvenient. This patch introducesSLAB_ACCOUNTflag which if passed tokmem_cache_createwill force accounting for every allocation from this cache even if__GFP_ACCOUNTis not passed.This patch does not make any of the existing caches use this flag - it will be done later in the series.
Quoted 6 lines
Note, a cache with
SLAB_ACCOUNTcannot be merged with a cache w/oSLAB_ACCOUNT, i.e. using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in).Suggested-by Tejun Heo <[email protected]>Signed-off-by Vladimir Davydov <[email protected]>
PATCH v2 5/6 vmalloc: allow to account vmalloc to memcg
In reply to Vladimir DavydovThis patch makes vmalloc family functions allocate vmalloc area pages with alloc_kmem_pages so that if __GFP_ACCOUNT is set they will be accounted to memcg. This is needed, at least, to account alloc_fdmem allocations.
--- mm/vmalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/vmalloc.c +3 -3
@@ -1476,7 +1476,7 @@ static void __vunmap(const void *addr, int deallocate_pages)struct page *page = area->pages[i];BUG_ON (!page); -__free_page (page); +__free_kmem_pages (page,0 ); }if (area->flags &VM_VPAGES )
@@ -1607,9 +1607,9 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,struct page *page;if (node ==NUMA_NO_NODE ) - page =alloc_page (alloc_mask); + page =alloc_kmem_pages (alloc_mask, order);else - page =alloc_pages_node (node, alloc_mask, order); + page =alloc_kmem_pages_node (node, alloc_mask, order);if (unlikely (!page)) {/* Successfully allocated i pages, free them in __vunmap() */
Signature · 1 line
2.1.4
Re: [PATCH v2 5/6] vmalloc: allow to account vmalloc to memcg
Quoted 6 lines · Vladimir Davydov
This patch makes vmalloc family functions allocate vmalloc area pages with
alloc_kmem_pagesso that if__GFP_ACCOUNTis set they will be accounted to memcg. This is needed, at least, to accountalloc_fdmemallocations.Signed-off-by Vladimir Davydov <[email protected]>
PATCH v2 6/6 Account certain kmem allocations to memcg
In reply to Vladimir DavydovThis patch marks those kmem allocations that are known to be easily triggered from userspace as __GFP_ACCOUNT/SLAB_ACCOUNT, which makes them accounted to memcg. For the list, see below:
- threadinfo
- task_struct
- task_delay_info
- pid
- cred
- mm_struct
- vm_area_struct and vm_region (nommu)
- anon_vma and anon_vma_chain
- signal_struct
- sighand_struct
- fs_struct
- files_struct
- fdtable and fdtable->full_fds_bits
- dentry and external_name
- inode for all filesystems. This is the most tedious part, because most filesystems overwrite the alloc_inode method.
The list is by far not complete, so feel free to add more objects. Nevertheless, it should be close to "account everything" approach and keep most workloads within bounds. Malevolent users will be able to breach the limit, but this was possible even with the former "account everything" approach (simply because it did not account everything in fact).
--- arch/powerpc/platforms/cell/spufs/inode.c | 2 +- drivers/staging/lustre/lustre/llite/super25.c | 3 ++- fs/9p/v9fs.c | 2 +- fs/adfs/super.c | 2 +- fs/affs/super.c | 2 +- fs/afs/super.c | 2 +- fs/befs/linuxvfs.c | 2 +- fs/bfs/inode.c | 2 +- fs/block_dev.c | 2 +- fs/btrfs/inode.c | 3 ++- fs/ceph/super.c | 4 ++-- fs/cifs/cifsfs.c | 2 +- fs/coda/inode.c | 6 +++--- fs/dcache.c | 5 +++-- fs/ecryptfs/main.c | 6 ++++-- fs/efs/super.c | 6 +++--- fs/exofs/super.c | 4 ++-- fs/ext2/super.c | 2 +- fs/ext4/super.c | 2 +- fs/f2fs/super.c | 5 +++-- fs/fat/inode.c | 2 +- fs/file.c | 7 ++++--- fs/fuse/inode.c | 4 ++-- fs/gfs2/main.c | 3 ++- fs/hfs/super.c | 4 ++-- fs/hfsplus/super.c | 2 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hpfs/super.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 2 +- fs/isofs/inode.c | 2 +- fs/jffs2/super.c | 2 +- fs/jfs/super.c | 2 +- fs/logfs/inode.c | 3 ++- fs/minix/inode.c | 2 +- fs/ncpfs/inode.c | 2 +- fs/nfs/inode.c | 2 +- fs/nilfs2/super.c | 3 ++- fs/ntfs/super.c | 4 ++-- fs/ocfs2/dlmfs/dlmfs.c | 2 +- fs/ocfs2/super.c | 2 +- fs/openpromfs/inode.c | 2 +- fs/proc/inode.c | 3 ++- fs/qnx4/inode.c | 2 +- fs/qnx6/inode.c | 2 +- fs/reiserfs/super.c | 3 ++- fs/romfs/super.c | 4 ++-- fs/squashfs/super.c | 3 ++- fs/sysv/inode.c | 2 +- fs/ubifs/super.c | 4 ++-- fs/udf/super.c | 3 ++- fs/ufs/super.c | 2 +- fs/xfs/kmem.h | 1 + fs/xfs/xfs_super.c | 4 ++-- include/linux/thread_info.h | 5 +++-- ipc/mqueue.c | 2 +- kernel/cred.c | 4 ++-- kernel/delayacct.c | 2 +- kernel/fork.c | 22 +++++++++++++--------- kernel/pid.c | 2 +- mm/nommu.c | 2 +- mm/rmap.c | 6 ++++-- mm/shmem.c | 2 +- net/socket.c | 2 +- net/sunrpc/rpc_pipe.c | 2 +- 65 files changed, 114 insertions(+), 92 deletions(-)
arch/powerpc/platforms/cell/spufs/inode.c +1 -1
@@ -767,7 +767,7 @@ static int __init spufs_init(void) ret = -ENOMEM ; spufs_inode_cache =kmem_cache_create ("spufs_inode_cache" ,sizeof (struct spufs_inode_info ),0 , -SLAB_HWCACHE_ALIGN , spufs_init_once); +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , spufs_init_once);if (!spufs_inode_cache) goto out;
drivers/staging/lustre/lustre/llite/super25.c +2 -1
@@ -106,7 +106,8 @@ static int __init init_lustre_lite(void) rc = -ENOMEM ; ll_inode_cachep =kmem_cache_create ("lustre_inode_cache" ,sizeof (struct ll_inode_info ), -0 ,SLAB_HWCACHE_ALIGN ,NULL ); +0 ,SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , +NULL );if (ll_inode_cachep ==NULL ) goto out_cache;
fs/9p/v9fs.c +1 -1
@@ -575,7 +575,7 @@ static int v9fs_init_inode_cache(void) v9fs_inode_cache =kmem_cache_create ("v9fs_inode_cache" ,sizeof (struct v9fs_inode ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), v9fs_inode_init_once);if (!v9fs_inode_cache)return -ENOMEM ;
fs/adfs/super.c +1 -1
@@ -271,7 +271,7 @@ static int __init init_inodecache(void) adfs_inode_cachep =kmem_cache_create ("adfs_inode_cache" ,sizeof (struct adfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (adfs_inode_cachep ==NULL )return -ENOMEM ;
fs/affs/super.c +1 -1
@@ -132,7 +132,7 @@ static int __init init_inodecache(void) affs_inode_cachep =kmem_cache_create ("affs_inode_cache" ,sizeof (struct affs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (affs_inode_cachep ==NULL )return -ENOMEM ;
fs/afs/super.c +1 -1
@@ -91,7 +91,7 @@ int __init afs_fs_init(void) afs_inode_cachep =kmem_cache_create ("afs_inode_cache" ,sizeof (struct afs_vnode ),0 , -SLAB_HWCACHE_ALIGN , +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , afs_i_init_once);if (!afs_inode_cachep) {printk (KERN_NOTICE "kAFS: Failed to allocate inode cache\n" );
fs/befs/linuxvfs.c +1 -1
@@ -434,7 +434,7 @@ befs_init_inodecache(void) befs_inode_cachep =kmem_cache_create ("befs_inode_cache" ,sizeof (struct befs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (befs_inode_cachep ==NULL ) {pr_err ("%s: Couldn't initialize inode slabcache\n" , __func__);
fs/bfs/inode.c +1 -1
@@ -270,7 +270,7 @@ static int __init init_inodecache(void) bfs_inode_cachep =kmem_cache_create ("bfs_inode_cache" ,sizeof (struct bfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (bfs_inode_cachep ==NULL )return -ENOMEM ;
fs/block_dev.c +1 -1
@@ -567,7 +567,7 @@ void __init bdev_cache_init(void) bdev_cachep =kmem_cache_create ("bdev_cache" ,sizeof (struct bdev_inode ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD |SLAB_PANIC ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT |SLAB_PANIC ), init_once); err =register_filesystem (&bd_type);if (err)
fs/btrfs/inode.c +2 -1
@@ -9157,7 +9157,8 @@ int btrfs_init_cachep(void) { btrfs_inode_cachep =kmem_cache_create ("btrfs_inode" ,sizeof (struct btrfs_inode ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD |SLAB_ACCOUNT , + init_once);if (!btrfs_inode_cachep) goto fail;
fs/ceph/super.c +2 -2
@@ -639,8 +639,8 @@ static int __init init_caches(void) ceph_inode_cachep =kmem_cache_create ("ceph_inode_info" ,sizeof (struct ceph_inode_info ), __alignof__(struct ceph_inode_info ), - (SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD ), - ceph_inode_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , ceph_inode_init_once);if (ceph_inode_cachep ==NULL )return -ENOMEM ;
fs/cifs/cifsfs.c +1 -1
@@ -1040,7 +1040,7 @@ cifs_init_inodecache(void) cifs_inode_cachep =kmem_cache_create ("cifs_inode_cache" ,sizeof (struct cifsInodeInfo ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), cifs_init_once);if (cifs_inode_cachep ==NULL )return -ENOMEM ;
fs/coda/inode.c +3 -3
@@ -74,9 +74,9 @@ static void init_once(void *foo)int __init coda_init_inodecache (void ) { coda_inode_cachep =kmem_cache_create ("coda_inode_cache" , -sizeof (struct coda_inode_info ), -0 ,SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - init_once); +sizeof (struct coda_inode_info ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , init_once);if (coda_inode_cachep ==NULL )return -ENOMEM ;return 0 ;
fs/dcache.c +3 -2
@@ -1571,7 +1571,8 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) dentry->d_iname[DNAME_INLINE_LEN -1 ] =0 ;if (name->len >DNAME_INLINE_LEN -1 ) { size_t size = offsetof(struct external_name, name[1]); -struct external_name *p =kmalloc (size + name->len,GFP_KERNEL ); +struct external_name *p =kmalloc (size + name->len, +GFP_KERNEL_ACCOUNT );if (!p) {kmem_cache_free (dentry_cache, dentry);return NULL ;
@@ -3415,7 +3416,7 @@ static void __init dcache_init(void)* of the dcache. */ dentry_cache =KMEM_CACHE (dentry, -SLAB_RECLAIM_ACCOUNT |SLAB_PANIC |SLAB_MEM_SPREAD ); +SLAB_RECLAIM_ACCOUNT |SLAB_PANIC |SLAB_MEM_SPREAD |SLAB_ACCOUNT );/* Hash may have been set up in dcache_init_early */ if (!hashdist)
fs/ecryptfs/main.c +4 -2
@@ -663,6 +663,7 @@ static struct ecryptfs_cache_info {struct kmem_cache **cache;const char *name;size_t size; +unsigned long flags;void (*ctor)(void *obj); } ecryptfs_cache_infos[] = { {
@@ -684,6 +685,7 @@ static struct ecryptfs_cache_info { .cache = &ecryptfs_inode_info_cache, .name = "ecryptfs_inode_cache", .size = sizeof(struct ecryptfs_inode_info), + .flags = SLAB_ACCOUNT, .ctor = inode_info_init_once, }, {
@@ -755,8 +757,8 @@ static int ecryptfs_init_kmem_caches(void)struct ecryptfs_cache_info *info; info = &ecryptfs_cache_infos[i]; - *(info->cache) =kmem_cache_create (info->name, info->size, -0 ,SLAB_HWCACHE_ALIGN , info->ctor); + *(info->cache) =kmem_cache_create (info->name, info->size,0 , +SLAB_HWCACHE_ALIGN | info->flags, info->ctor);if (!*(info->cache)) {ecryptfs_free_kmem_caches (); ecryptfs_printk(KERN_WARNING, "%s: "
fs/efs/super.c +3 -3
@@ -94,9 +94,9 @@ static void init_once(void *foo)static int __init init_inodecache (void ) { efs_inode_cachep =kmem_cache_create ("efs_inode_cache" , -sizeof (struct efs_inode_info ), -0 ,SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - init_once); +sizeof (struct efs_inode_info ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , init_once);if (efs_inode_cachep ==NULL )return -ENOMEM ;return 0 ;
fs/exofs/super.c +2 -2
@@ -194,8 +194,8 @@ static int init_inodecache(void) { exofs_inode_cachep =kmem_cache_create ("exofs_inode_cache" ,sizeof (struct exofs_i_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - exofs_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , exofs_init_once);if (exofs_inode_cachep ==NULL )return -ENOMEM ;return 0 ;
fs/ext2/super.c +1 -1
@@ -200,7 +200,7 @@ static int __init init_inodecache(void) ext2_inode_cachep =kmem_cache_create ("ext2_inode_cache" ,sizeof (struct ext2_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ext2_inode_cachep ==NULL )return -ENOMEM ;
fs/ext4/super.c +1 -1
@@ -966,7 +966,7 @@ static int __init init_inodecache(void) ext4_inode_cachep =kmem_cache_create ("ext4_inode_cache" ,sizeof (struct ext4_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ext4_inode_cachep ==NULL )return -ENOMEM ;
fs/f2fs/super.c +3 -2
@@ -1424,8 +1424,9 @@ MODULE_ALIAS_FS("f2fs");static int __init init_inodecache (void ) { - f2fs_inode_cachep =f2fs_kmem_cache_create ("f2fs_inode_cache" , -sizeof (struct f2fs_inode_info )); + f2fs_inode_cachep =kmem_cache_create ("f2fs_inode_cache" , +sizeof (struct f2fs_inode_info ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT ,NULL );if (!f2fs_inode_cachep)return -ENOMEM ;return 0 ;
fs/fat/inode.c +1 -1
@@ -677,7 +677,7 @@ static int __init fat_init_inodecache(void) fat_inode_cachep =kmem_cache_create ("fat_inode_cache" ,sizeof (struct msdos_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (fat_inode_cachep ==NULL )return -ENOMEM ;
fs/file.c +4 -3
@@ -37,11 +37,12 @@ static void *alloc_fdmem(size_t size)* vmalloc() if the allocation size will be considered "large" by the VM. */ if (size <= (PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) { -void *data =kmalloc (size,GFP_KERNEL |__GFP_NOWARN|__GFP_NORETRY); +void *data =kmalloc (size,GFP_KERNEL_ACCOUNT | + __GFP_NOWARN | __GFP_NORETRY);if (data !=NULL )return data; } -return vmalloc (size); +return __vmalloc (size,GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM,PAGE_KERNEL ); }static void __free_fdtable (struct fdtable *fdt)
@@ -126,7 +127,7 @@ static struct fdtable * alloc_fdtable(unsigned int nr)if (unlikely (nr > sysctl_nr_open)) nr = ((sysctl_nr_open -1 ) | (BITS_PER_LONG -1 )) +1 ; - fdt =kmalloc (sizeof (struct fdtable ),GFP_KERNEL ); + fdt =kmalloc (sizeof (struct fdtable ),GFP_KERNEL_ACCOUNT );if (!fdt) goto out; fdt->max_fds = nr;
fs/fuse/inode.c +2 -2
@@ -1255,8 +1255,8 @@ static int __init fuse_fs_init(void)int err; fuse_inode_cachep =kmem_cache_create ("fuse_inode" , -sizeof (struct fuse_inode ), -0 ,SLAB_HWCACHE_ALIGN , +sizeof (struct fuse_inode ),0 , +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , fuse_inode_init_once); err = -ENOMEM ;if (!fuse_inode_cachep)
fs/gfs2/main.c +2 -1
@@ -112,7 +112,8 @@ static int __init init_gfs2_fs(void) gfs2_inode_cachep =kmem_cache_create ("gfs2_inode" ,sizeof (struct gfs2_inode ),0 ,SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD , +SLAB_MEM_SPREAD | +SLAB_ACCOUNT , gfs2_init_inode_once);if (!gfs2_inode_cachep) goto fail;
fs/hfs/super.c +2 -2
@@ -483,8 +483,8 @@ static int __init init_hfs_fs(void)int err; hfs_inode_cachep =kmem_cache_create ("hfs_inode_cache" , -sizeof (struct hfs_inode_info ),0 ,SLAB_HWCACHE_ALIGN , - hfs_init_once); +sizeof (struct hfs_inode_info ),0 , +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , hfs_init_once);if (!hfs_inode_cachep)return -ENOMEM ; err =register_filesystem (&hfs_fs_type);
fs/hfsplus/super.c +1 -1
@@ -663,7 +663,7 @@ static int __init init_hfsplus_fs(void)int err; hfsplus_inode_cachep =kmem_cache_create ("hfsplus_icache" , -HFSPLUS_INODE_SIZE ,0 ,SLAB_HWCACHE_ALIGN , +HFSPLUS_INODE_SIZE ,0 ,SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , hfsplus_init_once);if (!hfsplus_inode_cachep)return -ENOMEM ;
fs/hostfs/hostfs_kern.c +1 -1
@@ -223,7 +223,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb) {struct hostfs_inode_info *hi; - hi =kmalloc (sizeof (*hi),GFP_KERNEL ); + hi =kmalloc (sizeof (*hi),GFP_KERNEL_ACCOUNT );if (hi ==NULL )return NULL ; hi->fd =-1 ;
fs/hpfs/super.c +1 -1
@@ -261,7 +261,7 @@ static int init_inodecache(void) hpfs_inode_cachep =kmem_cache_create ("hpfs_inode_cache" ,sizeof (struct hpfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (hpfs_inode_cachep ==NULL )return -ENOMEM ;
fs/hugetlbfs/inode.c +1 -1
@@ -1322,7 +1322,7 @@ static int __init init_hugetlbfs_fs(void) error = -ENOMEM ; hugetlbfs_inode_cachep =kmem_cache_create ("hugetlbfs_inode_cache" ,sizeof (struct hugetlbfs_inode_info ), -0 ,0 , init_once); +0 ,SLAB_ACCOUNT , init_once);if (hugetlbfs_inode_cachep ==NULL ) goto out2;
fs/inode.c +1 -1
@@ -1882,7 +1882,7 @@ void __init inode_init(void)sizeof (struct inode ),0 , (SLAB_RECLAIM_ACCOUNT |SLAB_PANIC | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);/* Hash may have been set up in inode_init_early */
fs/isofs/inode.c +1 -1
@@ -94,7 +94,7 @@ static int __init init_inodecache(void) isofs_inode_cachep =kmem_cache_create ("isofs_inode_cache" ,sizeof (struct iso_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (isofs_inode_cachep ==NULL )return -ENOMEM ;
fs/jffs2/super.c +1 -1
@@ -387,7 +387,7 @@ static int __init init_jffs2_fs(void) jffs2_inode_cachep =kmem_cache_create ("jffs2_i" ,sizeof (struct jffs2_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), jffs2_i_init_once);if (!jffs2_inode_cachep) {pr_err ("error: Failed to initialise inode cache\n" );
fs/jfs/super.c +1 -1
@@ -901,7 +901,7 @@ static int __init init_jfs_fs(void) jfs_inode_cachep =kmem_cache_create ("jfs_ip" ,sizeof (struct jfs_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD |SLAB_ACCOUNT , init_once);if (jfs_inode_cachep ==NULL )return -ENOMEM ;
fs/logfs/inode.c +2 -1
@@ -408,7 +408,8 @@ const struct super_operations logfs_super_operations = {int logfs_init_inode_cache (void ) { logfs_inode_cache =kmem_cache_create ("logfs_inode_cache" , -sizeof (struct logfs_inode ),0 ,SLAB_RECLAIM_ACCOUNT , +sizeof (struct logfs_inode ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT , logfs_init_once);if (!logfs_inode_cache)return -ENOMEM ;
fs/minix/inode.c +1 -1
@@ -91,7 +91,7 @@ static int __init init_inodecache(void) minix_inode_cachep =kmem_cache_create ("minix_inode_cache" ,sizeof (struct minix_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (minix_inode_cachep ==NULL )return -ENOMEM ;
fs/ncpfs/inode.c +1 -1
@@ -82,7 +82,7 @@ static int init_inodecache(void) ncp_inode_cachep =kmem_cache_create ("ncp_inode_cache" ,sizeof (struct ncp_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ncp_inode_cachep ==NULL )return -ENOMEM ;
fs/nfs/inode.c +1 -1
@@ -1904,7 +1904,7 @@ static int __init nfs_init_inodecache(void) nfs_inode_cachep =kmem_cache_create ("nfs_inode_cache" ,sizeof (struct nfs_inode ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (nfs_inode_cachep ==NULL )return -ENOMEM ;
fs/nilfs2/super.c +2 -1
@@ -1419,7 +1419,8 @@ static int __init nilfs_init_cachep(void) { nilfs_inode_cachep =kmem_cache_create ("nilfs2_inode_cache" ,sizeof (struct nilfs_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT , nilfs_inode_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT , + nilfs_inode_init_once);if (!nilfs_inode_cachep) goto fail;
fs/ntfs/super.c +2 -2
@@ -3139,8 +3139,8 @@ static int __init init_ntfs_fs(void) ntfs_big_inode_cache =kmem_cache_create (ntfs_big_inode_cache_name,sizeof (big_ntfs_inode),0 , -SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - ntfs_big_inode_init_once); +SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , ntfs_big_inode_init_once);if (!ntfs_big_inode_cache) {pr_crit ("Failed to create %s!\n" , ntfs_big_inode_cache_name); goto big_inode_err_out;
fs/ocfs2/dlmfs/dlmfs.c +1 -1
@@ -638,7 +638,7 @@ static int __init init_dlmfs_fs(void) dlmfs_inode_cache =kmem_cache_create ("dlmfs_inode_cache" ,sizeof (struct dlmfs_inode_private ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), dlmfs_init_once);if (!dlmfs_inode_cache) { status = -ENOMEM ;
fs/ocfs2/super.c +1 -1
@@ -1771,7 +1771,7 @@ static int ocfs2_initialize_mem_caches(void)sizeof (struct ocfs2_inode_info ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), ocfs2_inode_init_once); ocfs2_dquot_cachep = kmem_cache_create("ocfs2_dquot_cache", sizeof(struct ocfs2_dquot),
fs/openpromfs/inode.c +1 -1
@@ -443,7 +443,7 @@ static int __init init_openprom_fs(void)sizeof (struct op_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), op_inode_init_once);if (!op_inode_cachep)return -ENOMEM ;
fs/proc/inode.c +2 -1
@@ -95,7 +95,8 @@ void __init proc_init_inodecache(void) proc_inode_cachep =kmem_cache_create ("proc_inode_cache" ,sizeof (struct proc_inode ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD |SLAB_PANIC ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT | +SLAB_PANIC ), init_once); }
fs/qnx4/inode.c +1 -1
@@ -364,7 +364,7 @@ static int init_inodecache(void) qnx4_inode_cachep =kmem_cache_create ("qnx4_inode_cache" ,sizeof (struct qnx4_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (qnx4_inode_cachep ==NULL )return -ENOMEM ;
fs/qnx6/inode.c +1 -1
@@ -624,7 +624,7 @@ static int init_inodecache(void) qnx6_inode_cachep =kmem_cache_create ("qnx6_inode_cache" ,sizeof (struct qnx6_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (!qnx6_inode_cachep)return -ENOMEM ;
fs/reiserfs/super.c +2 -1
@@ -626,7 +626,8 @@ static int __init init_inodecache(void)sizeof (struct reiserfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD | +SLAB_ACCOUNT ), init_once);if (reiserfs_inode_cachep ==NULL )return -ENOMEM ;
fs/romfs/super.c +2 -2
@@ -618,8 +618,8 @@ static int __init init_romfs_fs(void) romfs_inode_cachep =kmem_cache_create ("romfs_i" ,sizeof (struct romfs_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - romfs_i_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , romfs_i_init_once);if (!romfs_inode_cachep) {pr_err ("Failed to initialise inode cache\n" );
fs/squashfs/super.c +2 -1
@@ -420,7 +420,8 @@ static int __init init_inodecache(void) { squashfs_inode_cachep =kmem_cache_create ("squashfs_inode_cache" ,sizeof (struct squashfs_inode_info ),0 , -SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT , init_once); +SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT , + init_once);return squashfs_inode_cachep ?0 : -ENOMEM ; }
fs/sysv/inode.c +1 -1
@@ -353,7 +353,7 @@ int __init sysv_init_icache(void) { sysv_inode_cachep =kmem_cache_create ("sysv_inode_cache" ,sizeof (struct sysv_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD |SLAB_ACCOUNT , init_once);if (!sysv_inode_cachep)return -ENOMEM ;
fs/ubifs/super.c +2 -2
@@ -2241,8 +2241,8 @@ static int __init ubifs_init(void) ubifs_inode_slab =kmem_cache_create ("ubifs_inode_slab" ,sizeof (struct ubifs_inode ),0 , -SLAB_MEM_SPREAD |SLAB_RECLAIM_ACCOUNT , - &inode_slab_ctor); +SLAB_MEM_SPREAD |SLAB_RECLAIM_ACCOUNT | +SLAB_ACCOUNT , &inode_slab_ctor);if (!ubifs_inode_slab)return -ENOMEM ;
fs/udf/super.c +2 -1
@@ -179,7 +179,8 @@ static int __init init_inodecache(void) udf_inode_cachep =kmem_cache_create ("udf_inode_cache" ,sizeof (struct udf_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD | +SLAB_ACCOUNT ), init_once);if (!udf_inode_cachep)return -ENOMEM ;
fs/ufs/super.c +1 -1
@@ -1427,7 +1427,7 @@ static int __init init_inodecache(void) ufs_inode_cachep =kmem_cache_create ("ufs_inode_cache" ,sizeof (struct ufs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ufs_inode_cachep ==NULL )return -ENOMEM ;
fs/xfs/kmem.h +1 -0
@@ -84,6 +84,7 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags)#define KM_ZONE_HWALIGN SLAB_HWCACHE_ALIGN#define KM_ZONE_RECLAIM SLAB_RECLAIM_ACCOUNT#define KM_ZONE_SPREAD SLAB_MEM_SPREAD +#define KM_ZONE_ACCOUNT SLAB_ACCOUNT#define kmem_zone kmem_cache#define kmem_zone_t struct kmem_cache
fs/xfs/xfs_super.c +2 -2
@@ -1703,8 +1703,8 @@ xfs_init_zones(void) xfs_inode_zone =kmem_zone_init_flags (sizeof (xfs_inode_t),"xfs_inode" , -KM_ZONE_HWALIGN |KM_ZONE_RECLAIM |KM_ZONE_SPREAD , - xfs_fs_inode_init_once); +KM_ZONE_HWALIGN |KM_ZONE_RECLAIM |KM_ZONE_SPREAD | +KM_ZONE_ACCOUNT , xfs_fs_inode_init_once);if (!xfs_inode_zone) goto out_destroy_efi_zone;
include/linux/thread_info.h +3 -2
@@ -56,9 +56,10 @@ extern long do_no_restart_syscall(struct restart_block *parm);#ifdef __KERNEL__#ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \ + __GFP_ZERO)#else -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK)#endif /*
ipc/mqueue.c +1 -1
@@ -1438,7 +1438,7 @@ static int __init init_mqueue_fs(void) mqueue_inode_cachep =kmem_cache_create ("mqueue_inode_cache" ,sizeof (struct mqueue_inode_info ),0 , -SLAB_HWCACHE_ALIGN , init_once); +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , init_once);if (mqueue_inode_cachep ==NULL )return -ENOMEM ;
kernel/cred.c +2 -2
@@ -569,8 +569,8 @@ EXPORT_SYMBOL(revert_creds);void __init cred_init (void ) {/* allocate a slab in which we can store credentials */ - cred_jar =kmem_cache_create ("cred_jar" ,sizeof (struct cred ), -0 ,SLAB_HWCACHE_ALIGN |SLAB_PANIC ,NULL ); + cred_jar =kmem_cache_create ("cred_jar" ,sizeof (struct cred ),0 , +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_ACCOUNT ,NULL ); }/**
kernel/delayacct.c +1 -1
@@ -34,7 +34,7 @@ __setup("nodelayacct", delayacct_setup_disable);void delayacct_init (void ) { - delayacct_cache =KMEM_CACHE (task_delay_info,SLAB_PANIC ); + delayacct_cache =KMEM_CACHE (task_delay_info,SLAB_PANIC |SLAB_ACCOUNT );delayacct_tsk_init (&init_task); }
kernel/fork.c +13 -9
@@ -300,9 +300,9 @@ void __init fork_init(void)#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES#endif /* create a slab on which task_structs can be allocated */ - task_struct_cachep = -kmem_cache_create ("task_struct" , arch_task_struct_size, -ARCH_MIN_TASKALIGN ,SLAB_PANIC |SLAB_NOTRACK ,NULL ); + task_struct_cachep =kmem_cache_create ("task_struct" , + arch_task_struct_size,ARCH_MIN_TASKALIGN , +SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT ,NULL );#endif /* do the arch specific task caches init */
@@ -1851,16 +1851,19 @@ void __init proc_caches_init(void) sighand_cachep =kmem_cache_create ("sighand_cache" ,sizeof (struct sighand_struct ),0 ,SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_DESTROY_BY_RCU | -SLAB_NOTRACK , sighand_ctor); +SLAB_NOTRACK |SLAB_ACCOUNT , sighand_ctor); signal_cachep =kmem_cache_create ("signal_cache" ,sizeof (struct signal_struct ),0 , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL ); files_cachep =kmem_cache_create ("files_cache" ,sizeof (struct files_struct ),0 , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL ); fs_cachep =kmem_cache_create ("fs_cache" ,sizeof (struct fs_struct ),0 , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL );/* * FIXME! The "sizeof(struct mm_struct)" currently includes the * whole struct cpumask for the OFFSTACK case. We could change
@@ -1870,8 +1873,9 @@ void __init proc_caches_init(void)*/ mm_cachep =kmem_cache_create ("mm_struct" ,sizeof (struct mm_struct ),ARCH_MIN_MMSTRUCT_ALIGN , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); - vm_area_cachep =KMEM_CACHE (vm_area_struct,SLAB_PANIC ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL ); + vm_area_cachep =KMEM_CACHE (vm_area_struct,SLAB_PANIC |SLAB_ACCOUNT );mmap_init ();nsproxy_cache_init (); }
kernel/pid.c +1 -1
@@ -604,5 +604,5 @@ void __init pidmap_init(void)atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); init_pid_ns.pid_cachep =KMEM_CACHE (pid, -SLAB_HWCACHE_ALIGN |SLAB_PANIC ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_ACCOUNT ); }
mm/nommu.c +1 -1
@@ -560,7 +560,7 @@ void __init mmap_init(void) ret =percpu_counter_init (&vm_committed_as,0 ,GFP_KERNEL );VM_BUG_ON (ret); - vm_region_jar =KMEM_CACHE (vm_region,SLAB_PANIC ); + vm_region_jar =KMEM_CACHE (vm_region,SLAB_PANIC |SLAB_ACCOUNT ); }/*
mm/rmap.c +4 -2
@@ -428,8 +428,10 @@ static void anon_vma_ctor(void *data)void __init anon_vma_init (void ) { anon_vma_cachep =kmem_cache_create ("anon_vma" ,sizeof (struct anon_vma ), -0 ,SLAB_DESTROY_BY_RCU |SLAB_PANIC , anon_vma_ctor); - anon_vma_chain_cachep =KMEM_CACHE (anon_vma_chain,SLAB_PANIC ); +0 ,SLAB_DESTROY_BY_RCU |SLAB_PANIC |SLAB_ACCOUNT , + anon_vma_ctor); + anon_vma_chain_cachep =KMEM_CACHE (anon_vma_chain, +SLAB_PANIC |SLAB_ACCOUNT ); }/*
mm/shmem.c +1 -1
@@ -3107,7 +3107,7 @@ static int shmem_init_inodecache(void) { shmem_inode_cachep =kmem_cache_create ("shmem_inode_cache" ,sizeof (struct shmem_inode_info ), -0 ,SLAB_PANIC , shmem_init_inode); +0 ,SLAB_PANIC |SLAB_ACCOUNT , shmem_init_inode);return 0 ; }
net/socket.c +1 -1
@@ -293,7 +293,7 @@ static int init_inodecache(void)0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (sock_inode_cachep ==NULL )return -ENOMEM ;
net/sunrpc/rpc_pipe.c +1 -1
@@ -1500,7 +1500,7 @@ int register_rpc_pipefs(void) rpc_inode_cachep =kmem_cache_create ("rpc_inode_cache" ,sizeof (struct rpc_inode ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (!rpc_inode_cachep)return -ENOMEM ;
Signature · 7 lines
2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH v2 6/6] Account certain kmem allocations to memcg
Quoted 4 lines · Vladimir Davydov
This patch marks those kmem allocations that are known to be easily triggered from userspace as __GFP_ACCOUNT/SLAB_ACCOUNT, which makes them accounted to memcg. For the list, see below:
Quoted 16 lines
- threadinfo
-task_struct
-task_delay_info
- pid
- cred
-mm_struct
-vm_area_structandvm_region(nommu)
-anon_vmaandanon_vma_chain
-signal_struct
-sighand_struct
-fs_struct
-files_struct
- fdtable andfdtable->full_fds_bits
- dentry andexternal_name
- inode for all filesystems. This is the most tedious part, because most filesystems overwrite thealloc_inodemethod.
It would be imho nicer to split this into few patches based on the memory category (task management, address space, icache) with a justification.
Quoted 8 lines
The list is by far not complete, so feel free to add more objects. Nevertheless, it should be close to "account everything" approach and keep most workloads within bounds. Malevolent users will be able to breach the limit, but this was possible even with the former "account everything" approach (simply because it did not account everything in fact).
Signed-off-by Vladimir Davydov <[email protected]>
From a quick look it seems reasonable.
Quoted 1,042 lines
--- arch/powerpc/platforms/cell/spufs/inode.c | 2 +- drivers/staging/lustre/lustre/llite/super25.c | 3 ++- fs/9p/v9fs.c | 2 +- fs/adfs/super.c | 2 +- fs/affs/super.c | 2 +- fs/afs/super.c | 2 +- fs/befs/linuxvfs.c | 2 +- fs/bfs/inode.c | 2 +- fs/block_dev.c | 2 +- fs/btrfs/inode.c | 3 ++- fs/ceph/super.c | 4 ++-- fs/cifs/cifsfs.c | 2 +- fs/coda/inode.c | 6 +++--- fs/dcache.c | 5 +++-- fs/ecryptfs/main.c | 6 ++++-- fs/efs/super.c | 6 +++--- fs/exofs/super.c | 4 ++-- fs/ext2/super.c | 2 +- fs/ext4/super.c | 2 +- fs/f2fs/super.c | 5 +++-- fs/fat/inode.c | 2 +- fs/file.c | 7 ++++--- fs/fuse/inode.c | 4 ++-- fs/gfs2/main.c | 3 ++- fs/hfs/super.c | 4 ++-- fs/hfsplus/super.c | 2 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hpfs/super.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 2 +- fs/isofs/inode.c | 2 +- fs/jffs2/super.c | 2 +- fs/jfs/super.c | 2 +- fs/logfs/inode.c | 3 ++- fs/minix/inode.c | 2 +- fs/ncpfs/inode.c | 2 +- fs/nfs/inode.c | 2 +- fs/nilfs2/super.c | 3 ++- fs/ntfs/super.c | 4 ++-- fs/ocfs2/dlmfs/dlmfs.c | 2 +- fs/ocfs2/super.c | 2 +- fs/openpromfs/inode.c | 2 +- fs/proc/inode.c | 3 ++- fs/qnx4/inode.c | 2 +- fs/qnx6/inode.c | 2 +- fs/reiserfs/super.c | 3 ++- fs/romfs/super.c | 4 ++-- fs/squashfs/super.c | 3 ++- fs/sysv/inode.c | 2 +- fs/ubifs/super.c | 4 ++-- fs/udf/super.c | 3 ++- fs/ufs/super.c | 2 +- fs/xfs/kmem.h | 1 + fs/xfs/xfs_super.c | 4 ++-- include/linux/thread_info.h | 5 +++-- ipc/mqueue.c | 2 +- kernel/cred.c | 4 ++-- kernel/delayacct.c | 2 +- kernel/fork.c | 22 +++++++++++++--------- kernel/pid.c | 2 +- mm/nommu.c | 2 +- mm/rmap.c | 6 ++++-- mm/shmem.c | 2 +- net/socket.c | 2 +- net/sunrpc/rpc_pipe.c | 2 +- 65 files changed, 114 insertions(+), 92 deletions(-)arch/powerpc/platforms/cell/spufs/inode.c +1
-1@@ -767,7 +767,7 @@ static int __init spufs_init(void) ret = -ENOMEM ; spufs_inode_cache =kmem_cache_create ("spufs_inode_cache" ,sizeof (struct spufs_inode_info ),0 , -SLAB_HWCACHE_ALIGN , spufs_init_once); +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , spufs_init_once);if (!spufs_inode_cache) goto out;drivers/staging/lustre/lustre/llite/super25.c +2
-1@@ -106,7 +106,8 @@ static int __init init_lustre_lite(void) rc = -ENOMEM ; ll_inode_cachep =kmem_cache_create ("lustre_inode_cache" ,sizeof (struct ll_inode_info ), -0 ,SLAB_HWCACHE_ALIGN ,NULL ); +0 ,SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , +NULL );if (ll_inode_cachep ==NULL ) goto out_cache;fs/9p/v9fs.c +1
-1@@ -575,7 +575,7 @@ static int v9fs_init_inode_cache(void) v9fs_inode_cache =kmem_cache_create ("v9fs_inode_cache" ,sizeof (struct v9fs_inode ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), v9fs_inode_init_once);if (!v9fs_inode_cache)return -ENOMEM ;fs/adfs/super.c +1
-1@@ -271,7 +271,7 @@ static int __init init_inodecache(void) adfs_inode_cachep =kmem_cache_create ("adfs_inode_cache" ,sizeof (struct adfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (adfs_inode_cachep ==NULL )return -ENOMEM ;fs/affs/super.c +1
-1@@ -132,7 +132,7 @@ static int __init init_inodecache(void) affs_inode_cachep =kmem_cache_create ("affs_inode_cache" ,sizeof (struct affs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (affs_inode_cachep ==NULL )return -ENOMEM ;fs/afs/super.c +1
-1@@ -91,7 +91,7 @@ int __init afs_fs_init(void) afs_inode_cachep =kmem_cache_create ("afs_inode_cache" ,sizeof (struct afs_vnode ),0 , -SLAB_HWCACHE_ALIGN , +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , afs_i_init_once);if (!afs_inode_cachep) {printk (KERN_NOTICE "kAFS: Failed to allocate inode cache\n" );fs/befs/linuxvfs.c +1
-1@@ -434,7 +434,7 @@ befs_init_inodecache(void) befs_inode_cachep =kmem_cache_create ("befs_inode_cache" ,sizeof (struct befs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (befs_inode_cachep ==NULL ) {pr_err ("%s: Couldn't initialize inode slabcache\n" , __func__);fs/bfs/inode.c +1
-1@@ -270,7 +270,7 @@ static int __init init_inodecache(void) bfs_inode_cachep =kmem_cache_create ("bfs_inode_cache" ,sizeof (struct bfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (bfs_inode_cachep ==NULL )return -ENOMEM ;fs/block_dev.c +1
-1@@ -567,7 +567,7 @@ void __init bdev_cache_init(void) bdev_cachep =kmem_cache_create ("bdev_cache" ,sizeof (struct bdev_inode ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD |SLAB_PANIC ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT |SLAB_PANIC ), init_once); err =register_filesystem (&bd_type);if (err)fs/btrfs/inode.c +2
-1@@ -9157,7 +9157,8 @@ int btrfs_init_cachep(void) { btrfs_inode_cachep =kmem_cache_create ("btrfs_inode" ,sizeof (struct btrfs_inode ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD |SLAB_ACCOUNT , + init_once);if (!btrfs_inode_cachep) goto fail;fs/ceph/super.c +2
-2@@ -639,8 +639,8 @@ static int __init init_caches(void) ceph_inode_cachep =kmem_cache_create ("ceph_inode_info" ,sizeof (struct ceph_inode_info ), __alignof__(struct ceph_inode_info ), - (SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD ), - ceph_inode_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , ceph_inode_init_once);if (ceph_inode_cachep ==NULL )return -ENOMEM ;fs/cifs/cifsfs.c +1
-1@@ -1040,7 +1040,7 @@ cifs_init_inodecache(void) cifs_inode_cachep =kmem_cache_create ("cifs_inode_cache" ,sizeof (struct cifsInodeInfo ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), cifs_init_once);if (cifs_inode_cachep ==NULL )return -ENOMEM ;fs/coda/inode.c +3
-3@@ -74,9 +74,9 @@ static void init_once(void *foo)int __init coda_init_inodecache (void ) { coda_inode_cachep =kmem_cache_create ("coda_inode_cache" , -sizeof (struct coda_inode_info ), -0 ,SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - init_once); +sizeof (struct coda_inode_info ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , init_once);if (coda_inode_cachep ==NULL )return -ENOMEM ;return 0 ;fs/dcache.c +3
-2@@ -1571,7 +1571,8 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) dentry->d_iname[DNAME_INLINE_LEN -1 ] =0 ;if (name->len >DNAME_INLINE_LEN -1 ) { size_t size = offsetof(struct external_name, name[1]); -struct external_name *p =kmalloc (size + name->len,GFP_KERNEL ); +struct external_name *p =kmalloc (size + name->len, +GFP_KERNEL_ACCOUNT );if (!p) {kmem_cache_free (dentry_cache, dentry);return NULL ;@@ -3415,7 +3416,7 @@ static void __init dcache_init(void)* of the dcache. */ dentry_cache =KMEM_CACHE (dentry, -SLAB_RECLAIM_ACCOUNT |SLAB_PANIC |SLAB_MEM_SPREAD ); +SLAB_RECLAIM_ACCOUNT |SLAB_PANIC |SLAB_MEM_SPREAD |SLAB_ACCOUNT );/* Hash may have been set up in dcache_init_early */ if (!hashdist)fs/ecryptfs/main.c +4
-2@@ -663,6 +663,7 @@ static struct ecryptfs_cache_info {struct kmem_cache **cache;const char *name;size_t size; +unsigned long flags;void (*ctor)(void *obj); } ecryptfs_cache_infos[] = { {@@ -684,6 +685,7 @@ static struct ecryptfs_cache_info { .cache = &ecryptfs_inode_info_cache, .name = "ecryptfs_inode_cache", .size = sizeof(struct ecryptfs_inode_info), + .flags = SLAB_ACCOUNT, .ctor = inode_info_init_once, }, {@@ -755,8 +757,8 @@ static int ecryptfs_init_kmem_caches(void)struct ecryptfs_cache_info *info; info = &ecryptfs_cache_infos[i]; - *(info->cache) =kmem_cache_create (info->name, info->size, -0 ,SLAB_HWCACHE_ALIGN , info->ctor); + *(info->cache) =kmem_cache_create (info->name, info->size,0 , +SLAB_HWCACHE_ALIGN | info->flags, info->ctor);if (!*(info->cache)) {ecryptfs_free_kmem_caches (); ecryptfs_printk(KERN_WARNING, "%s: "fs/efs/super.c +3
-3@@ -94,9 +94,9 @@ static void init_once(void *foo)static int __init init_inodecache (void ) { efs_inode_cachep =kmem_cache_create ("efs_inode_cache" , -sizeof (struct efs_inode_info ), -0 ,SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - init_once); +sizeof (struct efs_inode_info ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , init_once);if (efs_inode_cachep ==NULL )return -ENOMEM ;return 0 ;fs/exofs/super.c +2
-2@@ -194,8 +194,8 @@ static int init_inodecache(void) { exofs_inode_cachep =kmem_cache_create ("exofs_inode_cache" ,sizeof (struct exofs_i_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - exofs_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , exofs_init_once);if (exofs_inode_cachep ==NULL )return -ENOMEM ;return 0 ;fs/ext2/super.c +1
-1@@ -200,7 +200,7 @@ static int __init init_inodecache(void) ext2_inode_cachep =kmem_cache_create ("ext2_inode_cache" ,sizeof (struct ext2_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ext2_inode_cachep ==NULL )return -ENOMEM ;fs/ext4/super.c +1
-1@@ -966,7 +966,7 @@ static int __init init_inodecache(void) ext4_inode_cachep =kmem_cache_create ("ext4_inode_cache" ,sizeof (struct ext4_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ext4_inode_cachep ==NULL )return -ENOMEM ;fs/f2fs/super.c +3
-2@@ -1424,8 +1424,9 @@ MODULE_ALIAS_FS("f2fs");static int __init init_inodecache (void ) { - f2fs_inode_cachep =f2fs_kmem_cache_create ("f2fs_inode_cache" , -sizeof (struct f2fs_inode_info )); + f2fs_inode_cachep =kmem_cache_create ("f2fs_inode_cache" , +sizeof (struct f2fs_inode_info ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT ,NULL );if (!f2fs_inode_cachep)return -ENOMEM ;return 0 ;fs/fat/inode.c +1
-1@@ -677,7 +677,7 @@ static int __init fat_init_inodecache(void) fat_inode_cachep =kmem_cache_create ("fat_inode_cache" ,sizeof (struct msdos_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (fat_inode_cachep ==NULL )return -ENOMEM ;fs/file.c +4
-3@@ -37,11 +37,12 @@ static void *alloc_fdmem(size_t size)* vmalloc() if the allocation size will be considered "large" by the VM. */ if (size <= (PAGE_SIZE <<PAGE_ALLOC_COSTLY_ORDER )) { -void *data =kmalloc (size,GFP_KERNEL |__GFP_NOWARN|__GFP_NORETRY); +void *data =kmalloc (size,GFP_KERNEL_ACCOUNT | + __GFP_NOWARN | __GFP_NORETRY);if (data !=NULL )return data; } -return vmalloc (size); +return __vmalloc (size,GFP_KERNEL_ACCOUNT | __GFP_HIGHMEM,PAGE_KERNEL ); }static void __free_fdtable (struct fdtable *fdt)@@ -126,7 +127,7 @@ static struct fdtable * alloc_fdtable(unsigned int nr)if (unlikely (nr > sysctl_nr_open)) nr = ((sysctl_nr_open -1 ) | (BITS_PER_LONG -1 )) +1 ; - fdt =kmalloc (sizeof (struct fdtable ),GFP_KERNEL ); + fdt =kmalloc (sizeof (struct fdtable ),GFP_KERNEL_ACCOUNT );if (!fdt) goto out; fdt->max_fds = nr;fs/fuse/inode.c +2
-2@@ -1255,8 +1255,8 @@ static int __init fuse_fs_init(void)int err; fuse_inode_cachep =kmem_cache_create ("fuse_inode" , -sizeof (struct fuse_inode ), -0 ,SLAB_HWCACHE_ALIGN , +sizeof (struct fuse_inode ),0 , +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , fuse_inode_init_once); err = -ENOMEM ;if (!fuse_inode_cachep)fs/gfs2/main.c +2
-1@@ -112,7 +112,8 @@ static int __init init_gfs2_fs(void) gfs2_inode_cachep =kmem_cache_create ("gfs2_inode" ,sizeof (struct gfs2_inode ),0 ,SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD , +SLAB_MEM_SPREAD | +SLAB_ACCOUNT , gfs2_init_inode_once);if (!gfs2_inode_cachep) goto fail;fs/hfs/super.c +2
-2@@ -483,8 +483,8 @@ static int __init init_hfs_fs(void)int err; hfs_inode_cachep =kmem_cache_create ("hfs_inode_cache" , -sizeof (struct hfs_inode_info ),0 ,SLAB_HWCACHE_ALIGN , - hfs_init_once); +sizeof (struct hfs_inode_info ),0 , +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , hfs_init_once);if (!hfs_inode_cachep)return -ENOMEM ; err =register_filesystem (&hfs_fs_type);fs/hfsplus/super.c +1
-1@@ -663,7 +663,7 @@ static int __init init_hfsplus_fs(void)int err; hfsplus_inode_cachep =kmem_cache_create ("hfsplus_icache" , -HFSPLUS_INODE_SIZE ,0 ,SLAB_HWCACHE_ALIGN , +HFSPLUS_INODE_SIZE ,0 ,SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , hfsplus_init_once);if (!hfsplus_inode_cachep)return -ENOMEM ;fs/hostfs/hostfs_kern.c +1
-1@@ -223,7 +223,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb) {struct hostfs_inode_info *hi; - hi =kmalloc (sizeof (*hi),GFP_KERNEL ); + hi =kmalloc (sizeof (*hi),GFP_KERNEL_ACCOUNT );if (hi ==NULL )return NULL ; hi->fd =-1 ;fs/hpfs/super.c +1
-1@@ -261,7 +261,7 @@ static int init_inodecache(void) hpfs_inode_cachep =kmem_cache_create ("hpfs_inode_cache" ,sizeof (struct hpfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (hpfs_inode_cachep ==NULL )return -ENOMEM ;fs/hugetlbfs/inode.c +1
-1@@ -1322,7 +1322,7 @@ static int __init init_hugetlbfs_fs(void) error = -ENOMEM ; hugetlbfs_inode_cachep =kmem_cache_create ("hugetlbfs_inode_cache" ,sizeof (struct hugetlbfs_inode_info ), -0 ,0 , init_once); +0 ,SLAB_ACCOUNT , init_once);if (hugetlbfs_inode_cachep ==NULL ) goto out2;fs/inode.c +1
-1@@ -1882,7 +1882,7 @@ void __init inode_init(void)sizeof (struct inode ),0 , (SLAB_RECLAIM_ACCOUNT |SLAB_PANIC | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);/* Hash may have been set up in inode_init_early */ fs/isofs/inode.c +1
-1@@ -94,7 +94,7 @@ static int __init init_inodecache(void) isofs_inode_cachep =kmem_cache_create ("isofs_inode_cache" ,sizeof (struct iso_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (isofs_inode_cachep ==NULL )return -ENOMEM ;fs/jffs2/super.c +1
-1@@ -387,7 +387,7 @@ static int __init init_jffs2_fs(void) jffs2_inode_cachep =kmem_cache_create ("jffs2_i" ,sizeof (struct jffs2_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), jffs2_i_init_once);if (!jffs2_inode_cachep) {pr_err ("error: Failed to initialise inode cache\n" );fs/jfs/super.c +1
-1@@ -901,7 +901,7 @@ static int __init init_jfs_fs(void) jfs_inode_cachep =kmem_cache_create ("jfs_ip" ,sizeof (struct jfs_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD |SLAB_ACCOUNT , init_once);if (jfs_inode_cachep ==NULL )return -ENOMEM ;fs/logfs/inode.c +2
-1@@ -408,7 +408,8 @@ const struct super_operations logfs_super_operations = {int logfs_init_inode_cache (void ) { logfs_inode_cache =kmem_cache_create ("logfs_inode_cache" , -sizeof (struct logfs_inode ),0 ,SLAB_RECLAIM_ACCOUNT , +sizeof (struct logfs_inode ),0 , +SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT , logfs_init_once);if (!logfs_inode_cache)return -ENOMEM ;fs/minix/inode.c +1
-1@@ -91,7 +91,7 @@ static int __init init_inodecache(void) minix_inode_cachep =kmem_cache_create ("minix_inode_cache" ,sizeof (struct minix_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (minix_inode_cachep ==NULL )return -ENOMEM ;fs/ncpfs/inode.c +1
-1@@ -82,7 +82,7 @@ static int init_inodecache(void) ncp_inode_cachep =kmem_cache_create ("ncp_inode_cache" ,sizeof (struct ncp_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ncp_inode_cachep ==NULL )return -ENOMEM ;fs/nfs/inode.c +1
-1@@ -1904,7 +1904,7 @@ static int __init nfs_init_inodecache(void) nfs_inode_cachep =kmem_cache_create ("nfs_inode_cache" ,sizeof (struct nfs_inode ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (nfs_inode_cachep ==NULL )return -ENOMEM ;fs/nilfs2/super.c +2
-1@@ -1419,7 +1419,8 @@ static int __init nilfs_init_cachep(void) { nilfs_inode_cachep =kmem_cache_create ("nilfs2_inode_cache" ,sizeof (struct nilfs_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT , nilfs_inode_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT , + nilfs_inode_init_once);if (!nilfs_inode_cachep) goto fail;fs/ntfs/super.c +2
-2@@ -3139,8 +3139,8 @@ static int __init init_ntfs_fs(void) ntfs_big_inode_cache =kmem_cache_create (ntfs_big_inode_cache_name,sizeof (big_ntfs_inode),0 , -SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - ntfs_big_inode_init_once); +SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , ntfs_big_inode_init_once);if (!ntfs_big_inode_cache) {pr_crit ("Failed to create %s!\n" , ntfs_big_inode_cache_name); goto big_inode_err_out;fs/ocfs2/dlmfs/dlmfs.c +1
-1@@ -638,7 +638,7 @@ static int __init init_dlmfs_fs(void) dlmfs_inode_cache =kmem_cache_create ("dlmfs_inode_cache" ,sizeof (struct dlmfs_inode_private ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), dlmfs_init_once);if (!dlmfs_inode_cache) { status = -ENOMEM ;fs/ocfs2/super.c +1
-1@@ -1771,7 +1771,7 @@ static int ocfs2_initialize_mem_caches(void)sizeof (struct ocfs2_inode_info ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), ocfs2_inode_init_once); ocfs2_dquot_cachep = kmem_cache_create("ocfs2_dquot_cache", sizeof(struct ocfs2_dquot),fs/openpromfs/inode.c +1
-1@@ -443,7 +443,7 @@ static int __init init_openprom_fs(void)sizeof (struct op_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), op_inode_init_once);if (!op_inode_cachep)return -ENOMEM ;fs/proc/inode.c +2
-1@@ -95,7 +95,8 @@ void __init proc_init_inodecache(void) proc_inode_cachep =kmem_cache_create ("proc_inode_cache" ,sizeof (struct proc_inode ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD |SLAB_PANIC ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT | +SLAB_PANIC ), init_once); }fs/qnx4/inode.c +1
-1@@ -364,7 +364,7 @@ static int init_inodecache(void) qnx4_inode_cachep =kmem_cache_create ("qnx4_inode_cache" ,sizeof (struct qnx4_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (qnx4_inode_cachep ==NULL )return -ENOMEM ;fs/qnx6/inode.c +1
-1@@ -624,7 +624,7 @@ static int init_inodecache(void) qnx6_inode_cachep =kmem_cache_create ("qnx6_inode_cache" ,sizeof (struct qnx6_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (!qnx6_inode_cachep)return -ENOMEM ;fs/reiserfs/super.c +2
-1@@ -626,7 +626,8 @@ static int __init init_inodecache(void)sizeof (struct reiserfs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD | +SLAB_ACCOUNT ), init_once);if (reiserfs_inode_cachep ==NULL )return -ENOMEM ;fs/romfs/super.c +2
-2@@ -618,8 +618,8 @@ static int __init init_romfs_fs(void) romfs_inode_cachep =kmem_cache_create ("romfs_i" ,sizeof (struct romfs_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , - romfs_i_init_once); +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD | +SLAB_ACCOUNT , romfs_i_init_once);if (!romfs_inode_cachep) {pr_err ("Failed to initialise inode cache\n" );fs/squashfs/super.c +2
-1@@ -420,7 +420,8 @@ static int __init init_inodecache(void) { squashfs_inode_cachep =kmem_cache_create ("squashfs_inode_cache" ,sizeof (struct squashfs_inode_info ),0 , -SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT , init_once); +SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT |SLAB_ACCOUNT , + init_once);return squashfs_inode_cachep ?0 : -ENOMEM ; }fs/sysv/inode.c +1
-1@@ -353,7 +353,7 @@ int __init sysv_init_icache(void) { sysv_inode_cachep =kmem_cache_create ("sysv_inode_cache" ,sizeof (struct sysv_inode_info ),0 , -SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD , +SLAB_RECLAIM_ACCOUNT |SLAB_MEM_SPREAD |SLAB_ACCOUNT , init_once);if (!sysv_inode_cachep)return -ENOMEM ;fs/ubifs/super.c +2
-2@@ -2241,8 +2241,8 @@ static int __init ubifs_init(void) ubifs_inode_slab =kmem_cache_create ("ubifs_inode_slab" ,sizeof (struct ubifs_inode ),0 , -SLAB_MEM_SPREAD |SLAB_RECLAIM_ACCOUNT , - &inode_slab_ctor); +SLAB_MEM_SPREAD |SLAB_RECLAIM_ACCOUNT | +SLAB_ACCOUNT , &inode_slab_ctor);if (!ubifs_inode_slab)return -ENOMEM ;fs/udf/super.c +2
-1@@ -179,7 +179,8 @@ static int __init init_inodecache(void) udf_inode_cachep =kmem_cache_create ("udf_inode_cache" ,sizeof (struct udf_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD | +SLAB_ACCOUNT ), init_once);if (!udf_inode_cachep)return -ENOMEM ;fs/ufs/super.c +1
-1@@ -1427,7 +1427,7 @@ static int __init init_inodecache(void) ufs_inode_cachep =kmem_cache_create ("ufs_inode_cache" ,sizeof (struct ufs_inode_info ),0 , (SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (ufs_inode_cachep ==NULL )return -ENOMEM ;fs/xfs/kmem.h +1
-0@@ -84,6 +84,7 @@ kmem_zalloc(size_t size, xfs_km_flags_t flags)#define KM_ZONE_HWALIGN SLAB_HWCACHE_ALIGN#define KM_ZONE_RECLAIM SLAB_RECLAIM_ACCOUNT#define KM_ZONE_SPREAD SLAB_MEM_SPREAD +#define KM_ZONE_ACCOUNT SLAB_ACCOUNT#define kmem_zone kmem_cache#define kmem_zone_t struct kmem_cachefs/xfs/xfs_super.c +2
-2@@ -1703,8 +1703,8 @@ xfs_init_zones(void) xfs_inode_zone =kmem_zone_init_flags (sizeof (xfs_inode_t),"xfs_inode" , -KM_ZONE_HWALIGN |KM_ZONE_RECLAIM |KM_ZONE_SPREAD , - xfs_fs_inode_init_once); +KM_ZONE_HWALIGN |KM_ZONE_RECLAIM |KM_ZONE_SPREAD | +KM_ZONE_ACCOUNT , xfs_fs_inode_init_once);if (!xfs_inode_zone) goto out_destroy_efi_zone;include/linux/thread_info.h +3
-2@@ -56,9 +56,10 @@ extern long do_no_restart_syscall(struct restart_block *parm);#ifdef __KERNEL__#ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \ + __GFP_ZERO)#else -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK)#endif /* ipc/mqueue.c +1
-1@@ -1438,7 +1438,7 @@ static int __init init_mqueue_fs(void) mqueue_inode_cachep =kmem_cache_create ("mqueue_inode_cache" ,sizeof (struct mqueue_inode_info ),0 , -SLAB_HWCACHE_ALIGN , init_once); +SLAB_HWCACHE_ALIGN |SLAB_ACCOUNT , init_once);if (mqueue_inode_cachep ==NULL )return -ENOMEM ;kernel/cred.c +2
-2@@ -569,8 +569,8 @@ EXPORT_SYMBOL(revert_creds);void __init cred_init (void ) {/* allocate a slab in which we can store credentials */ - cred_jar =kmem_cache_create ("cred_jar" ,sizeof (struct cred ), -0 ,SLAB_HWCACHE_ALIGN |SLAB_PANIC ,NULL ); + cred_jar =kmem_cache_create ("cred_jar" ,sizeof (struct cred ),0 , +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_ACCOUNT ,NULL ); }/** kernel/delayacct.c +1
-1@@ -34,7 +34,7 @@ __setup("nodelayacct", delayacct_setup_disable);void delayacct_init (void ) { - delayacct_cache =KMEM_CACHE (task_delay_info,SLAB_PANIC ); + delayacct_cache =KMEM_CACHE (task_delay_info,SLAB_PANIC |SLAB_ACCOUNT );delayacct_tsk_init (&init_task); }kernel/fork.c +13
-9@@ -300,9 +300,9 @@ void __init fork_init(void)#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES#endif /* create a slab on which task_structs can be allocated */ - task_struct_cachep = -kmem_cache_create ("task_struct" , arch_task_struct_size, -ARCH_MIN_TASKALIGN ,SLAB_PANIC |SLAB_NOTRACK ,NULL ); + task_struct_cachep =kmem_cache_create ("task_struct" , + arch_task_struct_size,ARCH_MIN_TASKALIGN , +SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT ,NULL );#endif /* do the arch specific task caches init */ @@ -1851,16 +1851,19 @@ void __init proc_caches_init(void) sighand_cachep =kmem_cache_create ("sighand_cache" ,sizeof (struct sighand_struct ),0 ,SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_DESTROY_BY_RCU | -SLAB_NOTRACK , sighand_ctor); +SLAB_NOTRACK |SLAB_ACCOUNT , sighand_ctor); signal_cachep =kmem_cache_create ("signal_cache" ,sizeof (struct signal_struct ),0 , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL ); files_cachep =kmem_cache_create ("files_cache" ,sizeof (struct files_struct ),0 , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL ); fs_cachep =kmem_cache_create ("fs_cache" ,sizeof (struct fs_struct ),0 , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL );/* * FIXME! The "sizeof(struct mm_struct)" currently includes the * whole struct cpumask for the OFFSTACK case. We could change @@ -1870,8 +1873,9 @@ void __init proc_caches_init(void)*/ mm_cachep =kmem_cache_create ("mm_struct" ,sizeof (struct mm_struct ),ARCH_MIN_MMSTRUCT_ALIGN , -SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK ,NULL ); - vm_area_cachep =KMEM_CACHE (vm_area_struct,SLAB_PANIC ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_NOTRACK |SLAB_ACCOUNT , +NULL ); + vm_area_cachep =KMEM_CACHE (vm_area_struct,SLAB_PANIC |SLAB_ACCOUNT );mmap_init ();nsproxy_cache_init (); }kernel/pid.c +1
-1@@ -604,5 +604,5 @@ void __init pidmap_init(void)atomic_dec (&init_pid_ns.pidmap[0 ].nr_free); init_pid_ns.pid_cachep =KMEM_CACHE (pid, -SLAB_HWCACHE_ALIGN |SLAB_PANIC ); +SLAB_HWCACHE_ALIGN |SLAB_PANIC |SLAB_ACCOUNT ); }mm/nommu.c +1
-1@@ -560,7 +560,7 @@ void __init mmap_init(void) ret =percpu_counter_init (&vm_committed_as,0 ,GFP_KERNEL );VM_BUG_ON (ret); - vm_region_jar =KMEM_CACHE (vm_region,SLAB_PANIC ); + vm_region_jar =KMEM_CACHE (vm_region,SLAB_PANIC |SLAB_ACCOUNT ); }/* mm/rmap.c +4
-2@@ -428,8 +428,10 @@ static void anon_vma_ctor(void *data)void __init anon_vma_init (void ) { anon_vma_cachep =kmem_cache_create ("anon_vma" ,sizeof (struct anon_vma ), -0 ,SLAB_DESTROY_BY_RCU |SLAB_PANIC , anon_vma_ctor); - anon_vma_chain_cachep =KMEM_CACHE (anon_vma_chain,SLAB_PANIC ); +0 ,SLAB_DESTROY_BY_RCU |SLAB_PANIC |SLAB_ACCOUNT , + anon_vma_ctor); + anon_vma_chain_cachep =KMEM_CACHE (anon_vma_chain, +SLAB_PANIC |SLAB_ACCOUNT ); }/* mm/shmem.c +1
-1@@ -3107,7 +3107,7 @@ static int shmem_init_inodecache(void) { shmem_inode_cachep =kmem_cache_create ("shmem_inode_cache" ,sizeof (struct shmem_inode_info ), -0 ,SLAB_PANIC , shmem_init_inode); +0 ,SLAB_PANIC |SLAB_ACCOUNT , shmem_init_inode);return 0 ; }net/socket.c +1
-1@@ -293,7 +293,7 @@ static int init_inodecache(void)0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (sock_inode_cachep ==NULL )return -ENOMEM ;net/sunrpc/rpc_pipe.c +1
-1@@ -1500,7 +1500,7 @@ int register_rpc_pipefs(void) rpc_inode_cachep =kmem_cache_create ("rpc_inode_cache" ,sizeof (struct rpc_inode ),0 , (SLAB_HWCACHE_ALIGN |SLAB_RECLAIM_ACCOUNT | -SLAB_MEM_SPREAD ), +SLAB_MEM_SPREAD |SLAB_ACCOUNT ), init_once);if (!rpc_inode_cachep)return -ENOMEM ;Signature · 1 line
2.1.4
Signature · 2 lines
Michal Hocko SUSE Labs
Re: [PATCH v2 6/6] Account certain kmem allocations to memcg
In reply to Vladimir DavydovQuoted 21 lines · Vladimir Davydov
This patch marks those kmem allocations that are known to be easily triggered from userspace as __GFP_ACCOUNT/SLAB_ACCOUNT, which makes them accounted to memcg. For the list, see below:
- threadinfo
-task_struct
-task_delay_info
- pid
- cred
-mm_struct
-vm_area_structandvm_region(nommu)
-anon_vmaandanon_vma_chain
-signal_struct
-sighand_struct
-fs_struct
-files_struct
- fdtable andfdtable->full_fds_bits
- dentry andexternal_name
- inode for all filesystems. This is the most tedious part, because most filesystems overwrite thealloc_inodemethod.
Quoted 8 lines
The list is by far not complete, so feel free to add more objects. Nevertheless, it should be close to "account everything" approach and keep most workloads within bounds. Malevolent users will be able to breach the limit, but this was possible even with the former "account everything" approach (simply because it did not account everything in fact).
Signed-off-by Vladimir Davydov <[email protected]>
Thanks for doing that work, Vladimir. It looks reasonable to me.
We can update the list as we go along and testing reveals more things that need to be considered. As far as malicious users go, I agree that we can not make this bullet proof, and so we shouldn't aim for that.