perfmon: fix pmc hw indices out-dated when multiple pmc 47/18447/2
authorSu Wang <su.z.wang@ericsson.com>
Thu, 21 Mar 2019 04:14:14 +0000 (00:14 -0400)
committerDamjan Marion <dmarion@me.com>
Tue, 26 Mar 2019 11:44:43 +0000 (11:44 +0000)
When adding two or more events using a single "set pmc",
the pmc hardware indices might be out-dated due to kernel
reschdeduling the perf_event hardware counters.
E.g. set pmc cpu-cycles cache-misses

Solution:
Open and enable all the events first, then aquire the
indices from the kernel.

Change-Id: I6913a871ab169e3b2855ac6159f527a1fca343e9
Signed-off-by: Su Wang <su.z.wang@ericsson.com>
src/plugins/perfmon/perfmon_periodic.c

index 12a1891..944a8e3 100644 (file)
@@ -171,19 +171,31 @@ enable_current_events (perfmon_main_t * pm)
       if (ioctl (fd, PERF_EVENT_IOC_ENABLE, 0) < 0)
        clib_unix_warning ("enable ioctl");
 
+      pm->perf_event_pages[i][my_thread_index] = (void *) p;
+      pm->pm_fds[i][my_thread_index] = fd;
+    }
+
+  /*
+   * Hardware events must be all opened and enabled before aquiring
+   * pmc indices, otherwise the pmc indices might be out-dated.
+   */
+  for (i = 0; i < limit; i++)
+    {
+      p =
+       (struct perf_event_mmap_page *)
+       pm->perf_event_pages[i][my_thread_index];
+
       /*
        * Software event counters - and others not capable of being
        * read via the "rdpmc" instruction - will be read
        * by system calls.
        */
-      if (pe.type == PERF_TYPE_SOFTWARE || p->cap_user_rdpmc == 0)
+      if (p == 0 || p->cap_user_rdpmc == 0)
        index = ~0;
       else
        index = p->index - 1;
 
       pm->rdpmc_indices[i][my_thread_index] = index;
-      pm->perf_event_pages[i][my_thread_index] = (void *) p;
-      pm->pm_fds[i][my_thread_index] = fd;
     }
 
   pm->n_active = i;