FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
bufmon.c
Go to the documentation of this file.
1 #include <vlib/vlib.h>
2 #include <vnet/plugin/plugin.h>
3 #include <vpp/app/version.h>
4 
5 typedef struct
6 {
7  u64 in;
12 
13 typedef struct
14 {
15  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
19 
20 typedef struct
21 {
23  int enabled;
25 
27 
28 static u32
30 {
34  u32 cur_node;
35 
36  if (PREDICT_FALSE (vm->thread_index >= vec_len (bm->ptd)))
37  {
38  clib_warning ("bufmon: thread index %d unknown for buffer %s (%d)",
39  vm->thread_index, is_free ? "free" : "alloc", n_buffers);
40  return n_buffers;
41  }
42 
43  ptd = vec_elt_at_index (bm->ptd, vm->thread_index);
44 
45  cur_node = ptd->cur_node;
46  if (cur_node >= vec_len (ptd->pnd))
47  {
50  }
51 
52  pnd = vec_elt_at_index (ptd->pnd, cur_node);
53 
54  if (is_free)
55  pnd->free += n_buffers;
56  else
57  pnd->alloc += n_buffers;
58 
59  return n_buffers;
60 }
61 
62 static u32
63 bufmon_alloc_callback (vlib_main_t *vm, u8 buffer_pool_index, u32 *buffers,
64  u32 n_buffers)
65 {
66  return bufmon_alloc_free_callback (vm, n_buffers, 0 /* is_free */);
67 }
68 
69 static u32
70 bufmon_free_callback (vlib_main_t *vm, u8 buffer_pool_index, u32 *buffers,
71  u32 n_buffers)
72 {
73  return bufmon_alloc_free_callback (vm, n_buffers, 1 /* is_free */);
74 }
75 
76 static u32
78 {
81  const u32 n = frame->n_vectors;
82  u32 nc = 0;
83  u32 i;
84 
85  vlib_get_buffers (vm, from, b, n);
86 
87  for (i = 0; i < n; i++)
88  {
89  const vlib_buffer_t *cb = b[i];
90  while (cb->flags & VLIB_BUFFER_NEXT_PRESENT)
91  {
92  nc++;
93  cb = vlib_get_buffer (vm, cb->next_buffer);
94  }
95  }
96 
97  return n + nc;
98 }
99 
100 static uword
103 {
105  bufmon_main_t *bm = &bufmon_main;
108  int pending_frames;
109  uword rv;
110 
112  ptd = vec_elt_at_index (bm->ptd, vm->thread_index);
113  vec_validate_aligned (ptd->pnd, node->node_index, CLIB_CACHE_LINE_BYTES);
114  pnd = vec_elt_at_index (ptd->pnd, node->node_index);
115 
116  if (frame)
117  pnd->in += bufmon_count_buffers (vm, frame);
118 
119  pending_frames = vec_len (nm->pending_frames);
120  ptd->cur_node = node->node_index;
121 
122  rv = node->function (vm, node, frame);
123 
124  ptd->cur_node = ~0;
125  for (; pending_frames < vec_len (nm->pending_frames); pending_frames++)
126  {
128  vec_elt_at_index (nm->pending_frames, pending_frames);
130  }
131 
132  return rv;
133 }
134 
135 static void
137 {
140  vlib_node_set_dispatch_wrapper (this_vlib_main, 0);
141 }
142 
143 static clib_error_t *
145 {
148  goto err0;
149 
151  if (vlib_node_set_dispatch_wrapper (this_vlib_main,
153  goto err1;
154 
155  return 0;
156 
157 err1:
159  vlib_node_set_dispatch_wrapper (this_vlib_main, 0);
160 err0:
162  return clib_error_return (0, "failed to register callback");
163 }
164 
165 static clib_error_t *
167 {
168  bufmon_main_t *bm = &bufmon_main;
169 
170  if (enable)
171  {
172  if (bm->enabled)
173  return 0;
175  if (error)
176  return error;
177  bm->enabled = 1;
178  }
179  else
180  {
181  if (!bm->enabled)
182  return 0;
184  bm->enabled = 0;
185  }
186 
187  return 0;
188 }
189 
190 static clib_error_t *
192  vlib_cli_command_t *cmd)
193 {
194  unformat_input_t _line_input, *line_input = &_line_input;
195  int on = 1;
196 
197  if (unformat_user (input, unformat_line_input, line_input))
198  {
199  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
200  {
201  if (unformat (line_input, "on"))
202  on = 1;
203  else if (unformat (line_input, "off"))
204  on = 0;
205  else
206  {
207  unformat_free (line_input);
208  return clib_error_return (0, "unknown input `%U'",
209  format_unformat_error, line_input);
210  }
211  }
212  unformat_free (line_input);
213  }
214 
215  return bufmon_enable_disable (vm, on);
216 }
217 
219  .path = "set buffer traces",
220  .short_help = "set buffer traces [on|off]",
221  .function = set_buffer_traces,
222 };
223 
224 static clib_error_t *
226  vlib_cli_command_t *cmd)
227 {
228  unformat_input_t _line_input, *line_input = &_line_input;
229  const bufmon_main_t *bm = &bufmon_main;
230  const bufmon_per_thread_data_t *ptd;
231  const bufmon_per_node_data_t *pnd;
232  int verbose = 0;
233  int status = 0;
234 
235  if (unformat_user (input, unformat_line_input, line_input))
236  {
237  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
238  {
239  if (unformat (line_input, "verbose"))
240  verbose = 1;
241  else if (unformat (line_input, "status"))
242  status = 1;
243  else
244  {
245  unformat_free (line_input);
246  return clib_error_return (0, "unknown input `%U'",
247  format_unformat_error, line_input);
248  }
249  }
250  unformat_free (line_input);
251  }
252 
253  if (status)
254  {
255  vlib_cli_output (vm, "buffers tracing is %s",
256  bm->enabled ? "on" : "off");
257  return 0;
258  }
259 
261  vlib_cli_output (vm, "%30s%20s%20s%20s%20s%20s", "Node", "Allocated",
262  "Freed", "In", "Out", "Buffered");
263  vec_foreach (ptd, bm->ptd)
264  {
265  vec_foreach (pnd, ptd->pnd)
266  {
267  const u64 in = pnd->alloc + pnd->in;
268  const u64 out = pnd->free + pnd->out;
269  const i64 buffered = in - out;
270  if (0 == in && 0 == out)
271  continue; /* skip nodes w/o activity */
272  if (0 == buffered && !verbose)
273  continue; /* if not verbose, skip nodes w/o buffered buffers */
274  vlib_cli_output (vm, "%30U%20lu%20lu%20lu%20lu%20ld",
275  format_vlib_node_name, vm, pnd - ptd->pnd,
276  pnd->alloc, pnd->free, pnd->in, pnd->out, buffered);
277  }
278  }
279 
280  return 0;
281 }
282 
284  .path = "show buffer traces",
285  .short_help = "show buffer traces [status|verbose]",
286  .function = show_buffer_traces,
287 };
288 
289 static clib_error_t *
291  vlib_cli_command_t *cmd)
292 {
293  const bufmon_main_t *bm = &bufmon_main;
294  const bufmon_per_thread_data_t *ptd;
295  const bufmon_per_node_data_t *pnd;
296 
297  vec_foreach (ptd, bm->ptd)
298  vec_foreach (pnd, ptd->pnd)
299  vec_reset_length (pnd);
300 
301  return 0;
302 }
303 
305  .path = "clear buffer traces",
306  .short_help = "clear buffer traces",
307  .function = clear_buffer_traces,
308 };
309 
311  .version = VPP_BUILD_VER,
312  .description = "Buffers monitoring plugin",
313 };
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
vlib.h
vlib_get_frame
static vlib_frame_t * vlib_get_frame(vlib_main_t *vm, vlib_frame_t *f)
Definition: node_funcs.h:273
vlib_buffer_t::next_buffer
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:149
vlib_pending_frame_t::frame
vlib_frame_t * frame
Definition: node.h:442
bufmon_per_node_data_t::alloc
u64 alloc
Definition: bufmon.c:9
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
bufmon_count_buffers
static u32 bufmon_count_buffers(vlib_main_t *vm, vlib_frame_t *frame)
Definition: bufmon.c:77
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
n_buffers
u32 n_buffers
Definition: interface_output.c:421
bufmon_per_node_data_t::out
u64 out
Definition: bufmon.c:8
bufmon_register_callbacks
static clib_error_t * bufmon_register_callbacks(vlib_main_t *vm)
Definition: bufmon.c:144
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
unformat_line_input
unformat_function_t unformat_line_input
Definition: format.h:275
CLIB_CACHE_LINE_ALIGN_MARK
#define CLIB_CACHE_LINE_ALIGN_MARK(mark)
Definition: cache.h:60
vlib_get_buffers
vlib_get_buffers(vm, from, b, n_left_from)
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
vlib_buffer_set_alloc_free_callback
__clib_export int vlib_buffer_set_alloc_free_callback(vlib_main_t *vm, vlib_buffer_alloc_free_callback_t *alloc_callback_fn, vlib_buffer_alloc_free_callback_t *free_callback_fn)
Definition: buffer.c:981
bufmon_per_node_data_t::in
u64 in
Definition: bufmon.c:7
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
bufmon_main_t
Definition: bufmon.c:20
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
vlib_main_t::node_main
vlib_node_main_t node_main
Definition: main.h:173
bufmon_dispatch_wrapper
static uword bufmon_dispatch_wrapper(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: bufmon.c:101
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
bufmon_main_t::enabled
int enabled
Definition: bufmon.c:23
show_buffer_traces
static clib_error_t * show_buffer_traces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: bufmon.c:225
vlib_pending_frame_t
Definition: node.h:439
unformat_input_t
struct _unformat_input_t unformat_input_t
vlib_frame_t
Definition: node.h:372
error
Definition: cJSON.c:88
i64
signed long i64
Definition: types.h:78
bufmon_enable_disable
static clib_error_t * bufmon_enable_disable(vlib_main_t *vm, int enable)
Definition: bufmon.c:166
set_buffer_traces
static clib_error_t * set_buffer_traces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: bufmon.c:191
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
format_vlib_buffer_pool_all
format_function_t format_vlib_buffer_pool_all
Definition: buffer.h:512
foreach_vlib_main
#define foreach_vlib_main()
Definition: threads.h:216
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
vlib_get_current_process_node_index
static u32 vlib_get_current_process_node_index(vlib_main_t *vm)
Definition: node_funcs.h:463
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
set_buffer_traces_command
static vlib_cli_command_t set_buffer_traces_command
(constructor) VLIB_CLI_COMMAND (set_buffer_traces_command)
Definition: bufmon.c:218
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
uword
u64 uword
Definition: types.h:112
bufmon_alloc_callback
static u32 bufmon_alloc_callback(vlib_main_t *vm, u8 buffer_pool_index, u32 *buffers, u32 n_buffers)
Definition: bufmon.c:63
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:215
bufmon_unregister_callbacks
static void bufmon_unregister_callbacks(vlib_main_t *vm)
Definition: bufmon.c:136
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
VLIB_PLUGIN_REGISTER
VLIB_PLUGIN_REGISTER()
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
bufmon_main
static bufmon_main_t bufmon_main
Definition: bufmon.c:26
bufmon_per_thread_data_t::pnd
bufmon_per_node_data_t * pnd
Definition: bufmon.c:16
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:58
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
plugin.h
vlib_node_set_dispatch_wrapper
static int vlib_node_set_dispatch_wrapper(vlib_main_t *vm, vlib_node_function_t *fn)
Definition: node_funcs.h:1264
show_buffer_traces_command
static vlib_cli_command_t show_buffer_traces_command
(constructor) VLIB_CLI_COMMAND (show_buffer_traces_command)
Definition: bufmon.c:283
bufmon_main_t::ptd
bufmon_per_thread_data_t * ptd
Definition: bufmon.c:22
format_vlib_node_name
format_function_t format_vlib_node_name
Definition: node_funcs.h:1235
bufmon_alloc_free_callback
static u32 bufmon_alloc_free_callback(vlib_main_t *vm, u32 n_buffers, const int is_free)
Definition: bufmon.c:29
u64
unsigned long u64
Definition: types.h:89
u32
unsigned int u32
Definition: types.h:88
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
clear_buffers_trace_command
static vlib_cli_command_t clear_buffers_trace_command
(constructor) VLIB_CLI_COMMAND (clear_buffers_trace_command)
Definition: bufmon.c:304
nm
nat44_ei_main_t * nm
Definition: nat44_ei_hairpinning.c:413
bufmon_per_node_data_t
Definition: bufmon.c:5
bufmon_per_thread_data_t::cur_node
u32 cur_node
Definition: bufmon.c:17
vlib_main_t
Definition: main.h:102
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
bufmon_free_callback
static u32 bufmon_free_callback(vlib_main_t *vm, u8 buffer_pool_index, u32 *buffers, u32 n_buffers)
Definition: bufmon.c:70
i
int i
Definition: flowhash_template.h:376
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
rv
int __clib_unused rv
Definition: application.c:491
vlib_node_main_t
Definition: node.h:665
vlib_node_runtime_t
Definition: node.h:454
bufmon_per_node_data_t::free
u64 free
Definition: bufmon.c:10
vlib_cli_command_t
Definition: cli.h:92
from
from
Definition: nat44_ei_hairpinning.c:415
clear_buffer_traces
static clib_error_t * clear_buffer_traces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: bufmon.c:290
bufmon_per_thread_data_t
Definition: bufmon.c:13
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111