Merge branch 'for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup updates from Tejun Heo: "The cgroup core saw several significant updates this cycle: - percpu_rwsem for threadgroup locking is reinstated. This was temporarily dropped due to down_write latency issues. Oleg's rework of percpu_rwsem which is scheduled to be merged in this merge window resolves the issue. - On the v2 hierarchy, when controllers are enabled and disabled, all operations are atomic and can fail and revert cleanly. This allows ->can_attach() failure which is necessary for cpu RT slices. - Tasks now stay associated with the original cgroups after exit until released. This allows tracking resources held by zombies (e.g. pids) and makes it easy to find out where zombies came from on the v2 hierarchy. The pids controller was broken before these changes as zombies escaped the limits; unfortunately, updating this behavior required too many invasive changes and I don't think it's a good idea to backport them, so the pids controller on 4.3, the first version which included the pids controller, will stay broken at least until I'm sure about the cgroup core changes. - Optimization of a couple common tests using static_key" * 'for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: (38 commits) cgroup: fix race condition around termination check in css_task_iter_next() blkcg: don't create "io.stat" on the root cgroup cgroup: drop cgroup__DEVEL__legacy_files_on_dfl cgroup: replace error handling in cgroup_init() with WARN_ON()s cgroup: add cgroup_subsys->free() method and use it to fix pids controller cgroup: keep zombies associated with their original cgroups cgroup: make css_set_rwsem a spinlock and rename it to css_set_lock cgroup: don't hold css_set_rwsem across css task iteration cgroup: reorganize css_task_iter functions cgroup: factor out css_set_move_task() cgroup: keep css_set and task lists in chronological order cgroup: make cgroup_destroy_locked() test cgroup_is_populated() cgroup: make css_sets pin the associated cgroups cgroup: relocate cgroup_[try]get/put() cgroup: move check_for_release() invocation cgroup: replace cgroup_has_tasks() with cgroup_is_populated() cgroup: make cgroup->nr_populated count the number of populated css_sets cgroup: remove an unused parameter from cgroup_task_migrate() cgroup: fix too early usage of static_branch_disable() cgroup: make cgroup_update_dfl_csses() migrate all target processes atomically ...
This commit is contained in:
1343
kernel/cgroup.c
1343
kernel/cgroup.c
File diff suppressed because it is too large
Load Diff
@@ -266,11 +266,9 @@ static void pids_fork(struct task_struct *task, void *priv)
|
||||
css_put(old_css);
|
||||
}
|
||||
|
||||
static void pids_exit(struct cgroup_subsys_state *css,
|
||||
struct cgroup_subsys_state *old_css,
|
||||
struct task_struct *task)
|
||||
static void pids_free(struct task_struct *task)
|
||||
{
|
||||
struct pids_cgroup *pids = css_pids(old_css);
|
||||
struct pids_cgroup *pids = css_pids(task_css(task, pids_cgrp_id));
|
||||
|
||||
pids_uncharge(pids, 1);
|
||||
}
|
||||
@@ -349,7 +347,7 @@ struct cgroup_subsys pids_cgrp_subsys = {
|
||||
.can_fork = pids_can_fork,
|
||||
.cancel_fork = pids_cancel_fork,
|
||||
.fork = pids_fork,
|
||||
.exit = pids_exit,
|
||||
.free = pids_free,
|
||||
.legacy_cftypes = pids_files,
|
||||
.dfl_cftypes = pids_files,
|
||||
};
|
||||
|
@@ -473,7 +473,8 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
|
||||
|
||||
/* On legacy hiearchy, we must be a subset of our parent cpuset. */
|
||||
ret = -EACCES;
|
||||
if (!cgroup_on_dfl(cur->css.cgroup) && !is_cpuset_subset(trial, par))
|
||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
!is_cpuset_subset(trial, par))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
@@ -497,7 +498,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
|
||||
* be changed to have empty cpus_allowed or mems_allowed.
|
||||
*/
|
||||
ret = -ENOSPC;
|
||||
if ((cgroup_has_tasks(cur->css.cgroup) || cur->attach_in_progress)) {
|
||||
if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) {
|
||||
if (!cpumask_empty(cur->cpus_allowed) &&
|
||||
cpumask_empty(trial->cpus_allowed))
|
||||
goto out;
|
||||
@@ -879,7 +880,8 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
|
||||
* If it becomes empty, inherit the effective mask of the
|
||||
* parent, which is guaranteed to have some CPUs.
|
||||
*/
|
||||
if (cgroup_on_dfl(cp->css.cgroup) && cpumask_empty(new_cpus))
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
cpumask_empty(new_cpus))
|
||||
cpumask_copy(new_cpus, parent->effective_cpus);
|
||||
|
||||
/* Skip the whole subtree if the cpumask remains the same. */
|
||||
@@ -896,7 +898,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
|
||||
cpumask_copy(cp->effective_cpus, new_cpus);
|
||||
spin_unlock_irq(&callback_lock);
|
||||
|
||||
WARN_ON(!cgroup_on_dfl(cp->css.cgroup) &&
|
||||
WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
!cpumask_equal(cp->cpus_allowed, cp->effective_cpus));
|
||||
|
||||
update_tasks_cpumask(cp);
|
||||
@@ -1135,7 +1137,8 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
|
||||
* If it becomes empty, inherit the effective mask of the
|
||||
* parent, which is guaranteed to have some MEMs.
|
||||
*/
|
||||
if (cgroup_on_dfl(cp->css.cgroup) && nodes_empty(*new_mems))
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
nodes_empty(*new_mems))
|
||||
*new_mems = parent->effective_mems;
|
||||
|
||||
/* Skip the whole subtree if the nodemask remains the same. */
|
||||
@@ -1152,7 +1155,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
|
||||
cp->effective_mems = *new_mems;
|
||||
spin_unlock_irq(&callback_lock);
|
||||
|
||||
WARN_ON(!cgroup_on_dfl(cp->css.cgroup) &&
|
||||
WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
!nodes_equal(cp->mems_allowed, cp->effective_mems));
|
||||
|
||||
update_tasks_nodemask(cp);
|
||||
@@ -1440,7 +1443,7 @@ static int cpuset_can_attach(struct cgroup_subsys_state *css,
|
||||
|
||||
/* allow moving tasks into an empty cpuset if on default hierarchy */
|
||||
ret = -ENOSPC;
|
||||
if (!cgroup_on_dfl(css->cgroup) &&
|
||||
if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) &&
|
||||
(cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)))
|
||||
goto out_unlock;
|
||||
|
||||
@@ -1484,9 +1487,8 @@ static void cpuset_attach(struct cgroup_subsys_state *css,
|
||||
{
|
||||
/* static buf protected by cpuset_mutex */
|
||||
static nodemask_t cpuset_attach_nodemask_to;
|
||||
struct mm_struct *mm;
|
||||
struct task_struct *task;
|
||||
struct task_struct *leader = cgroup_taskset_first(tset);
|
||||
struct task_struct *leader;
|
||||
struct cpuset *cs = css_cs(css);
|
||||
struct cpuset *oldcs = cpuset_attach_old_cs;
|
||||
|
||||
@@ -1512,26 +1514,30 @@ static void cpuset_attach(struct cgroup_subsys_state *css,
|
||||
}
|
||||
|
||||
/*
|
||||
* Change mm, possibly for multiple threads in a threadgroup. This is
|
||||
* expensive and may sleep.
|
||||
* Change mm for all threadgroup leaders. This is expensive and may
|
||||
* sleep and should be moved outside migration path proper.
|
||||
*/
|
||||
cpuset_attach_nodemask_to = cs->effective_mems;
|
||||
mm = get_task_mm(leader);
|
||||
if (mm) {
|
||||
mpol_rebind_mm(mm, &cpuset_attach_nodemask_to);
|
||||
cgroup_taskset_for_each_leader(leader, tset) {
|
||||
struct mm_struct *mm = get_task_mm(leader);
|
||||
|
||||
/*
|
||||
* old_mems_allowed is the same with mems_allowed here, except
|
||||
* if this task is being moved automatically due to hotplug.
|
||||
* In that case @mems_allowed has been updated and is empty,
|
||||
* so @old_mems_allowed is the right nodesets that we migrate
|
||||
* mm from.
|
||||
*/
|
||||
if (is_memory_migrate(cs)) {
|
||||
cpuset_migrate_mm(mm, &oldcs->old_mems_allowed,
|
||||
&cpuset_attach_nodemask_to);
|
||||
if (mm) {
|
||||
mpol_rebind_mm(mm, &cpuset_attach_nodemask_to);
|
||||
|
||||
/*
|
||||
* old_mems_allowed is the same with mems_allowed
|
||||
* here, except if this task is being moved
|
||||
* automatically due to hotplug. In that case
|
||||
* @mems_allowed has been updated and is empty, so
|
||||
* @old_mems_allowed is the right nodesets that we
|
||||
* migrate mm from.
|
||||
*/
|
||||
if (is_memory_migrate(cs)) {
|
||||
cpuset_migrate_mm(mm, &oldcs->old_mems_allowed,
|
||||
&cpuset_attach_nodemask_to);
|
||||
}
|
||||
mmput(mm);
|
||||
}
|
||||
mmput(mm);
|
||||
}
|
||||
|
||||
cs->old_mems_allowed = cpuset_attach_nodemask_to;
|
||||
@@ -1594,9 +1600,6 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
|
||||
case FILE_MEMORY_PRESSURE_ENABLED:
|
||||
cpuset_memory_pressure_enabled = !!val;
|
||||
break;
|
||||
case FILE_MEMORY_PRESSURE:
|
||||
retval = -EACCES;
|
||||
break;
|
||||
case FILE_SPREAD_PAGE:
|
||||
retval = update_flag(CS_SPREAD_PAGE, cs, val);
|
||||
break;
|
||||
@@ -1863,9 +1866,6 @@ static struct cftype files[] = {
|
||||
{
|
||||
.name = "memory_pressure",
|
||||
.read_u64 = cpuset_read_u64,
|
||||
.write_u64 = cpuset_write_u64,
|
||||
.private = FILE_MEMORY_PRESSURE,
|
||||
.mode = S_IRUGO,
|
||||
},
|
||||
|
||||
{
|
||||
@@ -1952,7 +1952,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
|
||||
cpuset_inc();
|
||||
|
||||
spin_lock_irq(&callback_lock);
|
||||
if (cgroup_on_dfl(cs->css.cgroup)) {
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) {
|
||||
cpumask_copy(cs->effective_cpus, parent->effective_cpus);
|
||||
cs->effective_mems = parent->effective_mems;
|
||||
}
|
||||
@@ -2029,7 +2029,7 @@ static void cpuset_bind(struct cgroup_subsys_state *root_css)
|
||||
mutex_lock(&cpuset_mutex);
|
||||
spin_lock_irq(&callback_lock);
|
||||
|
||||
if (cgroup_on_dfl(root_css->cgroup)) {
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) {
|
||||
cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask);
|
||||
top_cpuset.mems_allowed = node_possible_map;
|
||||
} else {
|
||||
@@ -2210,7 +2210,7 @@ retry:
|
||||
cpus_updated = !cpumask_equal(&new_cpus, cs->effective_cpus);
|
||||
mems_updated = !nodes_equal(new_mems, cs->effective_mems);
|
||||
|
||||
if (cgroup_on_dfl(cs->css.cgroup))
|
||||
if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys))
|
||||
hotplug_update_tasks(cs, &new_cpus, &new_mems,
|
||||
cpus_updated, mems_updated);
|
||||
else
|
||||
@@ -2241,7 +2241,7 @@ static void cpuset_hotplug_workfn(struct work_struct *work)
|
||||
static cpumask_t new_cpus;
|
||||
static nodemask_t new_mems;
|
||||
bool cpus_updated, mems_updated;
|
||||
bool on_dfl = cgroup_on_dfl(top_cpuset.css.cgroup);
|
||||
bool on_dfl = cgroup_subsys_on_dfl(cpuset_cgrp_subsys);
|
||||
|
||||
mutex_lock(&cpuset_mutex);
|
||||
|
||||
|
@@ -9460,17 +9460,9 @@ static void perf_cgroup_attach(struct cgroup_subsys_state *css,
|
||||
task_function_call(task, __perf_cgroup_move, task);
|
||||
}
|
||||
|
||||
static void perf_cgroup_exit(struct cgroup_subsys_state *css,
|
||||
struct cgroup_subsys_state *old_css,
|
||||
struct task_struct *task)
|
||||
{
|
||||
task_function_call(task, __perf_cgroup_move, task);
|
||||
}
|
||||
|
||||
struct cgroup_subsys perf_event_cgrp_subsys = {
|
||||
.css_alloc = perf_cgroup_css_alloc,
|
||||
.css_free = perf_cgroup_css_free,
|
||||
.exit = perf_cgroup_exit,
|
||||
.attach = perf_cgroup_attach,
|
||||
};
|
||||
#endif /* CONFIG_CGROUP_PERF */
|
||||
|
@@ -251,6 +251,7 @@ void __put_task_struct(struct task_struct *tsk)
|
||||
WARN_ON(atomic_read(&tsk->usage));
|
||||
WARN_ON(tsk == current);
|
||||
|
||||
cgroup_free(tsk);
|
||||
task_numa_free(tsk);
|
||||
security_task_free(tsk);
|
||||
exit_creds(tsk);
|
||||
@@ -1149,10 +1150,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
||||
tty_audit_fork(sig);
|
||||
sched_autogroup_fork(sig);
|
||||
|
||||
#ifdef CONFIG_CGROUPS
|
||||
init_rwsem(&sig->group_rwsem);
|
||||
#endif
|
||||
|
||||
sig->oom_score_adj = current->signal->oom_score_adj;
|
||||
sig->oom_score_adj_min = current->signal->oom_score_adj_min;
|
||||
|
||||
|
@@ -8244,13 +8244,6 @@ static void cpu_cgroup_attach(struct cgroup_subsys_state *css,
|
||||
sched_move_task(task);
|
||||
}
|
||||
|
||||
static void cpu_cgroup_exit(struct cgroup_subsys_state *css,
|
||||
struct cgroup_subsys_state *old_css,
|
||||
struct task_struct *task)
|
||||
{
|
||||
sched_move_task(task);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FAIR_GROUP_SCHED
|
||||
static int cpu_shares_write_u64(struct cgroup_subsys_state *css,
|
||||
struct cftype *cftype, u64 shareval)
|
||||
@@ -8582,7 +8575,6 @@ struct cgroup_subsys cpu_cgrp_subsys = {
|
||||
.fork = cpu_cgroup_fork,
|
||||
.can_attach = cpu_cgroup_can_attach,
|
||||
.attach = cpu_cgroup_attach,
|
||||
.exit = cpu_cgroup_exit,
|
||||
.legacy_cftypes = cpu_files,
|
||||
.early_init = 1,
|
||||
};
|
||||
|
Reference in New Issue
Block a user