virtio: fix txq locking
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 <bganne@cisco.com>
(cherry picked from commit b6b484d01a
)
This commit is contained in:

committed by
Andrew Yourtchenko

parent
ddb070e8b1
commit
47e0bd7303
@@ -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 last = vring->last_used_idx;
|
||||||
u16 n_left = vring->used->idx - last;
|
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,
|
vnet_gro_flow_table_schedule_node_on_dispatcher (vm,
|
||||||
txq_vring->flow_table);
|
txq_vring->flow_table);
|
||||||
|
clib_spinlock_unlock_if_init (&txq_vring->lockp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vring->used->flags & VRING_USED_F_NO_NOTIFY) == 0 &&
|
if ((vring->used->flags & VRING_USED_F_NO_NOTIFY) == 0 &&
|
||||||
|
@@ -494,6 +494,7 @@ virtio_pci_control_vring_init (vlib_main_t * vm, virtio_if_t * vif,
|
|||||||
clib_error_t *
|
clib_error_t *
|
||||||
virtio_pci_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 queue_num)
|
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;
|
clib_error_t *error = 0;
|
||||||
u16 queue_size = 0;
|
u16 queue_size = 0;
|
||||||
virtio_vring_t *vring;
|
virtio_vring_t *vring;
|
||||||
@@ -519,6 +520,7 @@ 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),
|
vec_validate_aligned (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num),
|
||||||
CLIB_CACHE_LINE_BYTES);
|
CLIB_CACHE_LINE_BYTES);
|
||||||
vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num));
|
vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS (queue_num));
|
||||||
|
if (vif->max_queue_pairs < vtm->n_vlib_mains)
|
||||||
clib_spinlock_init (&vring->lockp);
|
clib_spinlock_init (&vring->lockp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -91,6 +91,15 @@ clib_spinlock_lock (clib_spinlock_t * p)
|
|||||||
CLIB_LOCK_DBG (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
|
static_always_inline void
|
||||||
clib_spinlock_lock_if_init (clib_spinlock_t * p)
|
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);
|
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
|
static_always_inline void
|
||||||
clib_spinlock_unlock (clib_spinlock_t * p)
|
clib_spinlock_unlock (clib_spinlock_t * p)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user