[PATCH v2 5/6] perf sched timehist: Add -I/--idle-hist option

2016-12-08 Thread Namhyung Kim
The --idle-hist option is to analyze system idle state so which process
makes cpu to go idle.  If this option is specified, non-idle events will
be skipped and processes switching to/from idle will be shown.

This option is mostly useful when used with --summary(-only) option.  In
the idle-time summary view, idle time is accounted to previous thread
which is run before idle task.

The example output looks like following:

  Idle-time summary
  comm  parent  sched-outidle-time   min-idle
avg-idlemax-idle  stddev  migrations
  (count)   (msec) (msec)  
(msec)  (msec)   %
  
---
rcu_preempt[7]   2 95  550.872  0.011   
5.798  23.1467.63   0
   migration/1[16]   2  1   15.558 15.558  
15.558  15.5580.00   0
khugepaged[39]   2  13.062  3.062   
3.062   3.0620.00   0
 kworker/0:1H[124]   2  24.728  0.611   
2.364   4.116   74.12   0
  systemd-journal[167]   1  14.510  4.510   
4.510   4.5100.00   0
kworker/u16:3[558]   2 13   74.737  0.080   
5.749  12.960   21.96   0
   irq/34-iwlwifi[628]   2 21  118.403  0.032   
5.638  23.990   24.00   0
kworker/u17:0[673]   2  13.523  3.523   
3.523   3.5230.00   0
  dbus-daemon[722]   1  16.743  6.743   
6.743   6.7430.00   0
  ifplugd[741]   1  1   58.826 58.826  
58.826  58.8260.00   0
  wpa_supplicant[1490]   1  1   13.302 13.302  
13.302  13.3020.00   0
 wpa_actiond[1492]   1  24.064  0.168   
2.032   3.896   91.72   0
 dockerd[1500]   1  10.055  0.055   
0.055   0.0550.00   0
  ...

Signed-off-by: Namhyung Kim 
---
 tools/perf/Documentation/perf-sched.txt |  4 
 tools/perf/builtin-sched.c  | 38 -
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/tools/perf/Documentation/perf-sched.txt 
b/tools/perf/Documentation/perf-sched.txt
index 7775b1eb2bee..76173969ab80 100644
--- a/tools/perf/Documentation/perf-sched.txt
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -132,6 +132,10 @@ OPTIONS for 'perf sched timehist'
 --migrations::
Show migration events.
 
+-I::
+--idle-hist::
+   Show idle-related events only.
+
 --time::
Only analyze samples within given time window: ,. Times
have the format seconds.microseconds. If start is not given (i.e., time
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index da3ff3253741..6dc9e00d6392 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2420,7 +2420,28 @@ static int timehist_sched_change_event(struct perf_tool 
*tool,
t = ptime->end;
}
 
-   timehist_update_runtime_stats(tr, t, tprev);
+   if (!sched->idle_hist || thread->tid == 0) {
+   timehist_update_runtime_stats(tr, t, tprev);
+
+   if (sched->idle_hist) {
+   struct idle_thread_runtime *itr = (void *)tr;
+   struct thread_runtime *last_tr;
+
+   BUG_ON(thread->tid != 0);
+
+   if (itr->last_thread == NULL)
+   goto out;
+
+   /* add current idle time as last thread's runtime */
+   last_tr = thread__get_runtime(itr->last_thread);
+   if (last_tr == NULL)
+   goto out;
+
+   timehist_update_runtime_stats(last_tr, t, tprev);
+
+   itr->last_thread = NULL;
+   }
+   }
 
if (!sched->summary_only)
timehist_print_sample(sched, sample, , thread, t);
@@ -2542,9 +2563,15 @@ static void timehist_print_summary(struct perf_sched 
*sched,
if (comm_width < 30)
comm_width = 30;
 
-   printf("\nRuntime summary\n");
-   printf("%*s  parent   sched-in  ", comm_width, "comm");
-   printf("   run-timemin-run avg-run max-run  stddev  
migrations\n");
+   if (sched->idle_hist) {
+   printf("\nIdle-time summary\n");
+   printf("%*s  parent  sched-out  ", comm_width, "comm");
+   printf("  idle-time   min-idleavg-idlemax-idle  stddev  
migrations\n");
+   } else {
+   

[PATCH v2 5/6] perf sched timehist: Add -I/--idle-hist option

2016-12-08 Thread Namhyung Kim
The --idle-hist option is to analyze system idle state so which process
makes cpu to go idle.  If this option is specified, non-idle events will
be skipped and processes switching to/from idle will be shown.

This option is mostly useful when used with --summary(-only) option.  In
the idle-time summary view, idle time is accounted to previous thread
which is run before idle task.

The example output looks like following:

  Idle-time summary
  comm  parent  sched-outidle-time   min-idle
avg-idlemax-idle  stddev  migrations
  (count)   (msec) (msec)  
(msec)  (msec)   %
  
---
rcu_preempt[7]   2 95  550.872  0.011   
5.798  23.1467.63   0
   migration/1[16]   2  1   15.558 15.558  
15.558  15.5580.00   0
khugepaged[39]   2  13.062  3.062   
3.062   3.0620.00   0
 kworker/0:1H[124]   2  24.728  0.611   
2.364   4.116   74.12   0
  systemd-journal[167]   1  14.510  4.510   
4.510   4.5100.00   0
kworker/u16:3[558]   2 13   74.737  0.080   
5.749  12.960   21.96   0
   irq/34-iwlwifi[628]   2 21  118.403  0.032   
5.638  23.990   24.00   0
kworker/u17:0[673]   2  13.523  3.523   
3.523   3.5230.00   0
  dbus-daemon[722]   1  16.743  6.743   
6.743   6.7430.00   0
  ifplugd[741]   1  1   58.826 58.826  
58.826  58.8260.00   0
  wpa_supplicant[1490]   1  1   13.302 13.302  
13.302  13.3020.00   0
 wpa_actiond[1492]   1  24.064  0.168   
2.032   3.896   91.72   0
 dockerd[1500]   1  10.055  0.055   
0.055   0.0550.00   0
  ...

Signed-off-by: Namhyung Kim 
---
 tools/perf/Documentation/perf-sched.txt |  4 
 tools/perf/builtin-sched.c  | 38 -
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/tools/perf/Documentation/perf-sched.txt 
b/tools/perf/Documentation/perf-sched.txt
index 7775b1eb2bee..76173969ab80 100644
--- a/tools/perf/Documentation/perf-sched.txt
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -132,6 +132,10 @@ OPTIONS for 'perf sched timehist'
 --migrations::
Show migration events.
 
+-I::
+--idle-hist::
+   Show idle-related events only.
+
 --time::
Only analyze samples within given time window: ,. Times
have the format seconds.microseconds. If start is not given (i.e., time
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index da3ff3253741..6dc9e00d6392 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -2420,7 +2420,28 @@ static int timehist_sched_change_event(struct perf_tool 
*tool,
t = ptime->end;
}
 
-   timehist_update_runtime_stats(tr, t, tprev);
+   if (!sched->idle_hist || thread->tid == 0) {
+   timehist_update_runtime_stats(tr, t, tprev);
+
+   if (sched->idle_hist) {
+   struct idle_thread_runtime *itr = (void *)tr;
+   struct thread_runtime *last_tr;
+
+   BUG_ON(thread->tid != 0);
+
+   if (itr->last_thread == NULL)
+   goto out;
+
+   /* add current idle time as last thread's runtime */
+   last_tr = thread__get_runtime(itr->last_thread);
+   if (last_tr == NULL)
+   goto out;
+
+   timehist_update_runtime_stats(last_tr, t, tprev);
+
+   itr->last_thread = NULL;
+   }
+   }
 
if (!sched->summary_only)
timehist_print_sample(sched, sample, , thread, t);
@@ -2542,9 +2563,15 @@ static void timehist_print_summary(struct perf_sched 
*sched,
if (comm_width < 30)
comm_width = 30;
 
-   printf("\nRuntime summary\n");
-   printf("%*s  parent   sched-in  ", comm_width, "comm");
-   printf("   run-timemin-run avg-run max-run  stddev  
migrations\n");
+   if (sched->idle_hist) {
+   printf("\nIdle-time summary\n");
+   printf("%*s  parent  sched-out  ", comm_width, "comm");
+   printf("  idle-time   min-idleavg-idlemax-idle  stddev  
migrations\n");
+   } else {
+   printf("\nRuntime