diff options
author | Frode Isaksen <fisaksen@baylibre.com> | 2017-12-19 11:15:35 +0000 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2018-02-07 11:47:29 +0000 |
commit | c4a6287185179732dfc1e903c195ff90c19f1065 (patch) | |
tree | d35f5010dbd952e40f5c178322026445b55757c1 /meta-eas/recipes-kernel/linux/linux-renesas/0008-sched-fair-Fix-hierarchical-order-in-rq-leaf_cfs_rq_.patch | |
parent | 109dea1d5c5a38807b098b588584636ae636a302 (diff) |
This layer provides Energy Aware Scheduling (EAS) patcheseel_5.1.0eel_5.0.3eel_5.0.2eel/5.1.0eel/5.0.3eel/5.0.25.1.05.0.35.0.2eel
For the moment only for Renesas R-Car Gen3 SoC's.
Can be expanded for other SoC's by setting the machine
feature biglittle and provide the relevant EAS patches.
Bug-AGL: SPEC-813
Change-Id: I2b5e69c515c33e57be19b30466fe208d7b8ac1a5
Signed-off-by: Frode Isaksen <fisaksen@baylibre.com>
Diffstat (limited to 'meta-eas/recipes-kernel/linux/linux-renesas/0008-sched-fair-Fix-hierarchical-order-in-rq-leaf_cfs_rq_.patch')
-rw-r--r-- | meta-eas/recipes-kernel/linux/linux-renesas/0008-sched-fair-Fix-hierarchical-order-in-rq-leaf_cfs_rq_.patch | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/meta-eas/recipes-kernel/linux/linux-renesas/0008-sched-fair-Fix-hierarchical-order-in-rq-leaf_cfs_rq_.patch b/meta-eas/recipes-kernel/linux/linux-renesas/0008-sched-fair-Fix-hierarchical-order-in-rq-leaf_cfs_rq_.patch new file mode 100644 index 0000000..323a48f --- /dev/null +++ b/meta-eas/recipes-kernel/linux/linux-renesas/0008-sched-fair-Fix-hierarchical-order-in-rq-leaf_cfs_rq_.patch @@ -0,0 +1,171 @@ +From b351fc19a07fde281957aeb737cd32392c7bf5ba Mon Sep 17 00:00:00 2001 +From: Vincent Guittot <vincent.guittot@linaro.org> +Date: Tue, 8 Nov 2016 10:53:43 +0100 +Subject: [PATCH 08/92] sched/fair: Fix hierarchical order in + rq->leaf_cfs_rq_list + +Fix the insertion of cfs_rq in rq->leaf_cfs_rq_list to ensure that a +child will always be called before its parent. + +The hierarchical order in shares update list has been introduced by +commit: + + 67e86250f8ea ("sched: Introduce hierarchal order on shares update list") + +With the current implementation a child can be still put after its +parent. + +Lets take the example of: + + root + \ + b + /\ + c d* + | + e* + +with root -> b -> c already enqueued but not d -> e so the +leaf_cfs_rq_list looks like: head -> c -> b -> root -> tail + +The branch d -> e will be added the first time that they are enqueued, +starting with e then d. + +When e is added, its parents is not already on the list so e is put at +the tail : head -> c -> b -> root -> e -> tail + +Then, d is added at the head because its parent is already on the +list: head -> d -> c -> b -> root -> e -> tail + +e is not placed at the right position and will be called the last +whereas it should be called at the beginning. + +Because it follows the bottom-up enqueue sequence, we are sure that we +will finished to add either a cfs_rq without parent or a cfs_rq with a +parent that is already on the list. We can use this event to detect +when we have finished to add a new branch. For the others, whose +parents are not already added, we have to ensure that they will be +added after their children that have just been inserted the steps +before, and after any potential parents that are already in the list. +The easiest way is to put the cfs_rq just after the last inserted one +and to keep track of it untl the branch is fully added. + +Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Acked-by: Dietmar Eggemann <dietmar.eggemann@arm.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Morten.Rasmussen@arm.com +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: bsegall@google.com +Cc: kernellwp@gmail.com +Cc: pjt@google.com +Cc: yuyang.du@intel.com +Link: http://lkml.kernel.org/r/1478598827-32372-3-git-send-email-vincent.guittot@linaro.org +Signed-off-by: Ingo Molnar <mingo@kernel.org> +(cherry picked from commit 9c2791f936ef5fd04a118b5c284f2c9a95f4a647) +Signed-off-by: Gaku Inami <gaku.inami.xw@bp.renesas.com> +--- + kernel/sched/core.c | 1 + + kernel/sched/fair.c | 54 +++++++++++++++++++++++++++++++++++++++++++++------- + kernel/sched/sched.h | 1 + + 3 files changed, 49 insertions(+), 7 deletions(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index e891e12..391d6c9 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -7603,6 +7603,7 @@ void __init sched_init(void) + #ifdef CONFIG_FAIR_GROUP_SCHED + root_task_group.shares = ROOT_TASK_GROUP_LOAD; + INIT_LIST_HEAD(&rq->leaf_cfs_rq_list); ++ rq->tmp_alone_branch = &rq->leaf_cfs_rq_list; + /* + * How much cpu bandwidth does root_task_group get? + * +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 0731aff..4a67026 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -283,19 +283,59 @@ static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp) + static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) + { + if (!cfs_rq->on_list) { ++ struct rq *rq = rq_of(cfs_rq); ++ int cpu = cpu_of(rq); + /* + * Ensure we either appear before our parent (if already + * enqueued) or force our parent to appear after us when it is +- * enqueued. The fact that we always enqueue bottom-up +- * reduces this to two cases. ++ * enqueued. The fact that we always enqueue bottom-up ++ * reduces this to two cases and a special case for the root ++ * cfs_rq. Furthermore, it also means that we will always reset ++ * tmp_alone_branch either when the branch is connected ++ * to a tree or when we reach the beg of the tree + */ + if (cfs_rq->tg->parent && +- cfs_rq->tg->parent->cfs_rq[cpu_of(rq_of(cfs_rq))]->on_list) { +- list_add_rcu(&cfs_rq->leaf_cfs_rq_list, +- &rq_of(cfs_rq)->leaf_cfs_rq_list); +- } else { ++ cfs_rq->tg->parent->cfs_rq[cpu]->on_list) { ++ /* ++ * If parent is already on the list, we add the child ++ * just before. Thanks to circular linked property of ++ * the list, this means to put the child at the tail ++ * of the list that starts by parent. ++ */ ++ list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, ++ &(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list)); ++ /* ++ * The branch is now connected to its tree so we can ++ * reset tmp_alone_branch to the beginning of the ++ * list. ++ */ ++ rq->tmp_alone_branch = &rq->leaf_cfs_rq_list; ++ } else if (!cfs_rq->tg->parent) { ++ /* ++ * cfs rq without parent should be put ++ * at the tail of the list. ++ */ + list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, +- &rq_of(cfs_rq)->leaf_cfs_rq_list); ++ &rq->leaf_cfs_rq_list); ++ /* ++ * We have reach the beg of a tree so we can reset ++ * tmp_alone_branch to the beginning of the list. ++ */ ++ rq->tmp_alone_branch = &rq->leaf_cfs_rq_list; ++ } else { ++ /* ++ * The parent has not already been added so we want to ++ * make sure that it will be put after us. ++ * tmp_alone_branch points to the beg of the branch ++ * where we will add parent. ++ */ ++ list_add_rcu(&cfs_rq->leaf_cfs_rq_list, ++ rq->tmp_alone_branch); ++ /* ++ * update tmp_alone_branch to points to the new beg ++ * of the branch ++ */ ++ rq->tmp_alone_branch = &cfs_rq->leaf_cfs_rq_list; + } + + cfs_rq->on_list = 1; +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index 345c1cc..36f30e0 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -623,6 +623,7 @@ struct rq { + #ifdef CONFIG_FAIR_GROUP_SCHED + /* list of leaf cfs_rq on this cpu: */ + struct list_head leaf_cfs_rq_list; ++ struct list_head *tmp_alone_branch; + #endif /* CONFIG_FAIR_GROUP_SCHED */ + + /* +-- +1.9.1 + |