aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-12 04:08:34 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-13 04:22:45 -0400
commitea92ed5a8f4e6c638efe7de2efe8a875d580ad3f (patch)
treedcdad8cc0b26a3aec5fb98a261da147a7fa662df
parentd9340c1db3f52460a8335eeb127a2728c5bba6ce (diff)
perf sched: Add runtime stats
Extend the latency tracking structure with scheduling atom runtime info - and sum it up during per task display. (Also clean up a few details.) Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/builtin-sched.c58
1 files changed, 38 insertions, 20 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index a084c284e198..c382f530d4c6 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -243,8 +243,8 @@ add_sched_event_run(struct task_desc *task, nsec_t timestamp, u64 duration)
243 nr_run_events++; 243 nr_run_events++;
244} 244}
245 245
246static unsigned long targetless_wakeups; 246static unsigned long targetless_wakeups;
247static unsigned long multitarget_wakeups; 247static unsigned long multitarget_wakeups;
248 248
249static void 249static void
250add_sched_event_wakeup(struct task_desc *task, nsec_t timestamp, 250add_sched_event_wakeup(struct task_desc *task, nsec_t timestamp,
@@ -485,10 +485,10 @@ static void create_tasks(void)
485 } 485 }
486} 486}
487 487
488static nsec_t cpu_usage; 488static nsec_t cpu_usage;
489static nsec_t runavg_cpu_usage; 489static nsec_t runavg_cpu_usage;
490static nsec_t parent_cpu_usage; 490static nsec_t parent_cpu_usage;
491static nsec_t runavg_parent_cpu_usage; 491static nsec_t runavg_parent_cpu_usage;
492 492
493static void wait_for_tasks(void) 493static void wait_for_tasks(void)
494{ 494{
@@ -858,9 +858,9 @@ replay_fork_event(struct trace_fork_event *fork_event,
858} 858}
859 859
860static struct trace_sched_handler replay_ops = { 860static struct trace_sched_handler replay_ops = {
861 .wakeup_event = replay_wakeup_event, 861 .wakeup_event = replay_wakeup_event,
862 .switch_event = replay_switch_event, 862 .switch_event = replay_switch_event,
863 .fork_event = replay_fork_event, 863 .fork_event = replay_fork_event,
864}; 864};
865 865
866#define TASK_STATE_TO_CHAR_STR "RSDTtZX" 866#define TASK_STATE_TO_CHAR_STR "RSDTtZX"
@@ -877,6 +877,7 @@ struct lat_snapshot {
877 enum thread_state state; 877 enum thread_state state;
878 u64 wake_up_time; 878 u64 wake_up_time;
879 u64 sched_in_time; 879 u64 sched_in_time;
880 u64 runtime;
880}; 881};
881 882
882struct thread_latency { 883struct thread_latency {
@@ -951,6 +952,7 @@ latency_fork_event(struct trace_fork_event *fork_event __used,
951 /* should insert the newcomer */ 952 /* should insert the newcomer */
952} 953}
953 954
955__used
954static char sched_out_state(struct trace_switch_event *switch_event) 956static char sched_out_state(struct trace_switch_event *switch_event)
955{ 957{
956 const char *str = TASK_STATE_TO_CHAR_STR; 958 const char *str = TASK_STATE_TO_CHAR_STR;
@@ -960,17 +962,15 @@ static char sched_out_state(struct trace_switch_event *switch_event)
960 962
961static void 963static void
962lat_sched_out(struct thread_latency *lat, 964lat_sched_out(struct thread_latency *lat,
963 struct trace_switch_event *switch_event) 965 struct trace_switch_event *switch_event __used, u64 delta)
964{ 966{
965 struct lat_snapshot *snapshot; 967 struct lat_snapshot *snapshot;
966 968
967 if (sched_out_state(switch_event) == 'R')
968 return;
969
970 snapshot = calloc(sizeof(*snapshot), 1); 969 snapshot = calloc(sizeof(*snapshot), 1);
971 if (!snapshot) 970 if (!snapshot)
972 die("Non memory"); 971 die("Non memory");
973 972
973 snapshot->runtime = delta;
974 list_add_tail(&snapshot->list, &lat->snapshot_list); 974 list_add_tail(&snapshot->list, &lat->snapshot_list);
975} 975}
976 976
@@ -997,16 +997,31 @@ lat_sched_in(struct thread_latency *lat, u64 timestamp)
997 snapshot->sched_in_time = timestamp; 997 snapshot->sched_in_time = timestamp;
998} 998}
999 999
1000
1001static void 1000static void
1002latency_switch_event(struct trace_switch_event *switch_event, 1001latency_switch_event(struct trace_switch_event *switch_event,
1003 struct event *event __used, 1002 struct event *event __used,
1004 int cpu __used, 1003 int cpu,
1005 u64 timestamp, 1004 u64 timestamp,
1006 struct thread *thread __used) 1005 struct thread *thread __used)
1007{ 1006{
1008 struct thread_latency *out_lat, *in_lat; 1007 struct thread_latency *out_lat, *in_lat;
1009 struct thread *sched_out, *sched_in; 1008 struct thread *sched_out, *sched_in;
1009 u64 timestamp0;
1010 s64 delta;
1011
1012 if (cpu >= MAX_CPUS || cpu < 0)
1013 return;
1014
1015 timestamp0 = cpu_last_switched[cpu];
1016 cpu_last_switched[cpu] = timestamp;
1017 if (timestamp0)
1018 delta = timestamp - timestamp0;
1019 else
1020 delta = 0;
1021
1022 if (delta < 0)
1023 die("hm, delta: %Ld < 0 ?\n", delta);
1024
1010 1025
1011 sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match); 1026 sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
1012 sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match); 1027 sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
@@ -1028,7 +1043,7 @@ latency_switch_event(struct trace_switch_event *switch_event,
1028 } 1043 }
1029 1044
1030 lat_sched_in(in_lat, timestamp); 1045 lat_sched_in(in_lat, timestamp);
1031 lat_sched_out(out_lat, switch_event); 1046 lat_sched_out(out_lat, switch_event, delta);
1032} 1047}
1033 1048
1034static void 1049static void
@@ -1067,9 +1082,9 @@ latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
1067} 1082}
1068 1083
1069static struct trace_sched_handler lat_ops = { 1084static struct trace_sched_handler lat_ops = {
1070 .wakeup_event = latency_wakeup_event, 1085 .wakeup_event = latency_wakeup_event,
1071 .switch_event = latency_switch_event, 1086 .switch_event = latency_switch_event,
1072 .fork_event = latency_fork_event, 1087 .fork_event = latency_fork_event,
1073}; 1088};
1074 1089
1075static void output_lat_thread(struct thread_latency *lat) 1090static void output_lat_thread(struct thread_latency *lat)
@@ -1080,8 +1095,11 @@ static void output_lat_thread(struct thread_latency *lat)
1080 int ret; 1095 int ret;
1081 u64 max = 0, avg; 1096 u64 max = 0, avg;
1082 u64 total = 0, delta; 1097 u64 total = 0, delta;
1098 u64 total_runtime = 0;
1083 1099
1084 list_for_each_entry(shot, &lat->snapshot_list, list) { 1100 list_for_each_entry(shot, &lat->snapshot_list, list) {
1101 total_runtime += shot->runtime;
1102
1085 if (shot->state != THREAD_SCHED_IN) 1103 if (shot->state != THREAD_SCHED_IN)
1086 continue; 1104 continue;
1087 1105
@@ -1104,7 +1122,7 @@ static void output_lat_thread(struct thread_latency *lat)
1104 avg = total / count; 1122 avg = total / count;
1105 1123
1106 printf("|%9.3f ms |%9d | avg:%9.3f ms | max:%9.3f ms |\n", 1124 printf("|%9.3f ms |%9d | avg:%9.3f ms | max:%9.3f ms |\n",
1107 0.0, count, (double)avg/1e9, (double)max/1e9); 1125 (double)total_runtime/1e9, count, (double)avg/1e9, (double)max/1e9);
1108} 1126}
1109 1127
1110static void __cmd_lat(void) 1128static void __cmd_lat(void)