diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 12:16:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-20 12:16:21 -0500 |
commit | 502b24c23b44fbaa01cc2cbd86d8035845b7811f (patch) | |
tree | 3096deeb99f6acc2d72ee33f145008ec5e2c68b3 /kernel/sched/core.c | |
parent | ece8e0b2f9c980e5511fe8db2d68c6f1859b9d83 (diff) | |
parent | f169007b2773f285e098cb84c74aac0154d65ff7 (diff) |
Merge branch 'for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
Pull cgroup changes from Tejun Heo:
"Nothing too drastic.
- Removal of synchronize_rcu() from userland visible paths.
- Various fixes and cleanups from Li.
- cgroup_rightmost_descendant() added which will be used by cpuset
changes (it will be a separate pull request)."
* 'for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup:
cgroup: fail if monitored file and event_control are in different cgroup
cgroup: fix cgroup_rmdir() vs close(eventfd) race
cpuset: fix cpuset_print_task_mems_allowed() vs rename() race
cgroup: fix exit() vs rmdir() race
cgroup: remove bogus comments in cgroup_diput()
cgroup: remove synchronize_rcu() from cgroup_diput()
cgroup: remove duplicate RCU free on struct cgroup
sched: remove redundant NULL cgroup check in task_group_path()
sched: split out css_online/css_offline from tg creation/destruction
cgroup: initialize cgrp->dentry before css_alloc()
cgroup: remove a NULL check in cgroup_exit()
cgroup: fix bogus kernel warnings when cgroup_create() failed
cgroup: remove synchronize_rcu() from rebind_subsystems()
cgroup: remove synchronize_rcu() from cgroup_attach_{task|proc}()
cgroup: use new hashtable implementation
cgroups: fix cgroup_event_listener error handling
cgroups: move cgroup_event_listener.c to tools/cgroup
cgroup: implement cgroup_rightmost_descendant()
cgroup: remove unused dummy cgroup_fork_callbacks()
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 03d7784b7bd2..3a673a3b0c6b 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -7161,7 +7161,6 @@ static void free_sched_group(struct task_group *tg) | |||
7161 | struct task_group *sched_create_group(struct task_group *parent) | 7161 | struct task_group *sched_create_group(struct task_group *parent) |
7162 | { | 7162 | { |
7163 | struct task_group *tg; | 7163 | struct task_group *tg; |
7164 | unsigned long flags; | ||
7165 | 7164 | ||
7166 | tg = kzalloc(sizeof(*tg), GFP_KERNEL); | 7165 | tg = kzalloc(sizeof(*tg), GFP_KERNEL); |
7167 | if (!tg) | 7166 | if (!tg) |
@@ -7173,6 +7172,17 @@ struct task_group *sched_create_group(struct task_group *parent) | |||
7173 | if (!alloc_rt_sched_group(tg, parent)) | 7172 | if (!alloc_rt_sched_group(tg, parent)) |
7174 | goto err; | 7173 | goto err; |
7175 | 7174 | ||
7175 | return tg; | ||
7176 | |||
7177 | err: | ||
7178 | free_sched_group(tg); | ||
7179 | return ERR_PTR(-ENOMEM); | ||
7180 | } | ||
7181 | |||
7182 | void sched_online_group(struct task_group *tg, struct task_group *parent) | ||
7183 | { | ||
7184 | unsigned long flags; | ||
7185 | |||
7176 | spin_lock_irqsave(&task_group_lock, flags); | 7186 | spin_lock_irqsave(&task_group_lock, flags); |
7177 | list_add_rcu(&tg->list, &task_groups); | 7187 | list_add_rcu(&tg->list, &task_groups); |
7178 | 7188 | ||
@@ -7182,12 +7192,6 @@ struct task_group *sched_create_group(struct task_group *parent) | |||
7182 | INIT_LIST_HEAD(&tg->children); | 7192 | INIT_LIST_HEAD(&tg->children); |
7183 | list_add_rcu(&tg->siblings, &parent->children); | 7193 | list_add_rcu(&tg->siblings, &parent->children); |
7184 | spin_unlock_irqrestore(&task_group_lock, flags); | 7194 | spin_unlock_irqrestore(&task_group_lock, flags); |
7185 | |||
7186 | return tg; | ||
7187 | |||
7188 | err: | ||
7189 | free_sched_group(tg); | ||
7190 | return ERR_PTR(-ENOMEM); | ||
7191 | } | 7195 | } |
7192 | 7196 | ||
7193 | /* rcu callback to free various structures associated with a task group */ | 7197 | /* rcu callback to free various structures associated with a task group */ |
@@ -7200,6 +7204,12 @@ static void free_sched_group_rcu(struct rcu_head *rhp) | |||
7200 | /* Destroy runqueue etc associated with a task group */ | 7204 | /* Destroy runqueue etc associated with a task group */ |
7201 | void sched_destroy_group(struct task_group *tg) | 7205 | void sched_destroy_group(struct task_group *tg) |
7202 | { | 7206 | { |
7207 | /* wait for possible concurrent references to cfs_rqs complete */ | ||
7208 | call_rcu(&tg->rcu, free_sched_group_rcu); | ||
7209 | } | ||
7210 | |||
7211 | void sched_offline_group(struct task_group *tg) | ||
7212 | { | ||
7203 | unsigned long flags; | 7213 | unsigned long flags; |
7204 | int i; | 7214 | int i; |
7205 | 7215 | ||
@@ -7211,9 +7221,6 @@ void sched_destroy_group(struct task_group *tg) | |||
7211 | list_del_rcu(&tg->list); | 7221 | list_del_rcu(&tg->list); |
7212 | list_del_rcu(&tg->siblings); | 7222 | list_del_rcu(&tg->siblings); |
7213 | spin_unlock_irqrestore(&task_group_lock, flags); | 7223 | spin_unlock_irqrestore(&task_group_lock, flags); |
7214 | |||
7215 | /* wait for possible concurrent references to cfs_rqs complete */ | ||
7216 | call_rcu(&tg->rcu, free_sched_group_rcu); | ||
7217 | } | 7224 | } |
7218 | 7225 | ||
7219 | /* change task's runqueue when it moves between groups. | 7226 | /* change task's runqueue when it moves between groups. |
@@ -7584,6 +7591,19 @@ static struct cgroup_subsys_state *cpu_cgroup_css_alloc(struct cgroup *cgrp) | |||
7584 | return &tg->css; | 7591 | return &tg->css; |
7585 | } | 7592 | } |
7586 | 7593 | ||
7594 | static int cpu_cgroup_css_online(struct cgroup *cgrp) | ||
7595 | { | ||
7596 | struct task_group *tg = cgroup_tg(cgrp); | ||
7597 | struct task_group *parent; | ||
7598 | |||
7599 | if (!cgrp->parent) | ||
7600 | return 0; | ||
7601 | |||
7602 | parent = cgroup_tg(cgrp->parent); | ||
7603 | sched_online_group(tg, parent); | ||
7604 | return 0; | ||
7605 | } | ||
7606 | |||
7587 | static void cpu_cgroup_css_free(struct cgroup *cgrp) | 7607 | static void cpu_cgroup_css_free(struct cgroup *cgrp) |
7588 | { | 7608 | { |
7589 | struct task_group *tg = cgroup_tg(cgrp); | 7609 | struct task_group *tg = cgroup_tg(cgrp); |
@@ -7591,6 +7611,13 @@ static void cpu_cgroup_css_free(struct cgroup *cgrp) | |||
7591 | sched_destroy_group(tg); | 7611 | sched_destroy_group(tg); |
7592 | } | 7612 | } |
7593 | 7613 | ||
7614 | static void cpu_cgroup_css_offline(struct cgroup *cgrp) | ||
7615 | { | ||
7616 | struct task_group *tg = cgroup_tg(cgrp); | ||
7617 | |||
7618 | sched_offline_group(tg); | ||
7619 | } | ||
7620 | |||
7594 | static int cpu_cgroup_can_attach(struct cgroup *cgrp, | 7621 | static int cpu_cgroup_can_attach(struct cgroup *cgrp, |
7595 | struct cgroup_taskset *tset) | 7622 | struct cgroup_taskset *tset) |
7596 | { | 7623 | { |
@@ -7946,6 +7973,8 @@ struct cgroup_subsys cpu_cgroup_subsys = { | |||
7946 | .name = "cpu", | 7973 | .name = "cpu", |
7947 | .css_alloc = cpu_cgroup_css_alloc, | 7974 | .css_alloc = cpu_cgroup_css_alloc, |
7948 | .css_free = cpu_cgroup_css_free, | 7975 | .css_free = cpu_cgroup_css_free, |
7976 | .css_online = cpu_cgroup_css_online, | ||
7977 | .css_offline = cpu_cgroup_css_offline, | ||
7949 | .can_attach = cpu_cgroup_can_attach, | 7978 | .can_attach = cpu_cgroup_can_attach, |
7950 | .attach = cpu_cgroup_attach, | 7979 | .attach = cpu_cgroup_attach, |
7951 | .exit = cpu_cgroup_exit, | 7980 | .exit = cpu_cgroup_exit, |