i40evf_execute_vf_cmd() uses _atomic_set_cmd() to execute virtual channel commands safely in multi-process mode. However, it returns -1 when one process is pending. Add a spinlock to wait for the virtual channel will handle this issue in concurrent scenarios.
Fixes: 4861cde46116 ("i40e: new poll mode driver") Cc: sta...@dpdk.org Signed-off-by: Yuying Zhang <yuying.zh...@intel.com> --- drivers/net/i40e/i40e_ethdev.h | 1 + drivers/net/i40e/i40e_ethdev_vf.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 19f821829..514c0988b 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -1199,6 +1199,7 @@ struct i40e_vf { uint16_t max_pkt_len; /* Maximum packet length */ bool promisc_unicast_enabled; bool promisc_multicast_enabled; + rte_spinlock_t cmd_send_lock; uint32_t version_major; /* Major version number */ uint32_t version_minor; /* Minor version number */ diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 69cab8e73..7fdc58649 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -326,8 +326,11 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args) enum i40evf_aq_result ret; int err, i = 0; - if (_atomic_set_cmd(vf, args->ops)) + rte_spinlock_lock(&vf->cmd_send_lock); + if (_atomic_set_cmd(vf, args->ops)) { + rte_spinlock_unlock(&vf->cmd_send_lock); return -1; + } info.msg = args->out_buffer; info.buf_len = args->out_size; @@ -339,6 +342,7 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args) if (err) { PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops); _clear_cmd(vf); + rte_spinlock_unlock(&vf->cmd_send_lock); return err; } @@ -406,6 +410,7 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args) break; } + rte_spinlock_unlock(&vf->cmd_send_lock); return err | vf->cmd_retval; } @@ -1249,6 +1254,7 @@ i40evf_init_vf(struct rte_eth_dev *dev) vf->adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); vf->dev_data = dev->data; + rte_spinlock_init(&vf->cmd_send_lock); err = i40e_set_mac_type(hw); if (err) { PMD_INIT_LOG(ERR, "set_mac_type failed: %d", err); -- 2.25.1