mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 13:44:26 -04:00
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
This commit is contained in:
commit
5406812e59
13 changed files with 202 additions and 183 deletions
|
|
@ -90,7 +90,6 @@ enum {
|
|||
*/
|
||||
struct cgroup_file {
|
||||
/* do not access any fields from outside cgroup core */
|
||||
struct list_head node; /* anchored at css->files */
|
||||
struct kernfs_node *kn;
|
||||
};
|
||||
|
||||
|
|
@ -134,9 +133,6 @@ struct cgroup_subsys_state {
|
|||
*/
|
||||
u64 serial_nr;
|
||||
|
||||
/* all cgroup_files associated with this css */
|
||||
struct list_head files;
|
||||
|
||||
/* percpu_ref killing and RCU release */
|
||||
struct rcu_head rcu_head;
|
||||
struct work_struct destroy_work;
|
||||
|
|
@ -426,12 +422,9 @@ struct cgroup_subsys {
|
|||
void (*css_reset)(struct cgroup_subsys_state *css);
|
||||
void (*css_e_css_changed)(struct cgroup_subsys_state *css);
|
||||
|
||||
int (*can_attach)(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset);
|
||||
void (*cancel_attach)(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset);
|
||||
void (*attach)(struct cgroup_subsys_state *css,
|
||||
struct cgroup_taskset *tset);
|
||||
int (*can_attach)(struct cgroup_taskset *tset);
|
||||
void (*cancel_attach)(struct cgroup_taskset *tset);
|
||||
void (*attach)(struct cgroup_taskset *tset);
|
||||
int (*can_fork)(struct task_struct *task, void **priv_p);
|
||||
void (*cancel_fork)(struct task_struct *task, void *priv);
|
||||
void (*fork)(struct task_struct *task, void *priv);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
|
|||
int cgroup_add_dfl_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
|
||||
int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts);
|
||||
int cgroup_rm_cftypes(struct cftype *cfts);
|
||||
void cgroup_file_notify(struct cgroup_file *cfile);
|
||||
|
||||
char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen);
|
||||
int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry);
|
||||
|
|
@ -119,8 +120,10 @@ struct cgroup_subsys_state *css_rightmost_descendant(struct cgroup_subsys_state
|
|||
struct cgroup_subsys_state *css_next_descendant_post(struct cgroup_subsys_state *pos,
|
||||
struct cgroup_subsys_state *css);
|
||||
|
||||
struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset);
|
||||
struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset);
|
||||
struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset,
|
||||
struct cgroup_subsys_state **dst_cssp);
|
||||
struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset,
|
||||
struct cgroup_subsys_state **dst_cssp);
|
||||
|
||||
void css_task_iter_start(struct cgroup_subsys_state *css,
|
||||
struct css_task_iter *it);
|
||||
|
|
@ -235,30 +238,39 @@ void css_task_iter_end(struct css_task_iter *it);
|
|||
/**
|
||||
* cgroup_taskset_for_each - iterate cgroup_taskset
|
||||
* @task: the loop cursor
|
||||
* @dst_css: the destination css
|
||||
* @tset: taskset to iterate
|
||||
*
|
||||
* @tset may contain multiple tasks and they may belong to multiple
|
||||
* processes. When there are multiple tasks in @tset, if a task of a
|
||||
* process is in @tset, all tasks of the process are in @tset. Also, all
|
||||
* are guaranteed to share the same source and destination csses.
|
||||
* processes.
|
||||
*
|
||||
* On the v2 hierarchy, there may be tasks from multiple processes and they
|
||||
* may not share the source or destination csses.
|
||||
*
|
||||
* On traditional hierarchies, when there are multiple tasks in @tset, if a
|
||||
* task of a process is in @tset, all tasks of the process are in @tset.
|
||||
* Also, all are guaranteed to share the same source and destination csses.
|
||||
*
|
||||
* Iteration is not in any specific order.
|
||||
*/
|
||||
#define cgroup_taskset_for_each(task, tset) \
|
||||
for ((task) = cgroup_taskset_first((tset)); (task); \
|
||||
(task) = cgroup_taskset_next((tset)))
|
||||
#define cgroup_taskset_for_each(task, dst_css, tset) \
|
||||
for ((task) = cgroup_taskset_first((tset), &(dst_css)); \
|
||||
(task); \
|
||||
(task) = cgroup_taskset_next((tset), &(dst_css)))
|
||||
|
||||
/**
|
||||
* cgroup_taskset_for_each_leader - iterate group leaders in a cgroup_taskset
|
||||
* @leader: the loop cursor
|
||||
* @dst_css: the destination css
|
||||
* @tset: takset to iterate
|
||||
*
|
||||
* Iterate threadgroup leaders of @tset. For single-task migrations, @tset
|
||||
* may not contain any.
|
||||
*/
|
||||
#define cgroup_taskset_for_each_leader(leader, tset) \
|
||||
for ((leader) = cgroup_taskset_first((tset)); (leader); \
|
||||
(leader) = cgroup_taskset_next((tset))) \
|
||||
#define cgroup_taskset_for_each_leader(leader, dst_css, tset) \
|
||||
for ((leader) = cgroup_taskset_first((tset), &(dst_css)); \
|
||||
(leader); \
|
||||
(leader) = cgroup_taskset_next((tset), &(dst_css))) \
|
||||
if ((leader) != (leader)->group_leader) \
|
||||
; \
|
||||
else
|
||||
|
|
@ -516,19 +528,6 @@ static inline void pr_cont_cgroup_path(struct cgroup *cgrp)
|
|||
pr_cont_kernfs_path(cgrp->kn);
|
||||
}
|
||||
|
||||
/**
|
||||
* cgroup_file_notify - generate a file modified event for a cgroup_file
|
||||
* @cfile: target cgroup_file
|
||||
*
|
||||
* @cfile must have been obtained by setting cftype->file_offset.
|
||||
*/
|
||||
static inline void cgroup_file_notify(struct cgroup_file *cfile)
|
||||
{
|
||||
/* might not have been created due to one of the CFTYPE selector flags */
|
||||
if (cfile->kn)
|
||||
kernfs_notify(cfile->kn);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_CGROUPS */
|
||||
|
||||
struct cgroup_subsys_state;
|
||||
|
|
|
|||
Loading…
Reference in a new issue