vppinfra:fix pcap write large file(> 0x80000000) error.
[vpp.git] / src / vppinfra / perfmon / perfmon.h
1 /* 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
15 typedef 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
26 typedef 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
36 typedef struct
37 {
38   u8 *name;
39   u32 start;
40 } clib_perfmon_capture_group_t;
41
42 typedef 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
55 typedef 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
61 typedef struct
62 {
63   clib_perfmon_bundle_reg_t *bundle_regs;
64 } clib_perfmon_main_t;
65
66 extern clib_perfmon_main_t clib_perfmon_main;
67
68 static_always_inline void
69 clib_perfmon_ioctl (int fd, u32 req)
70 {
71 #ifdef __x86_64__
72   asm volatile("syscall"
73                :
74                : "D"(fd), "S"(req), "a"(__NR_ioctl), "d"(PERF_IOC_FLAG_GROUP)
75                : "rcx", "r11" /* registers modified by kernel */);
76 #else
77   ioctl (fd, req, PERF_IOC_FLAG_GROUP);
78 #endif
79 }
80
81 clib_error_t *clib_perfmon_init_by_bundle_name (clib_perfmon_ctx_t *ctx,
82                                                 char *fmt, ...);
83 void clib_perfmon_free (clib_perfmon_ctx_t *ctx);
84 void clib_perfmon_warmup (clib_perfmon_ctx_t *ctx);
85 void clib_perfmon_clear (clib_perfmon_ctx_t *ctx);
86 u64 *clib_perfmon_capture (clib_perfmon_ctx_t *ctx, u32 n_ops, char *fmt, ...);
87 void clib_perfmon_capture_group (clib_perfmon_ctx_t *ctx, char *fmt, ...);
88 format_function_t format_perfmon_bundle;
89
90 static_always_inline void
91 clib_perfmon_reset (clib_perfmon_ctx_t *ctx)
92 {
93   clib_perfmon_ioctl (ctx->group_fd, PERF_EVENT_IOC_RESET);
94 }
95 static_always_inline void
96 clib_perfmon_enable (clib_perfmon_ctx_t *ctx)
97 {
98   clib_perfmon_ioctl (ctx->group_fd, PERF_EVENT_IOC_ENABLE);
99 }
100 static_always_inline void
101 clib_perfmon_disable (clib_perfmon_ctx_t *ctx)
102 {
103   clib_perfmon_ioctl (ctx->group_fd, PERF_EVENT_IOC_DISABLE);
104 }
105
106 #define CLIB_PERFMON_BUNDLE(x)                                                \
107   static clib_perfmon_bundle_reg_t clib_perfmon_bundle_reg_##x;               \
108   static clib_perfmon_bundle_t clib_perfmon_bundle_##x;                       \
109   static void __clib_constructor clib_perfmon_bundle_reg_fn_##x (void)        \
110   {                                                                           \
111     clib_perfmon_bundle_reg_##x.bundle = &clib_perfmon_bundle_##x;            \
112     clib_perfmon_bundle_reg_##x.next = clib_perfmon_main.bundle_regs;         \
113     clib_perfmon_main.bundle_regs = &clib_perfmon_bundle_reg_##x;             \
114   }                                                                           \
115   static clib_perfmon_bundle_t clib_perfmon_bundle_##x
116
117 #endif