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
/* n_vectors */ n,
/* n_clocks */ t - last_time_stamp);
/* 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) =
{
/* *INDENT-OFF* */
ELOG_TYPE_DECLARE (e) =
#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_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;
/* State for input nodes. */
u8 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)
{
always_inline void
vlib_node_set_interrupt_pending (vlib_main_t *vm, u32 node_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);
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;
int something_changed = 0;
clib_bitmap_t *pending_int = 0;
int last_int = -1;
vec_validate (d, n_threads - 1);
vec_validate_init_empty (per_thread_node_state, n_threads - 1,
VLIB_NODE_STATE_DISABLED);
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)
/* find out desired node state on each thread */
pool_foreach (rxq, im->hw_if_rx_queues)
continue;
if (rxq->mode == VNET_HW_IF_RX_MODE_POLLING)
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;
if (per_thread_node_state[ti] == VLIB_NODE_STATE_POLLING)
continue;
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_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 */
}
/* construct per-thread polling vectors */
}
vlib_node_set_state (vm, node_index, per_thread_node_state[i]);
}
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);
if (last_int >= 0)
clib_interrupt_resize (&rt->rxq_interrupts, last_int + 1);
vec_free (d);
vec_free (per_thread_node_state);
vec_free (d);
vec_free (per_thread_node_state);
+ vec_free (per_thread_node_adaptive);