Commit 2f64e70c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Doug Ledford:

 - Various driver bug fixes in mlx5, mlx4, bnxt_re and qedr, ranging
   from bugs under load to bad error case handling

 - There in one largish patch fixing the locking in bnxt_re to avoid a
   machine hard lock situation

 - A few core bugs on error paths

 - A patch to reduce stack usage in the new CQ API

 - One mlx5 regression introduced in this merge window

 - There were new syzkaller scripts written for the RDMA subsystem and
   we are fixing issues found by the bot

 - One of the commits (aa0de36a “RDMA/mlx5: Fix integer overflow
   while resizing CQ”) is missing part of the commit log message and one
   of the SOB lines. The original patch was from Leon Romanovsky, and a
   cut-n-paste separator in the commit message confused patchworks which
   then put the end of message separator in the wrong place in the
   downloaded patch, and I didn’t notice in time. The patch made it into
   the official branch, and the only way to fix it in-place was to
   rebase. Given the pain that a rebase causes, and the fact that the
   patch has relevant tags for stable and syzkaller, a revert of the
   munged patch and a reapplication of the original patch with the log
   message intact was done.

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (25 commits)
  RDMA/mlx5: Fix integer overflow while resizing CQ
  Revert "RDMA/mlx5: Fix integer overflow while resizing CQ"
  RDMA/ucma: Check that user doesn't overflow QP state
  RDMA/mlx5: Fix integer overflow while resizing CQ
  RDMA/ucma: Limit possible option size
  IB/core: Fix possible crash to access NULL netdev
  RDMA/bnxt_re: Avoid Hard lockup during error CQE processing
  RDMA/core: Reduce poll batch for direct cq polling
  IB/mlx5: Fix an error code in __mlx5_ib_modify_qp()
  IB/mlx5: When not in dual port RoCE mode, use provided port as native
  IB/mlx4: Include GID type when deleting GIDs from HW table under RoCE
  IB/mlx4: Fix corruption of RoCEv2 IPv4 GIDs
  RDMA/qedr: Fix iWARP write and send with immediate
  RDMA/qedr: Fix kernel panic when running fio over NFSoRDMA
  RDMA/qedr: Fix iWARP connect with port mapper
  RDMA/qedr: Fix ipv6 destination address resolution
  IB/core : Add null pointer check in addr_resolve
  RDMA/bnxt_re: Fix the ib_reg failure cleanup
  RDMA/bnxt_re: Fix incorrect DB offset calculation
  RDMA/bnxt_re: Unconditionly fence non wire memory operations
  ...
parents b3337a6c 28e9091e
Loading
Loading
Loading
Loading
+5 −10
Original line number Diff line number Diff line
@@ -550,18 +550,13 @@ static int addr_resolve(struct sockaddr *src_in,
		dst_release(dst);
	}

	if (ndev->flags & IFF_LOOPBACK) {
	if (ndev) {
		if (ndev->flags & IFF_LOOPBACK)
			ret = rdma_translate_ip(dst_in, addr);
		/*
		 * Put the loopback device and get the translated
		 * device instead.
		 */
		dev_put(ndev);
		ndev = dev_get_by_index(addr->net, addr->bound_dev_if);
	} else {
		else
			addr->bound_dev_if = ndev->ifindex;
	}
		dev_put(ndev);
	}

	return ret;
}
+11 −10
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@

/* # of WCs to poll for with a single call to ib_poll_cq */
#define IB_POLL_BATCH			16
#define IB_POLL_BATCH_DIRECT		8

/* # of WCs to iterate over before yielding */
#define IB_POLL_BUDGET_IRQ		256
@@ -25,17 +26,17 @@
#define IB_POLL_FLAGS \
	(IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS)

static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *wcs,
			   int batch)
{
	int i, n, completed = 0;
	struct ib_wc *wcs = poll_wc ? : cq->wc;

	/*
	 * budget might be (-1) if the caller does not
	 * want to bound this call, thus we need unsigned
	 * minimum here.
	 */
	while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH,
	while ((n = ib_poll_cq(cq, min_t(u32, batch,
					 budget - completed), wcs)) > 0) {
		for (i = 0; i < n; i++) {
			struct ib_wc *wc = &wcs[i];
@@ -48,8 +49,7 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)

		completed += n;

		if (n != IB_POLL_BATCH ||
		    (budget != -1 && completed >= budget))
		if (n != batch || (budget != -1 && completed >= budget))
			break;
	}

@@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)
 */
int ib_process_cq_direct(struct ib_cq *cq, int budget)
{
	struct ib_wc wcs[IB_POLL_BATCH];
	struct ib_wc wcs[IB_POLL_BATCH_DIRECT];

	return __ib_process_cq(cq, budget, wcs);
	return __ib_process_cq(cq, budget, wcs, IB_POLL_BATCH_DIRECT);
}
EXPORT_SYMBOL(ib_process_cq_direct);

@@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget)
	struct ib_cq *cq = container_of(iop, struct ib_cq, iop);
	int completed;

	completed = __ib_process_cq(cq, budget, NULL);
	completed = __ib_process_cq(cq, budget, cq->wc, IB_POLL_BATCH);
	if (completed < budget) {
		irq_poll_complete(&cq->iop);
		if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
@@ -108,7 +108,8 @@ static void ib_cq_poll_work(struct work_struct *work)
	struct ib_cq *cq = container_of(work, struct ib_cq, work);
	int completed;

	completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL);
	completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, cq->wc,
				    IB_POLL_BATCH);
	if (completed >= IB_POLL_BUDGET_WORKQUEUE ||
	    ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)
		queue_work(ib_comp_wq, &cq->work);
+4 −2
Original line number Diff line number Diff line
@@ -536,14 +536,14 @@ int ib_register_device(struct ib_device *device,
	ret = device->query_device(device, &device->attrs, &uhw);
	if (ret) {
		pr_warn("Couldn't query the device attributes\n");
		goto cache_cleanup;
		goto cg_cleanup;
	}

	ret = ib_device_register_sysfs(device, port_callback);
	if (ret) {
		pr_warn("Couldn't register device %s with driver model\n",
			device->name);
		goto cache_cleanup;
		goto cg_cleanup;
	}

	device->reg_state = IB_DEV_REGISTERED;
@@ -559,6 +559,8 @@ int ib_register_device(struct ib_device *device,
	mutex_unlock(&device_mutex);
	return 0;

cg_cleanup:
	ib_device_unregister_rdmacg(device);
cache_cleanup:
	ib_cache_cleanup_one(device);
	ib_cache_release_one(device);
+3 −4
Original line number Diff line number Diff line
@@ -1291,10 +1291,9 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,

		resolved_dev = dev_get_by_index(dev_addr.net,
						dev_addr.bound_dev_if);
		if (resolved_dev->flags & IFF_LOOPBACK) {
			dev_put(resolved_dev);
			resolved_dev = idev;
			dev_hold(resolved_dev);
		if (!resolved_dev) {
			dev_put(idev);
			return -ENODEV;
		}
		ndev = ib_get_ndev_from_path(rec);
		rcu_read_lock();
+6 −0
Original line number Diff line number Diff line
@@ -1149,6 +1149,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
		return -EFAULT;

	if (cmd.qp_state > IB_QPS_ERR)
		return -EINVAL;

	ctx = ucma_get_ctx(file, cmd.id);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);
@@ -1294,6 +1297,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);

	if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
		return -EINVAL;

	optval = memdup_user((void __user *) (unsigned long) cmd.optval,
			     cmd.optlen);
	if (IS_ERR(optval)) {
Loading