aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2010-11-23 21:37:04 -0800
committerJonas ABERG <jonas.aberg@stericsson.com>2011-04-01 13:30:52 +0200
commitb0071d59dfe203a7d7364588b4fcf109167efb0f (patch)
tree7e8700f1010fcf9b32c2e7f3b63facb56919d588 /include
parent54eefaf5f25ef9a531e37b30ec90d2d567ed65d0 (diff)
cgroup: Remove call to synchronize_rcu in cgroup_attach_task
synchronize_rcu can be very expensive, averaging 100 ms in some cases. In cgroup_attach_task, it is used to prevent a task->cgroups pointer dereferenced in an RCU read side critical section from being invalidated, by delaying the call to put_css_set until after an RCU grace period. To avoid the call to synchronize_rcu, make the put_css_set call rcu-safe by moving the deletion of the css_set links into free_css_set_work, scheduled by the rcu callback free_css_set_rcu. The decrement of the cgroup refcount is no longer synchronous with the call to put_css_set, which can result in the cgroup refcount staying positive after the last call to cgroup_attach_task returns. To allow the cgroup to be deleted with cgroup_rmdir synchronously after cgroup_attach_task, have rmdir check the refcount of all associated css_sets. If cgroup_rmdir is called on a cgroup for which the css_sets all have refcount zero but the cgroup refcount is nonzero, reuse the rmdir waitqueue to block the rmdir until free_css_set_work is called. Signed-off-by: Colin Cross <ccross@android.com> Change-Id: If12ca64cd978752a8e3a37a6230fb0bd485f63f9 Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/19515 Tested-by: Piotr TOMASZEWSKI <piotr.tomaszewski@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/cgroup.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index eb56ba0a753..e82e721e10b 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -275,6 +275,7 @@ struct css_set {
/* For RCU-protected deletion */
struct rcu_head rcu_head;
+ struct work_struct work;
};
/*