diff options
author | Mohsin Kazmi <sykazmi@cisco.com> | 2020-12-02 16:39:42 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2020-12-04 22:54:34 +0000 |
commit | 24841867d17f0b57abcce6353e23c9a668e70517 (patch) | |
tree | 0ba662cba4a2e509cb3342a0a2ff06c7d0d2ecbc /src/vnet/devices/virtio/device.c | |
parent | 8ed06c0dd349be7bb8f61a3189afb8c79ef565b4 (diff) |
virtio: fix the interrupt handling for packed queues
Type: fix
Change-Id: I2cc1cfd519e5b3502c59cf72e95e454f9122b8e5
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 | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index 3bb2ac72b99..5e38d631c77 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -996,8 +996,10 @@ VNET_DEVICE_CLASS_TX_FN (virtio_device_class) (vlib_main_t * vm, clib_spinlock_lock_if_init (&vring->lockp); - if ((vring->used->flags & VRING_USED_F_NO_NOTIFY) == 0 && - (vring->last_kick_avail_idx != vring->avail->idx)) + if (packed && (vring->device_event->flags != VRING_EVENT_F_DISABLE)) + virtio_kick (vm, vring, vif); + else if ((vring->used->flags & VRING_USED_F_NO_NOTIFY) == 0 && + (vring->last_kick_avail_idx != vring->avail->idx)) virtio_kick (vm, vring, vif); if (vif->packet_coalesce) @@ -1078,6 +1080,24 @@ virtio_clear_hw_interface_counters (u32 instance) /* Nothing for now */ } +static_always_inline void +virtio_set_rx_interrupt (virtio_if_t * vif, virtio_vring_t * vring) +{ + if (vif->is_packed) + vring->driver_event->flags &= ~VRING_EVENT_F_DISABLE; + else + vring->avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; +} + +static_always_inline void +virtio_set_rx_polling (virtio_if_t * vif, virtio_vring_t * vring) +{ + if (vif->is_packed) + vring->driver_event->flags |= VRING_EVENT_F_DISABLE; + else + vring->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; +} + 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) @@ -1090,7 +1110,7 @@ virtio_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, if (vif->type == VIRTIO_IF_TYPE_PCI && !(vif->support_int_mode)) { - rx_vring->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; + virtio_set_rx_polling (vif, rx_vring); return clib_error_return (0, "interrupt mode is not supported"); } @@ -1105,7 +1125,7 @@ virtio_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, virtio_send_interrupt_node.index, VIRTIO_EVENT_STOP_TIMER, 0); } - rx_vring->avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; + virtio_set_rx_polling (vif, rx_vring); } else { @@ -1117,7 +1137,7 @@ virtio_interface_rx_mode_change (vnet_main_t * vnm, u32 hw_if_index, u32 qid, virtio_send_interrupt_node.index, VIRTIO_EVENT_START_TIMER, 0); } - rx_vring->avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; + virtio_set_rx_interrupt (vif, rx_vring); } rx_vring->mode = mode; |