summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2021-03-19 13:12:41 -0700
committerDamjan Marion <dmarion@me.com>2021-03-23 19:58:06 +0000
commit982e44fcc482cc9bc08e46c2a36ab66b0861bacb (patch)
tree7f1ad87cd446a6a5db831c947e007d889b6ce1ba
parent3853b26c5d8db27df6e2f00539bf021e565614ac (diff)
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
-rw-r--r--src/vlib/main.c10
-rw-r--r--src/vlib/node.h1
-rw-r--r--src/vlib/node_funcs.h21
-rw-r--r--src/vnet/interface/runtime.c13
4 files changed, 37 insertions, 8 deletions
diff --git a/src/vlib/main.c b/src/vlib/main.c
index 41f74b9bdf6..fc6fadb625e 100644
--- a/src/vlib/main.c
+++ b/src/vlib/main.c
@@ -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) =
diff --git a/src/vlib/node.h b/src/vlib/node.h
index 9a3bb8370af..aae5103908d 100644
--- a/src/vlib/node.h
+++ b/src/vlib/node.h
@@ -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;
diff --git a/src/vlib/node_funcs.h b/src/vlib/node_funcs.h
index d65fd2e061d..3c90a88efa0 100644
--- a/src/vlib/node_funcs.h
+++ b/src/vlib/node_funcs.h
@@ -225,6 +225,27 @@ vlib_node_get_state (vlib_main_t * vm, u32 node_index)
}
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)
{
vlib_node_main_t *nm = &vm->node_main;
diff --git a/src/vnet/interface/runtime.c b/src/vnet/interface/runtime.c
index 019d3ee28d0..c7631272d00 100644
--- a/src/vnet/interface/runtime.c
+++ b/src/vnet/interface/runtime.c
@@ -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);
}