Adding support to parse user data event and prepare
it for later processing.

Link: http://lkml.kernel.org/n/[email protected]
Signed-off-by: Jiri Olsa <[email protected]>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   |  8 ++++++++
 tools/perf/util/evsel.c   | 20 ++++++++++++++++++--
 tools/perf/util/session.c | 23 +++++++++++++++++------
 tools/perf/util/tool.h    |  1 +
 5 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 44e603c27944..89f20ae9d949 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -43,6 +43,7 @@ static const char *perf_event__names[] = {
        [PERF_RECORD_SWITCH]                    = "SWITCH",
        [PERF_RECORD_SWITCH_CPU_WIDE]           = "SWITCH_CPU_WIDE",
        [PERF_RECORD_NAMESPACES]                = "NAMESPACES",
+       [PERF_RECORD_USER_DATA]                 = "USER_DATA",
        [PERF_RECORD_HEADER_ATTR]               = "ATTR",
        [PERF_RECORD_HEADER_EVENT_TYPE]         = "EVENT_TYPE",
        [PERF_RECORD_HEADER_TRACING_DATA]       = "TRACING_DATA",
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 546539da1592..5ac657aebb67 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -99,6 +99,12 @@ struct sample_event {
        u64 array[];
 };
 
+struct user_data_event {
+       struct perf_event_header        header;
+       u64 type;
+       u64 array[];
+};
+
 struct regs_dump {
        u64 abi;
        u64 mask;
@@ -203,6 +209,7 @@ struct perf_sample {
        u32 raw_size;
        u64 data_src;
        u64 phys_addr;
+       u64 user_data_id;
        u32 flags;
        u16 insn_len;
        u8  cpumode;
@@ -633,6 +640,7 @@ union perf_event {
        struct read_event               read;
        struct throttle_event           throttle;
        struct sample_event             sample;
+       struct user_data_event          user_data;
        struct attr_event               attr;
        struct event_update_event       event_update;
        struct event_type_event         event_type;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 035da5d1fdd3..6f6eab6bc108 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1508,7 +1508,7 @@ static void __p_sample_type(char *buf, size_t size, u64 
value)
                bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW),
                bit_name(BRANCH_STACK), bit_name(REGS_USER), 
bit_name(STACK_USER),
                bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC),
-               bit_name(WEIGHT), bit_name(PHYS_ADDR),
+               bit_name(WEIGHT), bit_name(PHYS_ADDR), bit_name(USER_DATA_ID),
                { .name = NULL, }
        };
 #undef bit_name
@@ -1602,6 +1602,7 @@ int perf_event_attr__fprintf(FILE *fp, struct 
perf_event_attr *attr,
        PRINT_ATTRf(context_switch, p_unsigned);
        PRINT_ATTRf(write_backward, p_unsigned);
        PRINT_ATTRf(namespaces, p_unsigned);
+       PRINT_ATTRf(user_data, p_unsigned);
 
        PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, 
p_unsigned);
        PRINT_ATTRf(bp_type, p_unsigned);
@@ -2310,6 +2311,10 @@ perf_sample__parse(struct perf_sample *data, struct 
parse_args *arg)
                array++;
        }
 
+       if (type & PERF_SAMPLE_USER_DATA_ID) {
+               data->user_data_id = *array;
+               array++;
+       }
        return 0;
 }
 
@@ -2335,7 +2340,15 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, 
union perf_event *event,
        if (event->header.type != PERF_RECORD_SAMPLE) {
                if (!evsel->attr.sample_id_all)
                        return 0;
-               return perf_evsel__parse_id_sample(evsel, event, data);
+
+               perf_evsel__parse_id_sample(evsel, event, data);
+
+               if (event->header.type != PERF_RECORD_USER_DATA)
+                       return 0;
+
+               arg.type  = event->user_data.type;
+               arg.array = event->user_data.array;
+               return perf_sample__parse(data, &arg);
        }
 
        if (perf_event__check_size(event, evsel->sample_size))
@@ -2493,6 +2506,9 @@ size_t perf_event__sample_event_size(const struct 
perf_sample *sample, u64 type,
        if (type & PERF_SAMPLE_PHYS_ADDR)
                result += sizeof(u64);
 
+       if (type & PERF_SAMPLE_USER_DATA_ID)
+               result += sizeof(u64);
+
        return result;
 }
 
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index da0635e2f100..cb910ea6f0a0 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -361,6 +361,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 {
        if (tool->sample == NULL)
                tool->sample = process_event_sample_stub;
+       if (tool->user_data == NULL)
+               tool->user_data = process_event_sample_stub;
        if (tool->mmap == NULL)
                tool->mmap = process_event_stub;
        if (tool->mmap2 == NULL)
@@ -1127,6 +1129,13 @@ static void dump_sample(struct perf_evsel *evsel, union 
perf_event *event,
        if (sample_type & PERF_SAMPLE_TRANSACTION)
                printf("... transaction: %" PRIx64 "\n", sample->transaction);
 
+       if (sample_type & PERF_SAMPLE_USER_DATA_ID) {
+               if (sample->misc & PERF_RECORD_MISC_USER_DATA)
+                       printf("... user data ID: %" PRIu64 "\n", 
sample->user_data_id);
+               else
+                       printf("... user data ID: N/A\n");
+       }
+
        if (sample_type & PERF_SAMPLE_READ)
                sample_read__printf(sample, evsel->attr.read_format);
 }
@@ -1225,12 +1234,12 @@ static int deliver_sample_group(struct perf_evlist 
*evlist,
 }
 
 static int
- perf_evlist__deliver_sample(struct perf_evlist *evlist,
-                            struct perf_tool *tool,
-                            union  perf_event *event,
-                            struct perf_sample *sample,
-                            struct perf_evsel *evsel,
-                            struct machine *machine)
+perf_evlist__deliver_sample(struct perf_evlist *evlist,
+                           struct perf_tool *tool,
+                           union  perf_event *event,
+                           struct perf_sample *sample,
+                           struct perf_evsel *evsel,
+                           struct machine *machine)
 {
        /* We know evsel != NULL. */
        u64 sample_type = evsel->attr.sample_type;
@@ -1276,6 +1285,8 @@ static int machines__deliver_event(struct machines 
*machines,
                        return 0;
                }
                return perf_evlist__deliver_sample(evlist, tool, event, sample, 
evsel, machine);
+       case PERF_RECORD_USER_DATA:
+               return tool->user_data(tool, event, sample, evsel, machine);
        case PERF_RECORD_MMAP:
                return tool->mmap(tool, event, sample, machine);
        case PERF_RECORD_MMAP2:
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index 183c91453522..9ae190d4d0aa 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -43,6 +43,7 @@ enum show_feature_header {
 
 struct perf_tool {
        event_sample    sample,
+                       user_data,
                        read;
        event_op        mmap,
                        mmap2,
-- 
2.13.6

Reply via email to