diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2012-05-29 18:06:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 19:22:20 -0400 |
commit | 91c63734f6908425903aed69c04035592f18d398 (patch) | |
tree | 6790827ab915b17c63d5c39d8c72c47f3764f868 /kernel/cgroup.c | |
parent | 0ce72d4f7333248efbef1f3309770c7edb1b2625 (diff) |
kernel: cgroup: push rcu read locking from css_is_ancestor() to callsite
Library functions should not grab locks when the callsites can do it,
even if the lock nests like the rcu read-side lock does.
Push the rcu_read_lock() from css_is_ancestor() to its single user,
mem_cgroup_same_or_subtree() in preparation for another user that may
already hold the rcu read-side lock.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Konstantin Khlebnikov <khlebnikov@openvz.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: Michal Hocko <mhocko@suse.cz>
Acked-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index a0c6af34d500..0f3527d6184a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -5132,7 +5132,7 @@ EXPORT_SYMBOL_GPL(css_depth); | |||
5132 | * @root: the css supporsed to be an ancestor of the child. | 5132 | * @root: the css supporsed to be an ancestor of the child. |
5133 | * | 5133 | * |
5134 | * Returns true if "root" is an ancestor of "child" in its hierarchy. Because | 5134 | * Returns true if "root" is an ancestor of "child" in its hierarchy. Because |
5135 | * this function reads css->id, this use rcu_dereference() and rcu_read_lock(). | 5135 | * this function reads css->id, the caller must hold rcu_read_lock(). |
5136 | * But, considering usual usage, the csses should be valid objects after test. | 5136 | * But, considering usual usage, the csses should be valid objects after test. |
5137 | * Assuming that the caller will do some action to the child if this returns | 5137 | * Assuming that the caller will do some action to the child if this returns |
5138 | * returns true, the caller must take "child";s reference count. | 5138 | * returns true, the caller must take "child";s reference count. |
@@ -5144,18 +5144,18 @@ bool css_is_ancestor(struct cgroup_subsys_state *child, | |||
5144 | { | 5144 | { |
5145 | struct css_id *child_id; | 5145 | struct css_id *child_id; |
5146 | struct css_id *root_id; | 5146 | struct css_id *root_id; |
5147 | bool ret = true; | ||
5148 | 5147 | ||
5149 | rcu_read_lock(); | ||
5150 | child_id = rcu_dereference(child->id); | 5148 | child_id = rcu_dereference(child->id); |
5149 | if (!child_id) | ||
5150 | return false; | ||
5151 | root_id = rcu_dereference(root->id); | 5151 | root_id = rcu_dereference(root->id); |
5152 | if (!child_id | 5152 | if (!root_id) |
5153 | || !root_id | 5153 | return false; |
5154 | || (child_id->depth < root_id->depth) | 5154 | if (child_id->depth < root_id->depth) |
5155 | || (child_id->stack[root_id->depth] != root_id->id)) | 5155 | return false; |
5156 | ret = false; | 5156 | if (child_id->stack[root_id->depth] != root_id->id) |
5157 | rcu_read_unlock(); | 5157 | return false; |
5158 | return ret; | 5158 | return true; |
5159 | } | 5159 | } |
5160 | 5160 | ||
5161 | void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css) | 5161 | void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css) |