diff options
Diffstat (limited to 'tools/perf/builtin-sched.c')
-rw-r--r-- | tools/perf/builtin-sched.c | 101 |
1 files changed, 76 insertions, 25 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index de93a2604528..0215936696ed 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -653,6 +653,30 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head) | |||
653 | return 0; | 653 | return 0; |
654 | } | 654 | } |
655 | 655 | ||
656 | |||
657 | struct raw_event_sample { | ||
658 | u32 size; | ||
659 | char data[0]; | ||
660 | }; | ||
661 | |||
662 | #define FILL_FIELD(ptr, field, event, data) \ | ||
663 | ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data) | ||
664 | |||
665 | #define FILL_ARRAY(ptr, array, event, data) \ | ||
666 | do { \ | ||
667 | void *__array = raw_field_ptr(event, #array, data); \ | ||
668 | memcpy(ptr.array, __array, sizeof(ptr.array)); \ | ||
669 | } while(0) | ||
670 | |||
671 | #define FILL_COMMON_FIELDS(ptr, event, data) \ | ||
672 | do { \ | ||
673 | FILL_FIELD(ptr, common_type, event, data); \ | ||
674 | FILL_FIELD(ptr, common_flags, event, data); \ | ||
675 | FILL_FIELD(ptr, common_preempt_count, event, data); \ | ||
676 | FILL_FIELD(ptr, common_pid, event, data); \ | ||
677 | FILL_FIELD(ptr, common_tgid, event, data); \ | ||
678 | } while (0) | ||
679 | |||
656 | struct trace_wakeup_event { | 680 | struct trace_wakeup_event { |
657 | u32 size; | 681 | u32 size; |
658 | 682 | ||
@@ -671,22 +695,32 @@ struct trace_wakeup_event { | |||
671 | }; | 695 | }; |
672 | 696 | ||
673 | static void | 697 | static void |
674 | process_sched_wakeup_event(struct trace_wakeup_event *wakeup_event, struct event *event, | 698 | process_sched_wakeup_event(struct raw_event_sample *raw, struct event *event, |
675 | int cpu __used, u64 timestamp __used, struct thread *thread __used) | 699 | int cpu __used, u64 timestamp __used, struct thread *thread __used) |
676 | { | 700 | { |
677 | struct task_desc *waker, *wakee; | 701 | struct task_desc *waker, *wakee; |
702 | struct trace_wakeup_event wakeup_event; | ||
703 | |||
704 | FILL_COMMON_FIELDS(wakeup_event, event, raw->data); | ||
705 | |||
706 | FILL_ARRAY(wakeup_event, comm, event, raw->data); | ||
707 | FILL_FIELD(wakeup_event, pid, event, raw->data); | ||
708 | FILL_FIELD(wakeup_event, prio, event, raw->data); | ||
709 | FILL_FIELD(wakeup_event, success, event, raw->data); | ||
710 | FILL_FIELD(wakeup_event, cpu, event, raw->data); | ||
711 | |||
678 | 712 | ||
679 | if (verbose) { | 713 | if (verbose) { |
680 | printf("sched_wakeup event %p\n", event); | 714 | printf("sched_wakeup event %p\n", event); |
681 | 715 | ||
682 | printf(" ... pid %d woke up %s/%d\n", | 716 | printf(" ... pid %d woke up %s/%d\n", |
683 | wakeup_event->common_pid, | 717 | wakeup_event.common_pid, |
684 | wakeup_event->comm, | 718 | wakeup_event.comm, |
685 | wakeup_event->pid); | 719 | wakeup_event.pid); |
686 | } | 720 | } |
687 | 721 | ||
688 | waker = register_pid(wakeup_event->common_pid, "<unknown>"); | 722 | waker = register_pid(wakeup_event.common_pid, "<unknown>"); |
689 | wakee = register_pid(wakeup_event->pid, wakeup_event->comm); | 723 | wakee = register_pid(wakeup_event.pid, wakeup_event.comm); |
690 | 724 | ||
691 | add_sched_event_wakeup(waker, timestamp, wakee); | 725 | add_sched_event_wakeup(waker, timestamp, wakee); |
692 | } | 726 | } |
@@ -714,13 +748,24 @@ struct trace_switch_event { | |||
714 | unsigned long cpu_last_switched[MAX_CPUS]; | 748 | unsigned long cpu_last_switched[MAX_CPUS]; |
715 | 749 | ||
716 | static void | 750 | static void |
717 | process_sched_switch_event(struct trace_switch_event *switch_event, struct event *event, | 751 | process_sched_switch_event(struct raw_event_sample *raw, struct event *event, |
718 | int cpu __used, u64 timestamp __used, struct thread *thread __used) | 752 | int cpu __used, u64 timestamp __used, struct thread *thread __used) |
719 | { | 753 | { |
754 | struct trace_switch_event switch_event; | ||
720 | struct task_desc *prev, *next; | 755 | struct task_desc *prev, *next; |
721 | u64 timestamp0; | 756 | u64 timestamp0; |
722 | s64 delta; | 757 | s64 delta; |
723 | 758 | ||
759 | FILL_COMMON_FIELDS(switch_event, event, raw->data); | ||
760 | |||
761 | FILL_ARRAY(switch_event, prev_comm, event, raw->data); | ||
762 | FILL_FIELD(switch_event, prev_pid, event, raw->data); | ||
763 | FILL_FIELD(switch_event, prev_prio, event, raw->data); | ||
764 | FILL_FIELD(switch_event, prev_state, event, raw->data); | ||
765 | FILL_ARRAY(switch_event, next_comm, event, raw->data); | ||
766 | FILL_FIELD(switch_event, next_pid, event, raw->data); | ||
767 | FILL_FIELD(switch_event, next_prio, event, raw->data); | ||
768 | |||
724 | if (verbose) | 769 | if (verbose) |
725 | printf("sched_switch event %p\n", event); | 770 | printf("sched_switch event %p\n", event); |
726 | 771 | ||
@@ -738,18 +783,18 @@ process_sched_switch_event(struct trace_switch_event *switch_event, struct event | |||
738 | 783 | ||
739 | if (verbose) { | 784 | if (verbose) { |
740 | printf(" ... switch from %s/%d to %s/%d [ran %Ld nsecs]\n", | 785 | printf(" ... switch from %s/%d to %s/%d [ran %Ld nsecs]\n", |
741 | switch_event->prev_comm, switch_event->prev_pid, | 786 | switch_event.prev_comm, switch_event.prev_pid, |
742 | switch_event->next_comm, switch_event->next_pid, | 787 | switch_event.next_comm, switch_event.next_pid, |
743 | delta); | 788 | delta); |
744 | } | 789 | } |
745 | 790 | ||
746 | prev = register_pid(switch_event->prev_pid, switch_event->prev_comm); | 791 | prev = register_pid(switch_event.prev_pid, switch_event.prev_comm); |
747 | next = register_pid(switch_event->next_pid, switch_event->next_comm); | 792 | next = register_pid(switch_event.next_pid, switch_event.next_comm); |
748 | 793 | ||
749 | cpu_last_switched[cpu] = timestamp; | 794 | cpu_last_switched[cpu] = timestamp; |
750 | 795 | ||
751 | add_sched_event_run(prev, timestamp, delta); | 796 | add_sched_event_run(prev, timestamp, delta); |
752 | add_sched_event_sleep(prev, timestamp, switch_event->prev_state); | 797 | add_sched_event_sleep(prev, timestamp, switch_event.prev_state); |
753 | } | 798 | } |
754 | 799 | ||
755 | struct trace_fork_event { | 800 | struct trace_fork_event { |
@@ -768,16 +813,25 @@ struct trace_fork_event { | |||
768 | }; | 813 | }; |
769 | 814 | ||
770 | static void | 815 | static void |
771 | process_sched_fork_event(struct trace_fork_event *fork_event, struct event *event, | 816 | process_sched_fork_event(struct raw_event_sample *raw, struct event *event, |
772 | int cpu __used, u64 timestamp __used, struct thread *thread __used) | 817 | int cpu __used, u64 timestamp __used, struct thread *thread __used) |
773 | { | 818 | { |
819 | struct trace_fork_event fork_event; | ||
820 | |||
821 | FILL_COMMON_FIELDS(fork_event, event, raw->data); | ||
822 | |||
823 | FILL_ARRAY(fork_event, parent_comm, event, raw->data); | ||
824 | FILL_FIELD(fork_event, parent_pid, event, raw->data); | ||
825 | FILL_ARRAY(fork_event, child_comm, event, raw->data); | ||
826 | FILL_FIELD(fork_event, child_pid, event, raw->data); | ||
827 | |||
774 | if (verbose) { | 828 | if (verbose) { |
775 | printf("sched_fork event %p\n", event); | 829 | printf("sched_fork event %p\n", event); |
776 | printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid); | 830 | printf("... parent: %s/%d\n", fork_event.parent_comm, fork_event.parent_pid); |
777 | printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid); | 831 | printf("... child: %s/%d\n", fork_event.child_comm, fork_event.child_pid); |
778 | } | 832 | } |
779 | register_pid(fork_event->parent_pid, fork_event->parent_comm); | 833 | register_pid(fork_event.parent_pid, fork_event.parent_comm); |
780 | register_pid(fork_event->child_pid, fork_event->child_comm); | 834 | register_pid(fork_event.child_pid, fork_event.child_comm); |
781 | } | 835 | } |
782 | 836 | ||
783 | static void process_sched_exit_event(struct event *event, | 837 | static void process_sched_exit_event(struct event *event, |
@@ -791,10 +845,7 @@ static void | |||
791 | process_raw_event(event_t *raw_event __used, void *more_data, | 845 | process_raw_event(event_t *raw_event __used, void *more_data, |
792 | int cpu, u64 timestamp, struct thread *thread) | 846 | int cpu, u64 timestamp, struct thread *thread) |
793 | { | 847 | { |
794 | struct { | 848 | struct raw_event_sample *raw = more_data; |
795 | u32 size; | ||
796 | char data[0]; | ||
797 | } *raw = more_data; | ||
798 | struct event *event; | 849 | struct event *event; |
799 | int type; | 850 | int type; |
800 | 851 | ||
@@ -802,13 +853,13 @@ process_raw_event(event_t *raw_event __used, void *more_data, | |||
802 | event = trace_find_event(type); | 853 | event = trace_find_event(type); |
803 | 854 | ||
804 | if (!strcmp(event->name, "sched_switch")) | 855 | if (!strcmp(event->name, "sched_switch")) |
805 | process_sched_switch_event(more_data, event, cpu, timestamp, thread); | 856 | process_sched_switch_event(raw, event, cpu, timestamp, thread); |
806 | if (!strcmp(event->name, "sched_wakeup")) | 857 | if (!strcmp(event->name, "sched_wakeup")) |
807 | process_sched_wakeup_event(more_data, event, cpu, timestamp, thread); | 858 | process_sched_wakeup_event(raw, event, cpu, timestamp, thread); |
808 | if (!strcmp(event->name, "sched_wakeup_new")) | 859 | if (!strcmp(event->name, "sched_wakeup_new")) |
809 | process_sched_wakeup_event(more_data, event, cpu, timestamp, thread); | 860 | process_sched_wakeup_event(raw, event, cpu, timestamp, thread); |
810 | if (!strcmp(event->name, "sched_process_fork")) | 861 | if (!strcmp(event->name, "sched_process_fork")) |
811 | process_sched_fork_event(more_data, event, cpu, timestamp, thread); | 862 | process_sched_fork_event(raw, event, cpu, timestamp, thread); |
812 | if (!strcmp(event->name, "sched_process_exit")) | 863 | if (!strcmp(event->name, "sched_process_exit")) |
813 | process_sched_exit_event(event, cpu, timestamp, thread); | 864 | process_sched_exit_event(event, cpu, timestamp, thread); |
814 | } | 865 | } |