diff options
author | 2020-10-12 13:01:24 +0200 | |
---|---|---|
committer | 2020-10-21 11:20:01 +0000 | |
commit | a5203b53d4fa227560333b890d3e79fc220d1bfd (patch) | |
tree | 04ac639280910abbf8a12fd973b207f177b67a12 /src/vnet/devices/virtio/device.c | |
parent | 302b25a00ed913767798d58148ef4d36092ee490 (diff) |
virtio: run process to send interrupts to input nodes
Type: improvement
virtio interfaces support packet coalescing and buffering which
depends on timer expiry to flush the stored packets periodically.
virtio input node checks timer expiry and schedules tx queue
accordingly. In poll mode, timer expiry is handled naturally,
as input node runs periodically. In interrupt mode, virtio
input node depends on the interrupts send from backend.
Stored packets could starve, if there would not be interrupts
to input node.
This patch implements a process node which periodically
sends interrupt to virtio input node given coalescing or buffering
feature is enabled on an interface.
Change-Id: Ic38f749f74b001073d4d0579dca149d0a4cea039
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Diffstat (limited to 'src/vnet/devices/virtio/device.c')
-rw-r--r-- | src/vnet/devices/virtio/device.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index 084be962ed7..521d76a8da4 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -761,11 +761,11 @@ static clib_error_t * virtio_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, vnet_hw_if_rx_mode mode) { + vlib_main_t *vm = vnm->vlib_main; virtio_main_t *mm = &virtio_main; vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index); virtio_if_t *vif = pool_elt_at_index (mm->interfaces, hw->dev_instance); virtio_vring_t *rx_vring = vec_elt_at_index (vif->rxq_vrings, qid); - virtio_vring_t *tx_vring = 0; if (vif->type == VIRTIO_IF_TYPE_PCI && !(vif->support_int_mode)) { @@ -775,32 +775,32 @@ virtio_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, if (mode == VNET_HW_IF_RX_MODE_POLLING) { - vec_foreach (tx_vring, vif->txq_vrings) - { - /* only enable packet coalesce in poll mode */ - gro_flow_table_set_is_enable (tx_vring->flow_table, 1); - /* only enable packet buffering in poll mode */ - virtio_vring_buffering_set_is_enable (tx_vring->buffering, 1); - } + if (vif->packet_coalesce || vif->packet_buffering) + { + if (mm->interrupt_queues_count > 0) + mm->interrupt_queues_count--; + if (mm->interrupt_queues_count == 0) + vlib_process_signal_event (vm, + virtio_send_interrupt_node.index, + VIRTIO_EVENT_STOP_TIMER, 0); + } rx_vring->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; } else { if (vif->packet_coalesce || vif->packet_buffering) { - virtio_log_warning (vif, - "interface %U is in interrupt mode, disabling packet coalescing or buffering", - format_vnet_sw_if_index_name, vnet_get_main (), - vif->sw_if_index); - vec_foreach (tx_vring, vif->txq_vrings) - { - gro_flow_table_set_is_enable (tx_vring->flow_table, 0); - virtio_vring_buffering_set_is_enable (tx_vring->buffering, 0); - } + mm->interrupt_queues_count++; + if (mm->interrupt_queues_count == 1) + vlib_process_signal_event (vm, + virtio_send_interrupt_node.index, + VIRTIO_EVENT_START_TIMER, 0); } rx_vring->avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; } + rx_vring->mode = mode; + return 0; } |