@@ -20,6 +20,7 @@ static const char *__doc_err_only__=
20
20
#include <unistd.h>
21
21
#include <locale.h>
22
22
23
+ #include <sys/resource.h>
23
24
#include <getopt.h>
24
25
#include <net/if.h>
25
26
#include <time.h>
@@ -89,6 +90,23 @@ static const char *err2str(int err)
89
90
return redir_names [err ];
90
91
return NULL ;
91
92
}
93
+ /* enum xdp_action */
94
+ #define XDP_UNKNOWN XDP_REDIRECT + 1
95
+ #define XDP_ACTION_MAX (XDP_UNKNOWN + 1)
96
+ static const char * xdp_action_names [XDP_ACTION_MAX ] = {
97
+ [XDP_ABORTED ] = "XDP_ABORTED" ,
98
+ [XDP_DROP ] = "XDP_DROP" ,
99
+ [XDP_PASS ] = "XDP_PASS" ,
100
+ [XDP_TX ] = "XDP_TX" ,
101
+ [XDP_REDIRECT ] = "XDP_REDIRECT" ,
102
+ [XDP_UNKNOWN ] = "XDP_UNKNOWN" ,
103
+ };
104
+ static const char * action2str (int action )
105
+ {
106
+ if (action < XDP_ACTION_MAX )
107
+ return xdp_action_names [action ];
108
+ return NULL ;
109
+ }
92
110
93
111
struct record {
94
112
__u64 counter ;
@@ -97,46 +115,80 @@ struct record {
97
115
98
116
struct stats_record {
99
117
struct record xdp_redir [REDIR_RES_MAX ];
118
+ struct record xdp_exception [XDP_ACTION_MAX ];
100
119
};
101
120
102
121
static void stats_print_headers (bool err_only )
103
122
{
104
123
if (err_only )
105
124
printf ("\n%s\n" , __doc_err_only__ );
106
125
107
- printf ("%-14s %-10s %-18s %-9s\n" ,
108
- "XDP_REDIRECT" , "pps " , "pps-human-readable" , "measure-period" );
126
+ printf ("%-14s %-11s %-10s %-18s %-9s\n" ,
127
+ "ACTION" , "result" , "pps " , "pps-human-readable" , "measure-period" );
128
+ }
129
+
130
+ static double calc_period (struct record * r , struct record * p )
131
+ {
132
+ double period_ = 0 ;
133
+ __u64 period = 0 ;
134
+
135
+ period = r -> timestamp - p -> timestamp ;
136
+ if (period > 0 )
137
+ period_ = ((double ) period / NANOSEC_PER_SEC );
138
+
139
+ return period_ ;
140
+ }
141
+
142
+ static double calc_pps (struct record * r , struct record * p , double period )
143
+ {
144
+ __u64 packets = 0 ;
145
+ double pps = 0 ;
146
+
147
+ if (period > 0 ) {
148
+ packets = r -> counter - p -> counter ;
149
+ pps = packets / period ;
150
+ }
151
+ return pps ;
109
152
}
110
153
111
154
static void stats_print (struct stats_record * rec ,
112
155
struct stats_record * prev ,
113
156
bool err_only )
114
157
{
158
+ double period = 0 , pps = 0 ;
159
+ struct record * r , * p ;
115
160
int i = 0 ;
116
161
162
+ char * fmt = "%-14s %-11s %-10.0f %'-18.0f %f\n" ;
163
+
164
+ /* tracepoint: xdp:xdp_redirect_* */
117
165
if (err_only )
118
166
i = REDIR_ERROR ;
119
167
120
168
for (; i < REDIR_RES_MAX ; i ++ ) {
121
- struct record * r = & rec -> xdp_redir [i ];
122
- struct record * p = & prev -> xdp_redir [i ];
123
- __u64 period = 0 ;
124
- __u64 packets = 0 ;
125
- double pps = 0 ;
126
- double period_ = 0 ;
169
+ r = & rec -> xdp_redir [i ];
170
+ p = & prev -> xdp_redir [i ];
127
171
128
172
if (p -> timestamp ) {
129
- packets = r -> counter - p -> counter ;
130
- period = r -> timestamp - p -> timestamp ;
131
- if (period > 0 ) {
132
- period_ = ((double ) period / NANOSEC_PER_SEC );
133
- pps = packets / period_ ;
134
- }
173
+ period = calc_period (r , p );
174
+ pps = calc_pps (r , p , period );
135
175
}
176
+ printf (fmt , "XDP_REDIRECT" , err2str (i ), pps , pps , period );
177
+ }
136
178
137
- printf ("%-14s %-10.0f %'-18.0f %f\n" ,
138
- err2str (i ), pps , pps , period_ );
179
+ /* tracepoint: xdp:xdp_exception */
180
+ for (i = 0 ; i < XDP_ACTION_MAX ; i ++ ) {
181
+ r = & rec -> xdp_exception [i ];
182
+ p = & prev -> xdp_exception [i ];
183
+ if (p -> timestamp ) {
184
+ period = calc_period (r , p );
185
+ pps = calc_pps (r , p , period );
186
+ }
187
+ if (pps > 0 )
188
+ printf (fmt , action2str (i ), "Exception" ,
189
+ pps , pps , period );
139
190
}
191
+ printf ("\n" );
140
192
}
141
193
142
194
static __u64 get_key32_value64_percpu (int fd , __u32 key )
@@ -160,25 +212,33 @@ static __u64 get_key32_value64_percpu(int fd, __u32 key)
160
212
return sum ;
161
213
}
162
214
163
- static bool stats_collect (int fd , struct stats_record * rec )
215
+ static bool stats_collect (struct stats_record * rec )
164
216
{
217
+ int fd ;
165
218
int i ;
166
219
167
220
/* TODO: Detect if someone unloaded the perf event_fd's, as
168
221
* this can happen by someone running perf-record -e
169
222
*/
170
223
224
+ fd = map_data [0 ].fd ; /* map0: redirect_err_cnt */
171
225
for (i = 0 ; i < REDIR_RES_MAX ; i ++ ) {
172
226
rec -> xdp_redir [i ].timestamp = gettime ();
173
227
rec -> xdp_redir [i ].counter = get_key32_value64_percpu (fd , i );
174
228
}
229
+
230
+ fd = map_data [1 ].fd ; /* map1: exception_cnt */
231
+ for (i = 0 ; i < XDP_ACTION_MAX ; i ++ ) {
232
+ rec -> xdp_exception [i ].timestamp = gettime ();
233
+ rec -> xdp_exception [i ].counter = get_key32_value64_percpu (fd , i );
234
+ }
235
+
175
236
return true;
176
237
}
177
238
178
239
static void stats_poll (int interval , bool err_only )
179
240
{
180
241
struct stats_record rec , prev ;
181
- int map_fd ;
182
242
183
243
memset (& rec , 0 , sizeof (rec ));
184
244
@@ -190,16 +250,17 @@ static void stats_poll(int interval, bool err_only)
190
250
printf ("\n%s" , __doc__ );
191
251
192
252
/* TODO Need more advanced stats on error types */
193
- if (verbose )
194
- printf (" - Stats map : %s\n" , map_data [0 ].name );
195
- map_fd = map_data [0 ]. fd ;
196
-
197
- stats_print_headers ( err_only );
253
+ if (verbose ) {
254
+ printf (" - Stats map0 : %s\n" , map_data [0 ].name );
255
+ printf ( " - Stats map1: %s\n" , map_data [1 ]. name ) ;
256
+ printf ( "\n" );
257
+ }
198
258
fflush (stdout );
199
259
200
260
while (1 ) {
201
261
memcpy (& prev , & rec , sizeof (rec ));
202
- stats_collect (map_fd , & rec );
262
+ stats_collect (& rec );
263
+ stats_print_headers (err_only );
203
264
stats_print (& rec , & prev , err_only );
204
265
fflush (stdout );
205
266
sleep (interval );
@@ -235,6 +296,7 @@ static void print_bpf_prog_info(void)
235
296
236
297
int main (int argc , char * * argv )
237
298
{
299
+ struct rlimit r = {RLIM_INFINITY , RLIM_INFINITY };
238
300
int longindex = 0 , opt ;
239
301
int ret = EXIT_SUCCESS ;
240
302
char bpf_obj_file [256 ];
@@ -265,13 +327,18 @@ int main(int argc, char **argv)
265
327
}
266
328
}
267
329
330
+ if (setrlimit (RLIMIT_MEMLOCK , & r )) {
331
+ perror ("setrlimit(RLIMIT_MEMLOCK)" );
332
+ return EXIT_FAILURE ;
333
+ }
334
+
268
335
if (load_bpf_file (bpf_obj_file )) {
269
336
printf ("ERROR - bpf_log_buf: %s" , bpf_log_buf );
270
- return 1 ;
337
+ return EXIT_FAILURE ;
271
338
}
272
339
if (!prog_fd [0 ]) {
273
340
printf ("ERROR - load_bpf_file: %s\n" , strerror (errno ));
274
- return 1 ;
341
+ return EXIT_FAILURE ;
275
342
}
276
343
277
344
if (debug ) {
0 commit comments