FD.io VPP  v19.01.1-17-ge106252
Vector Packet Processing
main.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * main.c: main vector processing loop
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <math.h>
41 #include <vppinfra/format.h>
42 #include <vlib/vlib.h>
43 #include <vlib/threads.h>
45 
46 #include <vlib/unix/unix.h>
47 #include <vlib/unix/cj.h>
48 
50 
51 /* Actually allocate a few extra slots of vector data to support
52  speculative vector enqueues which overflow vector data in next frame. */
53 #define VLIB_FRAME_SIZE_ALLOC (VLIB_FRAME_SIZE + 4)
54 
56 
58 vlib_frame_bytes (u32 n_scalar_bytes, u32 n_vector_bytes)
59 {
60  u32 n_bytes;
61 
62  /* Make room for vlib_frame_t plus scalar arguments. */
63  n_bytes = vlib_frame_vector_byte_offset (n_scalar_bytes);
64 
65  /* Make room for vector arguments.
66  Allocate a few extra slots of vector data to support
67  speculative vector enqueues which overflow vector data in next frame. */
68 #define VLIB_FRAME_SIZE_EXTRA 4
69  n_bytes += (VLIB_FRAME_SIZE + VLIB_FRAME_SIZE_EXTRA) * n_vector_bytes;
70 
71  /* Magic number is first 32bit number after vector data.
72  Used to make sure that vector data is never overrun. */
73 #define VLIB_FRAME_MAGIC (0xabadc0ed)
74  n_bytes += sizeof (u32);
75 
76  /* Pad to cache line. */
77  n_bytes = round_pow2 (n_bytes, CLIB_CACHE_LINE_BYTES);
78 
79  return n_bytes;
80 }
81 
84 {
85  void *p = f;
86 
88 
90 
91  return p;
92 }
93 
94 static vlib_frame_size_t *
96  u32 n_scalar_bytes, u32 n_vector_bytes)
97 {
98  uword key = (n_scalar_bytes << 16) | n_vector_bytes;
99  uword *p, i;
100 
101  p = hash_get (nm->frame_size_hash, key);
102  if (p)
103  i = p[0];
104  else
105  {
106  i = vec_len (nm->frame_sizes);
107  vec_validate (nm->frame_sizes, i);
108  hash_set (nm->frame_size_hash, key, i);
109  }
110 
111  return vec_elt_at_index (nm->frame_sizes, i);
112 }
113 
114 static u32
116  u32 frame_flags)
117 {
118  vlib_node_main_t *nm = &vm->node_main;
119  vlib_frame_size_t *fs;
120  vlib_node_t *to_node;
121  vlib_frame_t *f;
122  u32 fi, l, n, scalar_size, vector_size;
123 
124  to_node = vlib_get_node (vm, to_node_index);
125 
126  scalar_size = to_node->scalar_size;
127  vector_size = to_node->vector_size;
128 
129  fs = get_frame_size_info (nm, scalar_size, vector_size);
130  n = vlib_frame_bytes (scalar_size, vector_size);
131  if ((l = vec_len (fs->free_frame_indices)) > 0)
132  {
133  /* Allocate from end of free list. */
134  fi = fs->free_frame_indices[l - 1];
135  f = vlib_get_frame_no_check (vm, fi);
136  _vec_len (fs->free_frame_indices) = l - 1;
137  }
138  else
139  {
141  fi = vlib_frame_index_no_check (vm, f);
142  }
143 
144  /* Poison frame when debugging. */
145  if (CLIB_DEBUG > 0)
146  clib_memset (f, 0xfe, n);
147 
148  /* Insert magic number. */
149  {
150  u32 *magic;
151 
152  magic = vlib_frame_find_magic (f, to_node);
153  *magic = VLIB_FRAME_MAGIC;
154  }
155 
156  f->frame_flags = VLIB_FRAME_IS_ALLOCATED | frame_flags;
157  f->n_vectors = 0;
158  f->scalar_size = scalar_size;
159  f->vector_size = vector_size;
160  f->flags = 0;
161 
162  fs->n_alloc_frames += 1;
163 
164  return fi;
165 }
166 
167 /* Allocate a frame for from FROM_NODE to TO_NODE via TO_NEXT_INDEX.
168  Returns frame index. */
169 static u32
171  u32 to_next_index)
172 {
173  vlib_node_t *from_node;
174 
175  from_node = vlib_get_node (vm, from_node_runtime->node_index);
176  ASSERT (to_next_index < vec_len (from_node->next_nodes));
177 
178  return vlib_frame_alloc_to_node (vm, from_node->next_nodes[to_next_index],
179  /* frame_flags */ 0);
180 }
181 
182 vlib_frame_t *
184 {
185  u32 fi = vlib_frame_alloc_to_node (vm, to_node_index,
186  /* frame_flags */
188  return vlib_get_frame (vm, fi);
189 }
190 
191 void
193 {
195  vlib_node_t *to_node;
196 
197  if (f->n_vectors == 0)
198  return;
199 
200  to_node = vlib_get_node (vm, to_node_index);
201 
202  vec_add2 (vm->node_main.pending_frames, p, 1);
203 
205  p->frame_index = vlib_frame_index (vm, f);
206  p->node_runtime_index = to_node->runtime_index;
208 }
209 
210 /* Free given frame. */
211 void
213 {
214  vlib_node_main_t *nm = &vm->node_main;
215  vlib_node_t *node;
216  vlib_frame_size_t *fs;
217  u32 frame_index;
218 
220 
221  node = vlib_get_node (vm, r->node_index);
222  fs = get_frame_size_info (nm, node->scalar_size, node->vector_size);
223 
224  frame_index = vlib_frame_index (vm, f);
225 
227 
228  /* No next frames may point to freed frame. */
229  if (CLIB_DEBUG > 0)
230  {
231  vlib_next_frame_t *nf;
233  ASSERT (nf->frame_index != frame_index);
234  }
235 
237 
238  vec_add1 (fs->free_frame_indices, frame_index);
239  ASSERT (fs->n_alloc_frames > 0);
240  fs->n_alloc_frames -= 1;
241 }
242 
243 static clib_error_t *
245  unformat_input_t * input, vlib_cli_command_t * cmd)
246 {
247  vlib_node_main_t *nm = &vm->node_main;
248  vlib_frame_size_t *fs;
249 
250  vlib_cli_output (vm, "%=6s%=12s%=12s", "Size", "# Alloc", "# Free");
251  vec_foreach (fs, nm->frame_sizes)
252  {
253  u32 n_alloc = fs->n_alloc_frames;
254  u32 n_free = vec_len (fs->free_frame_indices);
255 
256  if (n_alloc + n_free > 0)
257  vlib_cli_output (vm, "%=6d%=12d%=12d",
258  fs - nm->frame_sizes, n_alloc, n_free);
259  }
260 
261  return 0;
262 }
263 
264 /* *INDENT-OFF* */
265 VLIB_CLI_COMMAND (show_frame_stats_cli, static) = {
266  .path = "show vlib frame-allocation",
267  .short_help = "Show node dispatch frame statistics",
268  .function = show_frame_stats,
269 };
270 /* *INDENT-ON* */
271 
272 /* Change ownership of enqueue rights to given next node. */
273 static void
275  vlib_node_runtime_t * node_runtime,
276  u32 next_index)
277 {
278  vlib_node_main_t *nm = &vm->node_main;
279  vlib_next_frame_t *next_frame;
280  vlib_node_t *node, *next_node;
281 
282  node = vec_elt (nm->nodes, node_runtime->node_index);
283 
284  /* Only internal & input nodes are allowed to call other nodes. */
286  || node->type == VLIB_NODE_TYPE_INPUT
287  || node->type == VLIB_NODE_TYPE_PROCESS);
288 
289  ASSERT (vec_len (node->next_nodes) == node_runtime->n_next_nodes);
290 
291  next_frame =
292  vlib_node_runtime_get_next_frame (vm, node_runtime, next_index);
293  next_node = vec_elt (nm->nodes, node->next_nodes[next_index]);
294 
295  if (next_node->owner_node_index != VLIB_INVALID_NODE_INDEX)
296  {
297  /* Get frame from previous owner. */
298  vlib_next_frame_t *owner_next_frame;
299  vlib_next_frame_t tmp;
300 
301  owner_next_frame =
303  next_node->owner_node_index,
304  next_node->owner_next_index);
305 
306  /* Swap target next frame with owner's. */
307  tmp = owner_next_frame[0];
308  owner_next_frame[0] = next_frame[0];
309  next_frame[0] = tmp;
310 
311  /*
312  * If next_frame is already pending, we have to track down
313  * all pending frames and fix their next_frame_index fields.
314  */
315  if (next_frame->flags & VLIB_FRAME_PENDING)
316  {
318  if (next_frame->frame_index != ~0)
319  {
320  vec_foreach (p, nm->pending_frames)
321  {
322  if (p->frame_index == next_frame->frame_index)
323  {
324  p->next_frame_index =
325  next_frame - vm->node_main.next_frames;
326  }
327  }
328  }
329  }
330  }
331  else
332  {
333  /* No previous owner. Take ownership. */
334  next_frame->flags |= VLIB_FRAME_OWNER;
335  }
336 
337  /* Record new owner. */
338  next_node->owner_node_index = node->index;
339  next_node->owner_next_index = next_index;
340 
341  /* Now we should be owner. */
342  ASSERT (next_frame->flags & VLIB_FRAME_OWNER);
343 }
344 
345 /* Make sure that magic number is still there.
346  Otherwise, it is likely that caller has overrun frame arguments. */
347 always_inline void
349  vlib_frame_t * f, vlib_node_t * n, uword next_index)
350 {
351  vlib_node_t *next_node = vlib_get_node (vm, n->next_nodes[next_index]);
352  u32 *magic = vlib_frame_find_magic (f, next_node);
353  ASSERT (VLIB_FRAME_MAGIC == magic[0]);
354 }
355 
356 vlib_frame_t *
358  vlib_node_runtime_t * node,
359  u32 next_index, u32 allocate_new_next_frame)
360 {
361  vlib_frame_t *f;
362  vlib_next_frame_t *nf;
363  u32 n_used;
364 
365  nf = vlib_node_runtime_get_next_frame (vm, node, next_index);
366 
367  /* Make sure this next frame owns right to enqueue to destination frame. */
368  if (PREDICT_FALSE (!(nf->flags & VLIB_FRAME_OWNER)))
369  vlib_next_frame_change_ownership (vm, node, next_index);
370 
371  /* ??? Don't need valid flag: can use frame_index == ~0 */
373  {
374  nf->frame_index = vlib_frame_alloc (vm, node, next_index);
376  }
377 
378  f = vlib_get_frame (vm, nf->frame_index);
379 
380  /* Has frame been removed from pending vector (e.g. finished dispatching)?
381  If so we can reuse frame. */
382  if ((nf->flags & VLIB_FRAME_PENDING)
383  && !(f->frame_flags & VLIB_FRAME_PENDING))
384  {
385  nf->flags &= ~VLIB_FRAME_PENDING;
386  f->n_vectors = 0;
387  f->flags = 0;
388  }
389 
390  /* Allocate new frame if current one is marked as no-append or
391  it is already full. */
392  n_used = f->n_vectors;
393  if (n_used >= VLIB_FRAME_SIZE || (allocate_new_next_frame && n_used > 0) ||
395  {
396  /* Old frame may need to be freed after dispatch, since we'll have
397  two redundant frames from node -> next node. */
399  {
400  vlib_frame_t *f_old = vlib_get_frame (vm, nf->frame_index);
402  }
403 
404  /* Allocate new frame to replace full one. */
405  nf->frame_index = vlib_frame_alloc (vm, node, next_index);
406  f = vlib_get_frame (vm, nf->frame_index);
407  n_used = f->n_vectors;
408  }
409 
410  /* Should have free vectors in frame now. */
411  ASSERT (n_used < VLIB_FRAME_SIZE);
412 
413  if (CLIB_DEBUG > 0)
414  {
415  validate_frame_magic (vm, f,
416  vlib_get_node (vm, node->node_index), next_index);
417  }
418 
419  return f;
420 }
421 
422 static void
424  vlib_node_runtime_t * rt,
425  u32 next_index, u32 n_vectors_left)
426 {
427  vlib_node_main_t *nm = &vm->node_main;
428  vlib_next_frame_t *nf;
429  vlib_frame_t *f;
430  vlib_node_runtime_t *next_rt;
431  vlib_node_t *next_node;
432  u32 n_before, n_after;
433 
434  nf = vlib_node_runtime_get_next_frame (vm, rt, next_index);
435  f = vlib_get_frame (vm, nf->frame_index);
436 
437  ASSERT (n_vectors_left <= VLIB_FRAME_SIZE);
438  n_after = VLIB_FRAME_SIZE - n_vectors_left;
439  n_before = f->n_vectors;
440 
441  ASSERT (n_after >= n_before);
442 
444  nf->node_runtime_index);
445  next_node = vlib_get_node (vm, next_rt->node_index);
446  if (n_after > 0 && next_node->validate_frame)
447  {
448  u8 *msg = next_node->validate_frame (vm, rt, f);
449  if (msg)
450  {
451  clib_warning ("%v", msg);
452  ASSERT (0);
453  }
454  vec_free (msg);
455  }
456 }
457 
458 void
461  u32 next_index, u32 n_vectors_left)
462 {
463  vlib_node_main_t *nm = &vm->node_main;
464  vlib_next_frame_t *nf;
465  vlib_frame_t *f;
466  u32 n_vectors_in_frame;
467 
468  if (buffer_main.callbacks_registered == 0 && CLIB_DEBUG > 0)
469  vlib_put_next_frame_validate (vm, r, next_index, n_vectors_left);
470 
471  nf = vlib_node_runtime_get_next_frame (vm, r, next_index);
472  f = vlib_get_frame (vm, nf->frame_index);
473 
474  /* Make sure that magic number is still there. Otherwise, caller
475  has overrun frame meta data. */
476  if (CLIB_DEBUG > 0)
477  {
478  vlib_node_t *node = vlib_get_node (vm, r->node_index);
479  validate_frame_magic (vm, f, node, next_index);
480  }
481 
482  /* Convert # of vectors left -> number of vectors there. */
483  ASSERT (n_vectors_left <= VLIB_FRAME_SIZE);
484  n_vectors_in_frame = VLIB_FRAME_SIZE - n_vectors_left;
485 
486  f->n_vectors = n_vectors_in_frame;
487 
488  /* If vectors were added to frame, add to pending vector. */
489  if (PREDICT_TRUE (n_vectors_in_frame > 0))
490  {
492  u32 v0, v1;
493 
494  r->cached_next_index = next_index;
495 
496  if (!(f->frame_flags & VLIB_FRAME_PENDING))
497  {
498  __attribute__ ((unused)) vlib_node_t *node;
499  vlib_node_t *next_node;
500  vlib_node_runtime_t *next_runtime;
501 
502  node = vlib_get_node (vm, r->node_index);
503  next_node = vlib_get_next_node (vm, r->node_index, next_index);
504  next_runtime = vlib_node_get_runtime (vm, next_node->index);
505 
506  vec_add2 (nm->pending_frames, p, 1);
507 
508  p->frame_index = nf->frame_index;
510  p->next_frame_index = nf - nm->next_frames;
511  nf->flags |= VLIB_FRAME_PENDING;
513 
514  /*
515  * If we're going to dispatch this frame on another thread,
516  * force allocation of a new frame. Otherwise, we create
517  * a dangling frame reference. Each thread has its own copy of
518  * the next_frames vector.
519  */
520  if (0 && r->thread_index != next_runtime->thread_index)
521  {
522  nf->frame_index = ~0;
524  }
525  }
526 
527  /* Copy trace flag from next_frame and from runtime. */
528  nf->flags |=
529  (nf->flags & VLIB_NODE_FLAG_TRACE) | (r->
531 
533  v1 = v0 + n_vectors_in_frame;
535  if (PREDICT_FALSE (v1 < v0))
536  {
537  vlib_node_t *node = vlib_get_node (vm, r->node_index);
538  vec_elt (node->n_vectors_by_next_node, next_index) += v0;
539  }
540  }
541 }
542 
543 /* Sync up runtime (32 bit counters) and main node stats (64 bit counters). */
544 never_inline void
547  uword n_calls, uword n_vectors, uword n_clocks,
548  uword n_ticks)
549 {
550  vlib_node_t *n = vlib_get_node (vm, r->node_index);
551 
552  n->stats_total.calls += n_calls + r->calls_since_last_overflow;
553  n->stats_total.vectors += n_vectors + r->vectors_since_last_overflow;
554  n->stats_total.clocks += n_clocks + r->clocks_since_last_overflow;
555  n->stats_total.perf_counter_ticks += n_ticks +
557  n->stats_total.perf_counter_vectors += n_vectors +
561 
567 }
568 
569 always_inline void __attribute__ ((unused))
571  vlib_process_t * p,
572  uword n_calls, uword n_vectors, uword n_clocks,
573  uword n_ticks)
574 {
575  vlib_node_runtime_t *rt = &p->node_runtime;
577  vlib_node_runtime_sync_stats (vm, rt, n_calls, n_vectors, n_clocks,
578  n_ticks);
579  n->stats_total.suspends += p->n_suspends;
580  p->n_suspends = 0;
581 }
582 
583 void
585 {
587 
588  if (n->type == VLIB_NODE_TYPE_PROCESS)
589  {
590  /* Nothing to do for PROCESS nodes except in main thread */
591  if (vm != &vlib_global_main)
592  return;
593 
596  p->n_suspends = 0;
597  rt = &p->node_runtime;
598  }
599  else
600  rt =
602  n->runtime_index);
603 
604  vlib_node_runtime_sync_stats (vm, rt, 0, 0, 0, 0);
605 
606  /* Sync up runtime next frame vector counters with main node structure. */
607  {
608  vlib_next_frame_t *nf;
609  uword i;
610  for (i = 0; i < rt->n_next_nodes; i++)
611  {
612  nf = vlib_node_runtime_get_next_frame (vm, rt, i);
616  }
617  }
618 }
619 
622  vlib_node_runtime_t * node,
623  uword n_calls,
624  uword n_vectors, uword n_clocks,
625  uword n_ticks)
626 {
627  u32 ca0, ca1, v0, v1, cl0, cl1, r;
628  u32 ptick0, ptick1, pvec0, pvec1;
629 
630  cl0 = cl1 = node->clocks_since_last_overflow;
631  ca0 = ca1 = node->calls_since_last_overflow;
632  v0 = v1 = node->vectors_since_last_overflow;
633  ptick0 = ptick1 = node->perf_counter_ticks_since_last_overflow;
634  pvec0 = pvec1 = node->perf_counter_vectors_since_last_overflow;
635 
636  ca1 = ca0 + n_calls;
637  v1 = v0 + n_vectors;
638  cl1 = cl0 + n_clocks;
639  ptick1 = ptick0 + n_ticks;
640  pvec1 = pvec0 + n_vectors;
641 
642  node->calls_since_last_overflow = ca1;
643  node->clocks_since_last_overflow = cl1;
644  node->vectors_since_last_overflow = v1;
647 
648  node->max_clock_n = node->max_clock > n_clocks ?
649  node->max_clock_n : n_vectors;
650  node->max_clock = node->max_clock > n_clocks ? node->max_clock : n_clocks;
651 
652  r = vlib_node_runtime_update_main_loop_vector_stats (vm, node, n_vectors);
653 
654  if (PREDICT_FALSE (ca1 < ca0 || v1 < v0 || cl1 < cl0) || (ptick1 < ptick0)
655  || (pvec1 < pvec0))
656  {
657  node->calls_since_last_overflow = ca0;
658  node->clocks_since_last_overflow = cl0;
659  node->vectors_since_last_overflow = v0;
662 
663  vlib_node_runtime_sync_stats (vm, node, n_calls, n_vectors, n_clocks,
664  n_ticks);
665  }
666 
667  return r;
668 }
669 
670 static inline u64
672 {
674  return ((*vm->vlib_node_runtime_perf_counter_cb) (vm));
675  return 0ULL;
676 }
677 
678 always_inline void
680  vlib_process_t * p,
681  uword n_calls, uword n_vectors, uword n_clocks,
682  uword n_ticks)
683 {
685  n_calls, n_vectors, n_clocks, n_ticks);
686 }
687 
688 static clib_error_t *
690  unformat_input_t * input, vlib_cli_command_t * cmd)
691 {
693  return 0;
694 }
695 
696 /* *INDENT-OFF* */
697 VLIB_CLI_COMMAND (elog_clear_cli, static) = {
698  .path = "event-logger clear",
699  .short_help = "Clear the event log",
700  .function = vlib_cli_elog_clear,
701 };
702 /* *INDENT-ON* */
703 
704 #ifdef CLIB_UNIX
705 static clib_error_t *
707  unformat_input_t * input, vlib_cli_command_t * cmd)
708 {
709  elog_main_t *em = &vm->elog_main;
710  char *file, *chroot_file;
711  clib_error_t *error = 0;
712 
713  if (!unformat (input, "%s", &file))
714  {
715  vlib_cli_output (vm, "expected file name, got `%U'",
716  format_unformat_error, input);
717  return 0;
718  }
719 
720  /* It's fairly hard to get "../oopsie" through unformat; just in case */
721  if (strstr (file, "..") || index (file, '/'))
722  {
723  vlib_cli_output (vm, "illegal characters in filename '%s'", file);
724  return 0;
725  }
726 
727  chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
728 
729  vec_free (file);
730 
731  vlib_cli_output (vm, "Saving %wd of %wd events to %s",
733  elog_buffer_capacity (em), chroot_file);
734 
736  error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
738  vec_free (chroot_file);
739  return error;
740 }
741 
742 void
744 {
746  elog_main_t *em = &vm->elog_main;
747  u8 *filename;
748  clib_error_t *error;
749 
750  if (!vm->elog_post_mortem_dump)
751  return;
752 
753  filename = format (0, "/tmp/elog_post_mortem.%d%c", getpid (), 0);
754  error = elog_write_file (em, (char *) filename, 1 /* flush ring */ );
755  if (error)
756  clib_error_report (error);
757  vec_free (filename);
758 }
759 
760 /* *INDENT-OFF* */
761 VLIB_CLI_COMMAND (elog_save_cli, static) = {
762  .path = "event-logger save",
763  .short_help = "event-logger save <filename> (saves log in /tmp/<filename>)",
764  .function = elog_save_buffer,
765 };
766 /* *INDENT-ON* */
767 
768 static clib_error_t *
770  unformat_input_t * input, vlib_cli_command_t * cmd)
771 {
772  elog_main_t *em = &vm->elog_main;
773 
775 
776  vlib_cli_output (vm, "Stopped the event logger...");
777  return 0;
778 }
779 
780 /* *INDENT-OFF* */
781 VLIB_CLI_COMMAND (elog_stop_cli, static) = {
782  .path = "event-logger stop",
783  .short_help = "Stop the event-logger",
784  .function = elog_stop,
785 };
786 /* *INDENT-ON* */
787 
788 static clib_error_t *
790  unformat_input_t * input, vlib_cli_command_t * cmd)
791 {
792  elog_main_t *em = &vm->elog_main;
793 
795 
796  vlib_cli_output (vm, "Restarted the event logger...");
797  return 0;
798 }
799 
800 /* *INDENT-OFF* */
801 VLIB_CLI_COMMAND (elog_restart_cli, static) = {
802  .path = "event-logger restart",
803  .short_help = "Restart the event-logger",
804  .function = elog_restart,
805 };
806 /* *INDENT-ON* */
807 
808 static clib_error_t *
810  unformat_input_t * input, vlib_cli_command_t * cmd)
811 {
812  elog_main_t *em = &vm->elog_main;
813  u32 tmp;
814 
815  /* Stop the parade */
817 
818  if (unformat (input, "%d", &tmp))
819  {
820  elog_alloc (em, tmp);
822  }
823  else
824  return clib_error_return (0, "Must specify how many events in the ring");
825 
826  vlib_cli_output (vm, "Resized ring and restarted the event logger...");
827  return 0;
828 }
829 
830 /* *INDENT-OFF* */
831 VLIB_CLI_COMMAND (elog_resize_cli, static) = {
832  .path = "event-logger resize",
833  .short_help = "event-logger resize <nnn>",
834  .function = elog_resize,
835 };
836 /* *INDENT-ON* */
837 
838 #endif /* CLIB_UNIX */
839 
840 static void
842 {
843  elog_main_t *em = &vm->elog_main;
844  elog_event_t *e, *es;
845  f64 dt;
846 
847  /* Show events in VLIB time since log clock starts after VLIB clock. */
848  dt = (em->init_time.cpu - vm->clib_time.init_cpu_time)
850 
851  es = elog_peek_events (em);
852  vlib_cli_output (vm, "%d of %d events in buffer, logger %s", vec_len (es),
853  em->event_ring_size,
855  "running" : "stopped");
856  vec_foreach (e, es)
857  {
858  vlib_cli_output (vm, "%18.9f: %U",
859  e->time + dt, format_elog_event, em, e);
860  n_events_to_show--;
861  if (n_events_to_show == 0)
862  break;
863  }
864  vec_free (es);
865 
866 }
867 
868 static clib_error_t *
870  unformat_input_t * input, vlib_cli_command_t * cmd)
871 {
872  u32 n_events_to_show;
873  clib_error_t *error = 0;
874 
875  n_events_to_show = 250;
877  {
878  if (unformat (input, "%d", &n_events_to_show))
879  ;
880  else if (unformat (input, "all"))
881  n_events_to_show = ~0;
882  else
883  return unformat_parse_error (input);
884  }
885  elog_show_buffer_internal (vm, n_events_to_show);
886  return error;
887 }
888 
889 /* *INDENT-OFF* */
890 VLIB_CLI_COMMAND (elog_show_cli, static) = {
891  .path = "show event-logger",
892  .short_help = "Show event logger info",
893  .function = elog_show_buffer,
894 };
895 /* *INDENT-ON* */
896 
897 void
899 {
901 }
902 
903 static inline void
905  u32 node_index,
906  u64 time, u32 n_vectors, u32 is_return)
907 {
909  elog_main_t *em = &evm->elog_main;
910 
911  if (VLIB_ELOG_MAIN_LOOP && n_vectors)
912  elog_track (em,
913  /* event type */
914  vec_elt_at_index (is_return
917  node_index),
918  /* track */
920  elog_track : &em->default_track),
921  /* data to log */ n_vectors);
922 }
923 
924 #if VLIB_BUFFER_TRACE_TRAJECTORY > 0
925 void (*vlib_buffer_trace_trajectory_cb) (vlib_buffer_t * b, u32 node_index);
926 void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b);
927 
928 void
929 vlib_buffer_trace_trajectory_init (vlib_buffer_t * b)
930 {
931  if (PREDICT_TRUE (vlib_buffer_trace_trajectory_init_cb != 0))
932  {
933  (*vlib_buffer_trace_trajectory_init_cb) (b);
934  }
935 }
936 
937 #endif
938 
939 static inline void
941 {
942 #if VLIB_BUFFER_TRACE_TRAJECTORY > 0
943  if (PREDICT_TRUE (vlib_buffer_trace_trajectory_cb != 0))
944  {
945  (*vlib_buffer_trace_trajectory_cb) (b, node_index);
946  }
947 #endif
948 }
949 
950 u8 *format_vnet_buffer_flags (u8 * s, va_list * args) __attribute__ ((weak));
951 u8 *
952 format_vnet_buffer_flags (u8 * s, va_list * args)
953 {
954  s = format (s, "BUG STUB %s", __FUNCTION__);
955  return s;
956 }
957 
958 u8 *format_vnet_buffer_opaque (u8 * s, va_list * args) __attribute__ ((weak));
959 u8 *
960 format_vnet_buffer_opaque (u8 * s, va_list * args)
961 {
962  s = format (s, "BUG STUB %s", __FUNCTION__);
963  return s;
964 }
965 
966 u8 *format_vnet_buffer_opaque2 (u8 * s, va_list * args)
967  __attribute__ ((weak));
968 u8 *
969 format_vnet_buffer_opaque2 (u8 * s, va_list * args)
970 {
971  s = format (s, "BUG STUB %s", __FUNCTION__);
972  return s;
973 }
974 
975 static u8 *
976 format_buffer_metadata (u8 * s, va_list * args)
977 {
978  vlib_buffer_t *b = va_arg (*args, vlib_buffer_t *);
979 
980  s = format (s, "flags: %U\n", format_vnet_buffer_flags, b);
981  s = format (s, "current_data: %d, current_length: %d\n",
982  (i32) (b->current_data), (i32) (b->current_length));
983  s = format (s, "current_config_index: %d, flow_id: %x, next_buffer: %x\n",
985  s = format (s, "error: %d, n_add_refs: %d, buffer_pool_index: %d\n",
986  (u32) (b->error), (u32) (b->n_add_refs),
987  (u32) (b->buffer_pool_index));
988  s = format (s,
989  "trace_index: %d, recycle_count: %d, len_not_first_buf: %d\n",
990  b->trace_index, b->recycle_count,
992  s = format (s, "free_list_index: %d\n", (u32) (b->free_list_index));
993  return s;
994 }
995 
996 #define A(x) vec_add1(vm->pcap_buffer, (x))
997 
998 static void
1000  vlib_node_runtime_t * node, vlib_frame_t * frame)
1001 {
1002  int i;
1003  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **bufp, *b;
1004  pcap_main_t *pm = &vm->dispatch_pcap_main;
1005  vlib_trace_main_t *tm = &vm->trace_main;
1006  u32 capture_size;
1007  vlib_node_t *n;
1008  i32 n_left;
1009  f64 time_now = vlib_time_now (vm);
1010  u32 *from;
1011  u8 *d;
1012  u8 string_count;
1013 
1014  /* Input nodes don't have frames yet */
1015  if (frame == 0 || frame->n_vectors == 0)
1016  return;
1017 
1018  from = vlib_frame_vector_args (frame);
1019  vlib_get_buffers (vm, from, bufs, frame->n_vectors);
1020  bufp = bufs;
1021 
1022  n = vlib_get_node (vm, node->node_index);
1023 
1024  for (i = 0; i < frame->n_vectors; i++)
1025  {
1027  {
1028  b = bufp[i];
1029 
1031  string_count = 0;
1032 
1033  /* Version, flags */
1036  A (0 /* string_count */ );
1037  A (n->protocol_hint);
1038 
1039  /* Buffer index (big endian) */
1040  A ((from[i] >> 24) & 0xff);
1041  A ((from[i] >> 16) & 0xff);
1042  A ((from[i] >> 8) & 0xff);
1043  A ((from[i] >> 0) & 0xff);
1044 
1045  /* Node name, NULL-terminated ASCII */
1046  vm->pcap_buffer = format (vm->pcap_buffer, "%v%c", n->name, 0);
1047  string_count++;
1048 
1049  vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
1050  format_buffer_metadata, b, 0);
1051  string_count++;
1052  vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
1054  string_count++;
1055  vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
1057  string_count++;
1058 
1059  /* Is this packet traced? */
1060  if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
1061  {
1064 
1065  vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
1066  format_vlib_trace, vm, h[0], 0);
1067  string_count++;
1068  }
1069 
1070  /* Save the string count */
1071  vm->pcap_buffer[2] = string_count;
1072 
1073  /* Figure out how many bytes in the pcap trace */
1074  capture_size = vec_len (vm->pcap_buffer) +
1075  +vlib_buffer_length_in_chain (vm, b);
1076 
1078  n_left = clib_min (capture_size, 16384);
1079  d = pcap_add_packet (pm, time_now, n_left, capture_size);
1080 
1081  /* Copy the header */
1083  d += vec_len (vm->pcap_buffer);
1084 
1085  n_left = clib_min
1086  (vlib_buffer_length_in_chain (vm, b),
1087  (16384 - vec_len (vm->pcap_buffer)));
1088  /* Copy the packet data */
1089  while (1)
1090  {
1091  u32 copy_length = clib_min ((u32) n_left, b->current_length);
1092  clib_memcpy_fast (d, b->data + b->current_data, copy_length);
1093  n_left -= b->current_length;
1094  if (n_left <= 0)
1095  break;
1096  d += b->current_length;
1097  ASSERT (b->flags & VLIB_BUFFER_NEXT_PRESENT);
1098  b = vlib_get_buffer (vm, b->next_buffer);
1099  }
1101  }
1102  }
1103 }
1104 
1107  vlib_node_runtime_t * node,
1108  vlib_node_type_t type,
1109  vlib_node_state_t dispatch_state,
1110  vlib_frame_t * frame, u64 last_time_stamp)
1111 {
1112  uword n, v;
1113  u64 t;
1114  vlib_node_main_t *nm = &vm->node_main;
1115  vlib_next_frame_t *nf;
1116 
1117  if (CLIB_DEBUG > 0)
1118  {
1119  vlib_node_t *n = vlib_get_node (vm, node->node_index);
1120  ASSERT (n->type == type);
1121  }
1122 
1123  /* Only non-internal nodes may be disabled. */
1124  if (type != VLIB_NODE_TYPE_INTERNAL && node->state != dispatch_state)
1125  {
1126  ASSERT (type != VLIB_NODE_TYPE_INTERNAL);
1127  return last_time_stamp;
1128  }
1129 
1130  if ((type == VLIB_NODE_TYPE_PRE_INPUT || type == VLIB_NODE_TYPE_INPUT)
1131  && dispatch_state != VLIB_NODE_STATE_INTERRUPT)
1132  {
1134  /* Only call node when count reaches zero. */
1135  if (c)
1136  {
1137  node->input_main_loops_per_call = c - 1;
1138  return last_time_stamp;
1139  }
1140  }
1141 
1142  /* Speculatively prefetch next frames. */
1143  if (node->n_next_nodes > 0)
1144  {
1145  nf = vec_elt_at_index (nm->next_frames, node->next_frame_index);
1146  CLIB_PREFETCH (nf, 4 * sizeof (nf[0]), WRITE);
1147  }
1148 
1149  vm->cpu_time_last_node_dispatch = last_time_stamp;
1150 
1151  if (1 /* || vm->thread_index == node->thread_index */ )
1152  {
1153  u64 pmc_before, pmc_delta;
1154 
1156  last_time_stamp,
1157  frame ? frame->n_vectors : 0,
1158  /* is_after */ 0);
1159 
1160  /*
1161  * To validate accounting: pmc_before = last_time_stamp
1162  * perf ticks should equal clocks/pkt...
1163  */
1164  pmc_before = vlib_node_runtime_perf_counter (vm);
1165 
1166  /*
1167  * Turn this on if you run into
1168  * "bad monkey" contexts, and you want to know exactly
1169  * which nodes they've visited... See ixge.c...
1170  */
1171  if (VLIB_BUFFER_TRACE_TRAJECTORY && frame)
1172  {
1173  int i;
1174  u32 *from;
1175  from = vlib_frame_vector_args (frame);
1176  for (i = 0; i < frame->n_vectors; i++)
1177  {
1178  vlib_buffer_t *b = vlib_get_buffer (vm, from[i]);
1179  add_trajectory_trace (b, node->node_index);
1180  }
1182  dispatch_pcap_trace (vm, node, frame);
1183  n = node->function (vm, node, frame);
1184  }
1185  else
1186  {
1188  dispatch_pcap_trace (vm, node, frame);
1189  n = node->function (vm, node, frame);
1190  }
1191 
1192  t = clib_cpu_time_now ();
1193 
1194  /*
1195  * To validate accounting: pmc_delta = t - pmc_before;
1196  * perf ticks should equal clocks/pkt...
1197  */
1198  pmc_delta = vlib_node_runtime_perf_counter (vm) - pmc_before;
1199 
1200  vlib_elog_main_loop_event (vm, node->node_index, t, n, /* is_after */
1201  1);
1202 
1203  vm->main_loop_vectors_processed += n;
1204  vm->main_loop_nodes_processed += n > 0;
1205 
1206  v = vlib_node_runtime_update_stats (vm, node,
1207  /* n_calls */ 1,
1208  /* n_vectors */ n,
1209  /* n_clocks */ t - last_time_stamp,
1210  pmc_delta /* PMC ticks */ );
1211 
1212  /* When in interrupt mode and vector rate crosses threshold switch to
1213  polling mode. */
1214  if ((dispatch_state == VLIB_NODE_STATE_INTERRUPT)
1215  || (dispatch_state == VLIB_NODE_STATE_POLLING
1216  && (node->flags
1218  {
1219 #ifdef DISPATCH_NODE_ELOG_REQUIRED
1220  ELOG_TYPE_DECLARE (e) =
1221  {
1222  .function = (char *) __FUNCTION__,.format =
1223  "%s vector length %d, switching to %s",.format_args =
1224  "T4i4t4",.n_enum_strings = 2,.enum_strings =
1225  {
1226  "interrupt", "polling",},};
1227  struct
1228  {
1229  u32 node_name, vector_length, is_polling;
1230  } *ed;
1232 #endif
1233 
1234  if ((dispatch_state == VLIB_NODE_STATE_INTERRUPT
1235  && v >= nm->polling_threshold_vector_length) &&
1236  !(node->flags &
1238  {
1239  vlib_node_t *n = vlib_get_node (vm, node->node_index);
1240  n->state = VLIB_NODE_STATE_POLLING;
1241  node->state = VLIB_NODE_STATE_POLLING;
1242  node->flags &=
1244  node->flags |=
1246  nm->input_node_counts_by_state[VLIB_NODE_STATE_INTERRUPT] -= 1;
1247  nm->input_node_counts_by_state[VLIB_NODE_STATE_POLLING] += 1;
1248 
1249 #ifdef DISPATCH_NODE_ELOG_REQUIRED
1250  ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e,
1251  w->elog_track);
1252  ed->node_name = n->name_elog_string;
1253  ed->vector_length = v;
1254  ed->is_polling = 1;
1255 #endif
1256  }
1257  else if (dispatch_state == VLIB_NODE_STATE_POLLING
1258  && v <= nm->interrupt_threshold_vector_length)
1259  {
1260  vlib_node_t *n = vlib_get_node (vm, node->node_index);
1261  if (node->flags &
1263  {
1264  /* Switch to interrupt mode after dispatch in polling one more time.
1265  This allows driver to re-enable interrupts. */
1266  n->state = VLIB_NODE_STATE_INTERRUPT;
1267  node->state = VLIB_NODE_STATE_INTERRUPT;
1268  node->flags &=
1270  nm->input_node_counts_by_state[VLIB_NODE_STATE_POLLING] -=
1271  1;
1272  nm->input_node_counts_by_state[VLIB_NODE_STATE_INTERRUPT] +=
1273  1;
1274 
1275  }
1276  else
1277  {
1278  node->flags |=
1280 #ifdef DISPATCH_NODE_ELOG_REQUIRED
1281  ed = ELOG_TRACK_DATA (&vlib_global_main.elog_main, e,
1282  w->elog_track);
1283  ed->node_name = n->name_elog_string;
1284  ed->vector_length = v;
1285  ed->is_polling = 0;
1286 #endif
1287  }
1288  }
1289  }
1290  }
1291 
1292  return t;
1293 }
1294 
1295 static u64
1296 dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index,
1297  u64 last_time_stamp)
1298 {
1299  vlib_node_main_t *nm = &vm->node_main;
1300  vlib_frame_t *f;
1301  vlib_next_frame_t *nf, nf_dummy;
1303  u32 restore_frame_index;
1305 
1306  /* See comment below about dangling references to nm->pending_frames */
1307  p = nm->pending_frames + pending_frame_index;
1308 
1310  p->node_runtime_index);
1311 
1312  f = vlib_get_frame (vm, p->frame_index);
1314  {
1315  /* No next frame: so use dummy on stack. */
1316  nf = &nf_dummy;
1318  nf->frame_index = ~p->frame_index;
1319  }
1320  else
1322 
1324 
1325  /* Force allocation of new frame while current frame is being
1326  dispatched. */
1327  restore_frame_index = ~0;
1328  if (nf->frame_index == p->frame_index)
1329  {
1330  nf->frame_index = ~0;
1333  restore_frame_index = p->frame_index;
1334  }
1335 
1336  /* Frame must be pending. */
1338  ASSERT (f->n_vectors > 0);
1339 
1340  /* Copy trace flag from next frame to node.
1341  Trace flag indicates that at least one vector in the dispatched
1342  frame is traced. */
1343  n->flags &= ~VLIB_NODE_FLAG_TRACE;
1344  n->flags |= (nf->flags & VLIB_FRAME_TRACE) ? VLIB_NODE_FLAG_TRACE : 0;
1345  nf->flags &= ~VLIB_FRAME_TRACE;
1346 
1347  last_time_stamp = dispatch_node (vm, n,
1349  VLIB_NODE_STATE_POLLING,
1350  f, last_time_stamp);
1351 
1353 
1354  /* Frame is ready to be used again, so restore it. */
1355  if (restore_frame_index != ~0)
1356  {
1357  /*
1358  * We musn't restore a frame that is flagged to be freed. This
1359  * shouldn't happen since frames to be freed post dispatch are
1360  * those used when the to-node frame becomes full i.e. they form a
1361  * sort of queue of frames to a single node. If we get here then
1362  * the to-node frame and the pending frame *were* the same, and so
1363  * we removed the to-node frame. Therefore this frame is no
1364  * longer part of the queue for that node and hence it cannot be
1365  * it's overspill.
1366  */
1368 
1369  /*
1370  * NB: dispatching node n can result in the creation and scheduling
1371  * of new frames, and hence in the reallocation of nm->pending_frames.
1372  * Recompute p, or no supper. This was broken for more than 10 years.
1373  */
1374  p = nm->pending_frames + pending_frame_index;
1375 
1376  /*
1377  * p->next_frame_index can change during node dispatch if node
1378  * function decides to change graph hook up.
1379  */
1382 
1383  if (~0 == nf->frame_index)
1384  {
1385  /* no new frame has been assigned to this node, use the saved one */
1386  nf->frame_index = restore_frame_index;
1387  f->n_vectors = 0;
1388  }
1389  else
1390  {
1391  /* The node has gained a frame, implying packets from the current frame
1392  were re-queued to this same node. we don't need the saved one
1393  anymore */
1394  vlib_frame_free (vm, n, f);
1395  }
1396  }
1397  else
1398  {
1400  {
1402  vlib_frame_free (vm, n, f);
1403  }
1404  }
1405 
1406  return last_time_stamp;
1407 }
1408 
1411 {
1412  return p->stack[0] == VLIB_PROCESS_STACK_MAGIC;
1413 }
1414 
1415 typedef struct
1416 {
1421 
1422 /* Called in process stack. */
1423 static uword
1425 {
1427  vlib_main_t *vm;
1428  vlib_node_runtime_t *node;
1429  vlib_frame_t *f;
1430  vlib_process_t *p;
1431  uword n;
1432 
1434 
1435  vm = a->vm;
1436  p = a->process;
1437  f = a->frame;
1438  node = &p->node_runtime;
1439 
1440  n = node->function (vm, node, f);
1441 
1443 
1444  clib_longjmp (&p->return_longjmp, n);
1445 
1446  return n;
1447 }
1448 
1449 /* Called in main stack. */
1452 {
1454  uword r;
1455 
1456  a.vm = vm;
1457  a.process = p;
1458  a.frame = f;
1459 
1463  (void *) p->stack + (1 << p->log2_n_stack_bytes));
1464 
1465  return r;
1466 }
1467 
1470 {
1471  uword r;
1478  return r;
1479 }
1480 
1481 static u64
1483  vlib_process_t * p, vlib_frame_t * f, u64 last_time_stamp)
1484 {
1485  vlib_node_main_t *nm = &vm->node_main;
1486  vlib_node_runtime_t *node_runtime = &p->node_runtime;
1487  vlib_node_t *node = vlib_get_node (vm, node_runtime->node_index);
1488  u32 old_process_index;
1489  u64 t;
1490  uword n_vectors, is_suspend;
1491 
1492  if (node->state != VLIB_NODE_STATE_POLLING
1495  return last_time_stamp;
1496 
1498 
1499  t = last_time_stamp;
1500  vlib_elog_main_loop_event (vm, node_runtime->node_index, t,
1501  f ? f->n_vectors : 0, /* is_after */ 0);
1502 
1503  /* Save away current process for suspend. */
1504  old_process_index = nm->current_process_index;
1506 
1507  n_vectors = vlib_process_startup (vm, p, f);
1508 
1509  nm->current_process_index = old_process_index;
1510 
1512  is_suspend = n_vectors == VLIB_PROCESS_RETURN_LONGJMP_SUSPEND;
1513  if (is_suspend)
1514  {
1516 
1517  n_vectors = 0;
1519  pf->node_runtime_index = node->runtime_index;
1520  pf->frame_index = f ? vlib_frame_index (vm, f) : ~0;
1521  pf->next_frame_index = ~0;
1522 
1523  p->n_suspends += 1;
1525 
1527  {
1528  TWT (tw_timer_wheel) * tw =
1529  (TWT (tw_timer_wheel) *) nm->timing_wheel;
1530  p->stop_timer_handle =
1531  TW (tw_timer_start) (tw,
1533  (node->runtime_index) /* [sic] pool idex */ ,
1534  0 /* timer_id */ ,
1536  }
1537  }
1538  else
1540 
1541  t = clib_cpu_time_now ();
1542 
1543  vlib_elog_main_loop_event (vm, node_runtime->node_index, t, is_suspend,
1544  /* is_after */ 1);
1545 
1547  /* n_calls */ !is_suspend,
1548  /* n_vectors */ n_vectors,
1549  /* n_clocks */ t - last_time_stamp,
1550  /* pmc_ticks */ 0ULL);
1551 
1552  return t;
1553 }
1554 
1555 void
1557 {
1558  vlib_node_main_t *nm = &vm->node_main;
1559  vlib_process_t *p = vec_elt (nm->processes, process_index);
1560  dispatch_process (vm, p, /* frame */ 0, /* cpu_time_now */ 0);
1561 }
1562 
1563 static u64
1565  uword process_index, u64 last_time_stamp)
1566 {
1567  vlib_node_main_t *nm = &vm->node_main;
1568  vlib_node_runtime_t *node_runtime;
1569  vlib_node_t *node;
1570  vlib_frame_t *f;
1571  vlib_process_t *p;
1573  u64 t, n_vectors, is_suspend;
1574 
1575  t = last_time_stamp;
1576 
1577  p = vec_elt (nm->processes, process_index);
1579  return last_time_stamp;
1580 
1583 
1586 
1587  node_runtime = &p->node_runtime;
1588  node = vlib_get_node (vm, node_runtime->node_index);
1589  f = pf->frame_index != ~0 ? vlib_get_frame (vm, pf->frame_index) : 0;
1590 
1591  vlib_elog_main_loop_event (vm, node_runtime->node_index, t,
1592  f ? f->n_vectors : 0, /* is_after */ 0);
1593 
1594  /* Save away current process for suspend. */
1596 
1597  n_vectors = vlib_process_resume (p);
1598  t = clib_cpu_time_now ();
1599 
1600  nm->current_process_index = ~0;
1601 
1602  is_suspend = n_vectors == VLIB_PROCESS_RETURN_LONGJMP_SUSPEND;
1603  if (is_suspend)
1604  {
1605  /* Suspend it again. */
1606  n_vectors = 0;
1607  p->n_suspends += 1;
1609  {
1610  p->stop_timer_handle =
1611  TW (tw_timer_start) ((TWT (tw_timer_wheel) *) nm->timing_wheel,
1613  (node->runtime_index) /* [sic] pool idex */ ,
1614  0 /* timer_id */ ,
1616  }
1617  }
1618  else
1619  {
1624  }
1625 
1626  t = clib_cpu_time_now ();
1627  vlib_elog_main_loop_event (vm, node_runtime->node_index, t, !is_suspend,
1628  /* is_after */ 1);
1629 
1631  /* n_calls */ !is_suspend,
1632  /* n_vectors */ n_vectors,
1633  /* n_clocks */ t - last_time_stamp,
1634  /* pmc_ticks */ 0ULL);
1635 
1636  return t;
1637 }
1638 
1639 void vl_api_send_pending_rpc_requests (vlib_main_t *) __attribute__ ((weak));
1640 void
1642 {
1643 }
1644 
1645 
1648 {
1649  vlib_node_main_t *nm = &vm->node_main;
1651  uword i;
1652  u64 cpu_time_now;
1654  u32 *last_node_runtime_indices = 0;
1655 
1656  /* Initialize pending node vector. */
1657  if (is_main)
1658  {
1659  vec_resize (nm->pending_frames, 32);
1660  _vec_len (nm->pending_frames) = 0;
1661  }
1662 
1663  /* Mark time of main loop start. */
1664  if (is_main)
1665  {
1666  cpu_time_now = vm->clib_time.last_cpu_time;
1667  vm->cpu_time_main_loop_start = cpu_time_now;
1668  }
1669  else
1670  cpu_time_now = clib_cpu_time_now ();
1671 
1672  /* Pre-allocate interupt runtime indices and lock. */
1674  vec_alloc (last_node_runtime_indices, 32);
1675  if (!is_main)
1677 
1678  /* Pre-allocate expired nodes. */
1683 
1684  /* Make sure the performance monitor counter is disabled */
1685  vm->perf_counter_id = ~0;
1686 
1687  /* Start all processes. */
1688  if (is_main)
1689  {
1690  uword i;
1691  nm->current_process_index = ~0;
1692  for (i = 0; i < vec_len (nm->processes); i++)
1693  cpu_time_now = dispatch_process (vm, nm->processes[i], /* frame */ 0,
1694  cpu_time_now);
1695  }
1696 
1697  while (1)
1698  {
1700 
1701  if (PREDICT_FALSE (_vec_len (vm->pending_rpc_requests) > 0))
1702  {
1703  if (!is_main)
1705  }
1706 
1707  if (!is_main)
1708  {
1710  vec_foreach (fqm, tm->frame_queue_mains)
1711  vlib_frame_queue_dequeue (vm, fqm);
1713  ((void (*)(vlib_main_t *)) vm->worker_thread_main_loop_callback)
1714  (vm);
1715  }
1716 
1717  /* Process pre-input nodes. */
1719  cpu_time_now = dispatch_node (vm, n,
1721  VLIB_NODE_STATE_POLLING,
1722  /* frame */ 0,
1723  cpu_time_now);
1724 
1725  /* Next process input nodes. */
1727  cpu_time_now = dispatch_node (vm, n,
1729  VLIB_NODE_STATE_POLLING,
1730  /* frame */ 0,
1731  cpu_time_now);
1732 
1733  if (PREDICT_TRUE (is_main && vm->queue_signal_pending == 0))
1734  vm->queue_signal_callback (vm);
1735 
1736  /* Next handle interrupts. */
1737  {
1738  /* unlocked read, for performance */
1739  uword l = _vec_len (nm->pending_interrupt_node_runtime_indices);
1740  uword i;
1741  if (PREDICT_FALSE (l > 0))
1742  {
1743  u32 *tmp;
1744  if (!is_main)
1745  {
1747  /* Re-read w/ lock held, in case another thread added an item */
1748  l = _vec_len (nm->pending_interrupt_node_runtime_indices);
1749  }
1750 
1753  last_node_runtime_indices;
1754  last_node_runtime_indices = tmp;
1755  _vec_len (last_node_runtime_indices) = 0;
1756  if (!is_main)
1758  for (i = 0; i < l; i++)
1759  {
1761  last_node_runtime_indices[i]);
1762  cpu_time_now =
1764  VLIB_NODE_STATE_INTERRUPT,
1765  /* frame */ 0,
1766  cpu_time_now);
1767  }
1768  }
1769  }
1770  /* Input nodes may have added work to the pending vector.
1771  Process pending vector until there is nothing left.
1772  All pending vectors will be processed from input -> output. */
1773  for (i = 0; i < _vec_len (nm->pending_frames); i++)
1774  cpu_time_now = dispatch_pending_node (vm, i, cpu_time_now);
1775  /* Reset pending vector for next iteration. */
1776  _vec_len (nm->pending_frames) = 0;
1777 
1778  if (is_main)
1779  {
1780  /* Check if process nodes have expired from timing wheel. */
1782 
1785  ((TWT (tw_timer_wheel) *) nm->timing_wheel, vlib_time_now (vm),
1787 
1789 
1790  if (PREDICT_FALSE
1791  (_vec_len (nm->data_from_advancing_timing_wheel) > 0))
1792  {
1793  uword i;
1794 
1795  for (i = 0; i < _vec_len (nm->data_from_advancing_timing_wheel);
1796  i++)
1797  {
1800 
1802  {
1805  di);
1806  vlib_node_t *n =
1808  vlib_process_t *p =
1809  vec_elt (nm->processes, n->runtime_index);
1810  void *data;
1811  data =
1813  te->event_type_index,
1814  te->n_data_elts,
1815  te->n_data_elt_bytes);
1816  if (te->n_data_bytes < sizeof (te->inline_event_data))
1818  te->n_data_bytes);
1819  else
1820  {
1822  te->n_data_bytes);
1824  }
1826  }
1827  else
1828  {
1829  cpu_time_now = clib_cpu_time_now ();
1830  cpu_time_now =
1831  dispatch_suspended_process (vm, di, cpu_time_now);
1832  }
1833  }
1834  _vec_len (nm->data_from_advancing_timing_wheel) = 0;
1835  }
1836  }
1838 
1839  /* Record time stamp in case there are no enabled nodes and above
1840  calls do not update time stamp. */
1841  cpu_time_now = clib_cpu_time_now ();
1842  }
1843 }
1844 
1845 static void
1847 {
1848  vlib_main_or_worker_loop (vm, /* is_main */ 1);
1849 }
1850 
1851 void
1853 {
1854  vlib_main_or_worker_loop (vm, /* is_main */ 0);
1855 }
1856 
1858 
1859 static clib_error_t *
1861 {
1862  int turn_on_mem_trace = 0;
1863 
1864  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1865  {
1866  if (unformat (input, "memory-trace"))
1867  turn_on_mem_trace = 1;
1868 
1869  else if (unformat (input, "elog-events %d",
1870  &vm->elog_main.event_ring_size))
1871  ;
1872  else if (unformat (input, "elog-post-mortem-dump"))
1873  vm->elog_post_mortem_dump = 1;
1874  else
1875  return unformat_parse_error (input);
1876  }
1877 
1878  unformat_free (input);
1879 
1880  /* Enable memory trace as early as possible. */
1881  if (turn_on_mem_trace)
1882  clib_mem_trace (1);
1883 
1884  return 0;
1885 }
1886 
1888 
1889 static void
1891 {
1892 }
1893 
1894 #define foreach_weak_reference_stub \
1895 _(vlib_map_stat_segment_init) \
1896 _(vpe_api_init) \
1897 _(vlibmemory_init) \
1898 _(map_api_segment_init)
1899 
1900 #define _(name) \
1901 clib_error_t *name (vlib_main_t *vm) __attribute__((weak)); \
1902 clib_error_t *name (vlib_main_t *vm) { return 0; }
1904 #undef _
1905 
1906 /* Main function. */
1907 int
1909 {
1910  clib_error_t *volatile error;
1911  vlib_node_main_t *nm = &vm->node_main;
1912 
1914 
1915  clib_time_init (&vm->clib_time);
1916 
1917  /* Turn on event log. */
1918  if (!vm->elog_main.event_ring_size)
1919  vm->elog_main.event_ring_size = 128 << 10;
1921  elog_enable_disable (&vm->elog_main, 1);
1922 
1923  /* Default name. */
1924  if (!vm->name)
1925  vm->name = "VLIB";
1926 
1927  if ((error = vlib_physmem_init (vm)))
1928  {
1929  clib_error_report (error);
1930  goto done;
1931  }
1932 
1933  if ((error = vlib_buffer_main_init (vm)))
1934  {
1935  clib_error_report (error);
1936  goto done;
1937  }
1938 
1939  if ((error = vlib_thread_init (vm)))
1940  {
1941  clib_error_report (error);
1942  goto done;
1943  }
1944 
1945  if ((error = vlib_map_stat_segment_init (vm)))
1946  {
1947  clib_error_report (error);
1948  goto done;
1949  }
1950 
1951  /* Register static nodes so that init functions may use them. */
1953 
1954  /* Set seed for random number generator.
1955  Allow user to specify seed to make random sequence deterministic. */
1956  if (!unformat (input, "seed %wd", &vm->random_seed))
1957  vm->random_seed = clib_cpu_time_now ();
1959 
1960  /* Initialize node graph. */
1961  if ((error = vlib_node_main_init (vm)))
1962  {
1963  /* Arrange for graph hook up error to not be fatal when debugging. */
1964  if (CLIB_DEBUG > 0)
1965  clib_error_report (error);
1966  else
1967  goto done;
1968  }
1969 
1970  /* Direct call / weak reference, for vlib standalone use-cases */
1971  if ((error = vpe_api_init (vm)))
1972  {
1973  clib_error_report (error);
1974  goto done;
1975  }
1976 
1977  if ((error = vlibmemory_init (vm)))
1978  {
1979  clib_error_report (error);
1980  goto done;
1981  }
1982 
1983  if ((error = map_api_segment_init (vm)))
1984  {
1985  clib_error_report (error);
1986  goto done;
1987  }
1988 
1989  /* See unix/main.c; most likely already set up */
1990  if (vm->init_functions_called == 0)
1991  vm->init_functions_called = hash_create (0, /* value bytes */ 0);
1992  if ((error = vlib_call_all_init_functions (vm)))
1993  goto done;
1994 
1995  /* Create default buffer free list. */
1997  "default");
1998 
1999  nm->timing_wheel = clib_mem_alloc_aligned (sizeof (TWT (tw_timer_wheel)),
2001 
2003  _vec_len (nm->data_from_advancing_timing_wheel) = 0;
2004 
2005  /* Create the process timing wheel */
2006  TW (tw_timer_wheel_init) ((TWT (tw_timer_wheel) *) nm->timing_wheel,
2007  0 /* no callback */ ,
2008  10e-6 /* timer period 10us */ ,
2009  ~0 /* max expirations per call */ );
2010 
2012  _vec_len (vm->pending_rpc_requests) = 0;
2014  _vec_len (vm->processing_rpc_requests) = 0;
2015 
2016  if ((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))
2017  goto done;
2018 
2019  /* Call all main loop enter functions. */
2020  {
2021  clib_error_t *sub_error;
2022  sub_error = vlib_call_all_main_loop_enter_functions (vm);
2023  if (sub_error)
2024  clib_error_report (sub_error);
2025  }
2026 
2028  {
2030  vm->main_loop_exit_set = 1;
2031  break;
2032 
2034  goto done;
2035 
2036  default:
2037  error = vm->main_loop_error;
2038  goto done;
2039  }
2040 
2041  vlib_main_loop (vm);
2042 
2043 done:
2044  /* Call all exit functions. */
2045  {
2046  clib_error_t *sub_error;
2047  sub_error = vlib_call_all_main_loop_exit_functions (vm);
2048  if (sub_error)
2049  clib_error_report (sub_error);
2050  }
2051 
2052  if (error)
2053  clib_error_report (error);
2054 
2055  return 0;
2056 }
2057 
2058 static inline clib_error_t *
2060  unformat_input_t * input,
2061  vlib_cli_command_t * cmd, int rx_tx)
2062 {
2063 #define PCAP_DEF_PKT_TO_CAPTURE (100)
2064 
2065  unformat_input_t _line_input, *line_input = &_line_input;
2066  pcap_main_t *pm = &vm->dispatch_pcap_main;
2067  u8 *filename;
2068  u8 *chroot_filename = 0;
2069  u32 max = 0;
2070  int enabled = 0;
2071  int errorFlag = 0;
2072  clib_error_t *error = 0;
2073  u32 node_index, add;
2074  vlib_trace_main_t *tm;
2075  vlib_trace_node_t *tn;
2076 
2077  /* Get a line of input. */
2078  if (!unformat_user (input, unformat_line_input, line_input))
2079  return 0;
2080 
2081  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2082  {
2083  if (unformat (line_input, "on"))
2084  {
2085  if (vm->dispatch_pcap_enable == 0)
2086  {
2087  enabled = 1;
2088  }
2089  else
2090  {
2091  vlib_cli_output (vm, "pcap dispatch capture already on...");
2092  errorFlag = 1;
2093  break;
2094  }
2095  }
2096  else if (unformat (line_input, "off"))
2097  {
2098  if (vm->dispatch_pcap_enable)
2099  {
2101  (vm, "captured %d pkts...", pm->n_packets_captured);
2102  if (pm->n_packets_captured)
2103  {
2105  error = pcap_write (pm);
2106  if (error)
2107  clib_error_report (error);
2108  else
2109  vlib_cli_output (vm, "saved to %s...", pm->file_name);
2110  }
2111  vm->dispatch_pcap_enable = 0;
2112  }
2113  else
2114  {
2115  vlib_cli_output (vm, "pcap tx capture already off...");
2116  errorFlag = 1;
2117  break;
2118  }
2119  }
2120  else if (unformat (line_input, "max %d", &max))
2121  {
2122  if (vm->dispatch_pcap_enable)
2123  {
2125  (vm,
2126  "can't change max value while pcap tx capture active...");
2127  errorFlag = 1;
2128  break;
2129  }
2130  pm->n_packets_to_capture = max;
2131  }
2132  else if (unformat (line_input, "file %s", &filename))
2133  {
2134  if (vm->dispatch_pcap_enable)
2135  {
2137  (vm, "can't change file while pcap tx capture active...");
2138  errorFlag = 1;
2139  break;
2140  }
2141 
2142  /* Brain-police user path input */
2143  if (strstr ((char *) filename, "..")
2144  || index ((char *) filename, '/'))
2145  {
2146  vlib_cli_output (vm, "illegal characters in filename '%s'",
2147  filename);
2148  vlib_cli_output (vm, "Hint: .. and / are not allowed.");
2149  vec_free (filename);
2150  errorFlag = 1;
2151  break;
2152  }
2153 
2154  chroot_filename = format (0, "/tmp/%s%c", filename, 0);
2155  vec_free (filename);
2156  }
2157  else if (unformat (line_input, "status"))
2158  {
2159  if (vm->dispatch_pcap_enable)
2160  {
2162  (vm, "pcap dispatch capture is on: %d of %d pkts...",
2164  vlib_cli_output (vm, "Capture to file %s", pm->file_name);
2165  }
2166  else
2167  {
2168  vlib_cli_output (vm, "pcap dispatch capture is off...");
2169  }
2170  break;
2171  }
2172  else if (unformat (line_input, "buffer-trace %U %d",
2173  unformat_vlib_node, vm, &node_index, &add))
2174  {
2175  if (vnet_trace_dummy == 0)
2178  vlib_cli_output (vm, "Buffer tracing of %d pkts from %U enabled...",
2179  add, format_vlib_node_name, vm, node_index);
2180 
2181  /* *INDENT-OFF* */
2183  {
2184  tm = &this_vlib_main->trace_main;
2185  tm->verbose = 0; /* not sure this ever did anything... */
2186  vec_validate (tm->nodes, node_index);
2187  tn = tm->nodes + node_index;
2188  tn->limit += add;
2189  tm->trace_enable = 1;
2190  }));
2191  /* *INDENT-ON* */
2192  }
2193 
2194  else
2195  {
2196  error = clib_error_return (0, "unknown input `%U'",
2197  format_unformat_error, line_input);
2198  errorFlag = 1;
2199  break;
2200  }
2201  }
2202  unformat_free (line_input);
2203 
2204 
2205  if (errorFlag == 0)
2206  {
2207  /* Since no error, save configured values. */
2208  if (chroot_filename)
2209  {
2210  if (pm->file_name)
2211  vec_free (pm->file_name);
2212  vec_add1 (chroot_filename, 0);
2213  pm->file_name = (char *) chroot_filename;
2214  }
2215 
2216  if (max)
2217  pm->n_packets_to_capture = max;
2218 
2219  if (enabled)
2220  {
2221  if (pm->file_name == 0)
2222  pm->file_name = (char *) format (0, "/tmp/dispatch.pcap%c", 0);
2223 
2224  pm->n_packets_captured = 0;
2225  pm->packet_type = PCAP_PACKET_TYPE_vpp;
2226  if (pm->lock == 0)
2227  clib_spinlock_init (&(pm->lock));
2228  vm->dispatch_pcap_enable = 1;
2229  vlib_cli_output (vm, "pcap dispatch capture on...");
2230  }
2231  }
2232  else if (chroot_filename)
2233  vec_free (chroot_filename);
2234 
2235  return error;
2236 }
2237 
2238 static clib_error_t *
2240  unformat_input_t * input,
2241  vlib_cli_command_t * cmd)
2242 {
2243  return pcap_dispatch_trace_command_internal (vm, input, cmd, VLIB_RX);
2244 }
2245 
2246 /*?
2247  * This command is used to start or stop pcap dispatch trace capture, or show
2248  * the capture status.
2249  *
2250  * This command has the following optional parameters:
2251  *
2252  * - <b>on|off</b> - Used to start or stop capture.
2253  *
2254  * - <b>max <nn></b> - Depth of local buffer. Once '<em>nn</em>' number
2255  * of packets have been received, buffer is flushed to file. Once another
2256  * '<em>nn</em>' number of packets have been received, buffer is flushed
2257  * to file, overwriting previous write. If not entered, value defaults
2258  * to 100. Can only be updated if packet capture is off.
2259  *
2260  * - <b>file <name></b> - Used to specify the output filename. The file will
2261  * be placed in the '<em>/tmp</em>' directory, so only the filename is
2262  * supported. Directory should not be entered. If file already exists, file
2263  * will be overwritten. If no filename is provided, '<em>/tmp/vpe.pcap</em>'
2264  * will be used. Can only be updated if packet capture is off.
2265  *
2266  * - <b>status</b> - Displays the current status and configured attributes
2267  * associated with a packet capture. If packet capture is in progress,
2268  * '<em>status</em>' also will return the number of packets currently in
2269  * the local buffer. All additional attributes entered on command line
2270  * with '<em>status</em>' will be ignored and not applied.
2271  *
2272  * @cliexpar
2273  * Example of how to display the status of capture when off:
2274  * @cliexstart{pcap dispatch trace status}
2275  * max is 100, for any interface to file /tmp/vpe.pcap
2276  * pcap dispatch capture is off...
2277  * @cliexend
2278  * Example of how to start a dispatch trace capture:
2279  * @cliexstart{pcap dispatch trace on max 35 file dispatchTrace.pcap}
2280  * pcap dispatch capture on...
2281  * @cliexend
2282  * Example of how to start a dispatch trace capture with buffer tracing
2283  * @cliexstart{pcap dispatch trace on max 10000 file dispatchTrace.pcap buffer-trace dpdk-input 1000}
2284  * pcap dispatch capture on...
2285  * @cliexend
2286  * Example of how to display the status of a tx packet capture in progress:
2287  * @cliexstart{pcap tx trace status}
2288  * max is 35, dispatch trace to file /tmp/vppTest.pcap
2289  * pcap tx capture is on: 20 of 35 pkts...
2290  * @cliexend
2291  * Example of how to stop a tx packet capture:
2292  * @cliexstart{vppctl pcap dispatch trace off}
2293  * captured 21 pkts...
2294  * saved to /tmp/dispatchTrace.pcap...
2295  * @cliexend
2296 ?*/
2297 /* *INDENT-OFF* */
2298 VLIB_CLI_COMMAND (pcap_dispatch_trace_command, static) = {
2299  .path = "pcap dispatch trace",
2300  .short_help =
2301  "pcap dispatch trace [on|off] [max <nn>] [file <name>] [status]\n"
2302  " [buffer-trace <input-node-name> <nn>]",
2303  .function = pcap_dispatch_trace_command_fn,
2304 };
2305 /* *INDENT-ON* */
2306 
2307 /*
2308  * fd.io coding-style-patch-verification: ON
2309  *
2310  * Local Variables:
2311  * eval: (c-set-style "gnu")
2312  * End:
2313  */
u32 * next_nodes
Definition: node.h:358
static void elog_enable_disable(elog_main_t *em, int is_enabled)
Enable or disable event logging.
Definition: elog.h:217
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u32 TW() tw_timer_start(TWT(tw_timer_wheel)*tw, u32 user_id, u32 timer_id, u64 interval)
Start a Tw Timer.
clib_error_t * vlib_call_all_main_loop_exit_functions(vlib_main_t *vm)
Definition: init.c:87
uword * pending_rpc_requests
Definition: main.h:220
vlib_main_t vlib_global_main
Definition: main.c:1857
f64 time
Absolute time as floating point number in seconds.
Definition: elog.h:66
void TW() tw_timer_wheel_init(TWT(tw_timer_wheel)*tw, void *expired_timer_callback, f64 timer_interval_in_seconds, u32 max_expirations)
Initialize a tw timer wheel template instance.
u16 vector_size
Definition: node.h:344
u32 max_clock
Maximum clock cycle for an invocation.
Definition: node.h:502
u32 next_frame_index
Start of next frames for this node.
Definition: node.h:516
static clib_error_t * show_frame_stats(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:244
#define hash_set(h, key, value)
Definition: hash.h:255
char * file_name
File name of pcap output.
Definition: pcap.h:162
u32 flags
Definition: vhost_user.h:115
vlib_node_type_t
Definition: node.h:69
#define clib_min(x, y)
Definition: clib.h:295
clib_error_t * vlib_call_all_main_loop_enter_functions(vlib_main_t *vm)
Definition: init.c:80
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:89
static void vlib_next_frame_change_ownership(vlib_main_t *vm, vlib_node_runtime_t *node_runtime, u32 next_index)
Definition: main.c:274
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:74
static vlib_next_frame_t * vlib_node_get_next_frame(vlib_main_t *vm, u32 node_index, u32 next_index)
Get pointer to frame by (node_index, next_index).
Definition: node_funcs.h:329
u32 interrupt_threshold_vector_length
Definition: node.h:742
vlib_process_t ** processes
Definition: node.h:763
static uword vlib_process_bootstrap(uword _a)
Definition: main.c:1424
format_function_t format_vlib_node_name
Definition: node_funcs.h:1171
vlib_node_runtime_t node_runtime
Definition: node.h:577
a
Definition: bitmap.h:538
u32 n_suspends
Definition: node.h:605
#define VLIB_PENDING_FRAME_NO_NEXT_FRAME
Definition: node.h:485
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:165
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:136
vlib_frame_t * vlib_get_next_frame_internal(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 allocate_new_next_frame)
Definition: main.c:357
uword * processing_rpc_requests
Definition: main.h:221
#define VLIB_PCAP_MAJOR_VERSION
Definition: main.h:378
vlib_trace_node_t * nodes
Definition: trace.h:86
static void vlib_elog_main_loop_event(vlib_main_t *vm, u32 node_index, u64 time, u32 n_vectors, u32 is_return)
Definition: main.c:904
static clib_error_t * elog_save_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:706
int elog_post_mortem_dump
Definition: main.h:202
uword dispatch_pcap_enable
Definition: main.h:139
#define PREDICT_TRUE(x)
Definition: clib.h:112
uword random_seed
Definition: main.h:170
unsigned long u64
Definition: types.h:89
static void vlib_increment_main_loop_counter(vlib_main_t *vm)
Definition: main.h:334
elog_time_stamp_t init_time
Timestamps.
Definition: elog.h:169
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
void clib_random_buffer_init(clib_random_buffer_t *b, uword seed)
Definition: random_buffer.c:62
u32 index
Definition: node.h:304
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:232
static void dummy_queue_signal_callback(vlib_main_t *vm)
Definition: main.c:1890
u32 current_process_index
Definition: node.h:766
static void vlib_process_update_stats(vlib_main_t *vm, vlib_process_t *p, uword n_calls, uword n_vectors, uword n_clocks, uword n_ticks)
Definition: main.c:679
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:98
u32 *TW() tw_timer_expire_timers_vec(TWT(tw_timer_wheel)*tw, f64 now, u32 *vec)
static void vlib_process_sync_stats(vlib_main_t *vm, vlib_process_t *p, uword n_calls, uword n_vectors, uword n_clocks, uword n_ticks)
Definition: main.c:570
u32 thread_index
Definition: main.h:179
static_always_inline uword vlib_process_startup(vlib_main_t *vm, vlib_process_t *p, vlib_frame_t *f)
Definition: main.c:1451
u32 main_loop_exit_set
Definition: main.h:98
static u64 dispatch_pending_node(vlib_main_t *vm, uword pending_frame_index, u64 last_time_stamp)
Definition: main.c:1296
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:525
static u64 clib_cpu_time_now(void)
Definition: time.h:75
u8 buffer_pool_index
index of buffer pool this buffer belongs.
Definition: buffer.h:144
elog_track_t elog_track
Definition: threads.h:100
u32 clocks_since_last_overflow
Number of clock cycles.
Definition: node.h:500
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:564
int i
u32 recycle_count
Used by L2 path recycle code.
Definition: buffer.h:154
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
static void elog_show_buffer_internal(vlib_main_t *vm, u32 n_events_to_show)
Definition: main.c:841
#define VLIB_MAIN_LOOP_EXIT_CLI
Definition: main.h:105
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
void clib_longjmp(clib_longjmp_t *save, uword return_value)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static vlib_frame_size_t * get_frame_size_info(vlib_node_main_t *nm, u32 n_scalar_bytes, u32 n_vector_bytes)
Definition: main.c:95
static clib_error_t * elog_show_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:869
u8 * format_elog_event(u8 *s, va_list *va)
Definition: elog.c:296
clib_time_t clib_time
Definition: main.h:65
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:450
clib_spinlock_t pending_interrupt_lock
Definition: node.h:736
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:267
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
uword clib_setjmp(clib_longjmp_t *save, uword return_value_not_taken)
#define vec_alloc(V, N)
Allocate space for N more elements (no header, unspecified alignment)
Definition: vec.h:280
unsigned char u8
Definition: types.h:56
static uword vlib_process_stack_is_valid(vlib_process_t *p)
Definition: main.c:1410
static vlib_frame_t * vlib_get_frame_no_check(vlib_main_t *vm, uword frame_index)
Definition: node_funcs.h:217
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
double f64
Definition: types.h:142
u16 scalar_size
Definition: node.h:344
u8 state
Definition: node.h:332
u16 thread_index
thread this node runs on
Definition: node.h:544
#define vlib_worker_thread_barrier_sync(X)
Definition: threads.h:204
static void vlib_worker_thread_barrier_check(void)
Definition: threads.h:390
u32 * pending_interrupt_node_runtime_indices
Definition: node.h:735
u32 input_main_loops_per_call
For input nodes: decremented on each main loop interation until it reaches zero and function is calle...
Definition: node.h:521
static void vlib_main_loop(vlib_main_t *vm)
Definition: main.c:1846
#define foreach_weak_reference_stub
Definition: main.c:1894
vlib_trace_header_t ** trace_buffer_pool
Definition: trace.h:72
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:110
#define static_always_inline
Definition: clib.h:99
PCAP main state data structure.
Definition: pcap.h:156
u32 trace_enable
Definition: trace.h:83
clib_spinlock_t lock
spinlock to protect e.g.
Definition: pcap.h:159
#define VLIB_FRAME_NO_APPEND
Definition: node.h:442
vlib_node_function_t * function
Node function to call.
Definition: node.h:492
void elog_init(elog_main_t *em, u32 n_events)
Definition: elog.c:493
#define VLIB_FRAME_MAGIC
#define always_inline
Definition: clib.h:98
u32 main_loop_vectors_processed
Definition: main.h:80
#define VLIB_INVALID_NODE_INDEX
Definition: node.h:398
static u32 vlib_frame_alloc(vlib_main_t *vm, vlib_node_runtime_t *from_node_runtime, u32 to_next_index)
Definition: main.c:170
u16 log2_n_stack_bytes
Definition: node.h:600
vlib_node_t ** nodes
Definition: node.h:722
u32 vectors_since_last_overflow
Number of vector elements processed by this node.
Definition: node.h:510
vlib_frame_t * frame
Definition: main.c:1419
void di(unformat_input_t *i)
Definition: unformat.c:163
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
Definition: main.c:183
#define clib_error_return(e, args...)
Definition: error.h:99
static void dispatch_pcap_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: main.c:999
#define VLIB_FRAME_ALIGN
Definition: node.h:402
u64 perf_counter_vectors
Definition: node.h:262
u64 perf_counter_ticks
Definition: node.h:261
static uword vlib_timing_wheel_data_is_timed_event(u32 d)
Definition: node.h:696
#define VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE
Definition: node.h:328
#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES
Definition: buffer.h:443
#define VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK
Definition: node.h:591
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:242
unsigned int u32
Definition: types.h:88
u64 cpu_time_main_loop_start
Definition: main.h:74
vlib_node_runtime_t * nodes_by_type[VLIB_N_NODE_TYPE]
Definition: node.h:732
static u32 vlib_frame_bytes(u32 n_scalar_bytes, u32 n_vector_bytes)
Definition: main.c:58
u32 * free_frame_indices
Definition: node.h:565
#define VLIB_MAIN_LOOP_EXIT_NONE
Definition: main.h:102
clib_error_t * vlib_node_main_init(vlib_main_t *vm)
Definition: node.c:631
#define VLIB_FRAME_SIZE
Definition: node.h:401
static vlib_next_frame_t * vlib_node_runtime_get_next_frame(vlib_main_t *vm, vlib_node_runtime_t *n, u32 next_index)
Definition: node_funcs.h:294
static u32 vlib_node_runtime_update_stats(vlib_main_t *vm, vlib_node_runtime_t *node, uword n_calls, uword n_vectors, uword n_clocks, uword n_ticks)
Definition: main.c:621
u8 * pcap_buffer
Definition: main.h:140
#define VLIB_PROCESS_IS_RUNNING
Definition: node.h:597
#define VLIB_PROCESS_RETURN_LONGJMP_RETURN
Definition: node.h:582
u64 max_clock_n
Definition: node.h:260
int callbacks_registered
Definition: buffer.h:458
unformat_function_t unformat_line_input
Definition: format.h:282
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:57
u32 calls_since_last_overflow
Number of calls.
Definition: node.h:508
char * name
Definition: main.h:111
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:36
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:511
static clib_error_t * elog_write_file(elog_main_t *em, char *clib_file, int flush_ring)
Definition: elog.h:529
u32 next_frame_index
Definition: node.h:482
static void * vlib_process_signal_event_helper(vlib_node_main_t *nm, vlib_node_t *n, vlib_process_t *p, uword t, uword n_data_elts, uword n_data_elt_bytes)
Definition: node_funcs.h:773
vlib_node_stats_t stats_total
Definition: node.h:294
static void vlib_put_next_frame_validate(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 next_index, u32 n_vectors_left)
Definition: main.c:423
u16 state
Input node state.
Definition: node.h:534
static u8 * format_buffer_metadata(u8 *s, va_list *args)
Definition: main.c:976
u32 frame_index
Definition: node.h:429
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:114
format_function_t format_vlib_trace
Definition: trace.h:92
vlib_signal_timed_event_data_t * signal_timed_event_data_pool
Definition: node.h:753
static u32 vlib_frame_index(vlib_main_t *vm, vlib_frame_t *f)
Definition: node_funcs.h:252
u16 frame_flags
Definition: node.h:408
#define VLIB_FRAME_IS_ALLOCATED
Definition: node.h:449
#define VLIB_FRAME_NO_FREE_AFTER_DISPATCH
Definition: node.h:438
struct _unformat_input_t unformat_input_t
static_always_inline u64 dispatch_node(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_node_type_t type, vlib_node_state_t dispatch_state, vlib_frame_t *frame, u64 last_time_stamp)
Definition: main.c:1106
u32 n_alloc_frames
Definition: node.h:562
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
Definition: main.c:192
static clib_error_t * pcap_dispatch_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:2239
static uword vlib_timing_wheel_data_get_index(u32 d)
Definition: node.h:714
u8 inline_event_data[64-3 *sizeof(u32)-2 *sizeof(u16)]
Definition: node.h:687
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
elog_event_type_t * node_return_elog_event_types
Definition: main.h:165
#define TWT(a)
void vlib_frame_free(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_frame_t *f)
Definition: main.c:212
u32 polling_threshold_vector_length
Definition: node.h:741
u64 * n_vectors_by_next_node
Definition: node.h:367
#define PREDICT_FALSE(x)
Definition: clib.h:111
u32 perf_counter_ticks_since_last_overflow
Perf counter ticks.
Definition: node.h:513
f64 seconds_per_clock
Definition: time.h:57
void elog_post_mortem_dump(void)
Definition: main.c:743
static vlib_frame_t * vlib_get_frame(vlib_main_t *vm, uword frame_index)
Definition: node_funcs.h:238
u8 protocol_hint
Definition: node.h:338
u32 node_index
Node index.
Definition: node.h:519
#define foreach_vlib_main(body)
Definition: threads.h:235
uword * init_functions_called
Definition: main.h:176
#define VLIB_ELOG_MAIN_LOOP
Definition: main.h:58
static void * pcap_add_packet(pcap_main_t *pm, f64 time_now, u32 n_bytes_in_trace, u32 n_bytes_in_packet)
Add packet.
Definition: pcap_funcs.h:37
#define VLIB_PROCESS_STACK_MAGIC
Definition: node.h:648
#define VLIB_PROCESS_RESUME_LONGJMP_RESUME
Definition: node.h:588
void clib_time_init(clib_time_t *c)
Definition: time.c:178
uword * frame_size_hash
Definition: node.h:778
void elog_alloc(elog_main_t *em, u32 n_events)
Definition: elog.c:479
clib_error_t * vlibmemory_init(vlib_main_t *vm)
Definition: memory_api.c:936
volatile u32 queue_signal_pending
Definition: main.h:190
int perf_counter_id
Definition: main.h:91
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:139
clib_error_t * map_api_segment_init(vlib_main_t *vm)
Definition: memory_api.c:482
u8 * name
Definition: node.h:288
static u64 dispatch_process(vlib_main_t *vm, vlib_process_t *p, vlib_frame_t *f, u64 last_time_stamp)
Definition: main.c:1482
u32 wraps
Definition: main.c:55
static u32 vlib_frame_index_no_check(vlib_main_t *vm, vlib_frame_t *f)
Definition: node_funcs.h:225
u64(* vlib_node_runtime_perf_counter_cb)(struct vlib_main_t *)
Definition: main.h:90
u32 owner_node_index
Definition: node.h:378
void vlib_register_all_static_nodes(vlib_main_t *vm)
Definition: node.c:540
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:216
static u32 vlib_node_runtime_update_main_loop_vector_stats(vlib_main_t *vm, vlib_node_runtime_t *node, uword n_vectors)
Definition: node_funcs.h:1059
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
u32 flow_id
Generic flow identifier.
Definition: buffer.h:127
svmdb_client_t * c
u16 n_vectors
Definition: node.h:420
u32 runtime_index
Definition: node.h:307
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:79
vlib_main_t * vm
Definition: buffer.c:301
static uword elog_n_events_in_buffer(elog_main_t *em)
Return number of events in the event-log buffer.
Definition: elog.h:188
static_always_inline void vlib_main_or_worker_loop(vlib_main_t *vm, int is_main)
Definition: main.c:1647
u32 node_runtime_index
Definition: node.h:476
vlib_pending_frame_t * pending_frames
Definition: node.h:748
int vlib_frame_queue_dequeue(vlib_main_t *vm, vlib_frame_queue_main_t *fqm)
Definition: threads.c:1579
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
clib_error_t * vpe_api_init(vlib_main_t *vm)
Definition: api.c:556
#define VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
Definition: node.h:317
#define clib_warning(format, args...)
Definition: error.h:59
#define VLIB_PROCESS_RESUME_PENDING
Definition: node.h:594
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:89
u32 perf_counter_vectors_since_last_overflow
Perf counter vectors.
Definition: node.h:514
#define VLIB_BUFFER_TRACE_TRAJECTORY
Compile time buffer trajectory tracing option Turn this on if you run into "bad monkey" contexts...
Definition: buffer.h:486
elog_main_t elog_main
Definition: main.h:157
clib_error_t * vlib_buffer_main_init(struct vlib_main_t *vm)
Definition: buffer.c:907
#define VLIB_FRAME_PENDING
Definition: node.h:452
static u32 vlib_frame_vector_byte_offset(u32 scalar_size)
Definition: node_funcs.h:263
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:459
#define ELOG_TYPE_DECLARE(f)
Definition: elog.h:439
clib_error_t * pcap_write(pcap_main_t *pm)
Write PCAP file.
Definition: pcap.c:89
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:241
u32 n_total_events_disable_limit
When count reaches limit logging is disabled.
Definition: elog.h:138
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
#define VLIB_PCAP_MINOR_VERSION
Definition: main.h:379
#define never_inline
Definition: clib.h:95
signed int i32
Definition: types.h:77
#define hash_create(elts, value_bytes)
Definition: hash.h:696
#define uword_to_pointer(u, type)
Definition: types.h:136
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:538
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:311
#define ASSERT(truth)
u64 last_cpu_time
Definition: time.h:50
static u64 vlib_node_runtime_perf_counter(vlib_main_t *vm)
Definition: main.c:671
static void elog_reset_buffer(elog_main_t *em)
Reset the event buffer.
Definition: elog.h:207
vlib_frame_queue_main_t * frame_queue_mains
Definition: threads.h:326
#define ELOG_TRACK_DATA(em, f, track)
Definition: elog.h:475
uword event_ring_size
Power of 2 number of elements in ring.
Definition: elog.h:144
u16 flags
Definition: node.h:411
u32 main_loop_nodes_processed
Definition: main.h:81
u64 cpu
CPU cycle counter.
Definition: elog.h:125
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:130
#define clib_error_report(e)
Definition: error.h:113
vlib_trace_main_t trace_main
Definition: main.h:135
u8 * format_vnet_buffer_opaque(u8 *s, va_list *args)
Definition: main.c:960
u8 * vnet_trace_dummy
Definition: trace.c:43
u8 * format_vnet_buffer_opaque2(u8 *s, va_list *args)
Definition: main.c:969
static uword pointer_to_uword(const void *p)
Definition: types.h:131
static u32 vlib_frame_alloc_to_node(vlib_main_t *vm, u32 to_node_index, u32 frame_flags)
Definition: main.c:115
u8 n_add_refs
Number of additional references to this buffer.
Definition: buffer.h:142
#define A(x)
Definition: main.c:996
void(* queue_signal_callback)(struct vlib_main_t *)
Definition: main.h:192
void vlib_gdb_show_event_log(void)
Definition: main.c:898
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
static_always_inline uword vlib_process_resume(vlib_process_t *p)
Definition: main.c:1469
#define VLIB_FRAME_OWNER
Definition: node.h:446
void vlib_node_sync_stats(vlib_main_t *vm, vlib_node_t *n)
Definition: main.c:584
#define vec_elt(v, i)
Get vector value at index i.
int vlib_main(vlib_main_t *volatile vm, unformat_input_t *input)
Definition: main.c:1908
#define unformat_parse_error(input)
Definition: format.h:268
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
Definition: buffer.h:156
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:168
void vlib_worker_loop(vlib_main_t *vm)
Definition: main.c:1852
never_inline void vlib_node_runtime_sync_stats(vlib_main_t *vm, vlib_node_runtime_t *r, uword n_calls, uword n_vectors, uword n_clocks, uword n_ticks)
Definition: main.c:545
static vlib_node_t * vlib_get_next_node(vlib_main_t *vm, u32 node_index, u32 next_index)
Get vlib node by graph arc (next) index.
Definition: node_funcs.h:72
static clib_error_t * pcap_dispatch_trace_command_internal(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, int rx_tx)
Definition: main.c:2059
void vl_api_send_pending_rpc_requests(vlib_main_t *)
Definition: main.c:1641
#define clib_mem_alloc_aligned_no_fail(size, align)
Definition: mem.h:166
CJ_GLOBAL_LOG_PROTOTYPE
Definition: main.c:49
u32 * data_from_advancing_timing_wheel
Definition: node.h:756
clib_error_t * vlib_physmem_init(vlib_main_t *vm)
Definition: physmem.c:94
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 input_node_counts_by_state[VLIB_N_NODE_STATE]
Definition: node.h:775
vlib_pending_frame_t * suspended_process_frames
Definition: node.h:769
vlib_node_main_t node_main
Definition: main.h:129
static u32 * vlib_frame_find_magic(vlib_frame_t *f, vlib_node_t *node)
Definition: main.c:83
u64 uword
Definition: types.h:112
u32 owner_next_index
Definition: node.h:378
u8 vector_size
Definition: node.h:417
vlib_next_frame_t * next_frames
Definition: node.h:745
static clib_error_t * elog_stop(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:769
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
clib_error_t * vlib_call_all_config_functions(vlib_main_t *vm, unformat_input_t *input, int is_early)
Definition: init.c:94
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:274
#define VLIB_FRAME_TRACE
Definition: node.h:458
u32 stop_timer_handle
Definition: node.h:630
clib_error_t * vlib_call_all_init_functions(vlib_main_t *vm)
Definition: init.c:67
#define VLIB_FRAME_SIZE_EXTRA
unformat_function_t unformat_vlib_node
Definition: node_funcs.h:1177
static void elog_track(elog_main_t *em, elog_event_type_t *type, elog_track_t *track, u32 data)
Log a single-datum event to a specific track, non-inline version.
Definition: elog.h:395
static u64 dispatch_suspended_process(vlib_main_t *vm, uword process_index, u64 last_time_stamp)
Definition: main.c:1564
vlib_frame_size_t * frame_sizes
Definition: node.h:781
u64 resume_clock_interval
Definition: node.h:627
static void add_trajectory_trace(vlib_buffer_t *b, u32 node_index)
Definition: main.c:940
u16 flags
Definition: node.h:590
elog_event_type_t * node_call_elog_event_types
Definition: main.h:164
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:140
vlib_node_type_t type
Definition: node.h:301
static vlib_process_t * vlib_get_process_from_node(vlib_main_t *vm, vlib_node_t *node)
Definition: node_funcs.h:208
uword clib_calljmp(uword(*func)(uword func_arg), uword func_arg, void *stack)
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u32 name_elog_string
Definition: node.h:291
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1468
vlib_node_state_t
Definition: node.h:274
pcap_main_t dispatch_pcap_main
Definition: main.h:138
u64 init_cpu_time
Definition: time.h:62
u32 suspended_process_frame_index
Definition: node.h:602
static void validate_frame_magic(vlib_main_t *vm, vlib_frame_t *f, vlib_node_t *n, uword next_index)
Definition: main.c:348
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
vlib_buffer_main_t buffer_main
Definition: buffer.c:56
static clib_error_t * vlib_main_configure(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:1860
u8 data[0]
Packet data.
Definition: buffer.h:176
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
static clib_error_t * vlib_cli_elog_clear(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:689
#define VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT
Definition: node.h:592
#define vec_foreach(var, vec)
Vector iterator.
elog_track_t default_track
Default track.
Definition: elog.h:163
clib_longjmp_t return_longjmp
Definition: node.h:580
u16 flags
Copy of main node flags.
Definition: node.h:532
u32 node_runtime_index
Definition: node.h:432
u32 n_total_events
Total number of events in buffer.
Definition: elog.h:134
u8 scalar_size
Definition: node.h:414
clib_longjmp_t main_loop_exit
Definition: main.h:101
clib_longjmp_t resume_longjmp
Definition: node.h:586
void clib_mem_trace(int enable)
Definition: mem_dlmalloc.c:404
static clib_error_t * elog_resize(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:809
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:145
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:326
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
#define TW(a)
clib_error_t * vlib_map_stat_segment_init(void)
Definition: stat_segment.c:212
static u32 vlib_timing_wheel_data_set_suspended_process(u32 i)
Definition: node.h:702
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:117
volatile void(* worker_thread_main_loop_callback)(struct vlib_main_t *)
Definition: main.h:196
void vlib_start_process(vlib_main_t *vm, uword process_index)
Definition: main.c:1556
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:82
void * timing_wheel
Definition: node.h:751
u8 * format_vnet_buffer_flags(u8 *s, va_list *args)
Definition: main.c:952
u32 n_packets_captured
Number of packets currently captured.
Definition: pcap.h:171
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:62
u32 trace_index
Specifies index into trace buffer if VLIB_PACKET_IS_TRACED flag is set.
Definition: buffer.h:151
clib_random_buffer_t random_buffer
Definition: main.h:173
static clib_error_t * elog_restart(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:789
#define VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE
Definition: node.h:329
vlib_buffer_free_list_index_t vlib_buffer_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
Definition: buffer.c:426
u8 *(* validate_frame)(struct vlib_main_t *vm, struct vlib_node_runtime_t *, struct vlib_frame_t *f)
Definition: node.h:388
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
Definition: defs.h:46
clib_error_t * main_loop_error
Definition: main.h:108
vlib_process_t * process
Definition: main.c:1418
elog_event_t * elog_peek_events(elog_main_t *em)
convert event ring events to events, and return them as a vector.
Definition: elog.c:536
static uword elog_buffer_capacity(elog_main_t *em)
Return number of events which can fit in the event buffer.
Definition: elog.h:198
u64 cpu_time_last_node_dispatch
Definition: main.h:71
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
#define VLIB_FRAME_FREE_AFTER_DISPATCH
Definition: node.h:455
clib_error_t * vlib_thread_init(vlib_main_t *vm)
Definition: threads.c:237
u32 vectors_since_last_overflow
Definition: node.h:461
u32 max_clock_n
Number of vectors in the recorded max_clock.
Definition: node.h:505
#define VLIB_PROCESS_RETURN_LONGJMP_SUSPEND
Definition: node.h:583
vlib_buffer_free_list_index_t free_list_index
Definition: buffer.h:160