sched/fair: Reorder cgroup creation code
authorPeter Zijlstra <peterz@infradead.org>
Wed, 22 Jun 2016 12:58:02 +0000 (14:58 +0200)
committerIngo Molnar <mingo@kernel.org>
Mon, 27 Jun 2016 10:17:55 +0000 (12:17 +0200)
A future patch needs rq->lock held _after_ we link the task_group into
the hierarchy. In order to avoid taking every rq->lock twice, reorder
things a little and create online_fair_sched_group() to be called
after we link the task_group.

All this code is still ran from css_alloc() so css_online() isn't in
fact used for this.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: bsegall@google.com
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
kernel/sched/core.c
kernel/sched/fair.c
kernel/sched/sched.h

index 14afa518948c95e162bbdfeb09e22bc8c448c401..4ede4fc65653c2f5d60b6b789d3639f4e9cc633a 100644 (file)
@@ -7717,6 +7717,8 @@ void sched_online_group(struct task_group *tg, struct task_group *parent)
        INIT_LIST_HEAD(&tg->children);
        list_add_rcu(&tg->siblings, &parent->children);
        spin_unlock_irqrestore(&task_group_lock, flags);
+
+       online_fair_sched_group(tg);
 }
 
 /* rcu callback to free various structures associated with a task group */
index 781788d547364cfb1b0ecb772609269b0bb66d95..62d5e7dcc7f821949fddbaf4cf1a3b6878e01270 100644 (file)
@@ -8624,10 +8624,6 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
                init_cfs_rq(cfs_rq);
                init_tg_cfs_entry(tg, cfs_rq, se, i, parent->se[i]);
                init_entity_runnable_average(se);
-
-               raw_spin_lock_irq(&rq->lock);
-               post_init_entity_util_avg(se);
-               raw_spin_unlock_irq(&rq->lock);
        }
 
        return 1;
@@ -8638,6 +8634,22 @@ err:
        return 0;
 }
 
+void online_fair_sched_group(struct task_group *tg)
+{
+       struct sched_entity *se;
+       struct rq *rq;
+       int i;
+
+       for_each_possible_cpu(i) {
+               rq = cpu_rq(i);
+               se = tg->se[i];
+
+               raw_spin_lock_irq(&rq->lock);
+               post_init_entity_util_avg(se);
+               raw_spin_unlock_irq(&rq->lock);
+       }
+}
+
 void unregister_fair_sched_group(struct task_group *tg)
 {
        unsigned long flags;
@@ -8742,6 +8754,8 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
        return 1;
 }
 
+void online_fair_sched_group(struct task_group *tg) { }
+
 void unregister_fair_sched_group(struct task_group *tg) { }
 
 #endif /* CONFIG_FAIR_GROUP_SCHED */
index 307bd04180951ac0aa34ef480fed86191fa5a6f2..28c42b789f700f31aea16569d28343ccdd348062 100644 (file)
@@ -321,6 +321,7 @@ extern int tg_nop(struct task_group *tg, void *data);
 
 extern void free_fair_sched_group(struct task_group *tg);
 extern int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent);
+extern void online_fair_sched_group(struct task_group *tg);
 extern void unregister_fair_sched_group(struct task_group *tg);
 extern void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
                        struct sched_entity *se, int cpu,