memory.min_usage
Subsystems (4)
PATCH 1/1 memory.min_usage
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
it's against 2.6.24-rc3-mm2 + memory.swappiness patch i posted here yesterday. but it's logically independent from the swappiness patch.
todo:
- restrict non-root user's operation ragardless of owner of cgroupfs files?
- make oom killer aware of this?
YAMAMOTO Takashi
---
include/linux/memcontrol.h renamed from include/linux/memcontrol.h.BACKUP2 +1 -0
@@ -47,6 +47,7 @@ extern int mem_cgroup_cache_charge(struc gfp_t gfp_mask);int task_in_mem_cgroup (struct task_struct *task,const struct mem_cgroup *mem);extern int mem_cgroup_swappiness (struct mem_cgroup *mem); +extern int mem_cgroup_canreclaim (struct page *page,struct mem_cgroup *mem);static inline struct mem_cgroup *mm_cgroup (const struct mm_struct *mm) {
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +52 -0
76 lines not on this page · raw message
mm/vmscan.c renamed from mm/vmscan.c.BACKUP2 +11 -0
@@ -531,6 +531,11 @@ static unsigned long shrink_page_list(st referenced && page_mapping_inuse(page)) goto activate_locked; +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) + goto activate_locked; +#endif /* CONFIG_CGROUP_MEM_CONT */ +#ifdef CONFIG_SWAP /* * Anonymous process memory has backing store?
@@ -1122,6 +1127,12 @@ static void shrink_active_list(unsignedlist_add (&page->lru, &l_active);continue ; } +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) { +list_add (&page->lru, &l_active); +continue ; + } +#endif /* CONFIG_CGROUP_MEM_CONT */ list_add (&page->lru, &l_inactive); }
A message that is not in the archive (sent off-list or not yet received): 20071204040934.44AF41D0BA3-Pcsii4f/[email protected]
Quoted 5 lines · On Tue, 4 Dec 2007 13:09:34 +0900 (JST)…
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
Thanks.
Quoted 2 lines
todo:
- restrict non-root user's operation ragardless of owner of cgroupfs files?
I like 'only-for-root' user. or CAP_SYS_RESOURCE.
Quoted 2 lines
- make oom killer aware of this?
For OOM-Killer, IMHO, no care is necessary (now).
This function can be considered as a kind of mlock(). A user can be aware of memory usage.
But, we may need some logic/reason to request this function.
mm/memcontrol.c struct mem_cgroup { · line 138
Quoted 2 lines
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +1
-0+unsigned long long min_usage;/* XXX should be a part of res_counter? */ /*
Maybe res_counter is better. (Added CC: to Pavel Emelianov)
Quoted 20 lines
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +20
-0+int mem_cgroup_canreclaim (struct page *page,struct mem_cgroup *mem1) +{ +struct page_cgroup *pc; +int result =1 ; + +if (mem1 !=NULL ) +return 1 ; + +lock_page_cgroup (page); + pc =page_get_page_cgroup (page); +if (pc) { +struct mem_cgroup *mem2 = pc->mem_cgroup; +unsigned long long min_usage; + +BUG_ON (mem2 ==NULL ); + min_usage = mem2->min_usage; +if (min_usage !=0 ) { +unsigned long flags; + +spin_lock_irqsave (&mem2->res.lock, flags);
mm/memcontrol.c int mem_cgroup_swappiness(struct mem_cgr · line 1196
Quoted 10 lines
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +10
-0+if (mem2->res.usage <= min_usage) + result =0 ; +spin_unlock_irqrestore (&mem2->res.lock, flags); + } + } +unlock_page_cgroup (page); + +return result; +} +
How about adding lock_and_get_page_cgroup(page)/put_page_cgroup() ? ==
struct page_cgroup *pc lock_and_get_page_cgroup(page)
{
struct page_cgroup *pc;
lock_page_cgroup(page);
pc = page_get_page_cgroup(page);
if (atomic_inc_not_zero(&pc->ref_cnt))
pc = NULL;
unlock_page_cgroup(page);
return pc;
}struct page_cgroup *pc put_page_cgroup(struct page_cgroup *pc)
{
mem_cgroup_uncharge(pc);
}==
BTW, how about add a status to res_counter ? My (based on your) current patch uses watermark_state.
Maybe we can change it to be resource_state and show following status.
RES_STATE_HIT_LIMIT,RES_STATE_ABOVE_HWATER,RES_STATE_ABOVE_LWATER,RES_STATE_STABLE, ?RES_STATE_BELOW_MIN,
Useful ?
Quoted 6 lines
static int
alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node){mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +0
-0struct mem_cgroup_per_node *pn;
mm/vmscan.c static unsigned long shrink_page_list(st · line 538
Quoted 8 lines
mm/vmscan.c renamed from mm/vmscan.c.BACKUP2 +5
-0@@ -531,6 +531,11 @@ static unsigned long shrink_page_list(st referenced && page_mapping_inuse(page)) goto activate_locked; +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) + goto activate_locked; +#endif /* CONFIG_CGROUP_MEM_CONT */ +
Maybe
==
if (scan_global_lru(sc) && !
mem_cgroup_canreclaim(page, sc->mem-cgroup))
goto activate_locked:==
mm/vmscan.c static void shrink_active_list(unsigned · line 1134
Quoted 13 lines
mm/vmscan.c renamed from mm/vmscan.c.BACKUP2 +0
-0#ifdef CONFIG_SWAP /* mm/vmscan.c renamed from mm/vmscan.c.BACKUP2 +5
-0* Anonymous process memory has backing store? @@ -1122,6 +1127,12 @@ static void shrink_active_list(unsignedlist_add (&page->lru, &l_active);continue ; } +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) { +list_add (&page->lru, &l_active); +continue ; + }
here too.
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): 20071204145831.da477f5b.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 45 lines
Quoted 20 lines
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +20
-0+int mem_cgroup_canreclaim (struct page *page,struct mem_cgroup *mem1) +{ +struct page_cgroup *pc; +int result =1 ; + +if (mem1 !=NULL ) +return 1 ; + +lock_page_cgroup (page); + pc =page_get_page_cgroup (page); +if (pc) { +struct mem_cgroup *mem2 = pc->mem_cgroup; +unsigned long long min_usage; + +BUG_ON (mem2 ==NULL ); + min_usage = mem2->min_usage; +if (min_usage !=0 ) { +unsigned long flags; + +spin_lock_irqsave (&mem2->res.lock, flags);mm/memcontrol.c int mem_cgroup_swappiness(struct mem_cgr · line 1196
Quoted 10 lines
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +10
-0+if (mem2->res.usage <= min_usage) + result =0 ; +spin_unlock_irqrestore (&mem2->res.lock, flags); + } + } +unlock_page_cgroup (page); + +return result; +} +How about adding lock_and_get_page_cgroup(page)/put_page_cgroup() ? ==
structpage_cgroup*pclock_and_get_page_cgroup(page){ struct page_cgroup *pc; lock_page_cgroup(page); pc = page_get_page_cgroup(page); if (atomic_inc_not_zero(&pc->ref_cnt)) pc = NULL; unlock_page_cgroup(page); return pc; }
Quoted 5 lines
struct
page_cgroup*pcput_page_cgroup(struct page_cgroup *pc){ mem_cgroup_uncharge(pc); }==
i'm not sure if it's a good idea given that reference counting (atomic_foo) has its own costs.
Quoted 5 lines
BTW, how about add a status to
res_counter? My (based on your) current patch useswatermark_state.Maybe we can change it to be
resource_stateand show following status.
Quoted 7 lines
RES_STATE_HIT_LIMIT,RES_STATE_ABOVE_HWATER,RES_STATE_ABOVE_LWATER,RES_STATE_STABLE, ?RES_STATE_BELOW_MIN,Useful ?
how about making res_counter use seq_lock?
Quoted 18 lines
Quoted 6 lines
static int
alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node){mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +0
-0struct mem_cgroup_per_node *pn;mm/vmscan.c static unsigned long shrink_page_list(st · line 538
Quoted 8 lines
mm/vmscan.c renamed from mm/vmscan.c.BACKUP2 +5
-0@@ -531,6 +531,11 @@ static unsigned long shrink_page_list(st referenced && page_mapping_inuse(page)) goto activate_locked; +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) + goto activate_locked; +#endif /* CONFIG_CGROUP_MEM_CONT */ +Maybe
==
if (scan_global_lru(sc)&& !
Quoted 3 lines
mem_cgroup_canreclaim(page, sc->mem-cgroup)) goto activate_locked:==
i don't think the decision belongs to callers.
(at least it wasn't my intention.)
YAMAMOTO Takashi
A message that is not in the archive (sent off-list or not yet received): 20071204070122.16DDD1D0BCD-Pcsii4f/[email protected]
Quoted 11 lines · On Tue, 4 Dec 2007 16:01:21 +0900 (JST)…
Quoted 11 lines
BTW, how about add a status to
res_counter? My (based on your) current patch useswatermark_state.Maybe we can change it to be
resource_stateand show following status.
RES_STATE_HIT_LIMIT,RES_STATE_ABOVE_HWATER,RES_STATE_ABOVE_LWATER,RES_STATE_STABLE, ?RES_STATE_BELOW_MIN,
Quoted 4 lines
Quoted 1 line
Useful ?
how about making
res_counteruseseq_lock?
I thought of that when I wrote hi/low watermark patches. But I didn't try....
Hmm, but maybe worth trying.
Pavel, can we change res_counter->lock to seq_lock ? If we can, I'll write a patch.
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): 20071204162753.c28cc550.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 4 lines · On Tue, 4 Dec 2007 16:27:53 +0900 KAMEZAWA Hiroyuki…
I thought of that when I wrote hi/low watermark patches. But I didn't try....
Hmm, but maybe worth trying.
But even with seqlock, we'll have to disable irq. And maybe my current high/low patch needs smp_rmb().
I'll consider a bit more.
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): 20071204164615.fc871e44.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 1 line
But even with seqlock, we'll have to disable irq.
for writers, sure.
readers don't need to disable irq.
YAMAMOTO Takashi
A message that is not in the archive (sent off-list or not yet received): 20071204075854.5850B1D0BFA-Pcsii4f/[email protected]
Re: [PATCH] memory.min_usage (seqlock for res_counter)
This is seqlock version res_counter.
Maybe this this will reduce # of spin_lock.
Pavel-san, How about this ?
-Kame
==
resource counter's spinlock can be seqlock. (res_counter doesn't include any pointers.)
And it will be good to avoid atomic ops if we can when we just checks value.
include/linux/res_counter.h | 24 +++++++----------------- kernel/res_counter.c | 14 +++++++------- 2 files changed, 14 insertions(+), 24 deletions(-)
include/linux/res_counter.h +8 -17
@@ -12,6 +12,7 @@*/ #include <linux/cgroup.h> +#include <linux/seqlock.h> /* * The core object. the cgroup that wishes to account for some
@@ -36,7 +37,7 @@ struct res_counter {* the lock to protect all of the above. * the routines below consider this to be IRQ-safe */ -spinlock_t lock; +seqlock_t lock; };/*
@@ -101,27 +102,17 @@ int res_counter_charge(struct res_countevoid res_counter_uncharge_locked (struct res_counter *counter,unsigned long val);void res_counter_uncharge (struct res_counter *counter,unsigned long val); -static inline bool res_counter_limit_check_locked (struct res_counter *cnt) -{ -if (cnt->usage < cnt->limit) -return true; - -return false; -} - -/* -* Helper function to detect if the cgroup is within it's limit or -* not. It's currently called from cgroup_rss_prepare() -*/ static inline bool res_counter_check_under_limit (struct res_counter *cnt) {bool ret; -unsigned long flags; +unsigned long seq; -spin_lock_irqsave (&cnt->lock, flags); - ret =res_counter_limit_check_locked (cnt); -spin_unlock_irqrestore (&cnt->lock, flags); +do { + seq =read_seqbegin (&cnt->lock); + ret = (cnt->usage < cnt->limit); + }while (read_seqretry (&cnt->lock, seq));return ret; } +#endif
kernel/res_counter.c +7 -7
@@ -15,7 +15,7 @@void res_counter_init (struct res_counter *counter) { -spin_lock_init (&counter->lock); +seqlock_init (&counter->lock); counter->limit = (unsigned long long )LLONG_MAX ; }
@@ -35,9 +35,9 @@ int res_counter_charge(struct res_counteint ret;unsigned long flags; -spin_lock_irqsave (&counter->lock, flags); +write_seqlock_irqsave (&counter->lock, flags); ret =res_counter_charge_locked (counter, val); -spin_unlock_irqrestore (&counter->lock, flags); +write_sequnlock_irqrestore (&counter->lock, flags);return ret; }
@@ -53,9 +53,9 @@ void res_counter_uncharge(struct res_cou {unsigned long flags; -spin_lock_irqsave (&counter->lock, flags); +write_seqlock_irqsave (&counter->lock, flags);res_counter_uncharge_locked (counter, val); -spin_unlock_irqrestore (&counter->lock, flags); +write_sequnlock_irqrestore (&counter->lock, flags); }
@@ -122,10 +122,10 @@ ssize_t res_counter_write(struct res_couif (*end !='\0' ) goto out_free; } -spin_lock_irqsave (&counter->lock, flags); +write_seqlock_irqsave (&counter->lock, flags); val =res_counter_member (counter, member); *val = tmp; -spin_unlock_irqrestore (&counter->lock, flags); +write_sequnlock_irqrestore (&counter->lock, flags); ret = nbytes; out_free:kfree (buf);
A message that is not in the archive (sent off-list or not yet received): 20071204195436.77fc911b.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Re: [PATCH] memory.min_usage (seqlock for res_counter)
Quoted 4 lines · KAMEZAWA Hiroyuki
This is seqlock version
res_counter.
Maybe this this will reduce # ofspin_lock.Pavel-san, How about this ?
AFAIS the readlock is used only in the check_under_limit(), but I think, that even if we read usage and limit values in this case non-atomically, this won't result in any dramatic sequence at all. No?
On the other hand, we make the charge/uncharge routines work longer :(
Quoted 124 lines
-Kame
==
resource counter's spinlock can be seqlock. (res_counterdoesn't include any pointers.)And it will be good to avoid atomic ops if we can when we just checks value.
Signed-off-by KAMEZAWA Hiroyuki <[email protected]>include/linux/res_counter.h | 24 +++++++----------------- kernel/res_counter.c | 14 +++++++------- 2 files changed, 14 insertions(+), 24 deletions(-)Index:
linux-2.6.24-rc3-mm2/include/linux/res_counter.h
===================================================================include/linux/res_counter.h +8
-17@@ -12,6 +12,7 @@*/ #include <linux/cgroup.h> +#include <linux/seqlock.h> /* * The core object. the cgroup that wishes to account for some @@ -36,7 +37,7 @@ struct res_counter {* the lock to protect all of the above. * the routines below consider this to be IRQ-safe */ -spinlock_t lock; +seqlock_t lock; };/* @@ -101,27 +102,17 @@ int res_counter_charge(struct res_countevoid res_counter_uncharge_locked (struct res_counter *counter,unsigned long val);void res_counter_uncharge (struct res_counter *counter,unsigned long val); -static inline bool res_counter_limit_check_locked (struct res_counter *cnt) -{ -if (cnt->usage < cnt->limit) -return true; - -return false; -} - -/* -* Helper function to detect if the cgroup is within it's limit or -* not. It's currently called from cgroup_rss_prepare() -*/ static inline bool res_counter_check_under_limit (struct res_counter *cnt) {bool ret; -unsigned long flags; +unsigned long seq; -spin_lock_irqsave (&cnt->lock, flags); - ret =res_counter_limit_check_locked (cnt); -spin_unlock_irqrestore (&cnt->lock, flags); +do { + seq =read_seqbegin (&cnt->lock); + ret = (cnt->usage < cnt->limit); + }while (read_seqretry (&cnt->lock, seq));return ret; } +#endif Index:
linux-2.6.24-rc3-mm2/kernel/res_counter.c
===================================================================kernel/res_counter.c +7
-7@@ -15,7 +15,7 @@void res_counter_init (struct res_counter *counter) { -spin_lock_init (&counter->lock); +seqlock_init (&counter->lock); counter->limit = (unsigned long long )LLONG_MAX ; }@@ -35,9 +35,9 @@ int res_counter_charge(struct res_counteint ret;unsigned long flags; -spin_lock_irqsave (&counter->lock, flags); +write_seqlock_irqsave (&counter->lock, flags); ret =res_counter_charge_locked (counter, val); -spin_unlock_irqrestore (&counter->lock, flags); +write_sequnlock_irqrestore (&counter->lock, flags);return ret; }@@ -53,9 +53,9 @@ void res_counter_uncharge(struct res_cou {unsigned long flags; -spin_lock_irqsave (&counter->lock, flags); +write_seqlock_irqsave (&counter->lock, flags);res_counter_uncharge_locked (counter, val); -spin_unlock_irqrestore (&counter->lock, flags); +write_sequnlock_irqrestore (&counter->lock, flags); }@@ -122,10 +122,10 @@ ssize_t res_counter_write(struct res_couif (*end !='\0' ) goto out_free; } -spin_lock_irqsave (&counter->lock, flags); +write_seqlock_irqsave (&counter->lock, flags); val =res_counter_member (counter, member); *val = tmp; -spin_unlock_irqrestore (&counter->lock, flags); +write_sequnlock_irqrestore (&counter->lock, flags); ret = nbytes; out_free:kfree (buf);
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH] memory.min_usage (seqlock for res_counter)
Quoted 11 lines · On Tue, 04 Dec 2007 14:10:42 +0300 Pavel Emelyanov…
Quoted 4 lines · KAMEZAWA Hiroyuki
This is seqlock version
res_counter.
Maybe this this will reduce # ofspin_lock.Pavel-san, How about this ?
AFAIS the readlock is used only in the
check_under_limit(), but I think, that even if we read usage and limit values in this case non-atomically, this won't result in any dramatic sequence at all. No?
Reader can detect *any* changes in res_counter member which happens while they access res_counter between seq_begin/seq_retry. Memory barrier and "sequence" of seq_lock guarantees this. So..there is no dramatical situation.
(it's used for accesing xtime.)
I'm sorry if I miss your point.
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): 20071205093455.0f46b456.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Re: [PATCH] memory.min_usage (seqlock for res_counter)
Quoted 13 lines · KAMEZAWA Hiroyuki
Quoted 10 lines · On Tue, 04 Dec 2007 14:10:42 +0300 Pavel Emelyanov…
Quoted 4 lines · KAMEZAWA Hiroyuki
This is seqlock version
res_counter.
Maybe this this will reduce # ofspin_lock.Pavel-san, How about this ?
AFAIS the readlock is used only in the
check_under_limit(), but I think, that even if we read usage and limit values in this case non-atomically, this won't result in any dramatic sequence at all. No?
Quoted 7 lines
Reader can detect *any* changes in
res_countermember which happens while they accessres_counterbetween seq_begin/seq_retry. Memory barrier and "sequence" ofseq_lockguarantees this. So..there is no dramatical situation.
(it's used for accesing xtime.)I'm sorry if I miss your point.
Sorry, let me explain it in other words.
I think, that protection in reader, that guarantees that it will see the valid result, is not very important - even if we compare usage and limit not atomically nothing serious will happen (in this particular case)
Quoted 4 lines
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH] memory.min_usage (seqlock for res_counter)
Quoted 7 lines · On Wed, 05 Dec 2007 12:12:22 +0300 Pavel Emelyanov…
Sorry, let me explain it in other words.
I think, that protection in reader, that guarantees that it will see the valid result, is not very important - even if we compare usage and limit not atomically nothing serious will happen (in this particular case)
Maybe there is no serious situation (now).
But programmers don't assume that the function may not return trustable result. And I think it shouldn be trustable AMAP.
I'd like to use seq_lock or res_counter_state, here.
BTW, I'm wondering I should hold off my patches until 2.6.25-rc series if they make things complex.
Thanks,
-Kame
A message that is not in the archive (sent off-list or not yet received): 20071205182927.41d140a7.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Re: [PATCH] memory.min_usage (seqlock for res_counter)
Quoted 5 lines · KAMEZAWA Hiroyuki
Quoted 2 lines · On Wed, 05 Dec 2007 12:12:22 +0300 Pavel Emelyanov…
Sorry, let me explain it in other words.
Quoted 8 lines
Quoted 5 lines
I think, that protection in reader, that guarantees that it will see the valid result, is not very important - even if we compare usage and limit not atomically nothing serious will happen (in this particular case)
Maybe there is no serious situation (now).
But programmers don't assume that the function may not return trustable result. And I think it shouldn be trustable AMAP.
Well... OK. Among other possible ways to achieve this goal seqlocks is the most preferable one from my POV.
Thanks :)
Quoted 4 lines
I'd like to use
seq_lockorres_counter_state, here.BTW, I'm wondering I should hold off my patches until 2.6.25-rc series if they make things complex.
Actually, Andrew wrote that he will pay little attention to new functionality till 2.6.24 release, so I think that serious patches should really be held off.
That's why I don't send the kmem controller yet :(
Quoted 2 lines
Thanks,
-Kame
Thanks,
Pavel
mm/memcontrol.c static u64 mem_cgroup_swappiness_read(st · line 1115
Quoted 7 lines · YAMAMOTO Takashi
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +7
-0+static u64 mem_cgroup_min_usage_read (struct cgroup *cont,struct cftype *cft) +{ +struct mem_cgroup *mem =mem_cgroup_from_cont (cont); + +return mem->min_usage; +} +
This won't be atomic on a 32-bit arch, and I don't think you have any locking.
Paul
A message that is not in the archive (sent off-list or not yet received): 6599ad830712032203t48e455cbjd25a40cf93cb453f-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 11 lines · YAMAMOTO Takashi
mm/memcontrol.c static u64 mem_cgroup_swappiness_read(st · line 1115
Quoted 7 lines
mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +7
-0+static u64 mem_cgroup_min_usage_read (struct cgroup *cont,struct cftype *cft) +{ +struct mem_cgroup *mem =mem_cgroup_from_cont (cont); + +return mem->min_usage; +} +This won't be atomic on a 32-bit arch, and I don't think you have any locking.
Quoted 1 line
Paul
sure. probably it's better to make it a part of res_counter.
YAMAMOTO Takashi
Quoted 5 lines · YAMAMOTO Takashi
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
Quoted 8 lines
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.it's against 2.6.24-rc3-mm2 + memory.swappiness patch i posted here yesterday. but it's logically independent from the swappiness patch.
Hi,
I think it's a good approach, but we need to make the reclaim dependent on priority. I think that if we stop reclaiming from a cgroup even though there is high global pressure, it might be a bad idea.
Quoted 2 lines
todo:
- restrict non-root user's operation ragardless of owner of cgroupfs files?
Sorry, I don't understand this and I think using file permissions is a good idea.
Quoted 2 lines
- make oom killer aware of this?
Yes, we might also need a memory controller version of
1. overcommit
2. oom_adj* parameters
Quoted 129 lines
YAMAMOTO Takashi
Signed-off-by YAMAMOTO Takashi <[email protected]>---
include/linux/memcontrol.h renamed from include/linux/memcontrol.h.BACKUP2 +1
-0@@ -47,6 +47,7 @@ extern int mem_cgroup_cache_charge(struc gfp_t gfp_mask);int task_in_mem_cgroup (struct task_struct *task,const struct mem_cgroup *mem);extern int mem_cgroup_swappiness (struct mem_cgroup *mem); +extern int mem_cgroup_canreclaim (struct page *page,struct mem_cgroup *mem);static inline struct mem_cgroup *mm_cgroup (const struct mm_struct *mm) {mm/memcontrol.c renamed from mm/memcontrol.c.BACKUP2 +52
-0@@ -134,6 +134,7 @@ struct mem_cgroup {unsigned long control_type;/* control RSS or RSS+Pagecache */ int prev_priority;/* for recording reclaim priority */ unsigned int swappiness;/* swappiness */ +unsigned long long min_usage;/* XXX should be a part of res_counter? */ /* * statistics. */ @@ -1096,6 +1097,22 @@ static u64 mem_cgroup_swappiness_read(streturn mem->swappiness; } +static int mem_cgroup_min_usage_write (struct cgroup *cont,struct cftype *cft, +u64 val) +{ +struct mem_cgroup *mem =mem_cgroup_from_cont (cont); + + mem->min_usage = val; +return 0 ; +} + +static u64 mem_cgroup_min_usage_read (struct cgroup *cont,struct cftype *cft) +{ +struct mem_cgroup *mem =mem_cgroup_from_cont (cont); + +return mem->min_usage; +} +static struct cftype mem_cgroup_files[] = { { .name ="usage_in_bytes" ,@@ -1132,6 +1149,11 @@ static struct cftype mem_cgroup_files[] .write_uint = mem_cgroup_swappiness_write, .read_uint = mem_cgroup_swappiness_read, }, + { + .name = "min_usage_in_bytes", + .write_uint = mem_cgroup_min_usage_write, + .read_uint = mem_cgroup_min_usage_read, + }, };/* XXX probably it's better to move try_to_free_mem_cgroup_pages to @@ -1142,6 +1164,36 @@ int mem_cgroup_swappiness(struct mem_cgrreturn mem->swappiness; } +int mem_cgroup_canreclaim (struct page *page,struct mem_cgroup *mem1) +{ +struct page_cgroup *pc; +int result =1 ; + +if (mem1 !=NULL ) +return 1 ; + +lock_page_cgroup (page); + pc =page_get_page_cgroup (page); +if (pc) { +struct mem_cgroup *mem2 = pc->mem_cgroup; +unsigned long long min_usage; + +BUG_ON (mem2 ==NULL ); + min_usage = mem2->min_usage; +if (min_usage !=0 ) { +unsigned long flags; + +spin_lock_irqsave (&mem2->res.lock, flags); +if (mem2->res.usage <= min_usage) + result =0 ; +spin_unlock_irqrestore (&mem2->res.lock, flags); + } + } +unlock_page_cgroup (page); + +return result; +} +static int alloc_mem_cgroup_per_zone_info (struct mem_cgroup *mem,int node) {struct mem_cgroup_per_node *pn;mm/vmscan.c renamed from mm/vmscan.c.BACKUP2 +11
-0@@ -531,6 +531,11 @@ static unsigned long shrink_page_list(st referenced && page_mapping_inuse(page)) goto activate_locked; +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) + goto activate_locked; +#endif /* CONFIG_CGROUP_MEM_CONT */ +#ifdef CONFIG_SWAP /* * Anonymous process memory has backing store? @@ -1122,6 +1127,12 @@ static void shrink_active_list(unsignedlist_add (&page->lru, &l_active);continue ; } +#ifdef CONFIG_CGROUP_MEM_CONT +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) { +list_add (&page->lru, &l_active); +continue ; + } +#endif /* CONFIG_CGROUP_MEM_CONT */ list_add (&page->lru, &l_inactive); }_______________________________________________
Containers mailing list Containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linux-foundation.org/mailman/listinfo/containers
Signature · 4 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL
RFC PATCH 1/1 memory.min_usage again
In reply to YAMAMOTO Takashihi,
Quoted 10 lines
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
Quoted 8 lines
it's against 2.6.24-rc3-mm2 + memory.swappiness patch i posted here yesterday. but it's logically independent from the swappiness patch.
todo:
- restrict non-root user's operation ragardless of owner of cgroupfs files?
- make oom killer aware of this?YAMAMOTO Takashi
here's a new version adapted to 2.6.27-rc5-mm1.
YAMAMOTO Takashi
---
include/linux/memcontrol.h +9 -0
@@ -72,6 +72,8 @@ extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem,extern long mem_cgroup_calc_reclaim (struct mem_cgroup *mem,struct zone *zone,int priority,enum lru_list lru); +extern int mem_cgroup_canreclaim (struct page *page,struct mem_cgroup *mem); +#else /* CONFIG_CGROUP_MEM_RES_CTLR */ static inline void page_reset_bad_cgroup (struct page *page) {
@@ -163,6 +165,13 @@ static inline long mem_cgroup_calc_reclaim(struct mem_cgroup *mem, {return 0 ; } + +static inline int mem_cgroup_canreclaim (struct page *page, +struct mem_cgroup *mem) +{ +return 1 ; +} +#endif /* CONFIG_CGROUP_MEM_CONT */ #endif /* _LINUX_MEMCONTROL_H */
mm/memcontrol.c +58 -0
78 lines not on this page · raw message
mm/vmscan.c +6 -1
@@ -673,6 +673,9 @@ static unsigned long shrink_page_list(struct list_head *page_list, referenced && page_mapping_inuse(page)) goto activate_locked; +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) + goto activate_locked; +#ifdef CONFIG_SWAP /* * Anonymous process memory has backing store?
@@ -1294,7 +1297,9 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,continue ; } -if (page_referenced (page,0 , sc->mem_cgroup)) { +if (!mem_cgroup_canreclaim (page, sc->mem_cgroup)) { +list_add (&page->lru, &l_active); + }else if (page_referenced (page,0 , sc->mem_cgroup)) { pgmoved++;if (file) {/* Referenced file pages stay active. */
Re: [PATCH][RFC] memory.min_usage again
Hi
Quoted 8 lines
Quoted 8 lines
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
Quoted 6 lines
Quoted 6 lines
it's against 2.6.24-rc3-mm2 + memory.swappiness patch i posted here yesterday. but it's logically independent from the swappiness patch.
todo:
- restrict non-root user's operation ragardless of owner of cgroupfs files?
- make oom killer aware of this?
This is really no good patch description.
You should write
- Why you think it is useful.
- Who need it.
A reviewer oftern want check to match coder's intention and actual code.
Re: [PATCH][RFC] memory.min_usage again
In reply to YAMAMOTO TakashiQuoted 12 lines · YAMAMOTO Takashi
hi,
Quoted 10 lines
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
Looking through the code I am a little worried, what if every cgroup is below minimum value and the system is under memory pressure, do we OOM, while we could have easily reclaimed?
I would prefer to see some heuristics around such a feature, mostly around the priority that do_try_to_free_pages() to determine how desperate we are for reclaiming memory.
Signature · 1 line
Balbir
Re: [PATCH][RFC] memory.min_usage again
Quoted 14 lines · On Wed, 10 Sep 2008 08:32:15 -0700 Balbir Singh…
Quoted 12 lines · YAMAMOTO Takashi
hi,
Quoted 10 lines
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
Quoted 8 lines
Looking through the code I am a little worried, what if every cgroup is below minimum value and the system is under memory pressure, do we OOM, while we could have easily reclaimed?
I would prefer to see some heuristics around such a feature, mostly around the priority that
do_try_to_free_pages()to determine how desperate we are for reclaiming memory.
Taking "priority" of memory reclaim path into account is good.
==
static unsigned long shrink_inactive_list(unsigned long max_scan,
struct zone *zone, struct scan_control *sc, int priority, int file)
==
How about ignore min_usage if "priority < DEF_PRIORITY - 2" ?
Thanks,
-Kame
Re: [PATCH][RFC] memory.min_usage again
hi,
Quoted 17 lines
Quoted 14 lines · On Wed, 10 Sep 2008 08:32:15 -0700 Balbir Singh <[email protected]>…
Quoted 12 lines · YAMAMOTO Takashi
hi,
Quoted 10 lines
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
Quoted 3 lines
Quoted 3 lines
Looking through the code I am a little worried, what if every cgroup is below minimum value and the system is under memory pressure, do we OOM, while we could have easily reclaimed?
i'm not sure what you are worring about. can you explain a little more? under the configuration, OOM is an expected behaviour.
Quoted 5 lines
Quoted 5 lines
I would prefer to see some heuristics around such a feature, mostly around the priority that
do_try_to_free_pages()to determine how desperate we are for reclaiming memory.
Quoted 8 lines
Taking "priority" of memory reclaim path into account is good.
==
static unsigned long shrink_inactive_list(unsigned longmax_scan,
struct zone *zone, structscan_control*sc, int priority, int file)
==
How about ignoremin_usageif "priority <DEF_PRIORITY- 2" ?
are you suggesting ignoring mlock etc as well in that case?
YAMAMOTO Takashi
Quoted 10 lines
Thanks,
-Kame--
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>
--
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][RFC] memory.min_usage again
Quoted 18 lines · YAMAMOTO Takashi
hi,
Quoted 16 lines
Quoted 13 lines · On Wed, 10 Sep 2008 08:32:15 -0700 Balbir Singh <[email protected]>…
Quoted 12 lines · YAMAMOTO Takashi
hi,
Quoted 10 lines
hi,
here's a patch to implement memory.min_usage, which controls the minimum memory usage for a cgroup.
it works similarly to mlock;
global memory reclamation doesn't reclaim memory from cgroups whose memory usage is below the value. setting it too high is a dangerous operation.
Quoted 7 lines
Quoted 3 lines
Quoted 3 lines
Looking through the code I am a little worried, what if every cgroup is below minimum value and the system is under memory pressure, do we OOM, while we could have easily reclaimed?
i'm not sure what you are worring about. can you explain a little more? under the configuration, OOM is an expected behaviour.
Yes, but an OOM will violate the min_memory right? We promise not to reclaim, but we can OOM. I would rather implement them as watermarks (best effort service, rather than a guarantee). OOMing the system sounds bad, specially if memory can be reclaimed.. No?
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
I would prefer to see some heuristics around such a feature, mostly around the priority that
do_try_to_free_pages()to determine how desperate we are for reclaiming memory.Taking "priority" of memory reclaim path into account is good.
Quoted 9 lines
Quoted 6 lines
==
static unsigned long shrink_inactive_list(unsigned longmax_scan,
struct zone *zone, structscan_control*sc, int priority, int file)
==
How about ignoremin_usageif "priority <DEF_PRIORITY- 2" ?are you suggesting ignoring mlock etc as well in that case?
No.. not at all, we will get an mlock controller as well.
Quoted 2 lines
YAMAMOTO Takashi
Signature · 7 lines
Balbir -- 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][RFC] memory.min_usage again
In reply to YAMAMOTO TakashiQuoted 7 lines · On Mon, 29 Sep 2008 09:43:32 +0900 (JST) [email protected] (YAMAMOTO…
Quoted 7 lines
Quoted 5 lines
I would prefer to see some heuristics around such a feature, mostly around the priority that
do_try_to_free_pages()to determine how desperate we are for reclaiming memory.Taking "priority" of memory reclaim path into account is good.
Quoted 9 lines
Quoted 6 lines
==
static unsigned long shrink_inactive_list(unsigned longmax_scan,
struct zone *zone, structscan_control*sc, int priority, int file)
==
How about ignoremin_usageif "priority <DEF_PRIORITY- 2" ?are you suggesting ignoring mlock etc as well in that case?
No. Just freeing pages, which are usually freed is good.
==
int mem_cgroup_canreclaim(struct page *page, struct mem_cgroup *mem1,
int priority)
{
struct page_cgroup *pc;
int result = 1;
if (mem1 != NULL)
return 1;
/* global lru is busy ? */
if (priority < DEF_PEIORITY - 1)
return 1;
....
}==
Maybe min_usage can works as *soft* mlock by this.
Or another idea.
Making memory.min_usage as memory.reclaim_priority_level and allows
priority_level == 0 => can_reclaim() returns 1 always. priority_level == 1 => can_reclaim returns 1 if priority < DEF_PRIORITY-1. priority_level == 2 => can_reclaim returns 1 if priority < DEF_PRIORITY-2.
(and only 0,1,2 are allowed.)
setting min_usage will not be prefered by lru management people. This can work as "advice" to global lru.
Hmm ?
Thanks,
-Kame
--
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>