Commit 7e4a6b57 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Jason Gunthorpe:
 "Several mlx5 bugs, crashers, and reports:

   - Limit stack usage

   - Fix mis-use of __xa_store/erase() without holding the lock to a
     locked version

   - Rate limit prints in the gid cache error cases

   - Fully initialize the event object before making it globally visible
     in an xarray

   - Fix deadlock inside the ODP code if the MMU notifier was called
     from a reclaim context

   - Include missed counters for some switchdev configurations and
     mulit-port MPV mode

   - Fix loopback packet support when in mulit-port MPV mode"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  RDMA/mlx5: Fix vport loopback for MPV device
  RDMA/mlx5: Fix CC counters query for MPV
  RDMA/mlx5: Fix HW counters query for non-representor devices
  IB/core: Annotate umem_mutex acquisition under fs_reclaim for lockdep
  IB/mlx5: Fix potential deadlock in MR deregistration
  RDMA/mlx5: Initialize obj_event->obj_sub_list before xa_insert
  RDMA/core: Rate limit GID cache warning messages
  RDMA/mlx5: Fix unsafe xarray access in implicit ODP handling
  RDMA/mlx5: reduce stack usage in mlx5_ib_ufile_hw_cleanup
parents 65c1736c a9a9e689
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -582,7 +582,7 @@ static int __ib_cache_gid_add(struct ib_device *ib_dev, u32 port,
out_unlock:
	mutex_unlock(&table->lock);
	if (ret)
		pr_warn("%s: unable to add gid %pI6 error=%d\n",
		pr_warn_ratelimited("%s: unable to add gid %pI6 error=%d\n",
				    __func__, gid->raw, ret);
	return ret;
}
+11 −0
Original line number Diff line number Diff line
@@ -76,6 +76,17 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
	end = ALIGN(end, page_size);
	if (unlikely(end < page_size))
		return -EOVERFLOW;
	/*
	 * The mmu notifier can be called within reclaim contexts and takes the
	 * umem_mutex. This is rare to trigger in testing, teach lockdep about
	 * it.
	 */
	if (IS_ENABLED(CONFIG_LOCKDEP)) {
		fs_reclaim_acquire(GFP_KERNEL);
		mutex_lock(&umem_odp->umem_mutex);
		mutex_unlock(&umem_odp->umem_mutex);
		fs_reclaim_release(GFP_KERNEL);
	}

	nr_entries = (end - start) >> PAGE_SHIFT;
	if (!(nr_entries * PAGE_SIZE / page_size))
+2 −2
Original line number Diff line number Diff line
@@ -398,7 +398,7 @@ static int do_get_hw_stats(struct ib_device *ibdev,
		return ret;

	/* We don't expose device counters over Vports */
	if (is_mdev_switchdev_mode(dev->mdev) && port_num != 0)
	if (is_mdev_switchdev_mode(dev->mdev) && dev->is_rep && port_num != 0)
		goto done;

	if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
@@ -418,7 +418,7 @@ static int do_get_hw_stats(struct ib_device *ibdev,
			 */
			goto done;
		}
		ret = mlx5_lag_query_cong_counters(dev->mdev,
		ret = mlx5_lag_query_cong_counters(mdev,
						   stats->value +
						   cnts->num_q_counters,
						   cnts->num_cong_counters,
+8 −2
Original line number Diff line number Diff line
@@ -1958,6 +1958,7 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table,
			/* Level1 is valid for future use, no need to free */
			return -ENOMEM;

		INIT_LIST_HEAD(&obj_event->obj_sub_list);
		err = xa_insert(&event->object_ids,
				key_level2,
				obj_event,
@@ -1966,7 +1967,6 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table,
			kfree(obj_event);
			return err;
		}
		INIT_LIST_HEAD(&obj_event->obj_sub_list);
	}

	return 0;
@@ -2669,7 +2669,7 @@ static void devx_wait_async_destroy(struct mlx5_async_cmd *cmd)

void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
{
	struct mlx5_async_cmd async_cmd[MAX_ASYNC_CMDS];
	struct mlx5_async_cmd *async_cmd;
	struct ib_ucontext *ucontext = ufile->ucontext;
	struct ib_device *device = ucontext->device;
	struct mlx5_ib_dev *dev = to_mdev(device);
@@ -2678,6 +2678,10 @@ void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
	int head = 0;
	int tail = 0;

	async_cmd = kcalloc(MAX_ASYNC_CMDS, sizeof(*async_cmd), GFP_KERNEL);
	if (!async_cmd)
		return;

	list_for_each_entry(uobject, &ufile->uobjects, list) {
		WARN_ON(uverbs_try_lock_object(uobject, UVERBS_LOOKUP_WRITE));

@@ -2713,6 +2717,8 @@ void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile)
		devx_wait_async_destroy(&async_cmd[head % MAX_ASYNC_CMDS]);
		head++;
	}

	kfree(async_cmd);
}

static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,
+33 −0
Original line number Diff line number Diff line
@@ -1791,6 +1791,33 @@ static void deallocate_uars(struct mlx5_ib_dev *dev,
					     context->devx_uid);
}

static int mlx5_ib_enable_lb_mp(struct mlx5_core_dev *master,
				struct mlx5_core_dev *slave)
{
	int err;

	err = mlx5_nic_vport_update_local_lb(master, true);
	if (err)
		return err;

	err = mlx5_nic_vport_update_local_lb(slave, true);
	if (err)
		goto out;

	return 0;

out:
	mlx5_nic_vport_update_local_lb(master, false);
	return err;
}

static void mlx5_ib_disable_lb_mp(struct mlx5_core_dev *master,
				  struct mlx5_core_dev *slave)
{
	mlx5_nic_vport_update_local_lb(slave, false);
	mlx5_nic_vport_update_local_lb(master, false);
}

int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp)
{
	int err = 0;
@@ -3495,6 +3522,8 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,

	lockdep_assert_held(&mlx5_ib_multiport_mutex);

	mlx5_ib_disable_lb_mp(ibdev->mdev, mpi->mdev);

	mlx5_core_mp_event_replay(ibdev->mdev,
				  MLX5_DRIVER_EVENT_AFFILIATION_REMOVED,
				  NULL);
@@ -3590,6 +3619,10 @@ static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
				  MLX5_DRIVER_EVENT_AFFILIATION_DONE,
				  &key);

	err = mlx5_ib_enable_lb_mp(ibdev->mdev, mpi->mdev);
	if (err)
		goto unbind;

	return true;

unbind:
Loading