Subsystems (2)
Johannes Weiner
maintainerHi,
these three patches are small fixes for urgent issues with memory cgroups and transparent huge pages. They are inspired by 4/7 of KAMEZAWA-san's recent series 'memcg : more fixes and clean up for 2.6.28-rc' to make memory cgroups work with THP.
2/3 fixes a bug that is first uncovered through 1/3. Minchan suggested this order for review purposes, but they should probably be applied the other way round (2, then 1) for better bisectability.
If everybody agrees, I would prefer these going into -mmotm now, and have further cleanups and optimizations based on them.
Hannes
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerPATCH 1/3 memcg: prevent endless loop when charging huge pages
The charging code can encounter a charge size that is bigger than a regular page in two situations: one is a batched charge to fill the per-cpu stocks, the other is a huge page charge.
This code is distributed over two functions, however, and only the outer one is aware of huge pages. In case the charging fails, the inner function will tell the outer function to retry if the charge size is bigger than regular pages--assuming batched charging is the only case. And the outer function will retry forever charging a huge page.
This patch makes sure the inner function can distinguish between batch charging and a single huge page charge. It will only signal another attempt if batch charging failed, and go into regular reclaim when it is called on behalf of a huge page.
--- mm/memcontrol.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)
mm/memcontrol.c +9 -2
@@ -1837,8 +1837,15 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask, flags |=MEM_CGROUP_RECLAIM_NOSWAP ; }else mem_over_limit =mem_cgroup_from_res_counter (fail_res, res); - -if (csize >PAGE_SIZE )/* change csize and retry */ +/* +* csize can be either a huge page (HPAGE_SIZE), a batch of +* regular pages (CHARGE_SIZE), or a single regular page +* (PAGE_SIZE). +* +* Never reclaim on behalf of optional batching, retry with a +* single page instead. +*/ +if (csize ==CHARGE_SIZE )return CHARGE_RETRY ;if (!(gfp_mask & __GFP_WAIT))
Signature · 8 lines
1.7.3.5 -- 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/ . Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/3] memcg: prevent endless loop when charging huge pages
Quoted 11 lines · Johannes Weiner
The charging code can encounter a charge size that is bigger than a regular page in two situations: one is a batched charge to fill the per-cpu stocks, the other is a huge page charge.
This code is distributed over two functions, however, and only the outer one is aware of huge pages. In case the charging fails, the inner function will tell the outer function to retry if the charge size is bigger than regular pages--assuming batched charging is the only case. And the outer function will retry forever charging a huge page.
Quoted 6 lines
This patch makes sure the inner function can distinguish between batch charging and a single huge page charge. It will only signal another attempt if batch charging failed, and go into regular reclaim when it is called on behalf of a huge page.
Signed-off-by Johannes Weiner <[email protected]>
Signature · 9 lines
Kind regards, Minchan Kim -- 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/ . Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/3] memcg: prevent endless loop when charging huge pages
In reply to Johannes WeinerQuoted 11 lines · On Mon, 31 Jan 2011 15:03:53 +0100 Johannes Weiner <[email protected]> wrote:
The charging code can encounter a charge size that is bigger than a regular page in two situations: one is a batched charge to fill the per-cpu stocks, the other is a huge page charge.
This code is distributed over two functions, however, and only the outer one is aware of huge pages. In case the charging fails, the inner function will tell the outer function to retry if the charge size is bigger than regular pages--assuming batched charging is the only case. And the outer function will retry forever charging a huge page.
Quoted 6 lines
This patch makes sure the inner function can distinguish between batch charging and a single huge page charge. It will only signal another attempt if batch charging failed, and go into regular reclaim when it is called on behalf of a huge page.
Signed-off-by Johannes Weiner <[email protected]>
Thank you very much.
Quoted 30 lines
--- mm/memcontrol.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)mm/memcontrol.c +9
-2@@ -1837,8 +1837,15 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask, flags |=MEM_CGROUP_RECLAIM_NOSWAP ; }else mem_over_limit =mem_cgroup_from_res_counter (fail_res, res); - -if (csize >PAGE_SIZE )/* change csize and retry */ +/* +* csize can be either a huge page (HPAGE_SIZE), a batch of +* regular pages (CHARGE_SIZE), or a single regular page +* (PAGE_SIZE). +* +* Never reclaim on behalf of optional batching, retry with a +* single page instead. +*/ +if (csize ==CHARGE_SIZE )return CHARGE_RETRY ;if (!(gfp_mask & __GFP_WAIT))Signature · 1 line
1.7.3.5
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerPATCH 2/3 memcg: prevent endless loop when charging huge pages to near-limit group
In reply to Johannes WeinerIf reclaim after a failed charging was unsuccessful, the limits are checked again, just in case they settled by means of other tasks.
This is all fine as long as every charge is of size PAGE_SIZE, because in that case, being below the limit means having at least PAGE_SIZE bytes available.
But with transparent huge pages, we may end up in an endless loop where charging and reclaim fail, but we keep going because the limits are not yet exceeded, although not allowing for a huge page.
Fix this up by explicitely checking for enough room, not just whether we are within limits.
--- include/linux/res_counter.h | 12 ++++++++++++ mm/memcontrol.c | 27 ++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-)
include/linux/res_counter.h +12 -0
@@ -182,6 +182,18 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)return ret; } +static inline bool res_counter_check_margin (struct res_counter *cnt, +unsigned long bytes) +{ +bool ret; +unsigned long flags; + +spin_lock_irqsave (&cnt->lock, flags); + ret = cnt->limit - cnt->usage >= bytes; +spin_unlock_irqrestore (&cnt->lock, flags); +return ret; +} +static inline bool res_counter_check_under_soft_limit (struct res_counter *cnt) {bool ret;
mm/memcontrol.c +20 -7
@@ -1111,6 +1111,15 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem)return false; } +static bool mem_cgroup_check_margin (struct mem_cgroup *mem,unsigned long bytes) +{ +if (!res_counter_check_margin (&mem->res, bytes)) +return false; +if (do_swap_account && !res_counter_check_margin (&mem->memsw, bytes)) +return false; +return true; +} +static unsigned int get_swappiness (struct mem_cgroup *memcg) {struct cgroup *cgrp = memcg->css.cgroup;
@@ -1852,15 +1861,19 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask,return CHARGE_WOULDBLOCK ; ret =mem_cgroup_hierarchical_reclaim (mem_over_limit,NULL , - gfp_mask, flags); + gfp_mask, flags); +if (mem_cgroup_check_margin (mem_over_limit, csize)) +return CHARGE_RETRY ;/* -* try_to_free_mem_cgroup_pages() might not give us a full -* picture of reclaim. Some pages are reclaimed and might be -* moved to swap cache or just unmapped from the cgroup. -* Check the limit again to see if the reclaim reduced the -* current usage of the cgroup before giving up +* Even though the limit is exceeded at this point, reclaim +* may have been able to free some pages. Retry the charge +* before killing the task. +* +* Only for regular pages, though: huge pages are rather +* unlikely to succeed so close to the limit, and we fall back +* to regular pages anyway in case of failure. */ -if (ret ||mem_cgroup_check_under_limit (mem_over_limit)) +if (csize ==PAGE_SIZE && ret)return CHARGE_RETRY ;/*
Signature · 8 lines
1.7.3.5 -- 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/ . Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [patch 2/3] memcg: prevent endless loop when charging huge pages to near-limit group
Quoted 21 lines · On Mon, 31 Jan 2011 15:03:54 +0100 Johannes Weiner <[email protected]> wrote:
include/linux/res_counter.h +12
-0+static inline bool res_counter_check_margin (struct res_counter *cnt, +unsigned long bytes) +{ +bool ret; +unsigned long flags; + +spin_lock_irqsave (&cnt->lock, flags); + ret = cnt->limit - cnt->usage >= bytes; +spin_unlock_irqrestore (&cnt->lock, flags); +return ret; +} +static inline bool res_counter_check_under_soft_limit (struct res_counter *cnt) {bool ret;mm/memcontrol.c +0
-0@@ -1111,6 +1111,15 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem)return false;
mm/memcontrol.c static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) · line 1121
Quoted 10 lines
mm/memcontrol.c +8
-0} +static bool mem_cgroup_check_margin (struct mem_cgroup *mem,unsigned long bytes) +{ +if (!res_counter_check_margin (&mem->res, bytes)) +return false; +if (do_swap_account && !res_counter_check_margin (&mem->memsw, bytes)) +return false; +return true; +}
argh.
If you ever have a function with the string "check" in its name, it's a good sign that you did something wrong.
Check what? Against what? Returning what?
mem_cgroup_check_under_limit() isn't toooo bad - the name tells you what's being checked and tells you what to expect the return value to mean.
But "res_counter_check_margin" and "mem_cgroup_check_margin" are just awful. Something like
bool res_counter_may_charge(counter, bytes)
would be much clearer.
If we really want to stick with the "check" names (perhaps as an ironic reference to res_counter's past mistakes) then please at least document the sorry things?
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
KAMEZAWA Hiroyuki
Acked-byRe: [patch 2/3] memcg: prevent endless loop when charging huge pages to near-limit group
Quoted 49 lines · On Mon, 31 Jan 2011 14:41:31 -0800 Andrew Morton <[email protected]>…
Quoted 21 lines · On Mon, 31 Jan 2011 15:03:54 +0100 Johannes Weiner <[email protected]> wrote:
include/linux/res_counter.h +12
-0+static inline bool res_counter_check_margin (struct res_counter *cnt, +unsigned long bytes) +{ +bool ret; +unsigned long flags; + +spin_lock_irqsave (&cnt->lock, flags); + ret = cnt->limit - cnt->usage >= bytes; +spin_unlock_irqrestore (&cnt->lock, flags); +return ret; +} +static inline bool res_counter_check_under_soft_limit (struct res_counter *cnt) {bool ret;mm/memcontrol.c +0
-0@@ -1111,6 +1111,15 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem)return false;mm/memcontrol.c static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) · line 1121
Quoted 10 lines
mm/memcontrol.c +8
-0} +static bool mem_cgroup_check_margin (struct mem_cgroup *mem,unsigned long bytes) +{ +if (!res_counter_check_margin (&mem->res, bytes)) +return false; +if (do_swap_account && !res_counter_check_margin (&mem->memsw, bytes)) +return false; +return true; +}argh.
If you ever have a function with the string "check" in its name, it's a good sign that you did something wrong.
Check what? Against what? Returning what?
mem_cgroup_check_under_limit()isn't toooo bad - the name tells you what's being checked and tells you what to expect the return value to mean.But "
res_counter_check_margin" and "mem_cgroup_check_margin" are just awful. Something like
Quoted 8 lines
bool
res_counter_may_charge(counter, bytes)would be much clearer.
If we really want to stick with the "check" names (perhaps as an ironic reference to res_counter's past mistakes) then please at least document the sorry things?
Ah, I ack the concept of patch.
Johannes, could you change name ? I'm sorry.
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerRe: [patch 2/3] memcg: prevent endless loop when charging huge pages to near-limit group
In reply to Andrew MortonQuoted 26 lines · Andrew Morton
Review static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) · line 1121
Quoted 12 lines · On Mon, 31 Jan 2011 15:03:54 +0100 Johannes Weiner <[email protected]> wrote:
(quoted diff) +8
-0@@ -1111,6 +1111,15 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) return false; } +static bool mem_cgroup_check_margin(struct mem_cgroup *mem, unsigned long bytes) +{ + if (!res_counter_check_margin(&mem->res, bytes)) + return false; + if (do_swap_account && !res_counter_check_margin(&mem->memsw, bytes)) + return false; + return true; +}argh.
If you ever have a function with the string "check" in its name, it's a good sign that you did something wrong.
Check what? Against what? Returning what?
mem_cgroup_check_under_limit()isn't toooo bad - the name tells you what's being checked and tells you what to expect the return value to mean.
Quoted 6 lines
But "
res_counter_check_margin" and "mem_cgroup_check_margin" are just awful. Something likebool
res_counter_may_charge(counter, bytes)would be much clearer.
That makes sense for the hard limit. But the oh-so-generic resource counters also have a soft limit, and you don't ask for that when you want to charge. Right now, I do not feel creative enough to come up with a symmetric-sounding counterpart.
Quoted 3 lines
If we really want to stick with the "check" names (perhaps as an ironic reference to res_counter's past mistakes) then please at least document the sorry things?
I cowardly went with this option and have a patch below to fold into this fix.
Maybe it would be better to use res_counter_margin(cnt) >= wanted throughout the code. Or still better, make memcg work on pages and res_counters on unsigned longs so the locking is no longer needed, together with an API for most obvious maths. I will work something out and submit it separately.
---
Subject: [patch fixup] res_counter: document res_counter_check_margin()
---
include/linux/res_counter.h +8 -0
@@ -182,6 +182,14 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)return ret; } +/** +* res_counter_check_margin - check if the counter allows charging +* @cnt: the resource counter to check +* @bytes: the number of bytes to check the remaining space against +* +* Returns a boolean value on whether the counter can be charged +* @bytes or whether this would exceed the limit. +*/ static inline bool res_counter_check_margin (struct res_counter *cnt,unsigned long bytes) {
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andrew Morton
maintainerRe: [patch 2/3] memcg: prevent endless loop when charging huge pages to near-limit group
Quoted 2 lines · On Tue, 1 Feb 2011 01:04:55 +0100 Johannes Weiner <[email protected]> wrote:
Maybe it would be better to use
res_counter_margin(cnt)>= wanted throughout the code.
yup.
Quoted 7 lines
include/linux/res_counter.h +1
-0@@ -182,6 +182,14 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)return ret; } +/**
include/linux/res_counter.h static inline bool res_counter_check_under_limit(struct res_counter *cnt) · line 195
Quoted 10 lines
include/linux/res_counter.h +7
-0+* res_counter_check_margin - check if the counter allows charging +* @cnt: the resource counter to check +* @bytes: the number of bytes to check the remaining space against +* +* Returns a boolean value on whether the counter can be charged +* @bytes or whether this would exceed the limit. +*/ static inline bool res_counter_check_margin (struct res_counter *cnt,unsigned long bytes) {
mem_cgroup_check_margin() needs some lipstick too.
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerRe: [patch 2/3] memcg: prevent endless loop when charging huge pages to near-limit group
Quoted 6 lines · Andrew Morton
Quoted 4 lines · On Tue, 1 Feb 2011 01:04:55 +0100 Johannes Weiner <[email protected]> wrote:
(quoted diff) +0
-0@@ -182,6 +182,14 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt) return ret; }
Quoted 13 lines
Review static inline bool res_counter_check_under_limit(struct res_counter *cnt) · line 195
Quoted 11 lines
(quoted diff) +8
-0+/** + * res_counter_check_margin - check if the counter allows charging + * @cnt: the resource counter to check + * @bytes: the number of bytes to check the remaining space against + * + * Returns a boolean value on whether the counter can be charged + * @bytes or whether this would exceed the limit. + */ static inline bool res_counter_check_margin(struct res_counter *cnt, unsigned long bytes) {
mem_cgroup_check_margin()needs some lipstick too.
*oink*
---
mm/memcontrol.c +8 -0
@@ -1111,6 +1111,14 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem)return false; } +/** +* mem_cgroup_check_margin - check if the memory cgroup allows charging +* @mem: memory cgroup to check +* @bytes: the number of bytes the caller intends to charge +* +* Returns a boolean value on whether @mem can be charged @bytes or +* whether this would exceed the limit. +*/ static bool mem_cgroup_check_margin (struct mem_cgroup *mem,unsigned long bytes) {if (!res_counter_check_margin (&mem->res, bytes))
--
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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainercover memcg: clean up limit checking
In reply to Andrew MortonQuoted 7 lines · Andrew Morton
Quoted 2 lines · On Tue, 1 Feb 2011 01:04:55 +0100 Johannes Weiner <[email protected]> wrote:
Maybe it would be better to use
res_counter_margin(cnt)>= wanted throughout the code.yup.
Okay, I cleaned it all up a bit for .39. While doing so, I also found that we are reclaiming one page too much when pushing back on behalf of soft limits.
So 1/2 fixes the soft limit reclaim off-by-one-page, and 2/2 reduces all the limit checks to two functions.
--
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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerPATCH 1/2 memcg: soft limit reclaim should end at limit not below
Soft limit reclaim continues until the usage is below the current soft limit, but the documented semantics are actually that soft limit reclaim will push usage back until the soft limits are met again.
--- include/linux/res_counter.h | 4 ++-- mm/memcontrol.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
include/linux/res_counter.h +2 -2
@@ -139,7 +139,7 @@ static inline bool res_counter_limit_check_locked(struct res_counter *cnt)static inline bool res_counter_soft_limit_check_locked (struct res_counter *cnt) { -if (cnt->usage < cnt->soft_limit) +if (cnt->usage <= cnt->soft_limit)return true;return false;
@@ -202,7 +202,7 @@ static inline bool res_counter_check_margin(struct res_counter *cnt,return ret; } -static inline bool res_counter_check_under_soft_limit (struct res_counter *cnt) +static inline bool res_counter_check_within_soft_limit (struct res_counter *cnt) {bool ret;unsigned long flags;
mm/memcontrol.c +1 -1
@@ -1451,7 +1451,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem,return ret; total += ret;if (check_soft) { -if (res_counter_check_under_soft_limit (&root_mem->res)) +if (res_counter_check_within_soft_limit (&root_mem->res))return total; }else if (mem_cgroup_check_under_limit (root_mem))return 1 + total;
Signature · 8 lines
1.7.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/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/2] memcg: soft limit reclaim should end at limit not below
Quoted 5 lines · On Thu, 3 Feb 2011 13:54:54 +0100 Johannes Weiner <[email protected]> wrote:
Soft limit reclaim continues until the usage is below the current soft limit, but the documented semantics are actually that soft limit reclaim will push usage back until the soft limits are met again.
Signed-off-by Johannes Weiner <[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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 1/2] memcg: soft limit reclaim should end at limit not below
In reply to Johannes WeinerQuoted 5 lines · Johannes Weiner
Soft limit reclaim continues until the usage is below the current soft limit, but the documented semantics are actually that soft limit reclaim will push usage back until the soft limits are met again.
Signed-off-by Johannes Weiner <[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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerPATCH 2/2 memcg: simplify the way memory limits are checked
In reply to Johannes WeinerSince transparent huge pages, checking whether memory cgroups are below their limits is no longer enough, but the actual amount of chargeable space is important.
To not have more than one limit-checking interface, replace memory_cgroup_check_under_limit() and memory_cgroup_check_margin() with a single memory_cgroup_margin() that returns the chargeable space and leaves the comparison to the callsite.
Soft limits are now checked the other way round, by using the already existing function that returns the amount by which soft limits are
exceeded: res_counter_soft_limit_excess().
Also remove all the corresponding functions on the res_counter side that are now no longer used.
--- include/linux/res_counter.h | 72 ++++++++---------------------------------- mm/memcontrol.c | 49 ++++++++++------------------- 2 files changed, 31 insertions(+), 90 deletions(-)
include/linux/res_counter.h +14 -58
@@ -129,20 +129,22 @@ int __must_check res_counter_charge(struct res_counter *counter,void 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; -} - -static inline bool res_counter_soft_limit_check_locked (struct res_counter *cnt) +/** +* res_counter_margin - calculate chargeable space of a counter +* @cnt: the counter +* +* Returns the difference between the hard limit and the current usage +* of resource counter @cnt. +*/ +static inline unsigned long long res_counter_margin (struct res_counter *cnt) { -if (cnt->usage <= cnt->soft_limit) -return true; +unsigned long long margin; +unsigned long flags; -return false; +spin_lock_irqsave (&cnt->lock, flags); + margin = cnt->limit - cnt->usage; +spin_unlock_irqrestore (&cnt->lock, flags); +return margin; }/**
@@ -167,52 +169,6 @@ res_counter_soft_limit_excess(struct res_counter *cnt)return excess; } -/* -* 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; - -spin_lock_irqsave (&cnt->lock, flags); - ret =res_counter_limit_check_locked (cnt); -spin_unlock_irqrestore (&cnt->lock, flags); -return ret; -} - -/** -* res_counter_check_margin - check if the counter allows charging -* @cnt: the resource counter to check -* @bytes: the number of bytes to check the remaining space against -* -* Returns a boolean value on whether the counter can be charged -* @bytes or whether this would exceed the limit. -*/ -static inline bool res_counter_check_margin (struct res_counter *cnt, -unsigned long bytes) -{ -bool ret; -unsigned long flags; - -spin_lock_irqsave (&cnt->lock, flags); - ret = cnt->limit - cnt->usage >= bytes; -spin_unlock_irqrestore (&cnt->lock, flags); -return ret; -} - -static inline bool res_counter_check_within_soft_limit (struct res_counter *cnt) -{ -bool ret; -unsigned long flags; - -spin_lock_irqsave (&cnt->lock, flags); - ret =res_counter_soft_limit_check_locked (cnt); -spin_unlock_irqrestore (&cnt->lock, flags); -return ret; -} -static inline void res_counter_reset_max (struct res_counter *cnt) {unsigned long flags;
mm/memcontrol.c +17 -32
84 lines not on this page · raw message
Signature · 8 lines
1.7.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/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 2/2] memcg: simplify the way memory limits are checked
Quoted 9 lines · On Thu, 3 Feb 2011 13:56:11 +0100 Johannes Weiner <[email protected]> wrote:
Since transparent huge pages, checking whether memory cgroups are below their limits is no longer enough, but the actual amount of chargeable space is important.
To not have more than one limit-checking interface, replace
memory_cgroup_check_under_limit()andmemory_cgroup_check_margin()with a singlememory_cgroup_margin()that returns the chargeable space and leaves the comparison to the callsite.
Quoted 8 lines
Soft limits are now checked the other way round, by using the already existing function that returns the amount by which soft limits are
exceeded:res_counter_soft_limit_excess().Also remove all the corresponding functions on the
res_counterside that are now no longer used.Signed-off-by Johannes Weiner <[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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 2/2] memcg: simplify the way memory limits are checked
In reply to Johannes WeinerQuoted 9 lines · Johannes Weiner
Since transparent huge pages, checking whether memory cgroups are below their limits is no longer enough, but the actual amount of chargeable space is important.
To not have more than one limit-checking interface, replace
memory_cgroup_check_under_limit()andmemory_cgroup_check_margin()with a singlememory_cgroup_margin()that returns the chargeable space and leaves the comparison to the callsite.
Quoted 8 lines
Soft limits are now checked the other way round, by using the already existing function that returns the amount by which soft limits are
exceeded:res_counter_soft_limit_excess().Also remove all the corresponding functions on the
res_counterside that are now no longer used.Signed-off-by Johannes Weiner <[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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 2/3] memcg: prevent endless loop when charging huge pages to near-limit group
In reply to Johannes WeinerQuoted 7 lines · Johannes Weiner
If reclaim after a failed charging was unsuccessful, the limits are checked again, just in case they settled by means of other tasks.
This is all fine as long as every charge is of size
PAGE_SIZE, because in that case, being below the limit means having at leastPAGE_SIZEbytes available.
Quoted 8 lines
But with transparent huge pages, we may end up in an endless loop where charging and reclaim fail, but we keep going because the limits are not yet exceeded, although not allowing for a huge page.
Fix this up by explicitely checking for enough room, not just whether we are within limits.
Signed-off-by Johannes Weiner <[email protected]>
Signature · 2 lines
Kind regards, Minchan Kim
Johannes Weiner
maintainerPATCH 3/3 memcg: never OOM when charging huge pages
In reply to Johannes WeinerHuge page coverage should obviously have less priority than the continued execution of a process.
Never kill a process when charging it a huge page fails. Instead, give up after the first failed reclaim attempt and fall back to regular pages.
--- mm/memcontrol.c | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-)
mm/memcontrol.c +8 -2
@@ -2343,13 +2343,19 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, gfp_t gfp_mask, enum charge_type ctype) { struct mem_cgroup *mem = NULL; +int page_size =PAGE_SIZE ;struct page_cgroup *pc; +bool oom = true;int ret; -int page_size =PAGE_SIZE ;if (PageTransHuge (page)) { page_size <<=compound_order (page);VM_BUG_ON (!PageTransHuge (page)); +/* +* Never OOM-kill a process for a huge page. The +* fault handler will fall back to regular pages. +*/ + oom = false; } pc =lookup_page_cgroup (page);
@@ -2358,7 +2364,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,return 0 ;prefetchw (pc); - ret =__mem_cgroup_try_charge (mm, gfp_mask, &mem, true, page_size); + ret =__mem_cgroup_try_charge (mm, gfp_mask, &mem, oom, page_size);if (ret || !mem)return ret;
Signature · 8 lines
1.7.3.5 -- 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/ . Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 3/3] memcg: never OOM when charging huge pages
Quoted 8 lines · Johannes Weiner
Huge page coverage should obviously have less priority than the continued execution of a process.
Never kill a process when charging it a huge page fails. Instead, give up after the first failed reclaim attempt and fall back to regular pages.
Signed-off-by Johannes Weiner <[email protected]>
Signature · 9 lines
Kind regards, Minchan Kim -- 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/ . Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [patch 3/3] memcg: never OOM when charging huge pages
In reply to Johannes WeinerQuoted 8 lines · On Mon, 31 Jan 2011 15:03:55 +0100 Johannes Weiner <[email protected]> wrote:
Huge page coverage should obviously have less priority than the continued execution of a process.
Never kill a process when charging it a huge page fails. Instead, give up after the first failed reclaim attempt and fall back to regular pages.
Signed-off-by Johannes Weiner <[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/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>