diff options
-rw-r--r-- | trace-graph.c | 103 |
1 files changed, 94 insertions, 9 deletions
diff --git a/trace-graph.c b/trace-graph.c index 513ed92..e055f35 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
@@ -59,6 +59,8 @@ | |||
59 | 59 | ||
60 | static gint ftrace_sched_switch_id = -1; | 60 | static gint ftrace_sched_switch_id = -1; |
61 | static gint event_sched_switch_id = -1; | 61 | static gint event_sched_switch_id = -1; |
62 | static gint event_wakeup_id = -1; | ||
63 | static gint event_wakeup_new_id = -1; | ||
62 | 64 | ||
63 | static gint largest_cpu_label = 0; | 65 | static gint largest_cpu_label = 0; |
64 | 66 | ||
@@ -623,6 +625,72 @@ static void print_rec_info(struct record *record, struct pevent *pevent, int cpu | |||
623 | 625 | ||
624 | #define CPU_BOARDER 5 | 626 | #define CPU_BOARDER 5 |
625 | 627 | ||
628 | static int check_sched_wakeup(struct graph_info *ginfo, | ||
629 | struct record *record, | ||
630 | gint *pid) | ||
631 | { | ||
632 | static struct format_field *wakeup_pid_field; | ||
633 | static struct format_field *wakeup_success_field; | ||
634 | static struct format_field *wakeup_new_pid_field; | ||
635 | static struct format_field *wakeup_new_success_field; | ||
636 | struct event_format *event; | ||
637 | unsigned long long val; | ||
638 | gboolean found; | ||
639 | gint id; | ||
640 | |||
641 | if (event_wakeup_id < 0) { | ||
642 | |||
643 | found = FALSE; | ||
644 | |||
645 | event = pevent_find_event_by_name(ginfo->pevent, | ||
646 | "sched", "sched_wakeup"); | ||
647 | if (event) { | ||
648 | found = TRUE; | ||
649 | event_wakeup_id = event->id; | ||
650 | wakeup_pid_field = pevent_find_field(event, "pid"); | ||
651 | wakeup_success_field = pevent_find_field(event, "success"); | ||
652 | } | ||
653 | |||
654 | |||
655 | event = pevent_find_event_by_name(ginfo->pevent, | ||
656 | "sched", "sched_wakeup_new"); | ||
657 | if (event) { | ||
658 | found = TRUE; | ||
659 | event_wakeup_new_id = event->id; | ||
660 | wakeup_new_pid_field = pevent_find_field(event, "pid"); | ||
661 | wakeup_new_success_field = pevent_find_field(event, "success"); | ||
662 | } | ||
663 | if (!found) | ||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | id = pevent_data_type(ginfo->pevent, record); | ||
668 | |||
669 | if (id == event_wakeup_id) { | ||
670 | /* We only want those that actually woke up the task */ | ||
671 | pevent_read_number_field(wakeup_success_field, record->data, &val); | ||
672 | if (!val) | ||
673 | return 0; | ||
674 | pevent_read_number_field(wakeup_pid_field, record->data, &val); | ||
675 | if (pid) | ||
676 | *pid = val; | ||
677 | return 1; | ||
678 | } | ||
679 | |||
680 | if (id == event_wakeup_new_id) { | ||
681 | /* We only want those that actually woke up the task */ | ||
682 | pevent_read_number_field(wakeup_new_success_field, record->data, &val); | ||
683 | if (!val) | ||
684 | return 0; | ||
685 | pevent_read_number_field(wakeup_new_pid_field, record->data, &val); | ||
686 | if (pid) | ||
687 | *pid = val; | ||
688 | return 1; | ||
689 | } | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
626 | static int check_sched_switch(struct graph_info *ginfo, | 694 | static int check_sched_switch(struct graph_info *ginfo, |
627 | struct record *record, | 695 | struct record *record, |
628 | gint *pid, const char **comm) | 696 | gint *pid, const char **comm) |
@@ -637,20 +705,21 @@ static int check_sched_switch(struct graph_info *ginfo, | |||
637 | 705 | ||
638 | if (event_sched_switch_id < 0) { | 706 | if (event_sched_switch_id < 0) { |
639 | event = pevent_find_event_by_name(ginfo->pevent, | 707 | event = pevent_find_event_by_name(ginfo->pevent, |
708 | "sched", "sched_switch"); | ||
709 | if (!event) | ||
710 | return 0; | ||
711 | |||
712 | event_sched_switch_id = event->id; | ||
713 | event_pid_field = pevent_find_field(event, "next_pid"); | ||
714 | event_comm_field = pevent_find_field(event, "next_comm"); | ||
715 | |||
716 | event = pevent_find_event_by_name(ginfo->pevent, | ||
640 | "ftrace", "context_switch"); | 717 | "ftrace", "context_switch"); |
641 | if (event) { | 718 | if (event) { |
642 | ftrace_sched_switch_id = event->id; | 719 | ftrace_sched_switch_id = event->id; |
643 | ftrace_pid_field = pevent_find_field(event, "next_pid"); | 720 | ftrace_pid_field = pevent_find_field(event, "next_pid"); |
644 | ftrace_comm_field = pevent_find_field(event, "next_comm"); | 721 | ftrace_comm_field = pevent_find_field(event, "next_comm"); |
645 | } | 722 | } |
646 | |||
647 | event = pevent_find_event_by_name(ginfo->pevent, | ||
648 | "sched", "sched_switch"); | ||
649 | if (!event) | ||
650 | die("can't find event sched_switch!"); | ||
651 | event_sched_switch_id = event->id; | ||
652 | event_pid_field = pevent_find_field(event, "next_pid"); | ||
653 | event_comm_field = pevent_find_field(event, "next_comm"); | ||
654 | } | 723 | } |
655 | 724 | ||
656 | id = pevent_data_type(ginfo->pevent, record); | 725 | id = pevent_data_type(ginfo->pevent, record); |
@@ -1223,9 +1292,13 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
1223 | gint x; | 1292 | gint x; |
1224 | gint p1 = 0, p2 = 0, p3 = 0; | 1293 | gint p1 = 0, p2 = 0, p3 = 0; |
1225 | gint last_event_id = 0; | 1294 | gint last_event_id = 0; |
1295 | gint wake_pid; | ||
1296 | gint last_wake_pid; | ||
1226 | gint event_id; | 1297 | gint event_id; |
1227 | gboolean filter; | 1298 | gboolean filter; |
1228 | gboolean is_sched_switch; | 1299 | gboolean is_sched_switch; |
1300 | gboolean is_wakeup; | ||
1301 | gboolean last_is_wakeup = FALSE; | ||
1229 | const char *comm; | 1302 | const char *comm; |
1230 | 1303 | ||
1231 | /* Calculate the size of 16 characters */ | 1304 | /* Calculate the size of 16 characters */ |
@@ -1313,6 +1386,11 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
1313 | 1386 | ||
1314 | last_pid = pid; | 1387 | last_pid = pid; |
1315 | 1388 | ||
1389 | /* Lets see if a filtered task is waking up */ | ||
1390 | is_wakeup = check_sched_wakeup(ginfo, record, &wake_pid); | ||
1391 | if (filter && is_wakeup) | ||
1392 | filter = graph_filter_on_task(ginfo, wake_pid); | ||
1393 | |||
1316 | if (!filter) { | 1394 | if (!filter) { |
1317 | filter = graph_filter_on_event(ginfo, record); | 1395 | filter = graph_filter_on_event(ginfo, record); |
1318 | if (!filter) | 1396 | if (!filter) |
@@ -1329,15 +1407,22 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
1329 | if (!p3) | 1407 | if (!p3) |
1330 | p3 = 1; | 1408 | p3 = 1; |
1331 | 1409 | ||
1410 | if (last_is_wakeup) | ||
1411 | pid = last_wake_pid; | ||
1412 | else | ||
1413 | pid = last_pid; | ||
1414 | |||
1332 | /* first record, continue */ | 1415 | /* first record, continue */ |
1333 | if (p2) | 1416 | if (p2) |
1334 | draw_event_label(ginfo, cpu, last_event_id, last_pid, | 1417 | draw_event_label(ginfo, cpu, last_event_id, pid, |
1335 | p1, p2, p3, width_16, font); | 1418 | p1, p2, p3, width_16, font); |
1336 | 1419 | ||
1337 | p1 = p2; | 1420 | p1 = p2; |
1338 | p2 = p3; | 1421 | p2 = p3; |
1339 | 1422 | ||
1340 | last_event_id = event_id; | 1423 | last_event_id = event_id; |
1424 | last_is_wakeup = is_wakeup; | ||
1425 | last_wake_pid = wake_pid; | ||
1341 | } | 1426 | } |
1342 | 1427 | ||
1343 | free_record(record); | 1428 | free_record(record); |