21 #include <asm/unistd.h> 22 #include <sys/ioctl.h> 27 int group_fd,
unsigned long flags)
31 ret = syscall (__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
49 cc = (i == 0) ? c0 : c1;
56 if ((read_result = read (pm->
pm_fds[i][my_thread_index], &sw_value,
57 sizeof (sw_value)) !=
sizeof (sw_value)))
60 (
"counter read returned %d, expected %d",
61 read_result,
sizeof (sw_value));
118 struct perf_event_attr pe;
120 struct perf_event_mmap_page *p = 0;
131 for (i = 0; i < limit; i++)
136 memset (&pe, 0,
sizeof (
struct perf_event_attr));
138 pe.size =
sizeof (
struct perf_event_attr);
146 if (pe.type != PERF_TYPE_SOFTWARE)
149 pe.exclude_kernel = 1;
163 if (pe.type != PERF_TYPE_SOFTWARE)
165 p = mmap (0, pm->
page_size, PROT_READ, MAP_SHARED, fd, 0);
176 if (ioctl (fd, PERF_EVENT_IOC_RESET, 0) < 0)
179 if (ioctl (fd, PERF_EVENT_IOC_ENABLE, 0) < 0)
183 pm->
pm_fds[
i][my_thread_index] = fd;
190 for (i = 0; i < limit; i++)
193 (
struct perf_event_mmap_page *)
201 if (p == 0 || p->cap_user_rdpmc == 0)
204 index = p->index - 1;
234 if (pm->
pm_fds[i][my_thread_index] == 0)
237 if (ioctl (pm->
pm_fds[i][my_thread_index], PERF_EVENT_IOC_DISABLE, 0) <
246 (void) close (pm->
pm_fds[i][my_thread_index]);
247 pm->
pm_fds[
i][my_thread_index] = 0;
289 all = (last_set == ~0);
309 (
vlib_mains[i]->worker_thread_main_loop_callbacks,
310 vlib_mains[i]->worker_thread_main_loop_callback_tmp,
311 vlib_mains[i]->worker_thread_main_loop_callback_lock,
330 u64 vectors_this_counter;
376 nodes = node_dups[j];
378 for (i = 0; i <
vec_len (nodes); i++)
388 for (k = 0; k < 2; k++)
390 u64 counter_value, counter_last_clear;
414 capture_name =
format (0,
"t%d-%v%c", j, n->
name, 0);
422 memset (c, 0,
sizeof (*c));
436 counter_name = (
u8 *) current_event->
name;
442 counter_value - counter_last_clear);
460 all = (last_set == ~0);
472 (
vlib_mains[i]->worker_thread_main_loop_callbacks,
473 vlib_mains[i]->worker_thread_main_loop_callback_tmp,
474 vlib_mains[i]->worker_thread_main_loop_callback_lock,
487 (
vlib_mains[i]->worker_thread_main_loop_callbacks,
488 vlib_mains[i]->worker_thread_main_loop_callback_lock,
519 (
vlib_mains[i]->worker_thread_main_loop_callbacks,
520 vlib_mains[i]->worker_thread_main_loop_callback_tmp,
521 vlib_mains[i]->worker_thread_main_loop_callback_lock,
532 uword *event_data = 0;
550 for (i = 0; i <
vec_len (event_data); i++)
573 .name =
"perfmon-periodic-process",
perfmon_capture_t * capture_pool
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static void worker_thread_start_event(vlib_main_t *vm)
u64 * vectors_this_counter
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
static void clear_counters(perfmon_main_t *pm)
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags)
clib_spinlock_t worker_thread_main_loop_callback_lock
#define clib_memcpy_fast(a, b, c)
static void disable_events(perfmon_main_t *pm)
static f64 vlib_time_now(vlib_main_t *vm)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static void enable_current_events(perfmon_main_t *pm)
#define hash_set_mem(h, key, value)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
vlib_main_t ** vlib_mains
void(** vlib_node_runtime_perf_counter_cb_tmp)(struct vlib_main_t *, u64 *, u64 *, vlib_node_runtime_t *, vlib_frame_t *, int)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define vlib_worker_thread_barrier_sync(X)
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
vlib_node_stats_t stats_last_clear
void(** vlib_node_runtime_perf_counter_cbs)(struct vlib_main_t *, u64 *, u64 *, vlib_node_runtime_t *, vlib_frame_t *, int)
void(**volatile worker_thread_main_loop_callback_tmp)(struct vlib_main_t *)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 * thread_and_node_name
void scrape_and_clear_counters(perfmon_main_t *pm)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vlib_node_stats_t stats_total
static uword clib_bitmap_last_set(uword *ai)
Return the higest numbered set bit in a bitmap.
#define clib_callback_is_set(h, l, f)
predicate function says whether the specified function is enabled
static void worker_thread_stop_event(vlib_main_t *vm)
#define VLIB_REGISTER_NODE(x,...)
static void handle_timeout(vlib_main_t *vm, perfmon_main_t *pm, f64 now)
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
#define clib_callback_enable_disable(h, tmp, l, f, enable)
Add or remove a callback to the specified callback set.
static void clib_mem_free(void *p)
perfmon_event_config_t * single_events_to_collect
static u64 clib_rdpmc(int counter_id)
perfmon_main_t perfmon_main
static void * clib_mem_alloc(uword size)
void(**volatile worker_thread_main_loop_callbacks)(struct vlib_main_t *)
static vlib_main_t * vlib_get_main(void)
uword * capture_by_thread_and_node_name
static void start_event(perfmon_main_t *pm, f64 now, uword event_data)
void vlib_node_sync_stats(vlib_main_t *vm, vlib_node_t *n)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_node_main_t node_main
#define clib_unix_warning(format, args...)
#define hash_get_mem(h, key)
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
static uword perfmon_periodic_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
vlib_node_registration_t perfmon_periodic_node
(constructor) VLIB_REGISTER_NODE (perfmon_periodic_node)
static void 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)