Kernel memory accounting container (v2)
Subsystems (3)
cover Kernel memory accounting container (v2)
Long time ago we decided to start memory control with the user memory container. Now this container in -mm tree and I think we can start with (at least discussion of) the kmem one.
Changes from v.1:
* fixed Paul's comment about subsystem registration
* return ERR_PTR from ->create callback, not NULL
* make container-to-object assignment in rcu-safe section
* make turning accounting on and off with "1" and "0"
============================================================
First of all - why do we need this kind of control. The major "pros" is that kernel memory control protects the system from DoS attacks by processes that live in container. As our experience shows many exploits simply do not work in the container with limited kernel memory.
I can split the kernel memory container into 4 parts:
1. kmalloc-ed objects control
2. vmalloc-ed objects control
3. buddy allocated pages control
4. kmem_cache_alloc-ed objects control
the control of first tree types of objects has one peculiarity:
one need to explicitly point out which allocations he wants to account and this becomes not-configurable and is to be discussed.
On the other hands such objects as anon_vma-s, file-s, sighangds, vfsmounts, etc are created by user request always and should always be accounted. Fortunately they are allocated from their own caches and thus the whole kmem cache can be accountable.
This is exactly what this patchset does - it adds the ability to account for the total size of kmem-cache-allocated objects from specified kmem caches.
This is based on the SLUB allocator, Paul's containers and the resource counters I made for RSS controller and which are in -mm tree already.
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
As I have already told kmalloc caches cannot be accounted easily so turning the accounting on for them will fail with -EINVAL. Turning the accounting off is possible only if the cache has no objects. This is done so because turning accounting off implies unaccounting of all the objects in the cache, but due to full-pages in slub are not stored in any lists (usually) this is impossible to do so, however I'm open for discussion of how to make this work.
I know it's maybe too late, since some of you may be preparing for the Summit or LinixConf, but I think that we can go on discussing these on LinuxConf.
The patches are applicable to the latest Morton's tree (that without the RSS controll) with the resource counters patch Andrew committed recently.
I've made some minimal testing for that and the similar code (without the containers interface but with the kmalloc accounting) is already in our 2.6.22 OpenVZ tree, so testing is going on.
Thanks,
Pavel
A message that is not in the archive (sent off-list or not yet received): [email protected]
RFC PATCH 1/3 Setup the kmem container
[PATCH 1/3] Setup the kmem container
Attach the controller to the containers. This can work with the SLUB allocator only. However, if we need I can port this on SLAB (and even SLOB ;) ).
This setup is simple and stupid.
---
include/linux/container_subsys.h | 6 ++ init/Kconfig | 6 ++ mm/slub.c | 110 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+)
include/linux/container_subsys.h +6 -0
@@ -36,3 +36,9 @@ SUBSYS(mem_container)#endif /* */ + +#ifdef CONFIG_CONTAINER_KMEM +SUBSYS(kmem) +#endif + +/* */
init/Kconfig +6 -0
@@ -353,6 +353,12 @@ config CONTAINER_MEM_CONT Provides a memory controller that manages both page cache and RSS memory. +config CONTAINER_KMEM + bool "Kernel memory controller for containers" + depends on CONTAINERS && RESOURCE_COUNTERS && SLUB + help + Provides a kernel memory usage control for containers + config PROC_PID_CPUSET bool "Include legacy /proc/<pid>/cpuset file" depends on CPUSETS
mm/slub.c +110 -0
119 lines not on this page · raw message
RFC PATCH 2/3 The accounting hooks and core
In reply to a message not in the archiveThe struct page gets an extra pointer (just like it has with the RSS controller) and this pointer points to the array of the kmem_container pointers - one for each object stored on that page itself.
Thus the i'th object on the page is accounted to the container pointed by the i'th pointer on that array and when the object is freed we unaccount its size to this particular container, not the container current task belongs to.
This is done so, because the context objects are freed is most often not the same as the one this objects was allocated in (due to RCU and reference counters).
Kmem cache marked as SLAB_CHARGE will perform the accounting.
---
include/linux/mm_types.h | 12 +++ include/linux/slab.h | 1 mm/slub.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 176 insertions(+), 2 deletions(-)
include/linux/mm_types.h +11 -1
@@ -83,9 +83,19 @@ struct page {void *virtual;/* Kernel virtual address (NULL if not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ + +/* +* one page cannot be mapped to the userspace and be +* allocated for slub at the same time +*/ +union {#ifdef CONFIG_CONTAINER_MEM_CONT -unsigned long page_container; +unsigned long page_container; +#endif +#ifdef CONFIG_CONTAINER_KMEM +struct kmem_container **containers;#endif + };#ifdef CONFIG_PAGE_OWNER int order;unsigned int gfp_mask;
include/linux/slab.h +1 -0
@@ -28,6 +28,7 @@#define SLAB_DESTROY_BY_RCU 0x00080000UL/* Defer freeing slabs to RCU */ #define SLAB_MEM_SPREAD 0x00100000UL/* Spread some memory over cpuset */ #define SLAB_TRACE 0x00200000UL/* Trace allocations and frees */ +#define SLAB_CHARGE 0x00400000UL/* Charge allocations */ /* The following flags affect the page allocator grouping pages by mobility */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL/* Objects are reclaimable */
mm/slub.c +164 -1
207 lines not on this page · raw message
RFC PATCH 3/3 Tune caches to be accountable or not
In reply to a message not in the archiveThe /sys/slab/<name>/cache_account attribute controls whether the cache <name> is to be accounted or not.
For the reasons described in the zeroth letter kmalloc caches are excluded and are not allowed to be merged.
By default no caches are accountable. Simply make
# echo -n 1 > /sys/slab/<name>cache_account to turn accounting on.
Other caches can be accountable, but if we turn accounting on on some cache and this cache is merged with some other, this "other" will be accountable as well. We can solve this by disabling of cache merging, but I'd prefer to know Christoph's opinion first.
Turning the accounting off is possible only when this cache is empty.
---
mm/slub.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+)
mm/slub.c +51 -0
@@ -2878,6 +2878,16 @@ static int slab_unmergeable(struct kmem_if (s->refcount <0 )return 1 ; +#ifdef CONFIG_CONTAINER_KMEM +/* +* many caches that can be accountable are usually merged with +* kmalloc caches, which are disabled for accounting for a while +*/ + +if (is_kmalloc_cache (s)) +return 1 ; +#endif +return 0 ; }
@@ -3842,6 +3852,44 @@ static ssize_t defrag_ratio_store(structSLAB_ATTR (defrag_ratio);#endif +#ifdef CONFIG_CONTAINER_KMEM +static ssize_t cache_account_show (struct kmem_cache *s,char *buf) +{ +return sprintf (buf,"%d\n" , !!(s->flags &SLAB_CHARGE )); +} + +static ssize_t cache_account_store (struct kmem_cache *s, +const char *buf,size_t length) +{ +if (buf[0 ] =='1' ) { +if (is_kmalloc_cache (s)) +/* +* cannot just make these caches accountable +*/ +return -EINVAL ; + + s->flags |=SLAB_CHARGE ; +return length; + } + +if (buf[0 ] =='0' ) { +if (any_slab_objects (s)) +/* +* we cannot turn this off because of the +* full slabs cannot be found in this case +*/ +return -EBUSY ; + + s->flags &= ~SLAB_CHARGE ; +return length; + } + +return -EINVAL ; +} + +SLAB_ATTR (cache_account); +#endif +static struct attribute * slab_attrs[] = { &slab_size_attr.attr, &object_size_attr.attr,
@@ -3872,6 +3920,9 @@ static struct attribute * slab_attrs[] =#ifdef CONFIG_NUMA &defrag_ratio_attr.attr,#endif +#ifdef CONFIG_CONTAINER_KMEM + &cache_account_attr.attr, +#endifNULL };
Quoted 13 lines · On Thu, 13 Sep 2007 13:11:35 +0400 Pavel Emelyanov…
First of all - why do we need this kind of control. The major "pros" is that kernel memory control protects the system from DoS attacks by processes that live in container. As our experience shows many exploits simply do not work in the container with limited kernel memory.
I can split the kernel memory container into 4 parts:
1. kmalloc-ed objects control
2. vmalloc-ed objects control
3. buddy allocated pages control
4. kmem_cache_alloc-ed objects control
<snip>
Quoted 4 lines
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
Hmm, how can we know "How many kmem will we need ?" in precise per-object style ? Is this useful ?
Following kind of limitation of user friendly params is bad ?
- # of file handles
- # of tasks
- # of sockets/ connections / packets
- # of posix IPC related things
- and other sources of DoS.
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): 20070913191950.ea100a62.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 16 lines · KAMEZAWA Hiroyuki
Quoted 6 lines · On Thu, 13 Sep 2007 13:11:35 +0400 Pavel Emelyanov…
First of all - why do we need this kind of control. The major "pros" is that kernel memory control protects the system from DoS attacks by processes that live in container. As our experience shows many exploits simply do not work in the container with limited kernel memory.
Quoted 7 lines
I can split the kernel memory container into 4 parts:
1. kmalloc-ed objects control
2. vmalloc-ed objects control
3. buddy allocated pages control
4. kmem_cache_alloc-ed objects control
Quoted 7 lines
<snip>
Quoted 4 lines
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
Hmm, how can we know "How many kmem will we need ?" in precise per-object style ? Is this useful ?
You can start with unlimited container and check how many kernel memory your applications use normally and set the limit to 120% of this.
You may also set this to some reasonable value like 50% of normal zone to protect your system from a fork bomb or similar.
This is the same question as "how many user pages will my container consume". The answer is - find it out experimentally or ask for someone who has already done so.
Quoted 7 lines
Following kind of limitation of user friendly params is bad ?
- # of file handles
- # of tasks
- # of sockets/ connections / packets
- # of posix IPC related things
- and other sources of DoS.
These are not enough and none of them are reasonable. E.g. the struct vm_area_struct objects are allocated for many mmap() calls, but how to find it out how many of them you will require.
However some controllers will be done as well.
Quoted 5 lines
Thanks,
-Kame
Quoted 35 lines · Pavel Emelyanov
Long time ago we decided to start memory control with the user memory container. Now this container in -mm tree and I think we can start with (at least discussion of) the kmem one.
Changes from v.1:
* fixed Paul's comment about subsystem registration
* returnERR_PTRfrom ->create callback, not NULL
* make container-to-object assignment in rcu-safe section
* make turning accounting on and off with "1" and "0"============================================================
First of all - why do we need this kind of control. The major "pros" is that kernel memory control protects the system from DoS attacks by processes that live in container. As our experience shows many exploits simply do not work in the container with limited kernel memory.
I can split the kernel memory container into 4 parts:
1. kmalloc-ed objects control
2. vmalloc-ed objects control
3. buddy allocated pages control
4. kmem_cache_alloc-ed objects controlthe control of first tree types of objects has one peculiarity:
one need to explicitly point out which allocations he wants to account and this becomes not-configurable and is to be discussed.On the other hands such objects as anon_vma-s, file-s, sighangds, vfsmounts, etc are created by user request always and should always be accounted. Fortunately they are allocated from their own caches and thus the whole kmem cache can be accountable.
Quoted 8 lines
This is exactly what this patchset does - it adds the ability to account for the total size of kmem-cache-allocated objects from specified kmem caches.
This is based on the SLUB allocator, Paul's containers and the resource counters I made for RSS controller and which are in -mm tree already.
Does this mean that the kernel memory container will have a dependency on SLUB and it will be disabled for SLAB and SLOB allocators? SLAB is going to go away soon anyway and I guess not too many people use SLOB.
Quoted 4 lines
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
Quoted 9 lines
As I have already told kmalloc caches cannot be accounted easily so turning the accounting on for them will fail with
-EINVAL. Turning the accounting off is possible only if the cache has no objects. This is done so because turning accounting off implies unaccounting of all the objects in the cache, but due to full-pages in slub are not stored in any lists (usually) this is impossible to do so, however I'm open for discussion of how to make this work.
I remember discussing with you, but I can't remember the rational, could you please explain it again.
Quoted 4 lines
I know it's maybe too late, since some of you may be preparing for the Summit or LinixConf, but I think that we can go on discussing these on LinuxConf.
The LinuxConf and kernel summit is done now :-)
Quoted 4 lines
The patches are applicable to the latest Morton's tree (that without the RSS controll) with the resource counters patch Andrew committed recently.
This is a bit confusing, it is applicable to 2.6.23-rc4-mm1?
Quoted 7 lines
I've made some minimal testing for that and the similar code (without the containers interface but with the kmalloc accounting) is already in our 2.6.22 OpenVZ tree, so testing is going on.
Thanks,
Pavel
Signature · 4 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL
A message that is not in the archive (sent off-list or not yet received): 46E91520.9060701-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org
Quoted 45 lines · Balbir Singh
Quoted 35 lines · Pavel Emelyanov
Long time ago we decided to start memory control with the user memory container. Now this container in -mm tree and I think we can start with (at least discussion of) the kmem one.
Changes from v.1:
* fixed Paul's comment about subsystem registration
* returnERR_PTRfrom ->create callback, not NULL
* make container-to-object assignment in rcu-safe section
* make turning accounting on and off with "1" and "0"============================================================
First of all - why do we need this kind of control. The major "pros" is that kernel memory control protects the system from DoS attacks by processes that live in container. As our experience shows many exploits simply do not work in the container with limited kernel memory.
I can split the kernel memory container into 4 parts:
1. kmalloc-ed objects control
2. vmalloc-ed objects control
3. buddy allocated pages control
4. kmem_cache_alloc-ed objects controlthe control of first tree types of objects has one peculiarity:
one need to explicitly point out which allocations he wants to account and this becomes not-configurable and is to be discussed.On the other hands such objects as anon_vma-s, file-s, sighangds, vfsmounts, etc are created by user request always and should always be accounted. Fortunately they are allocated from their own caches and thus the whole kmem cache can be accountable.
Quoted 8 lines
This is exactly what this patchset does - it adds the ability to account for the total size of kmem-cache-allocated objects from specified kmem caches.
This is based on the SLUB allocator, Paul's containers and the resource counters I made for RSS controller and which are in -mm tree already.
Quoted 4 lines
Does this mean that the kernel memory container will have a dependency on SLUB and it will be disabled for SLAB and SLOB allocators? SLAB is going to go away soon anyway and I guess not too many people use SLOB.
Right now it is, but I can port it on booth - slab and slob when slub is accepted.
Quoted 14 lines
Quoted 4 lines
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
Quoted 9 lines
As I have already told kmalloc caches cannot be accounted easily so turning the accounting on for them will fail with
-EINVAL. Turning the accounting off is possible only if the cache has no objects. This is done so because turning accounting off implies unaccounting of all the objects in the cache, but due to full-pages in slub are not stored in any lists (usually) this is impossible to do so, however I'm open for discussion of how to make this work.
Quoted 2 lines
I remember discussing with you, but I can't remember the rational, could you please explain it again.
The pages that are full of objects are not linked in any list in kmem_cache so we just cannot find them.
Quoted 6 lines
Quoted 4 lines
I know it's maybe too late, since some of you may be preparing for the Summit or LinixConf, but I think that we can go on discussing these on LinuxConf.
The LinuxConf and kernel summit is done now :-)
Oops :) Copy-paste :(
Quoted 6 lines
Quoted 4 lines
The patches are applicable to the latest Morton's tree (that without the RSS controll) with the resource counters patch Andrew committed recently.
This is a bit confusing, it is applicable to 2.6.23-rc4-mm1?
Yup. Copy-paste again... sorry :(
Quoted 9 lines
Quoted 7 lines
I've made some minimal testing for that and the similar code (without the containers interface but with the kmalloc accounting) is already in our 2.6.22 OpenVZ tree, so testing is going on.
Thanks,
Pavel
Quoted 7 lines · Pavel Emelyanov
This is based on the SLUB allocator, Paul's containers and the resource counters I made for RSS controller and which are in -mm tree already.
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
Hmmmm... Okay I have seen multiple people who want to control slab allocations and track memory for various reasons. Would it be possible to come up with some hook that would allow a subscription to certain SLUB events? That way multiple subsystems may track and maybe disallow certain allocations in various contexts.
A message that is not in the archive (sent off-list or not yet received): Pine.LNX.4.64.0709131135210.9590-RYO/[email protected]
Quoted 10 lines · Christoph Lameter
Quoted 7 lines · Pavel Emelyanov
This is based on the SLUB allocator, Paul's containers and the resource counters I made for RSS controller and which are in -mm tree already.
To play with it, one need to mount the container file system with -o kmem and then mark some caches as accountable via /sys/slab/<cache_name>/cache_account.
Quoted 5 lines
Hmmmm... Okay I have seen multiple people who want to control slab allocations and track memory for various reasons. Would it be possible to come up with some hook that would allow a subscription to certain SLUB events? That way multiple subsystems may track and maybe disallow certain allocations in various contexts.
Do you mean some more generic than just explicit call from slab_alloc, etc? Ok, I will work on it.
Thanks,
Pavel
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 8 lines · Pavel Emelyanov
Quoted 5 lines
Hmmmm... Okay I have seen multiple people who want to control slab allocations and track memory for various reasons. Would it be possible to come up with some hook that would allow a subscription to certain SLUB events? That way multiple subsystems may track and maybe disallow certain allocations in various contexts.
Do you mean some more generic than just explicit call from
slab_alloc, etc? Ok, I will work on it.
Yes I guess an API in slub to register callbacks for these things. This needs to include a way to control the granularity. Callbacks at the level of slab allocations are likely not that performance critical. But some uses may require control at the object level. There needs to be some way to tell SLUB to disable the fast path for a particular allocated slab because the API will police each individual allocation.
A message that is not in the archive (sent off-list or not yet received): Pine.LNX.4.64.0709141028120.15683-RYO/[email protected]
Quoted 10 lines · Christoph Lameter
Quoted 7 lines · Pavel Emelyanov
Quoted 5 lines
Hmmmm... Okay I have seen multiple people who want to control slab allocations and track memory for various reasons. Would it be possible to come up with some hook that would allow a subscription to certain SLUB events? That way multiple subsystems may track and maybe disallow certain allocations in various contexts.
Do you mean some more generic than just explicit call from
slab_alloc, etc? Ok, I will work on it.
Quoted 7 lines
Yes I guess an API in slub to register callbacks for these things. This needs to include a way to control the granularity. Callbacks at the level of slab allocations are likely not that performance critical. But some uses may require control at the object level. There needs to be some way to tell SLUB to disable the fast path for a particular allocated slab because the API will police each individual allocation.
OK. I see. I will do my best to prepare the first version this week.
Thanks,
Pavel