* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util [not found] <1573570093-1340-1-git-send-email-vincent.guittot@linaro.org> @ 2019-11-12 15:05 ` Vincent Guittot 2019-11-12 17:11 ` Valentin Schneider 2019-11-13 10:49 ` Dietmar Eggemann 0 siblings, 2 replies; 9+ messages in thread From: Vincent Guittot @ 2019-11-12 15:05 UTC (permalink / raw) To: linux-kernel, mingo, peterz, dietmar.eggemann, juri.lelli, rostedt, mgorman, dsmythies Cc: linux-pm, torvalds, tglx, sargun, tj, xiexiuqi, xiezhipeng1, srinivas.pandruvada Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : > update_cfs_rq_load_avg() calls cfs_rq_util_change() everytime pelt decays, > which might be inefficient when cpufreq driver has rate limitation. > > When a task is attached on a CPU, we have call path: > > update_blocked_averages() > update_cfs_rq_load_avg() > cfs_rq_util_change -- > trig frequency update > attach_entity_load_avg() > cfs_rq_util_change -- > trig frequency update > > The 1st frequency update will not take into account the utilization of the > newly attached task and the 2nd one might be discard because of rate > limitation of the cpufreq driver. > > update_cfs_rq_load_avg() is only called by update_blocked_averages() > and update_load_avg() so we can move the call to > {cfs_rq,cpufreq}_util_change() into these 2 functions. It's also > interesting to notice that update_load_avg() already calls directly > cfs_rq_util_change() for !SMP case. > > This changes will also ensure that cpufreq_update_util() is called even > when there is no more CFS rq in the leaf_cfs_rq_list to update but only > irq, rt or dl pelt signals. > > Reported-by: Doug Smythies <dsmythies@telus.net> > Fixes: 039ae8bcf7a5 ("sched/fair: Fix O(nr_cgroups) in the load balancing path") > Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> > > --- > > I have just rebased the patch on latest tip/sched/core and made it a proper > patchset after Doug reported that the problem has diseappeared according to > his 1st results but tests results are not all based on the same v5.4-rcX > and with menu instead of teo governor. > > kernel/sched/fair.c | 33 +++++++++++++++++++++------------ > 1 file changed, 21 insertions(+), 12 deletions(-) > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c > index e458f52..c93d534 100644 > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -3508,9 +3508,6 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) > cfs_rq->load_last_update_time_copy = sa->last_update_time; > #endif > > - if (decayed) > - cfs_rq_util_change(cfs_rq, 0); > - > return decayed; > } > > @@ -3620,8 +3617,12 @@ static inline void update_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s > attach_entity_load_avg(cfs_rq, se, SCHED_CPUFREQ_MIGRATION); > update_tg_load_avg(cfs_rq, 0); > > - } else if (decayed && (flags & UPDATE_TG)) > - update_tg_load_avg(cfs_rq, 0); > + } else if (decayed) { > + cfs_rq_util_change(cfs_rq, 0); > + > + if (flags & UPDATE_TG) > + update_tg_load_avg(cfs_rq, 0); > + } > } > > #ifndef CONFIG_64BIT > @@ -7484,6 +7485,7 @@ static void update_blocked_averages(int cpu) > const struct sched_class *curr_class; > struct rq_flags rf; > bool done = true; > + int decayed = 0; > > rq_lock_irqsave(rq, &rf); > update_rq_clock(rq); > @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) > * that RT, DL and IRQ signals have been updated before updating CFS. > */ > curr_class = rq->curr->sched_class; > - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > - update_irq_load_avg(rq, 0); > + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > + decayed |= update_irq_load_avg(rq, 0); > > /* Don't need periodic decay once load/util_avg are null */ > if (others_have_blocked(rq)) > @@ -7529,6 +7531,9 @@ static void update_blocked_averages(int cpu) > } > > update_blocked_load_status(rq, !done); > + > + if (decayed) > + cpufreq_update_util(rq, 0); > rq_unlock_irqrestore(rq, &rf); > } > > @@ -7585,6 +7590,7 @@ static inline void update_blocked_averages(int cpu) > struct cfs_rq *cfs_rq = &rq->cfs; > const struct sched_class *curr_class; > struct rq_flags rf; > + int decayed = 0; > > rq_lock_irqsave(rq, &rf); > update_rq_clock(rq); > @@ -7594,13 +7600,16 @@ static inline void update_blocked_averages(int cpu) > * that RT, DL and IRQ signals have been updated before updating CFS. > */ > curr_class = rq->curr->sched_class; > - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > - update_irq_load_avg(rq, 0); > + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > + decayed |= update_irq_load_avg(rq, 0); > > - update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); > + decayed |= update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); > > update_blocked_load_status(rq, cfs_rq_has_blocked(cfs_rq) || others_have_blocked(rq)); > + > + if (decayed) > + cpufreq_update_util(rq, 0); > rq_unlock_irqrestore(rq, &rf); > } > > -- > 2.7.4 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-12 15:05 ` [PATCH v2] sched/freq: move call to cpufreq_update_util Vincent Guittot @ 2019-11-12 17:11 ` Valentin Schneider 2019-11-12 17:20 ` Vincent Guittot 2019-11-13 10:49 ` Dietmar Eggemann 1 sibling, 1 reply; 9+ messages in thread From: Valentin Schneider @ 2019-11-12 17:11 UTC (permalink / raw) To: Vincent Guittot, linux-kernel, mingo, peterz, dietmar.eggemann, juri.lelli, rostedt, mgorman, dsmythies Cc: linux-pm, torvalds, tglx, sargun, tj, xiexiuqi, xiezhipeng1, srinivas.pandruvada Hi Vincent, I didn't see anything in that reply, was that just a spurious email? On 12/11/2019 15:05, Vincent Guittot wrote: > Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : >> update_cfs_rq_load_avg() calls cfs_rq_util_change() everytime pelt decays, >> which might be inefficient when cpufreq driver has rate limitation. >> >> When a task is attached on a CPU, we have call path: >> >> update_blocked_averages() >> update_cfs_rq_load_avg() >> cfs_rq_util_change -- > trig frequency update >> attach_entity_load_avg() >> cfs_rq_util_change -- > trig frequency update >> >> The 1st frequency update will not take into account the utilization of the >> newly attached task and the 2nd one might be discard because of rate >> limitation of the cpufreq driver. >> >> update_cfs_rq_load_avg() is only called by update_blocked_averages() >> and update_load_avg() so we can move the call to >> {cfs_rq,cpufreq}_util_change() into these 2 functions. It's also >> interesting to notice that update_load_avg() already calls directly >> cfs_rq_util_change() for !SMP case. >> >> This changes will also ensure that cpufreq_update_util() is called even >> when there is no more CFS rq in the leaf_cfs_rq_list to update but only >> irq, rt or dl pelt signals. >> >> Reported-by: Doug Smythies <dsmythies@telus.net> >> Fixes: 039ae8bcf7a5 ("sched/fair: Fix O(nr_cgroups) in the load balancing path") >> Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> >> >> --- >> >> I have just rebased the patch on latest tip/sched/core and made it a proper >> patchset after Doug reported that the problem has diseappeared according to >> his 1st results but tests results are not all based on the same v5.4-rcX >> and with menu instead of teo governor. >> >> kernel/sched/fair.c | 33 +++++++++++++++++++++------------ >> 1 file changed, 21 insertions(+), 12 deletions(-) >> >> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c >> index e458f52..c93d534 100644 >> --- a/kernel/sched/fair.c >> +++ b/kernel/sched/fair.c >> @@ -3508,9 +3508,6 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) >> cfs_rq->load_last_update_time_copy = sa->last_update_time; >> #endif >> >> - if (decayed) >> - cfs_rq_util_change(cfs_rq, 0); >> - >> return decayed; >> } >> >> @@ -3620,8 +3617,12 @@ static inline void update_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s >> attach_entity_load_avg(cfs_rq, se, SCHED_CPUFREQ_MIGRATION); >> update_tg_load_avg(cfs_rq, 0); >> >> - } else if (decayed && (flags & UPDATE_TG)) >> - update_tg_load_avg(cfs_rq, 0); >> + } else if (decayed) { >> + cfs_rq_util_change(cfs_rq, 0); >> + >> + if (flags & UPDATE_TG) >> + update_tg_load_avg(cfs_rq, 0); >> + } >> } >> >> #ifndef CONFIG_64BIT >> @@ -7484,6 +7485,7 @@ static void update_blocked_averages(int cpu) >> const struct sched_class *curr_class; >> struct rq_flags rf; >> bool done = true; >> + int decayed = 0; >> >> rq_lock_irqsave(rq, &rf); >> update_rq_clock(rq); >> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) >> * that RT, DL and IRQ signals have been updated before updating CFS. >> */ >> curr_class = rq->curr->sched_class; >> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >> - update_irq_load_avg(rq, 0); >> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >> + decayed |= update_irq_load_avg(rq, 0); >> >> /* Don't need periodic decay once load/util_avg are null */ >> if (others_have_blocked(rq)) >> @@ -7529,6 +7531,9 @@ static void update_blocked_averages(int cpu) >> } >> >> update_blocked_load_status(rq, !done); >> + >> + if (decayed) >> + cpufreq_update_util(rq, 0); >> rq_unlock_irqrestore(rq, &rf); >> } >> >> @@ -7585,6 +7590,7 @@ static inline void update_blocked_averages(int cpu) >> struct cfs_rq *cfs_rq = &rq->cfs; >> const struct sched_class *curr_class; >> struct rq_flags rf; >> + int decayed = 0; >> >> rq_lock_irqsave(rq, &rf); >> update_rq_clock(rq); >> @@ -7594,13 +7600,16 @@ static inline void update_blocked_averages(int cpu) >> * that RT, DL and IRQ signals have been updated before updating CFS. >> */ >> curr_class = rq->curr->sched_class; >> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >> - update_irq_load_avg(rq, 0); >> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >> + decayed |= update_irq_load_avg(rq, 0); >> >> - update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); >> + decayed |= update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); >> >> update_blocked_load_status(rq, cfs_rq_has_blocked(cfs_rq) || others_have_blocked(rq)); >> + >> + if (decayed) >> + cpufreq_update_util(rq, 0); >> rq_unlock_irqrestore(rq, &rf); >> } >> >> -- >> 2.7.4 >> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-12 17:11 ` Valentin Schneider @ 2019-11-12 17:20 ` Vincent Guittot 2019-11-12 17:44 ` Valentin Schneider 0 siblings, 1 reply; 9+ messages in thread From: Vincent Guittot @ 2019-11-12 17:20 UTC (permalink / raw) To: Valentin Schneider Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Dietmar Eggemann, Juri Lelli, Steven Rostedt, Mel Gorman, Doug Smythies, open list:THERMAL, Linus Torvalds, Thomas Gleixner, Sargun Dhillon, Tejun Heo, Xie XiuQi, xiezhipeng1, Srinivas Pandruvada On Tue, 12 Nov 2019 at 18:11, Valentin Schneider <valentin.schneider@arm.com> wrote: > > Hi Vincent, > > I didn't see anything in that reply, was that just a spurious email? there were a typo in one email address in the 1st message > > On 12/11/2019 15:05, Vincent Guittot wrote: > > Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : > >> update_cfs_rq_load_avg() calls cfs_rq_util_change() everytime pelt decays, > >> which might be inefficient when cpufreq driver has rate limitation. > >> > >> When a task is attached on a CPU, we have call path: > >> > >> update_blocked_averages() > >> update_cfs_rq_load_avg() > >> cfs_rq_util_change -- > trig frequency update > >> attach_entity_load_avg() > >> cfs_rq_util_change -- > trig frequency update > >> > >> The 1st frequency update will not take into account the utilization of the > >> newly attached task and the 2nd one might be discard because of rate > >> limitation of the cpufreq driver. > >> > >> update_cfs_rq_load_avg() is only called by update_blocked_averages() > >> and update_load_avg() so we can move the call to > >> {cfs_rq,cpufreq}_util_change() into these 2 functions. It's also > >> interesting to notice that update_load_avg() already calls directly > >> cfs_rq_util_change() for !SMP case. > >> > >> This changes will also ensure that cpufreq_update_util() is called even > >> when there is no more CFS rq in the leaf_cfs_rq_list to update but only > >> irq, rt or dl pelt signals. > >> > >> Reported-by: Doug Smythies <dsmythies@telus.net> > >> Fixes: 039ae8bcf7a5 ("sched/fair: Fix O(nr_cgroups) in the load balancing path") > >> Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> > >> > >> --- > >> > >> I have just rebased the patch on latest tip/sched/core and made it a proper > >> patchset after Doug reported that the problem has diseappeared according to > >> his 1st results but tests results are not all based on the same v5.4-rcX > >> and with menu instead of teo governor. > >> > >> kernel/sched/fair.c | 33 +++++++++++++++++++++------------ > >> 1 file changed, 21 insertions(+), 12 deletions(-) > >> > >> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c > >> index e458f52..c93d534 100644 > >> --- a/kernel/sched/fair.c > >> +++ b/kernel/sched/fair.c > >> @@ -3508,9 +3508,6 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq) > >> cfs_rq->load_last_update_time_copy = sa->last_update_time; > >> #endif > >> > >> - if (decayed) > >> - cfs_rq_util_change(cfs_rq, 0); > >> - > >> return decayed; > >> } > >> > >> @@ -3620,8 +3617,12 @@ static inline void update_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s > >> attach_entity_load_avg(cfs_rq, se, SCHED_CPUFREQ_MIGRATION); > >> update_tg_load_avg(cfs_rq, 0); > >> > >> - } else if (decayed && (flags & UPDATE_TG)) > >> - update_tg_load_avg(cfs_rq, 0); > >> + } else if (decayed) { > >> + cfs_rq_util_change(cfs_rq, 0); > >> + > >> + if (flags & UPDATE_TG) > >> + update_tg_load_avg(cfs_rq, 0); > >> + } > >> } > >> > >> #ifndef CONFIG_64BIT > >> @@ -7484,6 +7485,7 @@ static void update_blocked_averages(int cpu) > >> const struct sched_class *curr_class; > >> struct rq_flags rf; > >> bool done = true; > >> + int decayed = 0; > >> > >> rq_lock_irqsave(rq, &rf); > >> update_rq_clock(rq); > >> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) > >> * that RT, DL and IRQ signals have been updated before updating CFS. > >> */ > >> curr_class = rq->curr->sched_class; > >> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >> - update_irq_load_avg(rq, 0); > >> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >> + decayed |= update_irq_load_avg(rq, 0); > >> > >> /* Don't need periodic decay once load/util_avg are null */ > >> if (others_have_blocked(rq)) > >> @@ -7529,6 +7531,9 @@ static void update_blocked_averages(int cpu) > >> } > >> > >> update_blocked_load_status(rq, !done); > >> + > >> + if (decayed) > >> + cpufreq_update_util(rq, 0); > >> rq_unlock_irqrestore(rq, &rf); > >> } > >> > >> @@ -7585,6 +7590,7 @@ static inline void update_blocked_averages(int cpu) > >> struct cfs_rq *cfs_rq = &rq->cfs; > >> const struct sched_class *curr_class; > >> struct rq_flags rf; > >> + int decayed = 0; > >> > >> rq_lock_irqsave(rq, &rf); > >> update_rq_clock(rq); > >> @@ -7594,13 +7600,16 @@ static inline void update_blocked_averages(int cpu) > >> * that RT, DL and IRQ signals have been updated before updating CFS. > >> */ > >> curr_class = rq->curr->sched_class; > >> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >> - update_irq_load_avg(rq, 0); > >> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >> + decayed |= update_irq_load_avg(rq, 0); > >> > >> - update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); > >> + decayed |= update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq); > >> > >> update_blocked_load_status(rq, cfs_rq_has_blocked(cfs_rq) || others_have_blocked(rq)); > >> + > >> + if (decayed) > >> + cpufreq_update_util(rq, 0); > >> rq_unlock_irqrestore(rq, &rf); > >> } > >> > >> -- > >> 2.7.4 > >> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-12 17:20 ` Vincent Guittot @ 2019-11-12 17:44 ` Valentin Schneider 0 siblings, 0 replies; 9+ messages in thread From: Valentin Schneider @ 2019-11-12 17:44 UTC (permalink / raw) To: Vincent Guittot Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Dietmar Eggemann, Juri Lelli, Steven Rostedt, Mel Gorman, Doug Smythies, open list:THERMAL, Linus Torvalds, Thomas Gleixner, Sargun Dhillon, Tejun Heo, Xie XiuQi, xiezhipeng1, Srinivas Pandruvada On 12/11/2019 17:20, Vincent Guittot wrote: >> I didn't see anything in that reply, was that just a spurious email? > > there were a typo in one email address in the 1st message Oh right, got it, sorry. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-12 15:05 ` [PATCH v2] sched/freq: move call to cpufreq_update_util Vincent Guittot 2019-11-12 17:11 ` Valentin Schneider @ 2019-11-13 10:49 ` Dietmar Eggemann 2019-11-13 13:30 ` Vincent Guittot 1 sibling, 1 reply; 9+ messages in thread From: Dietmar Eggemann @ 2019-11-13 10:49 UTC (permalink / raw) To: Vincent Guittot, linux-kernel, mingo, peterz, juri.lelli, rostedt, mgorman, dsmythies Cc: linux-pm, torvalds, tglx, sargun, tj, xiexiuqi, xiezhipeng1, srinivas.pandruvada On 12.11.19 16:05, Vincent Guittot wrote: > Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : >> update_cfs_rq_load_avg() calls cfs_rq_util_change() everytime pelt decays, >> which might be inefficient when cpufreq driver has rate limitation. >> >> When a task is attached on a CPU, we have call path: >> >> update_blocked_averages() >> update_cfs_rq_load_avg() >> cfs_rq_util_change -- > trig frequency update >> attach_entity_load_avg() >> cfs_rq_util_change -- > trig frequency update This looks like attach_entity_load_avg() is called from update_blocked_averages(). Do you refer to the attach_entity_load_avg() call from attach_entity_cfs_rq() or update_load_avg() here? I assume the former. >> The 1st frequency update will not take into account the utilization of the >> newly attached task and the 2nd one might be discard because of rate >> limitation of the cpufreq driver. >> >> update_cfs_rq_load_avg() is only called by update_blocked_averages() >> and update_load_avg() so we can move the call to >> {cfs_rq,cpufreq}_util_change() into these 2 functions. It's also s/cpufreq_util_change()/cpufreq_update_util() ? [...] >> I have just rebased the patch on latest tip/sched/core and made it a proper >> patchset after Doug reported that the problem has diseappeared according to >> his 1st results but tests results are not all based on the same v5.4-rcX >> and with menu instead of teo governor. I had some minor tweaks to do putting this on a0e813f26ebc ("sched/core: Further clarify sched_class::set_next_task()") ? I saw the '[tip: sched/urgent] sched/pelt: Fix update of blocked PELT ordering' tip-bot msg this morning though. [...] >> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) >> * that RT, DL and IRQ signals have been updated before updating CFS. >> */ >> curr_class = rq->curr->sched_class; >> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >> - update_irq_load_avg(rq, 0); >> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >> + decayed |= update_irq_load_avg(rq, 0); Why not 'decayed = update_cfs_rq_load_avg()' like in the !CONFIG_FAIR_GROUP_SCHED case? [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-13 10:49 ` Dietmar Eggemann @ 2019-11-13 13:30 ` Vincent Guittot 2019-11-13 14:09 ` Dietmar Eggemann 0 siblings, 1 reply; 9+ messages in thread From: Vincent Guittot @ 2019-11-13 13:30 UTC (permalink / raw) To: Dietmar Eggemann Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Juri Lelli, Steven Rostedt, Mel Gorman, Doug Smythies, open list:THERMAL, Linus Torvalds, Thomas Gleixner, Sargun Dhillon, Tejun Heo, Xie XiuQi, xiezhipeng1, Srinivas Pandruvada On Wed, 13 Nov 2019 at 11:50, Dietmar Eggemann <dietmar.eggemann@arm.com> wrote: > > On 12.11.19 16:05, Vincent Guittot wrote: > > Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : > >> update_cfs_rq_load_avg() calls cfs_rq_util_change() everytime pelt decays, > >> which might be inefficient when cpufreq driver has rate limitation. > >> > >> When a task is attached on a CPU, we have call path: > >> > >> update_blocked_averages() > >> update_cfs_rq_load_avg() > >> cfs_rq_util_change -- > trig frequency update > >> attach_entity_load_avg() > >> cfs_rq_util_change -- > trig frequency update > > This looks like attach_entity_load_avg() is called from > update_blocked_averages(). Do you refer to the attach_entity_load_avg() > call from attach_entity_cfs_rq() or update_load_avg() here? I assume the > former. ah... typo mistake, i wanted to write update_load_avg update_blocked_averages() update_cfs_rq_load_avg() cfs_rq_util_change -- > trig frequency update attach_entity_load_avg() cfs_rq_util_change -- > trig frequency update > > >> The 1st frequency update will not take into account the utilization of the > >> newly attached task and the 2nd one might be discard because of rate > >> limitation of the cpufreq driver. > >> > >> update_cfs_rq_load_avg() is only called by update_blocked_averages() > >> and update_load_avg() so we can move the call to > >> {cfs_rq,cpufreq}_util_change() into these 2 functions. It's also > > s/cpufreq_util_change()/cpufreq_update_util() ? yes > > [...] > > >> I have just rebased the patch on latest tip/sched/core and made it a proper > >> patchset after Doug reported that the problem has diseappeared according to > >> his 1st results but tests results are not all based on the same v5.4-rcX > >> and with menu instead of teo governor. > > I had some minor tweaks to do putting this on a0e813f26ebc ("sched/core: > Further clarify sched_class::set_next_task()") ? I saw the '[tip: > sched/urgent] sched/pelt: Fix update of blocked PELT ordering' tip-bot > msg this morning though. yes, a0e813f26ebc was item 1 and this patch is item 2 on top > > [...] > > >> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) > >> * that RT, DL and IRQ signals have been updated before updating CFS. > >> */ > >> curr_class = rq->curr->sched_class; > >> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >> - update_irq_load_avg(rq, 0); > >> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >> + decayed |= update_irq_load_avg(rq, 0); > > Why not 'decayed = update_cfs_rq_load_avg()' like in the > !CONFIG_FAIR_GROUP_SCHED case? Because it is handled by the update_load_avg() in for_each_leaf_cfs_rq_safe() loop This means that we can have 2 calls to cpufreq_update_util in update_blocked_average() but at least the values will be up to date in both calls unlike previously. I'm going to prepare an additional patch to remove this useless call. I have also seen some possible further optimization that i need to study a bit more before preparing a patch > > [...] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-13 13:30 ` Vincent Guittot @ 2019-11-13 14:09 ` Dietmar Eggemann 2019-11-13 17:50 ` Vincent Guittot 0 siblings, 1 reply; 9+ messages in thread From: Dietmar Eggemann @ 2019-11-13 14:09 UTC (permalink / raw) To: Vincent Guittot Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Juri Lelli, Steven Rostedt, Mel Gorman, Doug Smythies, open list:THERMAL, Linus Torvalds, Thomas Gleixner, Sargun Dhillon, Tejun Heo, Xie XiuQi, xiezhipeng1, Srinivas Pandruvada On 13.11.19 14:30, Vincent Guittot wrote: > On Wed, 13 Nov 2019 at 11:50, Dietmar Eggemann <dietmar.eggemann@arm.com> wrote: >> >> On 12.11.19 16:05, Vincent Guittot wrote: >>> Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : [...] >>>> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) >>>> * that RT, DL and IRQ signals have been updated before updating CFS. >>>> */ >>>> curr_class = rq->curr->sched_class; >>>> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >>>> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >>>> - update_irq_load_avg(rq, 0); >>>> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); >>>> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); >>>> + decayed |= update_irq_load_avg(rq, 0); >> >> Why not 'decayed = update_cfs_rq_load_avg()' like in the >> !CONFIG_FAIR_GROUP_SCHED case? > > Because it is handled by the update_load_avg() in > for_each_leaf_cfs_rq_safe() loop > > This means that we can have 2 calls to cpufreq_update_util in > update_blocked_average() but at least the values will be up to date in > both calls unlike previously. > > I'm going to prepare an additional patch to remove this useless call. > I have also seen some possible further optimization that i need to > study a bit more before preparing a patch I see. The update_load_avg() call for the taskgroup skeleton se (cfs_rq->tg->se[cpu]). But what happens to the cpu which only has the root cfs_rq i the list? It doesn't have a skeleton se. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-13 14:09 ` Dietmar Eggemann @ 2019-11-13 17:50 ` Vincent Guittot 2019-11-13 18:09 ` Vincent Guittot 0 siblings, 1 reply; 9+ messages in thread From: Vincent Guittot @ 2019-11-13 17:50 UTC (permalink / raw) To: Dietmar Eggemann Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Juri Lelli, Steven Rostedt, Mel Gorman, Doug Smythies, open list:THERMAL, Linus Torvalds, Thomas Gleixner, Sargun Dhillon, Tejun Heo, Xie XiuQi, xiezhipeng1, Srinivas Pandruvada Le Wednesday 13 Nov 2019 à 15:09:47 (+0100), Dietmar Eggemann a écrit : > On 13.11.19 14:30, Vincent Guittot wrote: > > On Wed, 13 Nov 2019 at 11:50, Dietmar Eggemann <dietmar.eggemann@arm.com> wrote: > >> > >> On 12.11.19 16:05, Vincent Guittot wrote: > >>> Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : > > [...] > > >>>> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) > >>>> * that RT, DL and IRQ signals have been updated before updating CFS. > >>>> */ > >>>> curr_class = rq->curr->sched_class; > >>>> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >>>> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >>>> - update_irq_load_avg(rq, 0); > >>>> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > >>>> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > >>>> + decayed |= update_irq_load_avg(rq, 0); > >> > >> Why not 'decayed = update_cfs_rq_load_avg()' like in the > >> !CONFIG_FAIR_GROUP_SCHED case? > > > > Because it is handled by the update_load_avg() in > > for_each_leaf_cfs_rq_safe() loop > > > > This means that we can have 2 calls to cpufreq_update_util in > > update_blocked_average() but at least the values will be up to date in > > both calls unlike previously. > > > > I'm going to prepare an additional patch to remove this useless call. > > I have also seen some possible further optimization that i need to > > study a bit more before preparing a patch > > I see. The update_load_avg() call for the taskgroup skeleton se > (cfs_rq->tg->se[cpu]). But what happens to the cpu which only has the > root cfs_rq i the list? It doesn't have a skeleton se. you're right. I have to add the following to make sure it will be called diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 2eb1aa8..9fc077c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7604,9 +7604,13 @@ static void update_blocked_averages(int cpu) cpu, cfs_rq == &rq->cfs ? 0 : (long)cfs_rq->tg ); - if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) + if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) { update_tg_load_avg(cfs_rq, 0); + if (cfs_rq == &rq->cfs) + decayed = 1; + } + trace_sched_load_contrib_blocked(cpu, &cfs_rq->avg, cfs_rq == &rq->cfs ? 0 : (long)cfs_rq->tg ); ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] sched/freq: move call to cpufreq_update_util 2019-11-13 17:50 ` Vincent Guittot @ 2019-11-13 18:09 ` Vincent Guittot 0 siblings, 0 replies; 9+ messages in thread From: Vincent Guittot @ 2019-11-13 18:09 UTC (permalink / raw) To: Dietmar Eggemann Cc: linux-kernel, Ingo Molnar, Peter Zijlstra, Juri Lelli, Steven Rostedt, Mel Gorman, Doug Smythies, open list:THERMAL, Linus Torvalds, Thomas Gleixner, Sargun Dhillon, Tejun Heo, Xie XiuQi, xiezhipeng1, Srinivas Pandruvada Le Wednesday 13 Nov 2019 à 18:50:35 (+0100), Vincent Guittot a écrit : > Le Wednesday 13 Nov 2019 à 15:09:47 (+0100), Dietmar Eggemann a écrit : > > On 13.11.19 14:30, Vincent Guittot wrote: > > > On Wed, 13 Nov 2019 at 11:50, Dietmar Eggemann <dietmar.eggemann@arm.com> wrote: > > >> > > >> On 12.11.19 16:05, Vincent Guittot wrote: > > >>> Le Tuesday 12 Nov 2019 à 15:48:13 (+0100), Vincent Guittot a écrit : > > > > [...] > > > > >>>> @@ -7493,9 +7495,9 @@ static void update_blocked_averages(int cpu) > > >>>> * that RT, DL and IRQ signals have been updated before updating CFS. > > >>>> */ > > >>>> curr_class = rq->curr->sched_class; > > >>>> - update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > > >>>> - update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > > >>>> - update_irq_load_avg(rq, 0); > > >>>> + decayed |= update_rt_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &rt_sched_class); > > >>>> + decayed |= update_dl_rq_load_avg(rq_clock_pelt(rq), rq, curr_class == &dl_sched_class); > > >>>> + decayed |= update_irq_load_avg(rq, 0); > > >> > > >> Why not 'decayed = update_cfs_rq_load_avg()' like in the > > >> !CONFIG_FAIR_GROUP_SCHED case? > > > > > > Because it is handled by the update_load_avg() in > > > for_each_leaf_cfs_rq_safe() loop > > > > > > This means that we can have 2 calls to cpufreq_update_util in > > > update_blocked_average() but at least the values will be up to date in > > > both calls unlike previously. > > > > > > I'm going to prepare an additional patch to remove this useless call. > > > I have also seen some possible further optimization that i need to > > > study a bit more before preparing a patch > > > > I see. The update_load_avg() call for the taskgroup skeleton se > > (cfs_rq->tg->se[cpu]). But what happens to the cpu which only has the > > root cfs_rq i the list? It doesn't have a skeleton se. > > you're right. I have to add the following to make sure it will be called > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c > index 2eb1aa8..9fc077c 100644 > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -7604,9 +7604,13 @@ static void update_blocked_averages(int cpu) > cpu, > cfs_rq == &rq->cfs ? 0 : (long)cfs_rq->tg ); > > - if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) > + if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) { > update_tg_load_avg(cfs_rq, 0); > > + if (cfs_rq == &rq->cfs) > + decayed = 1; > + } > + > trace_sched_load_contrib_blocked(cpu, > &cfs_rq->avg, > cfs_rq == &rq->cfs ? 0 : (long)cfs_rq->tg ); the proper fix without some debug trace events :-) @@ -7567,9 +7569,13 @@ static void update_blocked_averages(int cpu) for_each_leaf_cfs_rq_safe(rq, cfs_rq, pos) { struct sched_entity *se; - if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) + if (update_cfs_rq_load_avg(cfs_rq_clock_pelt(cfs_rq), cfs_rq)) { update_tg_load_avg(cfs_rq, 0); + if (cfs_rq == &rq->cfs) + decayed = 1; + } + /* Propagate pending load changes to the parent, if any: */ se = cfs_rq->tg->se[cpu]; if (se && !skip_blocked_update(se)) > > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2019-11-13 18:09 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <1573570093-1340-1-git-send-email-vincent.guittot@linaro.org> 2019-11-12 15:05 ` [PATCH v2] sched/freq: move call to cpufreq_update_util Vincent Guittot 2019-11-12 17:11 ` Valentin Schneider 2019-11-12 17:20 ` Vincent Guittot 2019-11-12 17:44 ` Valentin Schneider 2019-11-13 10:49 ` Dietmar Eggemann 2019-11-13 13:30 ` Vincent Guittot 2019-11-13 14:09 ` Dietmar Eggemann 2019-11-13 17:50 ` Vincent Guittot 2019-11-13 18:09 ` Vincent Guittot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).