From 16052480c377127f9cb7facbab53f46e595b27cf Mon Sep 17 00:00:00 2001 From: Mohammed Hawari Date: Thu, 2 Jun 2022 13:55:36 +0200 Subject: [PATCH] vlib: vlib_validate_buffer_enqueue_with_aux_x1 This change implement a flavour of vlib_validate_buffer_enqueue_x1 with aux data support Change-Id: I2ecf7af49cf15ecd23b12d8acd57fe90546c1af7 Type: improvement Signed-off-by: Mohammed Hawari --- src/vlib/buffer_node.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/vlib/node_funcs.h | 24 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/vlib/buffer_node.h b/src/vlib/buffer_node.h index 5bc547a4570..c0268b21562 100644 --- a/src/vlib/buffer_node.h +++ b/src/vlib/buffer_node.h @@ -236,6 +236,53 @@ do { \ } \ } while (0) +/** \brief Finish enqueueing one buffer forward in the graph, along with its + aux_data if possible. Standard single loop boilerplate element. This is a + MACRO, with MULTIPLE SIDE EFFECTS. In the ideal case, next_index == + next0, which means that the speculative enqueue at the top of the + single loop has correctly dealt with the packet in hand. In that case, the + macro does nothing at all. This function MAY return to_next_aux = NULL if + next_index does not support aux data + + @param vm vlib_main_t pointer, varies by thread + @param node current node vlib_node_runtime_t pointer + @param next_index speculated next index used for both packets + @param to_next speculated vector pointer used for both packets + @param to_next_aux speculated aux_data pointer used for both packets + @param n_left_to_next number of slots left in speculated vector + @param bi0 first buffer index + @param aux0 first aux_data + @param next0 actual next index to be used for the first packet + + @return @c next_index -- speculative next index to be used for future packets + @return @c to_next -- speculative frame to be used for future packets + @return @c n_left_to_next -- number of slots left in speculative frame +*/ +#define vlib_validate_buffer_enqueue_with_aux_x1( \ + vm, node, next_index, to_next, to_next_aux, n_left_to_next, bi0, aux0, \ + next0) \ + do \ + { \ + ASSERT (bi0 != 0); \ + if (PREDICT_FALSE (next0 != next_index)) \ + { \ + vlib_put_next_frame (vm, node, next_index, n_left_to_next + 1); \ + next_index = next0; \ + vlib_get_next_frame_with_aux_safe (vm, node, next_index, to_next, \ + to_next_aux, n_left_to_next); \ + \ + to_next[0] = bi0; \ + to_next += 1; \ + if (to_next_aux) \ + { \ + to_next_aux[0] = aux0; \ + to_next_aux += 1; \ + } \ + n_left_to_next -= 1; \ + } \ + } \ + while (0) + always_inline uword generic_buffer_node_inline (vlib_main_t * vm, vlib_node_runtime_t * node, diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h index 62a1fecabd6..0f9f30a13d0 100644 --- a/src/vlib/node_funcs.h +++ b/src/vlib/node_funcs.h @@ -498,6 +498,16 @@ vlib_put_next_frame (vlib_main_t * vm, (v); \ }) +#define vlib_set_next_frame_with_aux_safe(vm, node, next_index, v, aux) \ + ({ \ + uword _n_left; \ + vlib_get_next_frame_with_aux_safe ((vm), (node), (next_index), (v), \ + (aux), _n_left); \ + ASSERT (_n_left > 0); \ + vlib_put_next_frame ((vm), (node), (next_index), _n_left - 1); \ + (v); \ + }) + always_inline void vlib_set_next_frame_buffer (vlib_main_t * vm, vlib_node_runtime_t * node, @@ -508,6 +518,20 @@ vlib_set_next_frame_buffer (vlib_main_t * vm, p[0] = buffer_index; } +always_inline void +vlib_set_next_frame_buffer_with_aux_safe (vlib_main_t *vm, + vlib_node_runtime_t *node, + u32 next_index, u32 buffer_index, + u32 aux) +{ + u32 *p; + u32 *a; + p = vlib_set_next_frame_with_aux_safe (vm, node, next_index, p, a); + p[0] = buffer_index; + if (a) + a[0] = aux; +} + vlib_frame_t *vlib_get_frame_to_node (vlib_main_t * vm, u32 to_node_index); void vlib_put_frame_to_node (vlib_main_t * vm, u32 to_node_index, vlib_frame_t * f); -- 2.16.6