Merge branch 'for-4.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup fixes from Tejun Heo: "More change than I'd have liked at this stage. The pids controller and the changes made to cgroup core to support it introduced and revealed several important issues. - Assigning membership to a newly created task and migrating it can race leading to incorrect accounting. Oleg fixed it by widening threadgroup synchronization. It looks like we'll be able to merge it with a different percpu rwsem which is used in fork path making things simpler and cheaper. - The recent change to extend cgroup membership to zombies (so that pid accounting can extend till the pid is actually released) missed pinning the underlying data structures leading to use-after-free. Fixed. - v2 hierarchy was calling subsystem callbacks with the wrong target cgroup_subsys_state based on the incorrect assumption that they share the same target. pids is the first controller affected by this. Subsys callbacks updated so that they can deal with multi-target migrations" * 'for-4.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup: cgroup_pids: don't account for the root cgroup cgroup: fix handling of multi-destination migration from subtree_control enabling cgroup_freezer: simplify propagation of CGROUP_FROZEN clearing in freezer_attach() cgroup: pids: kill pids_fork(), simplify pids_can_fork() and pids_cancel_fork() cgroup: pids: fix race between cgroup_post_fork() and cgroup_migrate() cgroup: make css_set pin its css's to avoid use-afer-free cgroup: fix cftype->file_offset handling
Dieser Commit ist enthalten in:
@@ -4779,23 +4779,18 @@ static void mem_cgroup_clear_mc(void)
|
||||
spin_unlock(&mc.lock);
|
||||
}
|
||||
|
||||
static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset)
|
||||
static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
|
||||
{
|
||||
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
|
||||
struct cgroup_subsys_state *css;
|
||||
struct mem_cgroup *memcg;
|
||||
struct mem_cgroup *from;
|
||||
struct task_struct *leader, *p;
|
||||
struct mm_struct *mm;
|
||||
unsigned long move_flags;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* We are now commited to this value whatever it is. Changes in this
|
||||
* tunable will only affect upcoming migrations, not the current one.
|
||||
* So we need to save it, and keep it going.
|
||||
*/
|
||||
move_flags = READ_ONCE(memcg->move_charge_at_immigrate);
|
||||
if (!move_flags)
|
||||
/* charge immigration isn't supported on the default hierarchy */
|
||||
if (cgroup_subsys_on_dfl(memory_cgrp_subsys))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -4805,13 +4800,23 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
|
||||
* multiple.
|
||||
*/
|
||||
p = NULL;
|
||||
cgroup_taskset_for_each_leader(leader, tset) {
|
||||
cgroup_taskset_for_each_leader(leader, css, tset) {
|
||||
WARN_ON_ONCE(p);
|
||||
p = leader;
|
||||
memcg = mem_cgroup_from_css(css);
|
||||
}
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We are now commited to this value whatever it is. Changes in this
|
||||
* tunable will only affect upcoming migrations, not the current one.
|
||||
* So we need to save it, and keep it going.
|
||||
*/
|
||||
move_flags = READ_ONCE(memcg->move_charge_at_immigrate);
|
||||
if (!move_flags)
|
||||
return 0;
|
||||
|
||||
from = mem_cgroup_from_task(p);
|
||||
|
||||
VM_BUG_ON(from == memcg);
|
||||
@@ -4842,8 +4847,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mem_cgroup_cancel_attach(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset)
|
||||
static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset)
|
||||
{
|
||||
if (mc.to)
|
||||
mem_cgroup_clear_mc();
|
||||
@@ -4985,10 +4989,10 @@ retry:
|
||||
atomic_dec(&mc.from->moving_account);
|
||||
}
|
||||
|
||||
static void mem_cgroup_move_task(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset)
|
||||
static void mem_cgroup_move_task(struct cgroup_taskset *tset)
|
||||
{
|
||||
struct task_struct *p = cgroup_taskset_first(tset);
|
||||
struct cgroup_subsys_state *css;
|
||||
struct task_struct *p = cgroup_taskset_first(tset, &css);
|
||||
struct mm_struct *mm = get_task_mm(p);
|
||||
|
||||
if (mm) {
|
||||
@@ -5000,17 +5004,14 @@ static void mem_cgroup_move_task(struct cgroup_subsys_state *css,
|
||||
mem_cgroup_clear_mc();
|
||||
}
|
||||
#else /* !CONFIG_MMU */
|
||||
static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset)
|
||||
static int mem_cgroup_can_attach(struct cgroup_taskset *tset)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void mem_cgroup_cancel_attach(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset)
|
||||
static void mem_cgroup_cancel_attach(struct cgroup_taskset *tset)
|
||||
{
|
||||
}
|
||||
static void mem_cgroup_move_task(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset)
|
||||
static void mem_cgroup_move_task(struct cgroup_taskset *tset)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren