perf: Use PERF_SAMPLE_IDENTIFIER
[akaros.git] / tools / profile / perf / perf_core.c
index 79b15b7..181d2f1 100644 (file)
@@ -467,8 +467,7 @@ static uint64_t *perf_get_event_values(int perf_fd, int ped, size_t *pnvalues)
        uint32_t i, n;
        uint64_t *values;
        uint64_t temp;
-       size_t bufsize = 3 * sizeof(uint64_t) + sizeof(uint32_t) +
-               MAX_NUM_CORES * sizeof(uint64_t);
+       size_t bufsize = sizeof(uint32_t) + MAX_NUM_CORES * sizeof(uint64_t);
        uint8_t *cmdbuf = xmalloc(bufsize);
        uint8_t *wptr = cmdbuf;
        const uint8_t *rptr = cmdbuf;
@@ -479,17 +478,11 @@ static uint64_t *perf_get_event_values(int perf_fd, int ped, size_t *pnvalues)
        xpwrite(perf_fd, cmdbuf, wptr - cmdbuf, 0);
        rsize = pread(perf_fd, cmdbuf, bufsize, 0);
 
-       if (rsize < (3 * sizeof(uint64_t) + sizeof(uint32_t))) {
+       if (rsize < (sizeof(uint32_t))) {
                fprintf(stderr, "Invalid read size while fetching event status: %ld\n",
                                rsize);
                exit(1);
        }
-
-       /* TODO: The kernel lies to us about this, it's all 0. */
-       rptr = get_le_u64(rptr, &temp);         /* discard ev.event */
-       rptr = get_le_u64(rptr, &temp);         /* discard ev.flags */
-       rptr = get_le_u64(rptr, &temp);         /* discard ev.trigger_count */
-
        rptr = get_le_u32(rptr, &n);
        if (((rptr - cmdbuf) + n * sizeof(uint64_t)) > rsize) {
                fprintf(stderr, "Invalid read size while fetching event status: %ld\n",
@@ -532,12 +525,16 @@ static void perf_close_event(int perf_fd, int ped)
        xpwrite(perf_fd, cmdbuf, wptr - cmdbuf, 0);
 }
 
-struct perf_context *perf_create_context(const struct perf_context_config *cfg)
+struct perf_context *perf_create_context(struct perf_context_config *cfg)
 {
        struct perf_context *pctx = xzmalloc(sizeof(struct perf_context));
 
+       pctx->cfg = cfg;
        pctx->perf_fd = xopen(cfg->perf_file, O_RDWR, 0);
-       pctx->kpctl_fd = xopen(cfg->kpctl_file, O_RDWR, 0);
+       /* perf record needs kpctl_fd, but other perf subcommands might not.  We'll
+        * delay the opening of kpctl until we need it, since kprof is picky about
+        * multiple users of kpctl. */
+       pctx->kpctl_fd = -1;
        perf_get_arch_info(pctx->perf_fd, &pctx->pai);
 
        return pctx;
@@ -545,7 +542,8 @@ struct perf_context *perf_create_context(const struct perf_context_config *cfg)
 
 void perf_free_context(struct perf_context *pctx)
 {
-       close(pctx->kpctl_fd);  /* disabled sampling */
+       if (pctx->kpctl_fd != -1)
+               close(pctx->kpctl_fd);  /* disabled sampling */
        close(pctx->perf_fd);   /* closes all events */
        free(pctx);
 }
@@ -577,10 +575,17 @@ void perf_stop_events(struct perf_context *pctx)
                perf_close_event(pctx->perf_fd, pctx->events[i].ped);
 }
 
+static void ensure_kpctl_is_open(struct perf_context *pctx)
+{
+       if (pctx->kpctl_fd == -1)
+               pctx->kpctl_fd = xopen(pctx->cfg->kpctl_file, O_RDWR, 0);
+}
+
 void perf_start_sampling(struct perf_context *pctx)
 {
        static const char * const enable_str = "start";
 
+       ensure_kpctl_is_open(pctx);
        xwrite(pctx->kpctl_fd, enable_str, strlen(enable_str));
 }
 
@@ -588,27 +593,20 @@ void perf_stop_sampling(struct perf_context *pctx)
 {
        static const char * const disable_str = "stop";
 
+       ensure_kpctl_is_open(pctx);
        xwrite(pctx->kpctl_fd, disable_str, strlen(disable_str));
 }
 
-void perf_context_show_values(struct perf_context *pctx, FILE *file)
+void perf_context_show_events(struct perf_context *pctx, FILE *file)
 {
-       for (int i = 0; i < pctx->event_count; i++) {
-               size_t nvalues;
-               struct perf_eventsel *sel = &pctx->events[i].sel;
-               uint64_t *values = perf_get_event_values(pctx->perf_fd,
-                                                                                                pctx->events[i].ped,
-                                                                                                &nvalues);
+       struct perf_eventsel *sel;
 
-               fprintf(file, "Event: %s, final code %p%s, trigger count %d\n\t",
+       for (int i = 0; i < pctx->event_count; i++) {
+               sel = &pctx->events[i].sel;
+               fprintf(file, "Event: %s, final code %p%s, trigger count %d\n",
                        sel->fq_str, sel->ev.event,
                        perfmon_is_fixed_event(&sel->ev) ? " (fixed)" : "",
                        sel->ev.trigger_count);
-               for (size_t j = 0; j < nvalues; j++)
-                       fprintf(file, "%lu ", values[j]);
-               fprintf(file, "\n");
-
-               free(values);
        }
 }