net/i40e: fix virtual channel conflict
i40evf_execute_vf_cmd() uses _atomic_set_cmd() to execute virtual
channel commands safely in multi-process mode and multi-thread mode.
However, it returns error when one process or thread is pending. Add
rte_spinlock_trylock() to handle this issue in concurrent scenarios.
Fixes: 4861cde461
("i40e: new poll mode driver")
Cc: stable@dpdk.org
Signed-off-by: Yuying Zhang <yuying.zhang@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
This commit is contained in:
parent
9cf9c02bf6
commit
99e47bbe4c
@ -1209,6 +1209,7 @@ struct i40e_vf {
|
||||
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 */
|
||||
uint16_t promisc_flags; /* Promiscuous setting */
|
||||
|
@ -314,7 +314,7 @@ _atomic_set_cmd(struct i40e_vf *vf, enum virtchnl_ops ops)
|
||||
#define ASQ_DELAY_MS 10
|
||||
|
||||
static int
|
||||
i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
|
||||
_i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
|
||||
{
|
||||
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
|
||||
@ -405,6 +405,19 @@ i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
|
||||
return err | vf->cmd_retval;
|
||||
}
|
||||
|
||||
static int
|
||||
i40evf_execute_vf_cmd(struct rte_eth_dev *dev, struct vf_cmd_info *args)
|
||||
{
|
||||
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
|
||||
int err;
|
||||
|
||||
while (!rte_spinlock_trylock(&vf->cmd_send_lock))
|
||||
rte_delay_us_sleep(50);
|
||||
err = _i40evf_execute_vf_cmd(dev, args);
|
||||
rte_spinlock_unlock(&vf->cmd_send_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check API version with sync wait until version read or fail from admin queue
|
||||
*/
|
||||
@ -1246,6 +1259,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);
|
||||
|
Loading…
Reference in New Issue
Block a user