aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r--kernel/sched/core.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 257002c13bb0..106167243d68 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7159,7 +7159,6 @@ static void free_sched_group(struct task_group *tg)
7159struct task_group *sched_create_group(struct task_group *parent) 7159struct task_group *sched_create_group(struct task_group *parent)
7160{ 7160{
7161 struct task_group *tg; 7161 struct task_group *tg;
7162 unsigned long flags;
7163 7162
7164 tg = kzalloc(sizeof(*tg), GFP_KERNEL); 7163 tg = kzalloc(sizeof(*tg), GFP_KERNEL);
7165 if (!tg) 7164 if (!tg)
@@ -7171,6 +7170,17 @@ struct task_group *sched_create_group(struct task_group *parent)
7171 if (!alloc_rt_sched_group(tg, parent)) 7170 if (!alloc_rt_sched_group(tg, parent))
7172 goto err; 7171 goto err;
7173 7172
7173 return tg;
7174
7175err:
7176 free_sched_group(tg);
7177 return ERR_PTR(-ENOMEM);
7178}
7179
7180void sched_online_group(struct task_group *tg, struct task_group *parent)
7181{
7182 unsigned long flags;
7183
7174 spin_lock_irqsave(&task_group_lock, flags); 7184 spin_lock_irqsave(&task_group_lock, flags);
7175 list_add_rcu(&tg->list, &task_groups); 7185 list_add_rcu(&tg->list, &task_groups);
7176 7186
@@ -7180,12 +7190,6 @@ struct task_group *sched_create_group(struct task_group *parent)
7180 INIT_LIST_HEAD(&tg->children); 7190 INIT_LIST_HEAD(&tg->children);
7181 list_add_rcu(&tg->siblings, &parent->children); 7191 list_add_rcu(&tg->siblings, &parent->children);
7182 spin_unlock_irqrestore(&task_group_lock, flags); 7192 spin_unlock_irqrestore(&task_group_lock, flags);
7183
7184 return tg;
7185
7186err:
7187 free_sched_group(tg);
7188 return ERR_PTR(-ENOMEM);
7189} 7193}
7190 7194
7191/* rcu callback to free various structures associated with a task group */ 7195/* rcu callback to free various structures associated with a task group */
@@ -7198,6 +7202,12 @@ static void free_sched_group_rcu(struct rcu_head *rhp)
7198/* Destroy runqueue etc associated with a task group */ 7202/* Destroy runqueue etc associated with a task group */
7199void sched_destroy_group(struct task_group *tg) 7203void sched_destroy_group(struct task_group *tg)
7200{ 7204{
7205 /* wait for possible concurrent references to cfs_rqs complete */
7206 call_rcu(&tg->rcu, free_sched_group_rcu);
7207}
7208
7209void sched_offline_group(struct task_group *tg)
7210{
7201 unsigned long flags; 7211 unsigned long flags;
7202 int i; 7212 int i;
7203 7213
@@ -7209,9 +7219,6 @@ void sched_destroy_group(struct task_group *tg)
7209 list_del_rcu(&tg->list); 7219 list_del_rcu(&tg->list);
7210 list_del_rcu(&tg->siblings); 7220 list_del_rcu(&tg->siblings);
7211 spin_unlock_irqrestore(&task_group_lock, flags); 7221 spin_unlock_irqrestore(&task_group_lock, flags);
7212
7213 /* wait for possible concurrent references to cfs_rqs complete */
7214 call_rcu(&tg->rcu, free_sched_group_rcu);
7215} 7222}
7216 7223
7217/* change task's runqueue when it moves between groups. 7224/* change task's runqueue when it moves between groups.
@@ -7563,6 +7570,19 @@ static struct cgroup_subsys_state *cpu_cgroup_css_alloc(struct cgroup *cgrp)
7563 return &tg->css; 7570 return &tg->css;
7564} 7571}
7565 7572
7573static int cpu_cgroup_css_online(struct cgroup *cgrp)
7574{
7575 struct task_group *tg = cgroup_tg(cgrp);
7576 struct task_group *parent;
7577
7578 if (!cgrp->parent)
7579 return 0;
7580
7581 parent = cgroup_tg(cgrp->parent);
7582 sched_online_group(tg, parent);
7583 return 0;
7584}
7585
7566static void cpu_cgroup_css_free(struct cgroup *cgrp) 7586static void cpu_cgroup_css_free(struct cgroup *cgrp)
7567{ 7587{
7568 struct task_group *tg = cgroup_tg(cgrp); 7588 struct task_group *tg = cgroup_tg(cgrp);
@@ -7570,6 +7590,13 @@ static void cpu_cgroup_css_free(struct cgroup *cgrp)
7570 sched_destroy_group(tg); 7590 sched_destroy_group(tg);
7571} 7591}
7572 7592
7593static void cpu_cgroup_css_offline(struct cgroup *cgrp)
7594{
7595 struct task_group *tg = cgroup_tg(cgrp);
7596
7597 sched_offline_group(tg);
7598}
7599
7573static int cpu_cgroup_can_attach(struct cgroup *cgrp, 7600static int cpu_cgroup_can_attach(struct cgroup *cgrp,
7574 struct cgroup_taskset *tset) 7601 struct cgroup_taskset *tset)
7575{ 7602{
@@ -7925,6 +7952,8 @@ struct cgroup_subsys cpu_cgroup_subsys = {
7925 .name = "cpu", 7952 .name = "cpu",
7926 .css_alloc = cpu_cgroup_css_alloc, 7953 .css_alloc = cpu_cgroup_css_alloc,
7927 .css_free = cpu_cgroup_css_free, 7954 .css_free = cpu_cgroup_css_free,
7955 .css_online = cpu_cgroup_css_online,
7956 .css_offline = cpu_cgroup_css_offline,
7928 .can_attach = cpu_cgroup_can_attach, 7957 .can_attach = cpu_cgroup_can_attach,
7929 .attach = cpu_cgroup_attach, 7958 .attach = cpu_cgroup_attach,
7930 .exit = cpu_cgroup_exit, 7959 .exit = cpu_cgroup_exit,