aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-sched.c101
-rw-r--r--tools/perf/util/trace-event-parse.c23
-rw-r--r--tools/perf/util/trace-event.h3
3 files changed, 102 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
657struct 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) \
666do { \
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) \
672do { \
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
656struct trace_wakeup_event { 680struct trace_wakeup_event {
657 u32 size; 681 u32 size;
658 682
@@ -671,22 +695,32 @@ struct trace_wakeup_event {
671}; 695};
672 696
673static void 697static void
674process_sched_wakeup_event(struct trace_wakeup_event *wakeup_event, struct event *event, 698process_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 {
714unsigned long cpu_last_switched[MAX_CPUS]; 748unsigned long cpu_last_switched[MAX_CPUS];
715 749
716static void 750static void
717process_sched_switch_event(struct trace_switch_event *switch_event, struct event *event, 751process_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
755struct trace_fork_event { 800struct trace_fork_event {
@@ -768,16 +813,25 @@ struct trace_fork_event {
768}; 813};
769 814
770static void 815static void
771process_sched_fork_event(struct trace_fork_event *fork_event, struct event *event, 816process_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
783static void process_sched_exit_event(struct event *event, 837static void process_sched_exit_event(struct event *event,
@@ -791,10 +845,7 @@ static void
791process_raw_event(event_t *raw_event __used, void *more_data, 845process_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}
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 16cf2d51c4e1..64d6e302751a 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1776,6 +1776,29 @@ static unsigned long long read_size(void *ptr, int size)
1776 } 1776 }
1777} 1777}
1778 1778
1779unsigned long long
1780raw_field_value(struct event *event, const char *name, void *data)
1781{
1782 struct format_field *field;
1783
1784 field = find_any_field(event, name);
1785 if (!field)
1786 return 0ULL;
1787
1788 return read_size(data + field->offset, field->size);
1789}
1790
1791void *raw_field_ptr(struct event *event, const char *name, void *data)
1792{
1793 struct format_field *field;
1794
1795 field = find_any_field(event, name);
1796 if (!field)
1797 return NULL;
1798
1799 return data + field->offset;
1800}
1801
1779static int get_common_info(const char *type, int *offset, int *size) 1802static int get_common_info(const char *type, int *offset, int *size)
1780{ 1803{
1781 struct event *event; 1804 struct event *event;
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index bc81612fd244..d35ebf1e29ff 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -236,6 +236,9 @@ extern int header_page_data_size;
236int parse_header_page(char *buf, unsigned long size); 236int parse_header_page(char *buf, unsigned long size);
237int trace_parse_common_type(void *data); 237int trace_parse_common_type(void *data);
238struct event *trace_find_event(int id); 238struct event *trace_find_event(int id);
239unsigned long long
240raw_field_value(struct event *event, const char *name, void *data);
241void *raw_field_ptr(struct event *event, const char *name, void *data);
239 242
240void read_tracing_data(struct perf_counter_attr *pattrs, int nb_counters); 243void read_tracing_data(struct perf_counter_attr *pattrs, int nb_counters);
241 244