diff options
| author | Tejun Heo <tj@kernel.org> | 2015-05-13 16:35:16 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2015-05-26 20:35:00 -0400 |
| commit | 7d7efec368d537226142cbe559f45797f18672f9 (patch) | |
| tree | 8b391dada2b97b66f9fbd4315b397516f13199de /kernel | |
| parent | 8ab456ac3697dbd1d3eae5d5817dba941faf89ee (diff) | |
sched, cgroup: reorganize threadgroup locking
threadgroup_change_begin/end() are used to mark the beginning and end
of threadgroup modifying operations to allow code paths which require
a threadgroup to stay stable across blocking operations to synchronize
against those sections using threadgroup_lock/unlock().
It's currently implemented as a general mechanism in sched.h using
per-signal_struct rwsem; however, this never grew non-cgroup use cases
and becomes noop if !CONFIG_CGROUPS. It turns out that cgroups is
gonna be better served with a different sycnrhonization scheme and is
a bit silly to keep cgroups specific details as a general mechanism.
What's general here is identifying the places where threadgroups are
modified. This patch restructures threadgroup locking so that
threadgroup_change_begin/end() become a place where subsystems which
need to sycnhronize against threadgroup changes can hook into.
cgroup_threadgroup_change_begin/end() which operate on the
per-signal_struct rwsem are created and threadgroup_lock/unlock() are
moved to cgroup.c and made static.
This is pure reorganization which doesn't cause any functional
changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cgroup.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index b91177f93416..980b1f52f39f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
| @@ -848,6 +848,48 @@ static struct css_set *find_css_set(struct css_set *old_cset, | |||
| 848 | return cset; | 848 | return cset; |
| 849 | } | 849 | } |
| 850 | 850 | ||
| 851 | void cgroup_threadgroup_change_begin(struct task_struct *tsk) | ||
| 852 | { | ||
| 853 | down_read(&tsk->signal->group_rwsem); | ||
| 854 | } | ||
| 855 | |||
| 856 | void cgroup_threadgroup_change_end(struct task_struct *tsk) | ||
| 857 | { | ||
| 858 | up_read(&tsk->signal->group_rwsem); | ||
| 859 | } | ||
| 860 | |||
| 861 | /** | ||
| 862 | * threadgroup_lock - lock threadgroup | ||
| 863 | * @tsk: member task of the threadgroup to lock | ||
| 864 | * | ||
| 865 | * Lock the threadgroup @tsk belongs to. No new task is allowed to enter | ||
| 866 | * and member tasks aren't allowed to exit (as indicated by PF_EXITING) or | ||
| 867 | * change ->group_leader/pid. This is useful for cases where the threadgroup | ||
| 868 | * needs to stay stable across blockable operations. | ||
| 869 | * | ||
| 870 | * fork and exit explicitly call threadgroup_change_{begin|end}() for | ||
| 871 | * synchronization. While held, no new task will be added to threadgroup | ||
| 872 | * and no existing live task will have its PF_EXITING set. | ||
| 873 | * | ||
| 874 | * de_thread() does threadgroup_change_{begin|end}() when a non-leader | ||
| 875 | * sub-thread becomes a new leader. | ||
| 876 | */ | ||
| 877 | static void threadgroup_lock(struct task_struct *tsk) | ||
| 878 | { | ||
| 879 | down_write(&tsk->signal->group_rwsem); | ||
| 880 | } | ||
| 881 | |||
| 882 | /** | ||
| 883 | * threadgroup_unlock - unlock threadgroup | ||
| 884 | * @tsk: member task of the threadgroup to unlock | ||
| 885 | * | ||
| 886 | * Reverse threadgroup_lock(). | ||
| 887 | */ | ||
| 888 | static inline void threadgroup_unlock(struct task_struct *tsk) | ||
| 889 | { | ||
| 890 | up_write(&tsk->signal->group_rwsem); | ||
| 891 | } | ||
| 892 | |||
| 851 | static struct cgroup_root *cgroup_root_from_kf(struct kernfs_root *kf_root) | 893 | static struct cgroup_root *cgroup_root_from_kf(struct kernfs_root *kf_root) |
| 852 | { | 894 | { |
| 853 | struct cgroup *root_cgrp = kf_root->kn->priv; | 895 | struct cgroup *root_cgrp = kf_root->kn->priv; |
