Messages in this thread | | | Date | Tue, 17 Apr 2018 10:41:31 -0300 | From | Arnaldo Carvalho de Melo <> | Subject | Re: measuring system wide CPU usage ignoring idle process |
| |
Em Thu, Nov 23, 2017 at 04:15:36PM +0100, Peter Zijlstra escreveu: > On Thu, Nov 23, 2017 at 11:42:20AM -0300, Arnaldo Carvalho de Melo wrote: > > What is wrong with perf_event_attr.exclude_idle? :-) > > Neither task- nor cpu-clock actually implement that.. > > Something like the _completely_untested_ below might cure that for > cpu-clock. I have the nagging feeling we actually already account the > idle time _somewhere_, but I couldn't remember and was too lazy to go > find -- but someone should if this were to become an actual patch. >
Stephane, this was the thread,
- Arnaldo
> --- > diff --git a/kernel/events/core.c b/kernel/events/core.c > index a59fe11558a4..5386d551b373 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -8900,6 +8908,10 @@ static void cpu_clock_event_update(struct perf_event *event) > u64 now; > > now = local_clock(); > + > + if (event->attr.exclude_idle) > + now -= idle_task(event->oncpu)->se.sum_exec_runtime; > + > prev = local64_xchg(&event->hw.prev_count, now); > local64_add(now - prev, &event->count); > } > diff --git a/kernel/sched/idle_task.c b/kernel/sched/idle_task.c > index d518664cce4f..419c620510c6 100644 > --- a/kernel/sched/idle_task.c > +++ b/kernel/sched/idle_task.c > @@ -27,9 +27,14 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int fl > static struct task_struct * > pick_next_task_idle(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) > { > + struct task_struct *idle = rq->idle; > + > put_prev_task(rq, prev); > update_idle_core(rq); > schedstat_inc(rq->sched_goidle); > + > + idle->se.exec_start = rq_clock_task(rq); > + > return rq->idle; > } > > @@ -48,6 +53,17 @@ dequeue_task_idle(struct rq *rq, struct task_struct *p, int flags) > > static void put_prev_task_idle(struct rq *rq, struct task_struct *prev) > { > + struct task_struct *idle = rq->idle; > + u64 delta, now; > + > + now = rq_clock_task(rq); > + delta = now - idle->se.exec_start; > + if (unlikely((s64)delta < 0)) > + delta = 0; > + > + idle->se.sum_exec_runtime += delta; > + idle->se.exec_start = now; > + > rq_last_tick_reset(rq); > } > > @@ -57,6 +73,9 @@ static void task_tick_idle(struct rq *rq, struct task_struct *curr, int queued) > > static void set_curr_task_idle(struct rq *rq) > { > + struct task_struct *idle = rq->idle; > + > + idle->se.exec_start = rq_clock_task(rq); > } > > static void switched_to_idle(struct rq *rq, struct task_struct *p)
| |