From b6b484d01adb8ab2ef5a50d5a3d6f3f097df2e0c Mon Sep 17 00:00:00 2001 From: Benoît Ganne Date: Tue, 15 Sep 2020 10:58:07 +0200 Subject: virtio: fix txq locking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize txq lock only if some txq are shared and check if another worker is already operating on the txq before processing gro timeouts in input node. Type: fix Change-Id: I89dab6c0e6eb6a7aa621fa1548b0a2c76e6c7581 Signed-off-by: Benoît Ganne --- src/vnet/devices/virtio/node.c | 4 +++- src/vnet/devices/virtio/pci.c | 4 +++- src/vppinfra/lock.h | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index 7fabe36401c..1c9cfd0cc03 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -279,10 +279,12 @@ virtio_device_input_gso_inline (vlib_main_t * vm, vlib_node_runtime_t * node, u16 last = vring->last_used_idx; u16 n_left = vring->used->idx - last; - if (vif->packet_coalesce) + if (vif->packet_coalesce + && clib_spinlock_trylock_if_init (&txq_vring->lockp)) { vnet_gro_flow_table_schedule_node_on_dispatcher (vm, txq_vring->flow_table); + clib_spinlock_unlock_if_init (&txq_vring->lockp); } if ((vring->used->flags & VRING_USED_F_NO_NOTIFY) == 0 && diff --git a/src/vnet/devices/virtio/pci.c b/src/vnet/devices/virtio/pci.c index 5ba9f36de81..df8e2bdaf68 100644 --- a/src/vnet/devices/virtio/pci.c +++ b/src/vnet/devices/virtio/pci.c @@ -494,6 +494,7 @@ virtio_pci_control_vring_init (vlib_main_t * vm, virtio_if_t * vif, clib_error_t * virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num) { + vlib_thread_main_t *vtm = vlib_get_thread_main (); clib_error_t *error = 0; u16 queue_size = 0; virtio_vring_t *vring; @@ -519,7 +520,8 @@ virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num) vec_validate_aligned (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num), CLIB_CACHE_LINE_BYTES); vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num)); - clib_spinlock_init (&vring->lockp); + if (vif->max_queue_pairs < vtm->n_vlib_mains) + clib_spinlock_init (&vring->lockp); } else { diff --git a/src/vppinfra/lock.h b/src/vppinfra/lock.h index 3cfe11cba17..470890b6ec7 100644 --- a/src/vppinfra/lock.h +++ b/src/vppinfra/lock.h @@ -91,6 +91,15 @@ clib_spinlock_lock (clib_spinlock_t * p) CLIB_LOCK_DBG (p); } +static_always_inline int +clib_spinlock_trylock (clib_spinlock_t * p) +{ + if (PREDICT_FALSE (CLIB_SPINLOCK_IS_LOCKED (p))) + return 0; + clib_spinlock_lock (p); + return 1; +} + static_always_inline void clib_spinlock_lock_if_init (clib_spinlock_t * p) { @@ -98,6 +107,14 @@ clib_spinlock_lock_if_init (clib_spinlock_t * p) clib_spinlock_lock (p); } +static_always_inline int +clib_spinlock_trylock_if_init (clib_spinlock_t * p) +{ + if (PREDICT_FALSE (*p != 0)) + return clib_spinlock_trylock (p); + return 1; +} + static_always_inline void clib_spinlock_unlock (clib_spinlock_t * p) { -- cgit 1.2.3-korg