}
static void
-read_current_perf_counters (vlib_main_t * vm, u64 * c0, u64 * c1)
+read_current_perf_counters (vlib_main_t * vm, u64 * c0, u64 * c1,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame, int before_or_after)
{
int i;
u64 *cc;
pe.exclude_hv = 1;
}
- cpu = vm->cpu_index;
+ cpu = vm->cpu_id;
fd = perf_event_open (&pe, 0, cpu, -1, 0);
if (fd == -1)
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;