Commit e414314c authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

sched: Fix latencytop and sleep profiling vs group scheduling

The latencytop and sleep accounting code assumes that any
scheduler entity represents a task, this is not so.

Cc: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent ed680c4a
...@@ -611,9 +611,13 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se) ...@@ -611,9 +611,13 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
{ {
#ifdef CONFIG_SCHEDSTATS #ifdef CONFIG_SCHEDSTATS
struct task_struct *tsk = NULL;
if (entity_is_task(se))
tsk = task_of(se);
if (se->sleep_start) { if (se->sleep_start) {
u64 delta = rq_of(cfs_rq)->clock - se->sleep_start; u64 delta = rq_of(cfs_rq)->clock - se->sleep_start;
struct task_struct *tsk = task_of(se);
if ((s64)delta < 0) if ((s64)delta < 0)
delta = 0; delta = 0;
...@@ -624,11 +628,11 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) ...@@ -624,11 +628,11 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
se->sleep_start = 0; se->sleep_start = 0;
se->sum_sleep_runtime += delta; se->sum_sleep_runtime += delta;
if (tsk)
account_scheduler_latency(tsk, delta >> 10, 1); account_scheduler_latency(tsk, delta >> 10, 1);
} }
if (se->block_start) { if (se->block_start) {
u64 delta = rq_of(cfs_rq)->clock - se->block_start; u64 delta = rq_of(cfs_rq)->clock - se->block_start;
struct task_struct *tsk = task_of(se);
if ((s64)delta < 0) if ((s64)delta < 0)
delta = 0; delta = 0;
...@@ -639,18 +643,20 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) ...@@ -639,18 +643,20 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
se->block_start = 0; se->block_start = 0;
se->sum_sleep_runtime += delta; se->sum_sleep_runtime += delta;
if (tsk) {
/* /*
* Blocking time is in units of nanosecs, so shift by 20 to * Blocking time is in units of nanosecs, so shift by
* get a milliseconds-range estimation of the amount of * 20 to get a milliseconds-range estimation of the
* time that the task spent sleeping: * amount of time that the task spent sleeping:
*/ */
if (unlikely(prof_on == SLEEP_PROFILING)) { if (unlikely(prof_on == SLEEP_PROFILING)) {
profile_hits(SLEEP_PROFILING,
profile_hits(SLEEP_PROFILING, (void *)get_wchan(tsk), (void *)get_wchan(tsk),
delta >> 20); delta >> 20);
} }
account_scheduler_latency(tsk, delta >> 10, 0); account_scheduler_latency(tsk, delta >> 10, 0);
} }
}
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment