diff options
author | Steven Luong <sluong@cisco.com> | 2021-04-21 09:54:34 -0700 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2021-08-18 12:25:34 +0000 |
commit | 38071b1331b44746679997f6e66081c4936d087c (patch) | |
tree | 2c25d05051510603a21528a7d7fcd15754a0ae09 /src/vnet/devices/virtio/vhost_user_output.c | |
parent | 91144fbf54764feb005a33419d0129febd2365d4 (diff) |
vhost: interrupt mode support with mq
vhost interrupt mode support with mq does not work when coalesce frame
is not configured to 0.
When packed-ring is configured, we were also setting the wrong flag
for want-interrupt.
No need to trigger an interrupt to RX infra if there is at least one
queue in the same thread that is doing polling.
Type: fix
Signed-off-by: Steven Luong <sluong@cisco.com>
Change-Id: I8e64250f2aa6bf611a777a53e4d2c1076d83305f
Diffstat (limited to 'src/vnet/devices/virtio/vhost_user_output.c')
-rw-r--r-- | src/vnet/devices/virtio/vhost_user_output.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/vnet/devices/virtio/vhost_user_output.c b/src/vnet/devices/virtio/vhost_user_output.c index 40faefadb42..d3e38bfa04e 100644 --- a/src/vnet/devices/virtio/vhost_user_output.c +++ b/src/vnet/devices/virtio/vhost_user_output.c @@ -1046,7 +1046,24 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, vhost_user_intf_t *vui = pool_elt_at_index (vum->vhost_user_interfaces, hif->dev_instance); vhost_user_vring_t *txvq = &vui->vrings[VHOST_VRING_IDX_TX (qid)]; + vhost_cpu_t *cpu; + if (mode == txvq->mode) + return 0; + + if ((mode != VNET_HW_IF_RX_MODE_POLLING) && + (mode != VNET_HW_IF_RX_MODE_ADAPTIVE) && + (mode != VNET_HW_IF_RX_MODE_INTERRUPT)) + { + vu_log_err (vui, "unhandled mode %d changed for if %d queue %d", mode, + hw_if_index, qid); + return clib_error_return (0, "unsupported"); + } + + if (txvq->thread_index == ~0) + return clib_error_return (0, "Queue initialization is not finished yet"); + + cpu = vec_elt_at_index (vum->cpus, txvq->thread_index); if ((mode == VNET_HW_IF_RX_MODE_INTERRUPT) || (mode == VNET_HW_IF_RX_MODE_ADAPTIVE)) { @@ -1057,11 +1074,14 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, } if (txvq->mode == VNET_HW_IF_RX_MODE_POLLING) { + ASSERT (cpu->polling_q_count != 0); + if (cpu->polling_q_count) + cpu->polling_q_count--; vum->ifq_count++; // Start the timer if this is the first encounter on interrupt // interface/queue if ((vum->ifq_count == 1) && - (vum->coalesce_time > 0.0) && (vum->coalesce_frames > 0)) + ((vum->coalesce_time > 0.0) || (vum->coalesce_frames > 0))) vlib_process_signal_event (vm, vhost_user_send_interrupt_node.index, VHOST_USER_EVENT_START_TIMER, 0); @@ -1072,10 +1092,10 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, if (((txvq->mode == VNET_HW_IF_RX_MODE_INTERRUPT) || (txvq->mode == VNET_HW_IF_RX_MODE_ADAPTIVE)) && vum->ifq_count) { + cpu->polling_q_count++; vum->ifq_count--; // Stop the timer if there is no more interrupt interface/queue - if ((vum->ifq_count == 0) && - (vum->coalesce_time > 0.0) && (vum->coalesce_frames > 0)) + if (vum->ifq_count == 0) vlib_process_signal_event (vm, vhost_user_send_interrupt_node.index, VHOST_USER_EVENT_STOP_TIMER, 0); @@ -1083,17 +1103,7 @@ vhost_user_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, } txvq->mode = mode; - if (mode == VNET_HW_IF_RX_MODE_POLLING) - txvq->used->flags = VRING_USED_F_NO_NOTIFY; - else if ((mode == VNET_HW_IF_RX_MODE_ADAPTIVE) || - (mode == VNET_HW_IF_RX_MODE_INTERRUPT)) - txvq->used->flags = 0; - else - { - vu_log_err (vui, "unhandled mode %d changed for if %d queue %d", mode, - hw_if_index, qid); - return clib_error_return (0, "unsupported"); - } + vhost_user_set_operation_mode (vui, txvq); return 0; } |