Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1703998 > unrolled thread
| Started by | Vincent Guittot <vincent.guittot@linaro.org> |
|---|---|
| First post | 2017-08-04 15:50 +0200 |
| Last post | 2017-08-08 16:10 +0200 |
| Articles | 6 — 2 participants |
Back to article view | Back to linux.kernel
[RESEND PATCH v2 0/2] sched/rt: track rt rq utilization Vincent Guittot <vincent.guittot@linaro.org> - 2017-08-04 15:50 +0200
[RESEND PATCH v2 2/2] cpufreq/schedutil: add rt utilization tracking Vincent Guittot <vincent.guittot@linaro.org> - 2017-08-04 15:50 +0200
[RESEND PATCH v2 1/2] sched/rt: add utilization tracking Vincent Guittot <vincent.guittot@linaro.org> - 2017-08-04 15:50 +0200
Re: [RESEND PATCH v2 1/2] sched/rt: add utilization tracking Peter Zijlstra <peterz@infradead.org> - 2017-08-07 18:50 +0200
Re: [RESEND PATCH v2 1/2] sched/rt: add utilization tracking Vincent Guittot <vincent.guittot@linaro.org> - 2017-08-08 16:00 +0200
Re: [RESEND PATCH v2 1/2] sched/rt: add utilization tracking Peter Zijlstra <peterz@infradead.org> - 2017-08-08 16:10 +0200
| From | Vincent Guittot <vincent.guittot@linaro.org> |
|---|---|
| Date | 2017-08-04 15:50 +0200 |
| Subject | [RESEND PATCH v2 0/2] sched/rt: track rt rq utilization |
| Message-ID | <uaL9f-7DN-11@gated-at.bofh.it> |
When both cfs and rt tasks compete to run on a CPU, we can see some frequency drops with schedutil governor. In such case, the cfs_rq's utilization doesn't reflect anymore the utilization of cfs tasks but only the remaining part that is not used by rt tasks. We should monitor the stolen utilization and take it into account when selecting OPP. Patch 1 tracks utilization of rt_rq. Patch 2 adds the rt_rq's utilization when selection OPP for cfs tasks This patchset doesn't change the OPP selection policy for RT tasks Change since v1: - Only a rebase. I have addressed the comments on previous version in patch 1/2 Vincent Guittot (2): sched/rt: add utilization tracking cpufreq/schedutil: add rt utilization tracking kernel/sched/cpufreq_schedutil.c | 2 +- kernel/sched/fair.c | 21 +++++++++++++++++++++ kernel/sched/rt.c | 9 +++++++++ kernel/sched/sched.h | 3 +++ 4 files changed, 34 insertions(+), 1 deletion(-) -- 2.7.4
[toc] | [next] | [standalone]
| From | Vincent Guittot <vincent.guittot@linaro.org> |
|---|---|
| Date | 2017-08-04 15:50 +0200 |
| Subject | [RESEND PATCH v2 2/2] cpufreq/schedutil: add rt utilization tracking |
| Message-ID | <uaL9g-7DN-23@gated-at.bofh.it> |
| In reply to | #1703998 |
Add both cfs and rt utilization when selecting an OPP as rt can preempt and steal cfs's running time. Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org> --- kernel/sched/cpufreq_schedutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 076a2e3..04fabea 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -161,7 +161,7 @@ static void sugov_get_util(unsigned long *util, unsigned long *max) cfs_max = arch_scale_cpu_capacity(NULL, smp_processor_id()); - *util = min(rq->cfs.avg.util_avg, cfs_max); + *util = min(rq->cfs.avg.util_avg + rq->rt.avg.util_avg, cfs_max); *max = cfs_max; } -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Vincent Guittot <vincent.guittot@linaro.org> |
|---|---|
| Date | 2017-08-04 15:50 +0200 |
| Subject | [RESEND PATCH v2 1/2] sched/rt: add utilization tracking |
| Message-ID | <uaL9g-7DN-21@gated-at.bofh.it> |
| In reply to | #1703998 |
schedutil governor relies on cfs_rq's util_avg to choose the OPP when cfs
tasks are running. When the CPU is overloaded by cfs and rt tasks, cfs tasks
are preempted by rt tasks and in this case util_avg reflects the remaining
capacity that is used by cfs tasks but not what cfs tasks want to use. In such
case, schedutil can select a lower OPP when cfs task runs whereas the CPU is
overloaded. In order to have a more accurate view of the utilization of the
CPU, we track the utilization that is used by RT tasks.
DL tasks are not taken into account as they have their own utilization
tracking mecanism.
We don't use rt_avg which doesn't have the same dynamic as PELT and which
can include IRQ time.
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
---
Change since v1:
- rebase on tip/sched/core
There were several comments on v1:
- As raised by Peter for v1, if IRQ time is taken into account in
rt_avg, it will not be accounted in rq->clock_task. This means that cfs
utilization is not affected by some extra contributions or decays
because of IRQ.
- Regading the sync of rt and cfs utilization, both cfs and rt use the same
rq->clock_task. Then, we have the same issue than cfs regarding blocked value.
The utilization of idle cfs/rt rqs are not updated regularly but only when a
load_balance is triggered (more precisely a call to update_blocked_average).
I'd like to fix this issue for both cfs and rt with a separate patch that
will ensure that utilization (and load) are updated regularly even for
idle CPUs
- One last open question is the location of rt utilization function in fair.c
file. PELT related funtions should probably move in a dedicated pelt.c file.
This would also help to address one comment about having a place to update
metrics of NOHZ idle CPUs. Thought ?
kernel/sched/fair.c | 21 +++++++++++++++++++++
kernel/sched/rt.c | 9 +++++++++
kernel/sched/sched.h | 3 +++
3 files changed, 33 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 008c514..50fe0a2 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3012,6 +3012,17 @@ __update_load_avg_cfs_rq(u64 now, int cpu, struct cfs_rq *cfs_rq)
cfs_rq->curr != NULL, cfs_rq);
}
+int update_rt_rq_load_avg(u64 now, int cpu, struct rt_rq *rt_rq, int running)
+{
+ int ret;
+
+ ret = ___update_load_avg(now, cpu, &rt_rq->avg, 0, running, NULL);
+
+
+ return ret;
+}
+
+
/*
* Signed add and clamp on underflow.
*
@@ -3539,6 +3550,11 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq)
return 0;
}
+int update_rt_rq_load_avg(u64 now, int cpu, struct rt_rq *rt_rq, int running)
+{
+ return 0;
+}
+
#define UPDATE_TG 0x0
#define SKIP_AGE_LOAD 0x0
@@ -6932,6 +6948,10 @@ static void update_blocked_averages(int cpu)
if (cfs_rq_is_decayed(cfs_rq))
list_del_leaf_cfs_rq(cfs_rq);
}
+
+ update_rt_rq_load_avg(rq_clock_task(rq), cpu, &rq->rt, 0);
+
+
rq_unlock_irqrestore(rq, &rf);
}
@@ -6991,6 +7011,7 @@ static inline void update_blocked_averages(int cpu)
rq_lock_irqsave(rq, &rf);
update_rq_clock(rq);
update_cfs_rq_load_avg(cfs_rq_clock_task(cfs_rq), cfs_rq, true);
+ update_rt_rq_load_avg(rq_clock_task(rq), cpu, &rq->rt, 0);
rq_unlock_irqrestore(rq, &rf);
}
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 45caf93..e72d572 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1534,6 +1534,8 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq)
return p;
}
+extern int update_rt_rq_load_avg(u64 now, int cpu, struct rt_rq *rt_rq, int running);
+
static struct task_struct *
pick_next_task_rt(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
{
@@ -1579,6 +1581,10 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
queue_push_tasks(rq);
+ if (p)
+ update_rt_rq_load_avg(rq_clock_task(rq), cpu_of(rq), rt_rq,
+ rq->curr->sched_class == &rt_sched_class);
+
return p;
}
@@ -1586,6 +1592,8 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
{
update_curr_rt(rq);
+ update_rt_rq_load_avg(rq_clock_task(rq), cpu_of(rq), &rq->rt, 1);
+
/*
* The previous task needs to be made eligible for pushing
* if it is still active
@@ -2368,6 +2376,7 @@ static void task_tick_rt(struct rq *rq, struct task_struct *p, int queued)
struct sched_rt_entity *rt_se = &p->rt;
update_curr_rt(rq);
+ update_rt_rq_load_avg(rq_clock_task(rq), cpu_of(rq), &rq->rt, 1);
watchdog(rq, p);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index eeef1a3..e7ee5b0 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -524,6 +524,9 @@ struct rt_rq {
unsigned long rt_nr_total;
int overloaded;
struct plist_head pushable_tasks;
+
+ struct sched_avg avg;
+
#ifdef HAVE_RT_PUSH_IPI
int push_flags;
int push_cpu;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-08-07 18:50 +0200 |
| Subject | Re: [RESEND PATCH v2 1/2] sched/rt: add utilization tracking |
| Message-ID | <ubTo6-2M8-17@gated-at.bofh.it> |
| In reply to | #1704004 |
[Multipart message — attachments visible in raw view] — view raw
On Fri, Aug 04, 2017 at 03:40:21PM +0200, Vincent Guittot wrote: > There were several comments on v1: > - As raised by Peter for v1, if IRQ time is taken into account in > rt_avg, it will not be accounted in rq->clock_task. This means that cfs > utilization is not affected by some extra contributions or decays > because of IRQ. Right. > - Regading the sync of rt and cfs utilization, both cfs and rt use the same > rq->clock_task. Then, we have the same issue than cfs regarding blocked value. > The utilization of idle cfs/rt rqs are not updated regularly but only when a > load_balance is triggered (more precisely a call to update_blocked_average). > I'd like to fix this issue for both cfs and rt with a separate patch that > will ensure that utilization (and load) are updated regularly even for > idle CPUs Yeah, that needs help. > - One last open question is the location of rt utilization function in fair.c > file. PELT related funtions should probably move in a dedicated pelt.c file. > This would also help to address one comment about having a place to update > metrics of NOHZ idle CPUs. Thought ? Probably, but I have a bunch of patches lined up changing that code, so lets not do that now. In any case, would something like the attached patches make sense? It completely replaces rt_avg with separate IRQ,RT and DL tracking.
[toc] | [prev] | [next] | [standalone]
| From | Vincent Guittot <vincent.guittot@linaro.org> |
|---|---|
| Date | 2017-08-08 16:00 +0200 |
| Subject | Re: [RESEND PATCH v2 1/2] sched/rt: add utilization tracking |
| Message-ID | <ucdd7-Hf-1@gated-at.bofh.it> |
| In reply to | #1705711 |
On 7 August 2017 at 18:44, Peter Zijlstra <peterz@infradead.org> wrote: > On Fri, Aug 04, 2017 at 03:40:21PM +0200, Vincent Guittot wrote: > >> There were several comments on v1: >> - As raised by Peter for v1, if IRQ time is taken into account in >> rt_avg, it will not be accounted in rq->clock_task. This means that cfs >> utilization is not affected by some extra contributions or decays >> because of IRQ. > > Right. > >> - Regading the sync of rt and cfs utilization, both cfs and rt use the same >> rq->clock_task. Then, we have the same issue than cfs regarding blocked value. >> The utilization of idle cfs/rt rqs are not updated regularly but only when a >> load_balance is triggered (more precisely a call to update_blocked_average). >> I'd like to fix this issue for both cfs and rt with a separate patch that >> will ensure that utilization (and load) are updated regularly even for >> idle CPUs > > Yeah, that needs help. > >> - One last open question is the location of rt utilization function in fair.c >> file. PELT related funtions should probably move in a dedicated pelt.c file. >> This would also help to address one comment about having a place to update >> metrics of NOHZ idle CPUs. Thought ? > > Probably, but I have a bunch of patches lined up changing that code, so > lets not do that now. ok. I can rebase and move the code once your patches will be there > > In any case, would something like the attached patches make sense? It > completely replaces rt_avg with separate IRQ,RT and DL tracking. That would be nice if we can replace rt_avg by something that has the same dynamic as PELT. The DL patch looks fine but can't we rely on deadline running bandwidth to get the figures instead ? I don't think that IRQ tracking patch is working. update_irq_load_avg(rq->clock, cpu_of(rq), rq, 1); is called in update_rq_clock_task() which is never called in irq context. In order to use PELT for tracking irq and paravirt, we should call update_irq_load_avg() for every context switch between irq/paravirt and task which will probably be too heavy. Nevertheless, we can Because PELT is cpu invariant, the used value must now be subtracted to cpu_capacity_orig of the local cpu in scale_rt_capacity, > >
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2017-08-08 16:10 +0200 |
| Subject | Re: [RESEND PATCH v2 1/2] sched/rt: add utilization tracking |
| Message-ID | <ucdmP-10i-29@gated-at.bofh.it> |
| In reply to | #1706584 |
On Tue, Aug 08, 2017 at 03:56:26PM +0200, Vincent Guittot wrote: > > I don't think that IRQ tracking patch is working. > update_irq_load_avg(rq->clock, cpu_of(rq), rq, 1); is called in > update_rq_clock_task() which is never called in irq context. In order > to use PELT for tracking irq and paravirt, we should call > update_irq_load_avg() for every context switch between irq/paravirt > and task which will probably be too heavy. Nevertheless, we can > Right, realized the same much later yesterday...
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web