mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
cgroups: let ss->can_attach and ss->attach do whole threadgroups at a time
Alter the ss->can_attach and ss->attach functions to be able to deal with a whole threadgroup at a time, for use in cgroup_attach_proc. (This is a pre-patch to cgroup-procs-writable.patch.) Currently, new mode of the attach function can only tell the subsystem about the old cgroup of the threadgroup leader. No subsystem currently needs that information for each thread that's being moved, but if one were to be added (for example, one that counts tasks within a group) this bit would need to be reworked a bit to tell the subsystem the right information. [[email protected]: fix build] Signed-off-by: Ben Blum <[email protected]> Signed-off-by: Paul Menage <[email protected]> Acked-by: Li Zefan <[email protected]> Reviewed-by: Matt Helsley <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Dave Young <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
c378369d8b
commit
be367d0992
9 changed files with 131 additions and 30 deletions
|
|
@ -1324,9 +1324,10 @@ static int fmeter_getrate(struct fmeter *fmp)
|
|||
static cpumask_var_t cpus_attach;
|
||||
|
||||
/* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */
|
||||
static int cpuset_can_attach(struct cgroup_subsys *ss,
|
||||
struct cgroup *cont, struct task_struct *tsk)
|
||||
static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
|
||||
struct task_struct *tsk, bool threadgroup)
|
||||
{
|
||||
int ret;
|
||||
struct cpuset *cs = cgroup_cs(cont);
|
||||
|
||||
if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
|
||||
|
|
@ -1343,18 +1344,51 @@ static int cpuset_can_attach(struct cgroup_subsys *ss,
|
|||
if (tsk->flags & PF_THREAD_BOUND)
|
||||
return -EINVAL;
|
||||
|
||||
return security_task_setscheduler(tsk, 0, NULL);
|
||||
ret = security_task_setscheduler(tsk, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (threadgroup) {
|
||||
struct task_struct *c;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) {
|
||||
ret = security_task_setscheduler(c, 0, NULL);
|
||||
if (ret) {
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpuset_attach(struct cgroup_subsys *ss,
|
||||
struct cgroup *cont, struct cgroup *oldcont,
|
||||
struct task_struct *tsk)
|
||||
static void cpuset_attach_task(struct task_struct *tsk, nodemask_t *to,
|
||||
struct cpuset *cs)
|
||||
{
|
||||
int err;
|
||||
/*
|
||||
* can_attach beforehand should guarantee that this doesn't fail.
|
||||
* TODO: have a better way to handle failure here
|
||||
*/
|
||||
err = set_cpus_allowed_ptr(tsk, cpus_attach);
|
||||
WARN_ON_ONCE(err);
|
||||
|
||||
task_lock(tsk);
|
||||
cpuset_change_task_nodemask(tsk, to);
|
||||
task_unlock(tsk);
|
||||
cpuset_update_task_spread_flag(cs, tsk);
|
||||
|
||||
}
|
||||
|
||||
static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont,
|
||||
struct cgroup *oldcont, struct task_struct *tsk,
|
||||
bool threadgroup)
|
||||
{
|
||||
nodemask_t from, to;
|
||||
struct mm_struct *mm;
|
||||
struct cpuset *cs = cgroup_cs(cont);
|
||||
struct cpuset *oldcs = cgroup_cs(oldcont);
|
||||
int err;
|
||||
|
||||
if (cs == &top_cpuset) {
|
||||
cpumask_copy(cpus_attach, cpu_possible_mask);
|
||||
|
|
@ -1363,15 +1397,19 @@ static void cpuset_attach(struct cgroup_subsys *ss,
|
|||
guarantee_online_cpus(cs, cpus_attach);
|
||||
guarantee_online_mems(cs, &to);
|
||||
}
|
||||
err = set_cpus_allowed_ptr(tsk, cpus_attach);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
task_lock(tsk);
|
||||
cpuset_change_task_nodemask(tsk, &to);
|
||||
task_unlock(tsk);
|
||||
cpuset_update_task_spread_flag(cs, tsk);
|
||||
/* do per-task migration stuff possibly for each in the threadgroup */
|
||||
cpuset_attach_task(tsk, &to, cs);
|
||||
if (threadgroup) {
|
||||
struct task_struct *c;
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) {
|
||||
cpuset_attach_task(c, &to, cs);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/* change mm; only needs to be done once even if threadgroup */
|
||||
from = oldcs->mems_allowed;
|
||||
to = cs->mems_allowed;
|
||||
mm = get_task_mm(tsk);
|
||||
|
|
|
|||
Loading…
Reference in a new issue