aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--trace-graph.c103
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
60static gint ftrace_sched_switch_id = -1; 60static gint ftrace_sched_switch_id = -1;
61static gint event_sched_switch_id = -1; 61static gint event_sched_switch_id = -1;
62static gint event_wakeup_id = -1;
63static gint event_wakeup_new_id = -1;
62 64
63static gint largest_cpu_label = 0; 65static 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
628static 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
626static int check_sched_switch(struct graph_info *ginfo, 694static 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);