vlib: add node adaptive mode flag

Don't switch nodes from interrupt to polling state unless adaptive mode
flag set. For starters, flag set only on interface input nodes
with no polling rx queue and at least one in adaptive mode.

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ica1c75f605ead82b7cf74c45c6a774461008f054
This commit is contained in:
Florin Coras
2021-03-19 13:12:41 -07:00
committed by Damjan Marion
parent 3853b26c5d
commit 982e44fcc4
4 changed files with 37 additions and 8 deletions
+3 -7
View File
@@ -1056,13 +1056,9 @@ dispatch_node (vlib_main_t * vm,
/* n_vectors */ n,
/* n_clocks */ t - last_time_stamp);
/* When in interrupt mode and vector rate crosses threshold switch to
polling mode. */
if (PREDICT_FALSE ((dispatch_state == VLIB_NODE_STATE_INTERRUPT)
|| (dispatch_state == VLIB_NODE_STATE_POLLING
&& (node->flags
&
VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE))))
/* When in adaptive mode and vector rate crosses threshold switch to
polling mode and vice versa. */
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_ADAPTIVE_MODE))
{
/* *INDENT-OFF* */
ELOG_TYPE_DECLARE (e) =
+1
View File
@@ -294,6 +294,7 @@ typedef struct vlib_node_t
#define VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE (1 << 6)
#define VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE (1 << 7)
#define VLIB_NODE_FLAG_TRACE_SUPPORTED (1 << 8)
#define VLIB_NODE_FLAG_ADAPTIVE_MODE (1 << 9)
/* State for input nodes. */
u8 state;
+21
View File
@@ -224,6 +224,27 @@ vlib_node_get_state (vlib_main_t * vm, u32 node_index)
return n->state;
}
always_inline void
vlib_node_set_flag (vlib_main_t *vm, u32 node_index, u16 flag, u8 enable)
{
vlib_node_runtime_t *r;
vlib_node_t *n;
n = vlib_get_node (vm, node_index);
r = vlib_node_get_runtime (vm, node_index);
if (enable)
{
n->flags |= flag;
r->flags |= flag;
}
else
{
n->flags &= ~flag;
r->flags &= ~flag;
}
}
always_inline void
vlib_node_set_interrupt_pending (vlib_main_t *vm, u32 node_index)
{
+12 -1
View File
@@ -64,6 +64,7 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
vnet_hw_if_rxq_poll_vector_t *pv, **d = 0;
vlib_node_state_t *per_thread_node_state = 0;
u32 n_threads = vec_len (vlib_mains);
u16 *per_thread_node_adaptive = 0;
int something_changed = 0;
clib_bitmap_t *pending_int = 0;
int last_int = -1;
@@ -74,6 +75,7 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
vec_validate (d, n_threads - 1);
vec_validate_init_empty (per_thread_node_state, n_threads - 1,
VLIB_NODE_STATE_DISABLED);
vec_validate_init_empty (per_thread_node_adaptive, n_threads - 1, 0);
/* find out desired node state on each thread */
pool_foreach (rxq, im->hw_if_rx_queues)
@@ -89,7 +91,10 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
continue;
if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
per_thread_node_state[ti] = VLIB_NODE_STATE_POLLING;
{
per_thread_node_state[ti] = VLIB_NODE_STATE_POLLING;
per_thread_node_adaptive[ti] = 0;
}
if (per_thread_node_state[ti] == VLIB_NODE_STATE_POLLING)
continue;
@@ -97,6 +102,9 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
if (rxq->mode == VNET_HW_IF_RX_MODE_INTERRUPT ||
rxq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE)
per_thread_node_state[ti] = VLIB_NODE_STATE_INTERRUPT;
if (rxq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE)
per_thread_node_adaptive[ti] = 1;
}
/* construct per-thread polling vectors */
@@ -190,6 +198,8 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
}
vlib_node_set_state (vm, node_index, per_thread_node_state[i]);
vlib_node_set_flag (vm, node_index, VLIB_NODE_FLAG_ADAPTIVE_MODE,
per_thread_node_adaptive[i]);
if (last_int >= 0)
clib_interrupt_resize (&rt->rxq_interrupts, last_int + 1);
@@ -219,4 +229,5 @@ vnet_hw_if_update_runtime_data (vnet_main_t *vnm, u32 hw_if_index)
vec_free (d);
vec_free (per_thread_node_state);
vec_free (per_thread_node_adaptive);
}