perf: Use a user_data blob for perf_event (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 23 May 2016 18:37:26 +0000 (14:37 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Jun 2016 15:48:37 +0000 (11:48 -0400)
Previously, the kernel had to emit something that perfconv could interpret
as-is to build a perf_event stream.  That was limiting.  Now, the user can
pass a blob with a perf_event that the kernel will send whenever the event
fires.  Basically user_data becomes the info field in any perfmon sample.

The user can do whatever they want with this - it can even be the original
event code if they choose.

Right now, perfconv doesn't know how to handle this new format.  That'll be
sorted out next patch.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/devarch.c
kern/arch/x86/perfmon.c
kern/arch/x86/ros/perfmon.h
tools/profile/perf/perf.c
tools/profile/perf/perf_core.c
tools/profile/perf/perf_core.h

index 2a45f6e..d2372b2 100644 (file)
@@ -395,6 +395,7 @@ static long arch_perf_write(struct perf_context *pc, const void *udata,
                        kptr = get_le_u64(kptr, &pev.event);
                        kptr = get_le_u64(kptr, &pev.flags);
                        kptr = get_le_u64(kptr, &pev.trigger_count);
+                       kptr = get_le_u64(kptr, &pev.user_data);
                        kptr = arch_read_core_set(&cset, kptr, ktop);
 
                        ped = perfmon_open_event(&cset, pc->ps, &pev);
index f48d683..05e46a3 100644 (file)
@@ -378,13 +378,7 @@ void perfmon_pcpu_init(void)
 
 static uint64_t perfmon_make_sample_event(const struct perfmon_event *pev)
 {
-       uint64_t ei = ((uint64_t) PMEV_GET_MASK(pev->event) << 8) |
-               PMEV_GET_EVENT(pev->event);
-
-       if (perfmon_is_fixed_event(pev))
-               ei |= 1 << 16;
-
-       return PROF_MKINFO(PROF_DOM_PMU, ei);
+       return pev->user_data;
 }
 
 void perfmon_interrupt(struct hw_trapframe *hw_tf, void *data)
index aa7091c..b63ad94 100644 (file)
@@ -24,6 +24,7 @@
  *   U64 EVENT_DESCRIPTOR;
  *   U64 EVENT_FLAGS;
  *   U64 EVENT_TRIGGER_COUNT;
+ *   U64 EVENT_USER_DATA;
  *   U32 NUM_CPUMASK_BYTES;
  *   U8 CPUMASK_BYTES[NUM_CPUMASK_BYTES];
  * PERFMON_CMD_COUNTER_OPEN response
@@ -103,6 +104,7 @@ struct perfmon_event {
        uint64_t event;
        uint64_t flags;
        uint64_t trigger_count;
+       uint64_t user_data;
 };
 
 static inline void perfmon_init_event(struct perfmon_event *pev)
index b1c69ee..1fd615b 100644 (file)
@@ -165,10 +165,10 @@ int main(int argc, char *argv[])
                        usage(argv[0]);
 
                for (i = 0; i < num_events; i++) {
-                       struct perf_eventsel sel;
+                       struct perf_eventsel *sel;
 
-                       perf_parse_event(events[i], &sel);
-                       perf_context_event_submit(pctx, &cores, &sel);
+                       sel = perf_parse_event(events[i]);
+                       perf_context_event_submit(pctx, &cores, sel);
                }
 
                if (!strcmp(argv[icmd], "sleep") && (icmd + 1) < argc)
index 6508085..702c3d7 100644 (file)
@@ -237,13 +237,16 @@ static bool parse_raw_encoding(const char *str, struct perf_eventsel *sel)
  * part of the event string.
  *
  * Kills the program on failure. */
-void perf_parse_event(const char *str, struct perf_eventsel *sel)
+struct perf_eventsel *perf_parse_event(const char *str)
 {
-       ZERO_DATA(*sel);
+       struct perf_eventsel *sel = xzmalloc(sizeof(struct perf_eventsel));
+
+       sel->ev.user_data = (uint64_t)sel;
        if (parse_os_encoding(str, sel))
                goto success;
        if (parse_raw_encoding(str, sel))
                goto success;
+       free(sel);
        fprintf(stderr, "Failed to parse event string %s\n", str);
        exit(-1);
 success:
@@ -252,6 +255,7 @@ success:
                PMEV_SET_USR(sel->ev.event, 1);
        }
        PMEV_SET_EN(sel->ev.event, 1);
+       return sel;
 }
 
 static void perf_get_arch_info(int perf_fd, struct perf_arch_info *pai)
@@ -286,6 +290,7 @@ static int perf_open_event(int perf_fd, const struct core_set *cores,
        wptr = put_le_u64(wptr, sel->ev.event);
        wptr = put_le_u64(wptr, sel->ev.flags);
        wptr = put_le_u64(wptr, sel->ev.trigger_count);
+       wptr = put_le_u64(wptr, sel->ev.user_data);
 
        for (i = CORE_SET_SIZE - 1; (i >= 0) && !cores->core_set[i]; i--)
                ;
index ea780bd..50b4f6f 100644 (file)
@@ -54,7 +54,7 @@ struct perf_context_config {
 
 void perf_initialize(int argc, char *argv[]);
 void perf_finalize(void);
-void perf_parse_event(const char *str, struct perf_eventsel *sel);
+struct perf_eventsel *perf_parse_event(const char *str);
 struct perf_context *perf_create_context(const struct perf_context_config *cfg);
 void perf_free_context(struct perf_context *pctx);
 void perf_flush_context_traces(struct perf_context *pctx);