memcg: remove -EINTR at rmdir()
Subsystems (3)
PATCH 1/2 memcg: remove -EINTR at rmdir()
2 follow-up patches for "memcg: move charges to root cgroup if use_hierarchy=0", developped/tested onto memcg-devel tree. Maybe no HUNK with -next and -mm.... -Kame
==
memcg: remove -EINTR at rmdir()
By commit "memcg: move charges to root cgroup if use_hierarchy=0", no memory reclaiming will occur at removing memory cgroup.
So, we don't need to take care of user interrupt by signal. This patch removes it.
(*) If -EINTR is returned here, cgroup will show WARNING.
--- mm/memcontrol.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-)
mm/memcontrol.c +0 -3
@@ -3890,9 +3890,6 @@ move_account: ret = -EBUSY ;if (cgroup_task_count (cgrp) || !list_empty (&cgrp->children)) goto out; - ret = -EINTR ; -if (signal_pending (current)) - goto out;/* This is for making all *used* pages to be on LRU. */ lru_add_drain_all ();drain_all_stock_sync (memcg);
Signature · 1 line
1.7.4.1
PATCH 2/2 memcg: clean up force_empty_list() return value check
By commit "memcg: move charges to root cgroup if use_hierarchy=0" mem_cgroup_move_parent() only returns -EBUSY, -EINVAL. So, we can remove -ENOMEM and -EINTR checks.
--- mm/memcontrol.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
mm/memcontrol.c +0 -5
@@ -3847,8 +3847,6 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, pc =lookup_page_cgroup (page); ret =mem_cgroup_move_parent (page, pc, memcg,GFP_KERNEL ); -if (ret == -ENOMEM || ret == -EINTR ) -break ;if (ret == -EBUSY || ret == -EINVAL ) {/* found lock contention or "pc" is obsolete. */
@@ -3910,9 +3908,6 @@ move_account: }mem_cgroup_end_move (memcg);memcg_oom_recover (memcg); -/* it seems parent cgroup doesn't have enough mem */ -if (ret == -ENOMEM ) - goto try_to_free;cond_resched ();/* "ret" should also be checked to ensure all lists are empty. */ }while (res_counter_read_u64 (&memcg->res,RES_USAGE ) >0 || ret);
Signature · 1 line
1.7.4.1
Re: [PATCH 2/2] memcg: clean up force_empty_list() return value check
Quoted 6 lines · KAMEZAWA Hiroyuki
By commit "memcg: move charges to root cgroup if use_hierarchy=0"
mem_cgroup_move_parent()only returns-EBUSY,-EINVAL. So, we can remove-ENOMEMand-EINTRchecks.Signed-off-by KAMEZAWA Hiroyuki <[email protected]>
Quoted 35 lines
--- mm/memcontrol.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)mm/memcontrol.c +0
-5@@ -3847,8 +3847,6 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, pc =lookup_page_cgroup (page); ret =mem_cgroup_move_parent (page, pc, memcg,GFP_KERNEL ); -if (ret == -ENOMEM || ret == -EINTR ) -break ;if (ret == -EBUSY || ret == -EINVAL ) {/* found lock contention or "pc" is obsolete. */ @@ -3910,9 +3908,6 @@ move_account: }mem_cgroup_end_move (memcg);memcg_oom_recover (memcg); -/* it seems parent cgroup doesn't have enough mem */ -if (ret == -ENOMEM ) - goto try_to_free;cond_resched ();/* "ret" should also be checked to ensure all lists are empty. */ }while (res_counter_read_u64 (&memcg->res,RES_USAGE ) >0 || ret);Signature · 7 lines
1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe cgroups" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 6 lines
Michal Hocko SUSE Labs SUSE LINUX s.r.o. Lihovarska 1060/12 190 00 Praha 9 Czech Republic
Andrew Morton
maintainerRe: [PATCH 2/2] memcg: clean up force_empty_list() return value check
In reply to Kamezawa HiroyukiQuoted 15 lines · On Mon, 18 Jun 2012 20:59:44 +0900 Kamezawa Hiroyuki…
By commit "memcg: move charges to root cgroup if use_hierarchy=0"
mem_cgroup_move_parent()only returns-EBUSY,-EINVAL. So, we can remove-ENOMEMand-EINTRchecks.Signed-off-by KAMEZAWA Hiroyuki <[email protected]>--- mm/memcontrol.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)mm/memcontrol.c +0
-0
mm/memcontrol.c static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, · line 3851
Quoted 7 lines
mm/memcontrol.c +0
-2@@ -3847,8 +3847,6 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, pc =lookup_page_cgroup (page); ret =mem_cgroup_move_parent (page, pc, memcg,GFP_KERNEL ); -if (ret == -ENOMEM || ret == -EINTR ) -break ;if (ret == -EBUSY || ret == -EINVAL ) {
This looks a bit fragile - if mem_cgroup_move_parent() is later changed (intentionally or otherwise!) to return -Esomethingelse then mem_cgroup_force_empty_list() will subtly break. Why not just do
if (ret < 0)
here?
--
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 2/2] memcg: clean up force_empty_list() return value check
Quoted 24 lines · Andrew Morton
Quoted 21 lines · On Mon, 18 Jun 2012 20:59:44 +0900 Kamezawa…
By commit "memcg: move charges to root cgroup if use_hierarchy=0"
mem_cgroup_move_parent()only returns-EBUSY,-EINVAL. So, we can remove-ENOMEMand-EINTRchecks.Signed-off-by KAMEZAWA Hiroyuki<[email protected]>--- mm/memcontrol.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)mm/memcontrol.c +0
-2@@ -3847,8 +3847,6 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, pc =lookup_page_cgroup (page); ret =mem_cgroup_move_parent (page, pc, memcg,GFP_KERNEL ); -if (ret == -ENOMEM || ret == -EINTR ) -break ;
Quoted 8 lines
mm/memcontrol.c static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, · line 3851
Quoted 1 line
mm/memcontrol.c +0
-0if (ret == -EBUSY || ret == -EINVAL ) {This looks a bit fragile - if
mem_cgroup_move_parent()is later changed (intentionally or otherwise!) to return -Esomethingelse thenmem_cgroup_force_empty_list()will subtly break. Why not just doif (ret< 0)
You're right. I'm sorry I haven't done enough clean-ups.
I made 2 more patches...I'll repost/remake all paches if it's better. one more patch will follow this email.
==
From eee5f31fc6378da19705de7187bb3f219ef6d7f6 Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <[email protected]>
Date: Thu, 21 Jun 2012 17:25:04 +0900
Subject: [PATCH 1/2] mem_cgroup_move_parent() doesn't need gfp_mask.
--- mm/memcontrol.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
mm/memcontrol.c +2 -3
@@ -2662,8 +2662,7 @@ out:static int mem_cgroup_move_parent (struct page *page,struct page_cgroup *pc, -struct mem_cgroup *child, -gfp_t gfp_mask) +struct mem_cgroup *child) {struct mem_cgroup *parent;unsigned int nr_pages;
@@ -3837,7 +3836,7 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, pc =lookup_page_cgroup (page); - ret =mem_cgroup_move_parent (page, pc, memcg,GFP_KERNEL ); + ret =mem_cgroup_move_parent (page, pc, memcg);if (ret == -EBUSY || ret == -EINVAL ) {/* found lock contention or "pc" is obsolete. */
Signature · 17 lines
1.7.4.1 -- 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 2/2] memcg: clean up force_empty_list() return value check
You're right and I think this will be much cleaner. ==
From 9b6224616282d74838b393485eb7c9215f546ec9 Mon Sep 17 00:00:00 2001
From: KAMEZAWA Hiroyuki <[email protected]>
Date: Thu, 21 Jun 2012 17:28:55 +0900
Subject: [PATCH 2/2] memcg: make mem_cgroup_force_empty_list() as boolean function
Now, mem_cgroup_force_empty_list() just returns 0 or -EBUSY and -EBUSY is just indicating 'you need to retry.'.
This patch makes mem_cgroup_force_empty_list() as boolean function and make the logic simpler.
--- mm/memcontrol.c | 13 +++---------- 1 files changed, 3 insertions(+), 10 deletions(-)
mm/memcontrol.c +3 -10
@@ -3797,7 +3797,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,* This routine traverse page_cgroup in given list and drop them all. * *And* this routine doesn't reclaim page itself, just removes page_cgroup. */ -static int mem_cgroup_force_empty_list (struct mem_cgroup *memcg, +static bool mem_cgroup_force_empty_list (struct mem_cgroup *memcg,int node,int zid,enum lru_list lru) {struct mem_cgroup_per_zone *mz;
@@ -3805,7 +3805,6 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg,struct list_head *list;struct page *busy;struct zone *zone; -int ret =0 ; zone = &NODE_DATA (node)->node_zones[zid]; mz =mem_cgroup_zoneinfo (memcg, node, zid);
@@ -3819,7 +3818,6 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg,struct page_cgroup *pc;struct page *page; - ret =0 ;spin_lock_irqsave (&zone->lru_lock, flags);if (list_empty (list)) {spin_unlock_irqrestore (&zone->lru_lock, flags);
@@ -3836,19 +3834,14 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg, pc =lookup_page_cgroup (page); - ret =mem_cgroup_move_parent (page, pc, memcg); - -if (ret == -EBUSY || ret == -EINVAL ) { +if (mem_cgroup_move_parent (page, pc, memcg)) {/* found lock contention or "pc" is obsolete. */ busy = page;cond_resched (); }else busy =NULL ; } - -if (!ret && !list_empty (list)) -return -EBUSY ; -return ret; +return !list_empty (list); }/*
Signature · 1 line
1.7.4.1
Andrew Morton
maintainerRe: [PATCH 2/2] memcg: clean up force_empty_list() return value check
Quoted 5 lines · On Thu, 21 Jun 2012 17:17:01 +0900 Kamezawa Hiroyuki…
Now,
mem_cgroup_force_empty_list()just returns 0 or-EBUSYand-EBUSYis just indicating 'you need to retry.'.
This patch makesmem_cgroup_force_empty_list()as boolean function and make the logic simpler.
For some reason I'm having trouble applying these patches - many rejects, need to massage it in by hand.
mm/memcontrol.c unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, · line 3801
Quoted 9 lines
mm/memcontrol.c +1
-1@@ -3797,7 +3797,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,* This routine traverse page_cgroup in given list and drop them all. * *And* this routine doesn't reclaim page itself, just removes page_cgroup. */ -static int mem_cgroup_force_empty_list (struct mem_cgroup *memcg, +static bool mem_cgroup_force_empty_list (struct mem_cgroup *memcg,int node,int zid,enum lru_list lru)
Let's document the return value. The mem_cgroup_force_empty_list() comment is a mess so I tried to help it a bit. How does this look?
mm/memcontrol.c renamed from mm/memcontrol.c~memcg-make-mem_cgroup_force_empty_list-return-bool-fix +4 -2
@@ -3609,8 +3609,10 @@ unsigned long mem_cgroup_soft_limit_recl }/* -* This routine traverse page_cgroup in given list and drop them all. -* *And* this routine doesn't reclaim page itself, just removes page_cgroup. +* Traverse a specified page_cgroup list and try to drop them all. This doesn't +* reclaim the pages page themselves - it just removes the page_cgroups. +* Returns true if some page_cgroups were not freed, indicating that the caller +* must retry this operation. */ static bool mem_cgroup_force_empty_list (struct mem_cgroup *memcg,int node,int zid,enum lru_list lru)
_
Re: [PATCH 2/2] memcg: clean up force_empty_list() return value check
Quoted 12 lines · Andrew Morton
Quoted 5 lines · On Thu, 21 Jun 2012 17:17:01 +0900 Kamezawa…
Now,
mem_cgroup_force_empty_list()just returns 0 or-EBUSYand-EBUSYis just indicating 'you need to retry.'.
This patch makesmem_cgroup_force_empty_list()as boolean function and make the logic simpler.For some reason I'm having trouble applying these patches - many rejects, need to massage it in by hand.
Oh, sorry. Is it space breakage or some ? (I had mailer troubles in the last week..) Or, maybe, my tree/patch queue was too old.
I'll rebased to new -mm tree when I post new patch.
Quoted 28 lines
mm/memcontrol.c unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, · line 3801
Quoted 9 lines
mm/memcontrol.c +1
-1@@ -3797,7 +3797,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,* This routine traverse page_cgroup in given list and drop them all. * *And* this routine doesn't reclaim page itself, just removes page_cgroup. */ -static int mem_cgroup_force_empty_list (struct mem_cgroup *memcg, +static bool mem_cgroup_force_empty_list (struct mem_cgroup *memcg,int node,int zid,enum lru_list lru)Let's document the return value. The
mem_cgroup_force_empty_list()comment is a mess so I tried to help it a bit. How does this look?mm/memcontrol.c renamed from mm/memcontrol.c~memcg-make-mem_cgroup_force_empty_list-return-bool-fix +4
-2@@ -3609,8 +3609,10 @@ unsigned long mem_cgroup_soft_limit_recl }/* -* This routine traverse page_cgroup in given list and drop them all. -* *And* this routine doesn't reclaim page itself, just removes page_cgroup. +* Traverse a specified page_cgroup list and try to drop them all. This doesn't +* reclaim the pages page themselves - it just removes the page_cgroups. +* Returns true if some page_cgroups were not freed, indicating that the caller +* must retry this operation. */ static bool mem_cgroup_force_empty_list (struct mem_cgroup *memcg,int node,int zid,enum lru_list lru)
Quoted 1 line
_
Seems nice! Thank you very much.
Regards,
-Kame
Quoted 8 lines · KAMEZAWA Hiroyuki
2 follow-up patches for "memcg: move charges to root cgroup if use_hierarchy=0", developped/tested onto memcg-devel tree. Maybe no HUNK with -next and -mm.... -Kame
==
memcg: remove-EINTRatrmdir()By commit "memcg: move charges to root cgroup if use_hierarchy=0", no memory reclaiming will occur at removing memory cgroup.
OK, so the there are only 2 reasons why move_parent could fail in this path. 1) it races with somebody else who is uncharging or moving the charge and 2) THP split.
1) works for us and 2) doens't seem to be serious enough to expect that it would stall rmdir on the group for unbound amount of time so the change is safe (can we make this into the changelog please?).
Quoted 5 lines
So, we don't need to take care of user interrupt by signal. This patch removes it.
(*) If-EINTRis returned here, cgroup will show WARNING.Signed-off-by KAMEZAWA Hiroyuki <[email protected]>
Quoted 26 lines
--- mm/memcontrol.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-)mm/memcontrol.c +0
-3@@ -3890,9 +3890,6 @@ move_account: ret = -EBUSY ;if (cgroup_task_count (cgrp) || !list_empty (&cgrp->children)) goto out; - ret = -EINTR ; -if (signal_pending (current)) - goto out;/* This is for making all *used* pages to be on LRU. */ lru_add_drain_all ();drain_all_stock_sync (memcg);Signature · 7 lines
1.7.4.1 -- To unsubscribe from this list: send the line "unsubscribe cgroups" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 12 lines
Michal Hocko SUSE Labs SUSE LINUX s.r.o. Lihovarska 1060/12 190 00 Praha 9 Czech Republic -- 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>
Quoted 10 lines · Michal Hocko
Quoted 8 lines · KAMEZAWA Hiroyuki
2 follow-up patches for "memcg: move charges to root cgroup if use_hierarchy=0", developped/tested onto memcg-devel tree. Maybe no HUNK with -next and -mm.... -Kame
==
memcg: remove-EINTRatrmdir()By commit "memcg: move charges to root cgroup if use_hierarchy=0", no memory reclaiming will occur at removing memory cgroup.
Quoted 7 lines
OK, so the there are only 2 reasons why
move_parentcould fail in this path. 1) it races with somebody else who is uncharging or moving the charge and 2) THP split.
1) works for us and 2) doens't seem to be serious enough to expect that it would stall rmdir on the group for unbound amount of time so the change is safe (can we make this into the changelog please?).
Yes. But the failure of move_parent() (-EBUSY) will be retried.
Remaining problems are
- attaching task while pre_destroy() is called.
- creating child cgroup while pre_destroy() is called.
I think I need to make a patch for cgroup layer as I previously posted. I'd like to try again.
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>
Quoted 19 lines · KAMEZAWA Hiroyuki
Quoted 10 lines · Michal Hocko
Quoted 8 lines · KAMEZAWA Hiroyuki
2 follow-up patches for "memcg: move charges to root cgroup if use_hierarchy=0", developped/tested onto memcg-devel tree. Maybe no HUNK with -next and -mm.... -Kame
==
memcg: remove-EINTRatrmdir()By commit "memcg: move charges to root cgroup if use_hierarchy=0", no memory reclaiming will occur at removing memory cgroup.
Quoted 7 lines
OK, so the there are only 2 reasons why
move_parentcould fail in this path. 1) it races with somebody else who is uncharging or moving the charge and 2) THP split.
1) works for us and 2) doens't seem to be serious enough to expect that it would stall rmdir on the group for unbound amount of time so the change is safe (can we make this into the changelog please?).
Quoted 5 lines
Yes. But the failure of
move_parent()(-EBUSY) will be retried.Remaining problems are
- attaching task whilepre_destroy()is called.
- creating child cgroup whilepre_destroy()is called.
I don't know why but I thought that tasks and subgroups are not alowed when pre_destroy is called. If this is possible then we probably want to check for pending signals or at least add cond_resched.
Quoted 7 lines
I think I need to make a patch for cgroup layer as I previously posted. I'd like to try again.
Thanks,
-Kame
Signature · 12 lines
Michal Hocko SUSE Labs SUSE LINUX s.r.o. Lihovarska 1060/12 190 00 Praha 9 Czech Republic -- 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>
Quoted 22 lines · Michal Hocko
Quoted 21 lines · KAMEZAWA Hiroyuki
Quoted 10 lines · Michal Hocko
Quoted 8 lines · KAMEZAWA Hiroyuki
2 follow-up patches for "memcg: move charges to root cgroup if use_hierarchy=0", developped/tested onto memcg-devel tree. Maybe no HUNK with -next and -mm.... -Kame
==
memcg: remove-EINTRatrmdir()By commit "memcg: move charges to root cgroup if use_hierarchy=0", no memory reclaiming will occur at removing memory cgroup.
Quoted 7 lines
OK, so the there are only 2 reasons why
move_parentcould fail in this path. 1) it races with somebody else who is uncharging or moving the charge and 2) THP split.
1) works for us and 2) doens't seem to be serious enough to expect that it would stall rmdir on the group for unbound amount of time so the change is safe (can we make this into the changelog please?).Yes. But the failure of
move_parent()(-EBUSY) will be retried.
Quoted 7 lines
Quoted 3 lines
Remaining problems are
- attaching task whilepre_destroy()is called.
- creating child cgroup whilepre_destroy()is called.I don't know why but I thought that tasks and subgroups are not alowed when
pre_destroyis called. If this is possible then we probably want to check for pending signals or at least addcond_resched.
Now, pre_destroy() call is done as
lock_cgroup_mutex(); do some pre-check, no child, no tasks. unlock_cgroup_mutex(); ->pre_destroy() lock_cgroup_mutex() check css's refcnt....
What I take care of now is following case.
CPU A CPU-B
unlock_cgroup_mutex()
->pre_destroy()
<delay by something> attach new task
add new charge detach the task
lock_cgroup_mutex()
check rss' refcnt
This will cause account leak even if I think this will not happen in the real world. I'd like to disable attach task.
Now, our ->pre_destroy() is quite fast because we don't have no memory reclaim. I believe we can call ->pre_destroy() without dropping cgroup_mutex.
lock_cgroup_mutex() do pre-check ->pre_destroy() check css's refcnt
I think this is straightforward. I'd like to post a patch. 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>