@@ -89,6 +89,23 @@ static const char *err2str(int err)
89
89
return redir_names [err ];
90
90
return NULL ;
91
91
}
92
+ /* enum xdp_action */
93
+ #define XDP_UNKNOWN XDP_REDIRECT + 1
94
+ #define XDP_ACTION_MAX (XDP_UNKNOWN + 1)
95
+ static const char * xdp_action_names [XDP_ACTION_MAX ] = {
96
+ [XDP_ABORTED ] = "XDP_ABORTED" ,
97
+ [XDP_DROP ] = "XDP_DROP" ,
98
+ [XDP_PASS ] = "XDP_PASS" ,
99
+ [XDP_TX ] = "XDP_TX" ,
100
+ [XDP_REDIRECT ] = "XDP_REDIRECT" ,
101
+ [XDP_UNKNOWN ] = "XDP_UNKNOWN" ,
102
+ };
103
+ static const char * action2str (int action )
104
+ {
105
+ if (action < XDP_ACTION_MAX )
106
+ return xdp_action_names [action ];
107
+ return NULL ;
108
+ }
92
109
93
110
struct record {
94
111
__u64 counter ;
@@ -97,46 +114,80 @@ struct record {
97
114
98
115
struct stats_record {
99
116
struct record xdp_redir [REDIR_RES_MAX ];
117
+ struct record xdp_exception [XDP_ACTION_MAX ];
100
118
};
101
119
102
120
static void stats_print_headers (bool err_only )
103
121
{
104
122
if (err_only )
105
123
printf ("\n%s\n" , __doc_err_only__ );
106
124
107
- printf ("%-14s %-10s %-18s %-9s\n" ,
108
- "XDP_REDIRECT" , "pps " , "pps-human-readable" , "measure-period" );
125
+ printf ("%-14s %-11s %-10s %-18s %-9s\n" ,
126
+ "ACTION" , "result" , "pps " , "pps-human-readable" , "measure-period" );
127
+ }
128
+
129
+ static double calc_period (struct record * r , struct record * p )
130
+ {
131
+ double period_ = 0 ;
132
+ __u64 period = 0 ;
133
+
134
+ period = r -> timestamp - p -> timestamp ;
135
+ if (period > 0 )
136
+ period_ = ((double ) period / NANOSEC_PER_SEC );
137
+
138
+ return period_ ;
139
+ }
140
+
141
+ static double calc_pps (struct record * r , struct record * p , double period )
142
+ {
143
+ __u64 packets = 0 ;
144
+ double pps = 0 ;
145
+
146
+ if (period > 0 ) {
147
+ packets = r -> counter - p -> counter ;
148
+ pps = packets / period ;
149
+ }
150
+ return pps ;
109
151
}
110
152
111
153
static void stats_print (struct stats_record * rec ,
112
154
struct stats_record * prev ,
113
155
bool err_only )
114
156
{
157
+ double period = 0 , pps = 0 ;
158
+ struct record * r , * p ;
115
159
int i = 0 ;
116
160
161
+ char * fmt = "%-14s %-11s %-10.0f %'-18.0f %f\n" ;
162
+
163
+ /* tracepoint: xdp:xdp_redirect_* */
117
164
if (err_only )
118
165
i = REDIR_ERROR ;
119
166
120
167
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 ;
168
+ r = & rec -> xdp_redir [i ];
169
+ p = & prev -> xdp_redir [i ];
127
170
128
171
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
- }
172
+ period = calc_period (r , p );
173
+ pps = calc_pps (r , p , period );
135
174
}
175
+ printf (fmt , "XDP_REDIRECT" , err2str (i ), pps , pps , period );
176
+ }
136
177
137
- printf ("%-14s %-10.0f %'-18.0f %f\n" ,
138
- err2str (i ), pps , pps , period_ );
178
+ /* tracepoint: xdp:xdp_exception */
179
+ for (i = 0 ; i < XDP_ACTION_MAX ; i ++ ) {
180
+ r = & rec -> xdp_exception [i ];
181
+ p = & prev -> xdp_exception [i ];
182
+ if (p -> timestamp ) {
183
+ period = calc_period (r , p );
184
+ pps = calc_pps (r , p , period );
185
+ }
186
+ if (pps > 0 )
187
+ printf (fmt , action2str (i ), "Exception" ,
188
+ pps , pps , period );
139
189
}
190
+ printf ("\n" );
140
191
}
141
192
142
193
static __u64 get_key32_value64_percpu (int fd , __u32 key )
@@ -160,25 +211,33 @@ static __u64 get_key32_value64_percpu(int fd, __u32 key)
160
211
return sum ;
161
212
}
162
213
163
- static bool stats_collect (int fd , struct stats_record * rec )
214
+ static bool stats_collect (struct stats_record * rec )
164
215
{
216
+ int fd ;
165
217
int i ;
166
218
167
219
/* TODO: Detect if someone unloaded the perf event_fd's, as
168
220
* this can happen by someone running perf-record -e
169
221
*/
170
222
223
+ fd = map_data [0 ].fd ; /* map0: redirect_err_cnt */
171
224
for (i = 0 ; i < REDIR_RES_MAX ; i ++ ) {
172
225
rec -> xdp_redir [i ].timestamp = gettime ();
173
226
rec -> xdp_redir [i ].counter = get_key32_value64_percpu (fd , i );
174
227
}
228
+
229
+ fd = map_data [1 ].fd ; /* map1: exception_cnt */
230
+ for (i = 0 ; i < XDP_ACTION_MAX ; i ++ ) {
231
+ rec -> xdp_exception [i ].timestamp = gettime ();
232
+ rec -> xdp_exception [i ].counter = get_key32_value64_percpu (fd , i );
233
+ }
234
+
175
235
return true;
176
236
}
177
237
178
238
static void stats_poll (int interval , bool err_only )
179
239
{
180
240
struct stats_record rec , prev ;
181
- int map_fd ;
182
241
183
242
memset (& rec , 0 , sizeof (rec ));
184
243
@@ -190,16 +249,17 @@ static void stats_poll(int interval, bool err_only)
190
249
printf ("\n%s" , __doc__ );
191
250
192
251
/* 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 );
252
+ if (verbose ) {
253
+ printf (" - Stats map0 : %s\n" , map_data [0 ].name );
254
+ printf ( " - Stats map1: %s\n" , map_data [1 ]. name ) ;
255
+ printf ( "\n" );
256
+ }
198
257
fflush (stdout );
199
258
200
259
while (1 ) {
201
260
memcpy (& prev , & rec , sizeof (rec ));
202
- stats_collect (map_fd , & rec );
261
+ stats_collect (& rec );
262
+ stats_print_headers (err_only );
203
263
stats_print (& rec , & prev , err_only );
204
264
fflush (stdout );
205
265
sleep (interval );
0 commit comments