diff options
| -rw-r--r-- | tools/perf/builtin-sched.c | 277 |
1 files changed, 97 insertions, 180 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 0df5e7a08c63..af305f57bd22 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
| @@ -97,73 +97,25 @@ struct work_atoms { | |||
| 97 | 97 | ||
| 98 | typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *); | 98 | typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *); |
| 99 | 99 | ||
| 100 | struct trace_switch_event { | 100 | struct perf_sched; |
| 101 | char *prev_comm; | ||
| 102 | u32 prev_pid; | ||
| 103 | u32 prev_prio; | ||
| 104 | u64 prev_state; | ||
| 105 | char *next_comm; | ||
| 106 | u32 next_pid; | ||
| 107 | u32 next_prio; | ||
| 108 | }; | ||
| 109 | |||
| 110 | struct trace_runtime_event { | ||
| 111 | char *comm; | ||
| 112 | u32 pid; | ||
| 113 | u64 runtime; | ||
| 114 | u64 vruntime; | ||
| 115 | }; | ||
| 116 | 101 | ||
| 117 | struct trace_wakeup_event { | 102 | struct trace_sched_handler { |
| 118 | char *comm; | 103 | int (*switch_event)(struct perf_sched *sched, struct perf_evsel *evsel, |
| 119 | u32 pid; | 104 | struct perf_sample *sample, struct machine *machine); |
| 120 | u32 prio; | ||
| 121 | u32 success; | ||
| 122 | u32 cpu; | ||
| 123 | }; | ||
| 124 | 105 | ||
| 125 | struct trace_fork_event { | 106 | int (*runtime_event)(struct perf_sched *sched, struct perf_evsel *evsel, |
| 126 | char *parent_comm; | 107 | struct perf_sample *sample, struct machine *machine); |
| 127 | u32 parent_pid; | ||
| 128 | char *child_comm; | ||
| 129 | u32 child_pid; | ||
| 130 | }; | ||
| 131 | 108 | ||
| 132 | struct trace_migrate_task_event { | 109 | int (*wakeup_event)(struct perf_sched *sched, struct perf_evsel *evsel, |
| 133 | char *comm; | 110 | struct perf_sample *sample, struct machine *machine); |
| 134 | u32 pid; | ||
| 135 | u32 prio; | ||
| 136 | u32 cpu; | ||
| 137 | }; | ||
| 138 | 111 | ||
| 139 | struct perf_sched; | 112 | int (*fork_event)(struct perf_sched *sched, struct perf_evsel *evsel, |
| 140 | 113 | struct perf_sample *sample); | |
| 141 | struct trace_sched_handler { | ||
| 142 | int (*switch_event)(struct perf_sched *sched, | ||
| 143 | struct trace_switch_event *event, | ||
| 144 | struct machine *machine, | ||
| 145 | struct perf_evsel *evsel, | ||
| 146 | struct perf_sample *sample); | ||
| 147 | |||
| 148 | int (*runtime_event)(struct perf_sched *sched, | ||
| 149 | struct trace_runtime_event *event, | ||
| 150 | struct machine *machine, | ||
| 151 | struct perf_sample *sample); | ||
| 152 | |||
| 153 | int (*wakeup_event)(struct perf_sched *sched, | ||
| 154 | struct trace_wakeup_event *event, | ||
| 155 | struct machine *machine, | ||
| 156 | struct perf_evsel *evsel, | ||
| 157 | struct perf_sample *sample); | ||
| 158 | |||
| 159 | int (*fork_event)(struct perf_sched *sched, | ||
| 160 | struct trace_fork_event *event, | ||
| 161 | struct perf_evsel *evsel); | ||
| 162 | 114 | ||
| 163 | int (*migrate_task_event)(struct perf_sched *sched, | 115 | int (*migrate_task_event)(struct perf_sched *sched, |
| 164 | struct trace_migrate_task_event *event, | 116 | struct perf_evsel *evsel, |
| 165 | struct machine *machine, | 117 | struct perf_sample *sample, |
| 166 | struct perf_sample *sample); | 118 | struct machine *machine); |
| 167 | }; | 119 | }; |
| 168 | 120 | ||
| 169 | struct perf_sched { | 121 | struct perf_sched { |
| @@ -700,33 +652,36 @@ static void test_calibrations(struct perf_sched *sched) | |||
| 700 | 652 | ||
| 701 | static int | 653 | static int |
| 702 | replay_wakeup_event(struct perf_sched *sched, | 654 | replay_wakeup_event(struct perf_sched *sched, |
| 703 | struct trace_wakeup_event *wakeup_event, | 655 | struct perf_evsel *evsel, struct perf_sample *sample, |
| 704 | struct machine *machine __maybe_unused, | 656 | struct machine *machine __maybe_unused) |
| 705 | struct perf_evsel *evsel, struct perf_sample *sample) | ||
| 706 | { | 657 | { |
| 658 | const char *comm = perf_evsel__strval(evsel, sample, "comm"); | ||
| 659 | const u32 pid = perf_evsel__intval(evsel, sample, "pid"); | ||
| 707 | struct task_desc *waker, *wakee; | 660 | struct task_desc *waker, *wakee; |
| 708 | 661 | ||
| 709 | if (verbose) { | 662 | if (verbose) { |
| 710 | printf("sched_wakeup event %p\n", evsel); | 663 | printf("sched_wakeup event %p\n", evsel); |
| 711 | 664 | ||
| 712 | printf(" ... pid %d woke up %s/%d\n", | 665 | printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid); |
| 713 | sample->tid, wakeup_event->comm, wakeup_event->pid); | ||
| 714 | } | 666 | } |
| 715 | 667 | ||
| 716 | waker = register_pid(sched, sample->tid, "<unknown>"); | 668 | waker = register_pid(sched, sample->tid, "<unknown>"); |
| 717 | wakee = register_pid(sched, wakeup_event->pid, wakeup_event->comm); | 669 | wakee = register_pid(sched, pid, comm); |
| 718 | 670 | ||
| 719 | add_sched_event_wakeup(sched, waker, sample->time, wakee); | 671 | add_sched_event_wakeup(sched, waker, sample->time, wakee); |
| 720 | return 0; | 672 | return 0; |
| 721 | } | 673 | } |
| 722 | 674 | ||
| 723 | static int | 675 | static int replay_switch_event(struct perf_sched *sched, |
| 724 | replay_switch_event(struct perf_sched *sched, | 676 | struct perf_evsel *evsel, |
| 725 | struct trace_switch_event *switch_event, | 677 | struct perf_sample *sample, |
| 726 | struct machine *machine __maybe_unused, | 678 | struct machine *machine __maybe_unused) |
| 727 | struct perf_evsel *evsel, | ||
| 728 | struct perf_sample *sample) | ||
| 729 | { | 679 | { |
| 680 | const char *prev_comm = perf_evsel__strval(evsel, sample, "prev_comm"), | ||
| 681 | *next_comm = perf_evsel__strval(evsel, sample, "next_comm"); | ||
| 682 | const u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"), | ||
| 683 | next_pid = perf_evsel__intval(evsel, sample, "next_pid"); | ||
| 684 | const u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state"); | ||
| 730 | struct task_desc *prev, __maybe_unused *next; | 685 | struct task_desc *prev, __maybe_unused *next; |
| 731 | u64 timestamp0, timestamp = sample->time; | 686 | u64 timestamp0, timestamp = sample->time; |
| 732 | int cpu = sample->cpu; | 687 | int cpu = sample->cpu; |
| @@ -749,35 +704,36 @@ replay_switch_event(struct perf_sched *sched, | |||
| 749 | return -1; | 704 | return -1; |
| 750 | } | 705 | } |
| 751 | 706 | ||
| 752 | if (verbose) { | 707 | pr_debug(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n", |
| 753 | printf(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n", | 708 | prev_comm, prev_pid, next_comm, next_pid, delta); |
| 754 | switch_event->prev_comm, switch_event->prev_pid, | ||
| 755 | switch_event->next_comm, switch_event->next_pid, | ||
| 756 | delta); | ||
| 757 | } | ||
| 758 | 709 | ||
| 759 | prev = register_pid(sched, switch_event->prev_pid, switch_event->prev_comm); | 710 | prev = register_pid(sched, prev_pid, prev_comm); |
| 760 | next = register_pid(sched, switch_event->next_pid, switch_event->next_comm); | 711 | next = register_pid(sched, next_pid, next_comm); |
| 761 | 712 | ||
| 762 | sched->cpu_last_switched[cpu] = timestamp; | 713 | sched->cpu_last_switched[cpu] = timestamp; |
| 763 | 714 | ||
| 764 | add_sched_event_run(sched, prev, timestamp, delta); | 715 | add_sched_event_run(sched, prev, timestamp, delta); |
| 765 | add_sched_event_sleep(sched, prev, timestamp, switch_event->prev_state); | 716 | add_sched_event_sleep(sched, prev, timestamp, prev_state); |
| 766 | 717 | ||
| 767 | return 0; | 718 | return 0; |
| 768 | } | 719 | } |
| 769 | 720 | ||
| 770 | static int | 721 | static int replay_fork_event(struct perf_sched *sched, struct perf_evsel *evsel, |
| 771 | replay_fork_event(struct perf_sched *sched, struct trace_fork_event *fork_event, | 722 | struct perf_sample *sample) |
| 772 | struct perf_evsel *evsel) | ||
| 773 | { | 723 | { |
| 724 | const char *parent_comm = perf_evsel__strval(evsel, sample, "parent_comm"), | ||
| 725 | *child_comm = perf_evsel__strval(evsel, sample, "child_comm"); | ||
| 726 | const u32 parent_pid = perf_evsel__intval(evsel, sample, "parent_pid"), | ||
| 727 | child_pid = perf_evsel__intval(evsel, sample, "child_pid"); | ||
| 728 | |||
| 774 | if (verbose) { | 729 | if (verbose) { |
| 775 | printf("sched_fork event %p\n", evsel); | 730 | printf("sched_fork event %p\n", evsel); |
| 776 | printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid); | 731 | printf("... parent: %s/%d\n", parent_comm, parent_pid); |
| 777 | printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid); | 732 | printf("... child: %s/%d\n", child_comm, child_pid); |
| 778 | } | 733 | } |
