浏览代码

IB/mlx4: Fix incorrectly releasing steerable UD QPs when have only ETH ports

Allocating steerable UD QPs depends on having at least one IB port,
while releasing those QPs does not.

As a result, when there are only ETH ports, the IB (RoCE) driver
requests releasing a qp range whose base qp is zero, with
qp count zero.

When SR-IOV is enabled, and the VF driver is running on a VM over
a hypervisor which treats such qp release calls as errors
(rather than NOPs), we see lines in the VM message log like:

 mlx4_core 0002:00:02.0: Failed to release qp range base:0 cnt:0

Fix this by adding a check for a zero count in mlx4_release_qp_range()
(which thus treats releasing 0 qps as a nop), and eliminating the
check for device managed flow steering when releasing steerable UD QPs.
(Freeing ib_uc_qpns_bitmap unconditionally is also OK, since it
remains NULL when steerable UD QPs are not allocated).

Cc: <stable@vger.kernel.org>
Fixes: 4196670be786 ("IB/mlx4: Don't allocate range of steerable UD QPs for Ethernet-only device")
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Jack Morgenstein 7 年之前
父节点
当前提交
852f692759
共有 2 个文件被更改,包括 8 次插入8 次删除
  1. 5 8
      drivers/infiniband/hw/mlx4/main.c
  2. 3 0
      drivers/net/ethernet/mellanox/mlx4/qp.c

+ 5 - 8
drivers/infiniband/hw/mlx4/main.c

@@ -3001,9 +3001,8 @@ err_steer_free_bitmap:
 	kfree(ibdev->ib_uc_qpns_bitmap);
 	kfree(ibdev->ib_uc_qpns_bitmap);
 
 
 err_steer_qp_release:
 err_steer_qp_release:
-	if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED)
-		mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
-				      ibdev->steer_qpn_count);
+	mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
+			      ibdev->steer_qpn_count);
 err_counter:
 err_counter:
 	for (i = 0; i < ibdev->num_ports; ++i)
 	for (i = 0; i < ibdev->num_ports; ++i)
 		mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]);
 		mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]);
@@ -3108,11 +3107,9 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
 		ibdev->iboe.nb.notifier_call = NULL;
 		ibdev->iboe.nb.notifier_call = NULL;
 	}
 	}
 
 
-	if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) {
-		mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
-				      ibdev->steer_qpn_count);
-		kfree(ibdev->ib_uc_qpns_bitmap);
-	}
+	mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
+			      ibdev->steer_qpn_count);
+	kfree(ibdev->ib_uc_qpns_bitmap);
 
 
 	iounmap(ibdev->uar_map);
 	iounmap(ibdev->uar_map);
 	for (p = 0; p < ibdev->num_ports; ++p)
 	for (p = 0; p < ibdev->num_ports; ++p)

+ 3 - 0
drivers/net/ethernet/mellanox/mlx4/qp.c

@@ -287,6 +287,9 @@ void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 	u64 in_param = 0;
 	u64 in_param = 0;
 	int err;
 	int err;
 
 
+	if (!cnt)
+		return;
+
 	if (mlx4_is_mfunc(dev)) {
 	if (mlx4_is_mfunc(dev)) {
 		set_param_l(&in_param, base_qpn);
 		set_param_l(&in_param, base_qpn);
 		set_param_h(&in_param, cnt);
 		set_param_h(&in_param, cnt);