aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4/main.c
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2014-09-11 14:11:20 +0300
committerRoland Dreier <roland@purestorage.com>2014-09-22 09:46:53 -0700
commit25476b0209b2e48dfb689e1b4cf7278875082b1f (patch)
tree4af5f11721425482801bf298bd96f85d9309e298 /drivers/infiniband/hw/mlx4/main.c
parentIB/mlx4: Do not allow APM under RoCE (diff)
downloadlinux-dev-25476b0209b2e48dfb689e1b4cf7278875082b1f.tar.xz
linux-dev-25476b0209b2e48dfb689e1b4cf7278875082b1f.zip
IB/mlx4: Fix VF mac handling in RoCE
We had several problems here. First, a race condition on QP1 mac handling between mlx4_ib_update_qps and mlx4_ib_modify_qp, which is fixed by taking the qp mutex in mlx4_ib_update_qps. Also, qp->pri.smac_port was not updated in mlx4_ib_update_qps. Last, in __mlx4_ib_modify_qp we did not properly handle the case where the mac is zero, but port is non-zero. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/mlx4/main.c')
-rw-r--r--drivers/infiniband/hw/mlx4/main.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index d57563b9d1fb..c7586a1cec30 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1667,9 +1667,11 @@ static void mlx4_ib_update_qps(struct mlx4_ib_dev *ibdev,
qp = ibdev->qp1_proxy[port - 1];
if (qp) {
int new_smac_index;
- u64 old_smac = qp->pri.smac;
+ u64 old_smac;
struct mlx4_update_qp_params update_params;
+ mutex_lock(&qp->mutex);
+ old_smac = qp->pri.smac;
if (new_smac == old_smac)
goto unlock;
@@ -1684,17 +1686,20 @@ static void mlx4_ib_update_qps(struct mlx4_ib_dev *ibdev,
release_mac = new_smac;
goto unlock;
}
-
+ /* if old port was zero, no mac was yet registered for this QP */
+ if (qp->pri.smac_port)
+ release_mac = old_smac;
qp->pri.smac = new_smac;
+ qp->pri.smac_port = port;
qp->pri.smac_index = new_smac_index;
-
- release_mac = old_smac;
}
unlock:
- mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]);
if (release_mac != MLX4_IB_INVALID_MAC)
mlx4_unregister_mac(ibdev->dev, port, release_mac);
+ if (qp)
+ mutex_unlock(&qp->mutex);
+ mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]);
}
static void mlx4_ib_get_dev_addr(struct net_device *dev,