blob: 5b904a632e31be300b283bc9f05e1bcf8d7a206f [file] [log] [blame]
Damjan Mariond5045e62022-04-06 21:16:37 +02001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2022 Cisco Systems, Inc.
3 */
4
5#ifndef included_perfmon_perfmon_h
6#define included_perfmon_perfmon_h
7
8#include <vppinfra/cpu.h>
9#ifdef __linux__
10#include <sys/ioctl.h>
11#include <linux/perf_event.h>
12#endif
13
14#define CLIB_PERFMON_MAX_EVENTS 7
15typedef struct
16{
17 char *name;
18 char *desc;
19 u64 config[CLIB_PERFMON_MAX_EVENTS];
20 u32 type;
21 u8 n_events;
22 format_function_t *format_fn;
23 char **column_headers;
24} clib_perfmon_bundle_t;
25
26typedef struct
27{
28 u64 time_enabled;
29 u64 time_running;
30 u64 data[CLIB_PERFMON_MAX_EVENTS];
31 u8 *desc;
32 u32 n_ops;
33 u32 group;
34} clib_perfmon_capture_t;
35
36typedef struct
37{
38 u8 *name;
39 u32 start;
40} clib_perfmon_capture_group_t;
41
42typedef struct
43{
44 int group_fd;
45 int *fds;
46 clib_perfmon_bundle_t *bundle;
47 u64 *data;
48 u8 debug : 1;
49 u32 n_captures;
50 clib_perfmon_capture_t *captures;
51 clib_perfmon_capture_group_t *capture_groups;
52 f64 ref_clock;
53} clib_perfmon_ctx_t;
54
55typedef struct clib_perfmon_bundle_reg
56{
57 clib_perfmon_bundle_t *bundle;
58 struct clib_perfmon_bundle_reg *next;
59} clib_perfmon_bundle_reg_t;
60
61typedef struct
62{
63 clib_perfmon_bundle_reg_t *bundle_regs;
64} clib_perfmon_main_t;
65
66extern clib_perfmon_main_t clib_perfmon_main;
67
68static_always_inline void
69clib_perfmon_ioctl (int fd, u32 req)
70{
Tom Jones7ec62fb2024-01-25 10:28:16 +000071#ifdef __linux__
Damjan Mariond5045e62022-04-06 21:16:37 +020072#ifdef __x86_64__
Guillaume Solignac6da77402022-04-13 12:03:48 +020073 asm volatile("syscall"
74 :
75 : "D"(fd), "S"(req), "a"(__NR_ioctl), "d"(PERF_IOC_FLAG_GROUP)
76 : "rcx", "r11" /* registers modified by kernel */);
Damjan Mariond5045e62022-04-06 21:16:37 +020077#else
78 ioctl (fd, req, PERF_IOC_FLAG_GROUP);
79#endif
Tom Jones7ec62fb2024-01-25 10:28:16 +000080#endif /* linux */
Damjan Mariond5045e62022-04-06 21:16:37 +020081}
82
83clib_error_t *clib_perfmon_init_by_bundle_name (clib_perfmon_ctx_t *ctx,
84 char *fmt, ...);
85void clib_perfmon_free (clib_perfmon_ctx_t *ctx);
86void clib_perfmon_warmup (clib_perfmon_ctx_t *ctx);
87void clib_perfmon_clear (clib_perfmon_ctx_t *ctx);
88u64 *clib_perfmon_capture (clib_perfmon_ctx_t *ctx, u32 n_ops, char *fmt, ...);
89void clib_perfmon_capture_group (clib_perfmon_ctx_t *ctx, char *fmt, ...);
90format_function_t format_perfmon_bundle;
91
Tom Jones7ec62fb2024-01-25 10:28:16 +000092#ifdef __linux__
Damjan Mariond5045e62022-04-06 21:16:37 +020093static_always_inline void
94clib_perfmon_reset (clib_perfmon_ctx_t *ctx)
95{
96 clib_perfmon_ioctl (ctx->group_fd, PERF_EVENT_IOC_RESET);
97}
98static_always_inline void
99clib_perfmon_enable (clib_perfmon_ctx_t *ctx)
100{
101 clib_perfmon_ioctl (ctx->group_fd, PERF_EVENT_IOC_ENABLE);
102}
103static_always_inline void
104clib_perfmon_disable (clib_perfmon_ctx_t *ctx)
105{
106 clib_perfmon_ioctl (ctx->group_fd, PERF_EVENT_IOC_DISABLE);
107}
Tom Jones7ec62fb2024-01-25 10:28:16 +0000108#elif __FreeBSD__
109static_always_inline void
110clib_perfmon_reset (clib_perfmon_ctx_t *ctx)
111{
112 /* TODO: Implement for FreeBSD */
113}
114static_always_inline void
115clib_perfmon_enable (clib_perfmon_ctx_t *ctx)
116{
117 /* TODO: Implement for FreeBSD */
118}
119static_always_inline void
120clib_perfmon_disable (clib_perfmon_ctx_t *ctx)
121{
122 /* TODO: Implement for FreeBSD */
123}
124#endif /* linux */
Damjan Mariond5045e62022-04-06 21:16:37 +0200125
126#define CLIB_PERFMON_BUNDLE(x) \
127 static clib_perfmon_bundle_reg_t clib_perfmon_bundle_reg_##x; \
128 static clib_perfmon_bundle_t clib_perfmon_bundle_##x; \
129 static void __clib_constructor clib_perfmon_bundle_reg_fn_##x (void) \
130 { \
131 clib_perfmon_bundle_reg_##x.bundle = &clib_perfmon_bundle_##x; \
132 clib_perfmon_bundle_reg_##x.next = clib_perfmon_main.bundle_regs; \
133 clib_perfmon_main.bundle_regs = &clib_perfmon_bundle_reg_##x; \
134 } \
135 static clib_perfmon_bundle_t clib_perfmon_bundle_##x
136
137#endif