memcg: fix a race when setting memcg.swappiness
Subsystems (2)
RFC PATCH 1/1 memcg: fix a race when setting memcg.swappiness
(suppose: memcg->use_hierarchy == 0 and memcg->swappiness == 60)
echo 10 > /memcg/0/swappiness |
mem_cgroup_swappiness_write() |
... | echo 1 > /memcg/0/use_hierarchy
| mkdir /mnt/0/1
| sub_memcg->swappiness = 60;
memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use hierarchy_lock here, because it doesn't protect the create() method.
Though IMO use cgroup_lock() in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of check cgrp->children list:
=================create() does:
lock memcg_parentmemcg->swappiness = memcg->parent->swappiness;
memcg_parent->child_count++;
unlock memcg_parent
and write() does:
lock memcg
if (!memcg->child_count) {
memcg->swappiness = swappiness;
} else {
report error;
}
unlock memcg
destroy() does:
lock memcg_parent
memcg_parent->child_count--;
unlock memcg_parent
=================
And there is a suble differnce with checking cgrp->children, that a cgroup is removed from parent's list in cgroup_rmdir(), while memcg->child_count is decremented in cgroup_diput().
--- mm/memcontrol.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)
mm/memcontrol.c +9 -1
@@ -1971,6 +1971,7 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft, {struct mem_cgroup *memcg =mem_cgroup_from_cont (cgrp);struct mem_cgroup *parent; +if (val >100 )return -EINVAL ;
@@ -1978,15 +1979,22 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft,return -EINVAL ; parent =mem_cgroup_from_cont (cgrp->parent); + +cgroup_lock (); +/* If under hierarchy, only empty-root can set this value */ if ((parent->use_hierarchy) || - (memcg->use_hierarchy && !list_empty (&cgrp->children))) + (memcg->use_hierarchy && !list_empty (&cgrp->children))) { +cgroup_unlock ();return -EINVAL ; + }spin_lock (&memcg->reclaim_param_lock); memcg->swappiness = val;spin_unlock (&memcg->reclaim_param_lock); +cgroup_unlock (); +return 0 ; }
Signature · 7 lines
1.5.4.rc3 -- 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>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 42 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan…
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent
Quoted 8 lines
=================
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>
Seems reasonable, but, hmm...
Why hierarchy_mutex can't be used for create() ?
-Kame
Quoted 49 lines
--- mm/memcontrol.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)mm/memcontrol.c +9
-1@@ -1971,6 +1971,7 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft, {struct mem_cgroup *memcg =mem_cgroup_from_cont (cgrp);struct mem_cgroup *parent; +if (val >100 )return -EINVAL ;@@ -1978,15 +1979,22 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft,return -EINVAL ; parent =mem_cgroup_from_cont (cgrp->parent); + +cgroup_lock (); +/* If under hierarchy, only empty-root can set this value */ if ((parent->use_hierarchy) || - (memcg->use_hierarchy && !list_empty (&cgrp->children))) + (memcg->use_hierarchy && !list_empty (&cgrp->children))) { +cgroup_unlock ();return -EINVAL ; + }spin_lock (&memcg->reclaim_param_lock); memcg->swappiness = val;spin_unlock (&memcg->reclaim_param_lock); +cgroup_unlock (); +return 0 ; }Signature · 7 lines
1.5.4.rc3 -- 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 42 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan <[email protected]> wrote:
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent
Quoted 8 lines
=================
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>
Seems reasonable, but, hmm...
Why hierarchy_mutex can't be used for create() ?
-Kame
Quoted 49 lines
--- mm/memcontrol.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-)mm/memcontrol.c +9
-1@@ -1971,6 +1971,7 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft, {struct mem_cgroup *memcg =mem_cgroup_from_cont (cgrp);struct mem_cgroup *parent; +if (val >100 )return -EINVAL ;@@ -1978,15 +1979,22 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft,return -EINVAL ; parent =mem_cgroup_from_cont (cgrp->parent); + +cgroup_lock (); +/* If under hierarchy, only empty-root can set this value */ if ((parent->use_hierarchy) || - (memcg->use_hierarchy && !list_empty (&cgrp->children))) + (memcg->use_hierarchy && !list_empty (&cgrp->children))) { +cgroup_unlock ();return -EINVAL ; + }spin_lock (&memcg->reclaim_param_lock); memcg->swappiness = val;spin_unlock (&memcg->reclaim_param_lock); +cgroup_unlock (); +return 0 ; }Signature · 7 lines
1.5.4.rc3 -- 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>
A message that is not in the archive (sent off-list or not yet received): 20090114132616.3cb7d568.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan…
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 9 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using cgroup_lock()?
Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?
We can make hierarchy_mutex work for this race by:
@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct
if (notify_on_release(parent))
set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);+ cgroup_lock_hierarchy(root);
+
for_each_subsys(root, ss) {
struct cgroup_subsys_state *css = ss->create(ss, cgrp);
if (IS_ERR(css)) {
+ cgroup_unlock_hierarchy(root);
err = PTR_ERR(css);
goto err_destroy;
}
init_cgroup_css(css, ss, cgrp);
}- cgroup_lock_hierarchy(root);
list_add(&cgrp->sibling, &cgrp->parent->children);
cgroup_unlock_hierarchy(root);
root->number_of_cgroups++;But this may not be what we want, because hierarchy_mutex is meant to be lightweight, so it's not held while subsys callbacks are invoked, except bind().
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan <[email protected]> wrote:
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 9 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using cgroup_lock()?
Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?
We can make hierarchy_mutex work for this race by:
@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct
if (notify_on_release(parent))
set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);+ cgroup_lock_hierarchy(root);
+
for_each_subsys(root, ss) {
struct cgroup_subsys_state *css = ss->create(ss, cgrp);
if (IS_ERR(css)) {
+ cgroup_unlock_hierarchy(root);
err = PTR_ERR(css);
goto err_destroy;
}
init_cgroup_css(css, ss, cgrp);
}- cgroup_lock_hierarchy(root);
list_add(&cgrp->sibling, &cgrp->parent->children);
cgroup_unlock_hierarchy(root);
root->number_of_cgroups++;But this may not be what we want, because hierarchy_mutex is meant to be lightweight, so it's not held while subsys callbacks are invoked, except bind().
--
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>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 86 lines · On Wed, 14 Jan 2009 14:47:18 +0800 Li Zefan…
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan…
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 9 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using
cgroup_lock()?Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?We can make
hierarchy_mutexwork for this race by:(quoted diff) +3
-1@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + cgroup_lock_hierarchy(root); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { + cgroup_unlock_hierarchy(root); err = PTR_ERR(css); goto err_destroy; } init_cgroup_css(css, ss, cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); cgroup_unlock_hierarchy(root); root->number_of_cgroups++;
Quoted 4 lines
But this may not be what we want, because
hierarchy_mutexis meant to be lightweight, so it's not held while subsys callbacks are invoked, exceptbind().
Ah, I see your point. But "we can't trust hieararchy_lock for create()" is a probelm. How about following ?
==
for_each-subsys(root,ss) {
if (ss->create) {
mutex_lock(&ss->hierarchy_mutex);
css = ss->create(ss, cgroup);
mutex_unlock(&ss->hierarchy_mutex);
if (IS_ERR(...)) {
}
}==
-Kame
Quoted 86 lines · On Wed, 14 Jan 2009 14:47:18 +0800 Li Zefan <[email protected]> wrote:
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan <[email protected]> wrote:
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 9 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using
cgroup_lock()?Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?We can make
hierarchy_mutexwork for this race by:(quoted diff) +3
-1@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + cgroup_lock_hierarchy(root); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { + cgroup_unlock_hierarchy(root); err = PTR_ERR(css); goto err_destroy; } init_cgroup_css(css, ss, cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); cgroup_unlock_hierarchy(root); root->number_of_cgroups++;
Quoted 4 lines
But this may not be what we want, because
hierarchy_mutexis meant to be lightweight, so it's not held while subsys callbacks are invoked, exceptbind().
Ah, I see your point. But "we can't trust hieararchy_lock for create()" is a probelm. How about following ?
==
for_each-subsys(root,ss) {
if (ss->create) {
mutex_lock(&ss->hierarchy_mutex);
css = ss->create(ss, cgroup);
mutex_unlock(&ss->hierarchy_mutex);
if (IS_ERR(...)) {
}
}==
-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>
A message that is not in the archive (sent off-list or not yet received): 20090114160551.143d7980.kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org
Quoted 86 lines · KAMEZAWA Hiroyuki
Quoted 83 lines · On Wed, 14 Jan 2009 14:47:18 +0800 Li Zefan…
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan…
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 8 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using
cgroup_lock()?Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?We can make
hierarchy_mutexwork for this race by:(quoted diff) +3
-1@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + cgroup_lock_hierarchy(root); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { + cgroup_unlock_hierarchy(root); err = PTR_ERR(css); goto err_destroy; } init_cgroup_css(css, ss, cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); cgroup_unlock_hierarchy(root); root->number_of_cgroups++;
Quoted 7 lines
Quoted 4 lines
But this may not be what we want, because
hierarchy_mutexis meant to be lightweight, so it's not held while subsys callbacks are invoked, exceptbind().Ah, I see your point. But "we can't trust
hieararchy_lockforcreate()" is a probelm. How about following ?
Yes, it can be a problem I think, so should be used carefully..
Quoted 9 lines
==
for_each-subsys(root,ss) { if (ss->create) { mutex_lock(&ss->hierarchy_mutex); css = ss->create(ss, cgroup); mutex_unlock(&ss->hierarchy_mutex); if (IS_ERR(...)) { } }
This won't work. :(
The lock should include both create() and list_add(&cgrp->sibling, &cgrp->parent->children);
Quoted 86 lines · KAMEZAWA Hiroyuki
Quoted 83 lines · On Wed, 14 Jan 2009 14:47:18 +0800 Li Zefan <[email protected]> wrote:
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan <[email protected]> wrote:
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 8 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using
cgroup_lock()?Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?We can make
hierarchy_mutexwork for this race by:(quoted diff) +3
-1@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + cgroup_lock_hierarchy(root); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { + cgroup_unlock_hierarchy(root); err = PTR_ERR(css); goto err_destroy; } init_cgroup_css(css, ss, cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); cgroup_unlock_hierarchy(root); root->number_of_cgroups++;
Quoted 7 lines
Quoted 4 lines
But this may not be what we want, because
hierarchy_mutexis meant to be lightweight, so it's not held while subsys callbacks are invoked, exceptbind().Ah, I see your point. But "we can't trust
hieararchy_lockforcreate()" is a probelm. How about following ?
Yes, it can be a problem I think, so should be used carefully..
Quoted 9 lines
==
for_each-subsys(root,ss) { if (ss->create) { mutex_lock(&ss->hierarchy_mutex); css = ss->create(ss, cgroup); mutex_unlock(&ss->hierarchy_mutex); if (IS_ERR(...)) { } }
This won't work. :(
The lock should include both create() and list_add(&cgrp->sibling, &cgrp->parent->children);
--
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>
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 107 lines · On Wed, 14 Jan 2009 15:22:06 +0800 Li Zefan…
Quoted 86 lines · KAMEZAWA Hiroyuki
Quoted 83 lines · On Wed, 14 Jan 2009 14:47:18 +0800 Li Zefan…
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan…
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 8 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using
cgroup_lock()?Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?We can make
hierarchy_mutexwork for this race by:(quoted diff) +3
-1@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + cgroup_lock_hierarchy(root); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { + cgroup_unlock_hierarchy(root); err = PTR_ERR(css); goto err_destroy; } init_cgroup_css(css, ss, cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); cgroup_unlock_hierarchy(root); root->number_of_cgroups++;Quoted 7 lines
Quoted 4 lines
But this may not be what we want, because
hierarchy_mutexis meant to be lightweight, so it's not held while subsys callbacks are invoked, exceptbind().Ah, I see your point. But "we can't trust
hieararchy_lockforcreate()" is a probelm. How about following ?Yes, it can be a problem I think, so should be used carefully..
Quoted 9 lines
==
for_each-subsys(root,ss) { if (ss->create) { mutex_lock(&ss->hierarchy_mutex); css = ss->create(ss, cgroup); mutex_unlock(&ss->hierarchy_mutex); if (IS_ERR(...)) { } }
Quoted 5 lines
This won't work. :(
The lock should include both
create()andlist_add(&cgrp->sibling, &cgrp->parent->children);
I see. Hmm...it seems that we have to use cgroup_lock, now. please go ahead. memory.use_hierarchy file also uses cgroup_lock.
Acked-by; KAMEZAWA Hiroyuki <[email protected]>
Thank you!
-Kame
Quoted 107 lines · On Wed, 14 Jan 2009 15:22:06 +0800 Li Zefan <[email protected]> wrote:
Quoted 86 lines · KAMEZAWA Hiroyuki
Quoted 83 lines · On Wed, 14 Jan 2009 14:47:18 +0800 Li Zefan <[email protected]> wrote:
Quoted 47 lines · KAMEZAWA Hiroyuki
Quoted 44 lines · On Wed, 14 Jan 2009 11:24:18 +0800 Li Zefan <[email protected]> wrote:
(suppose:
memcg->use_hierarchy== 0 andmemcg->swappiness== 60)echo 10 > /memcg/0/swappiness | mem_cgroup_swappiness_write() | ... | echo 1 > /memcg/0/use_hierarchy | mkdir /mnt/0/1 | sub_memcg->swappiness = 60; memcg->swappiness = 10; |In the above scenario, we end up having 2 different swappiness values in a single hierarchy.
Note we can't use
hierarchy_lockhere, because it doesn't protect thecreate()method.Though IMO use
cgroup_lock()in simple write functions is OK, Paul would like to avoid it. And he sugguested use a counter to count the number of children instead of checkcgrp->childrenlist:=================
create()does:lock
memcg_parentmemcg->swappiness=memcg->parent->swappiness;
memcg_parent->child_count++;
unlockmemcg_parentand
write()does:lock memcg
if (!memcg->child_count) {
memcg->swappiness= swappiness;
} else {
report error;
}
unlock memcg
destroy()does:
lockmemcg_parent
memcg_parent->child_count--;
unlockmemcg_parent=================
Quoted 8 lines
Quoted 6 lines
And there is a suble differnce with checking
cgrp->children, that a cgroup is removed from parent's list incgroup_rmdir(), whilememcg->child_countis decremented incgroup_diput().Signed-off-by Li Zefan <[email protected]>Seems reasonable, but, hmm...
Do you mean you agree to avoid using
cgroup_lock()?Quoted 2 lines
Why
hierarchy_mutexcan't be used forcreate()?We can make
hierarchy_mutexwork for this race by:(quoted diff) +3
-1@@ -2403,16 +2403,18 @@ static long cgroup_create(struct cgroup *parent, struct if (notify_on_release(parent)) set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + cgroup_lock_hierarchy(root); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { + cgroup_unlock_hierarchy(root); err = PTR_ERR(css); goto err_destroy; } init_cgroup_css(css, ss, cgrp); } - cgroup_lock_hierarchy(root); list_add(&cgrp->sibling, &cgrp->parent->children); cgroup_unlock_hierarchy(root); root->number_of_cgroups++;Quoted 7 lines
Quoted 4 lines
But this may not be what we want, because
hierarchy_mutexis meant to be lightweight, so it's not held while subsys callbacks are invoked, exceptbind().Ah, I see your point. But "we can't trust
hieararchy_lockforcreate()" is a probelm. How about following ?Yes, it can be a problem I think, so should be used carefully..
Quoted 9 lines
==
for_each-subsys(root,ss) { if (ss->create) { mutex_lock(&ss->hierarchy_mutex); css = ss->create(ss, cgroup); mutex_unlock(&ss->hierarchy_mutex); if (IS_ERR(...)) { } }
Quoted 5 lines
This won't work. :(
The lock should include both
create()andlist_add(&cgrp->sibling, &cgrp->parent->children);
I see. Hmm...it seems that we have to use cgroup_lock, now. please go ahead. memory.use_hierarchy file also uses cgroup_lock.
Acked-by; KAMEZAWA Hiroyuki <[email protected]>
Thank you!
-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>