This commit takes advantage of the atomic operation with the VLAN VM
workaround object reference count to make sure the object to be thread
safe and not to be created or destroyed in parallel.
Signed-off-by: Suanming Mou <suanmingm@nvidia.com>
---
drivers/net/mlx5/linux/mlx5_vlan_os.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
@@ -45,10 +45,11 @@
return;
vlan->created = 0;
MLX5_ASSERT(vlan_dev[vlan->tag].refcnt);
- if (--vlan_dev[vlan->tag].refcnt == 0 &&
- vlan_dev[vlan->tag].ifindex) {
+ if (!__atomic_sub_fetch(&vlan_dev[vlan->tag].refcnt,
+ 1, __ATOMIC_RELAXED)) {
mlx5_nl_vlan_vmwa_delete(vmwa, vlan_dev[vlan->tag].ifindex);
- vlan_dev[vlan->tag].ifindex = 0;
+ __atomic_store_n(&vlan_dev[vlan->tag].ifindex,
+ 0, __ATOMIC_RELAXED);
}
}
@@ -72,16 +73,21 @@
MLX5_ASSERT(priv->vmwa_context);
if (vlan->created || !vmwa)
return;
- if (vlan_dev[vlan->tag].refcnt == 0) {
- MLX5_ASSERT(!vlan_dev[vlan->tag].ifindex);
+ if (__atomic_add_fetch
+ (&vlan_dev[vlan->tag].refcnt, 1, __ATOMIC_RELAXED) == 1) {
+ /* Make sure ifindex is destroyed. */
+ rte_wait_until_equal_32(&vlan_dev[vlan->tag].ifindex,
+ 0, __ATOMIC_RELAXED);
vlan_dev[vlan->tag].ifindex =
mlx5_nl_vlan_vmwa_create(vmwa, vmwa->vf_ifindex,
vlan->tag);
+ if (!vlan_dev[vlan->tag].ifindex) {
+ __atomic_store_n(&vlan_dev[vlan->tag].refcnt,
+ 0, __ATOMIC_RELAXED);
+ return;
+ }
}
- if (vlan_dev[vlan->tag].ifindex) {
- vlan_dev[vlan->tag].refcnt++;
- vlan->created = 1;
- }
+ vlan->created = 1;
}
/*