Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e38335d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull rdma fixes from Jason Gunthorpe:
 "Things are looking pretty quiet here in RDMA, not too many bug fixes
  rolling in right now. The usual driver bug fixes and fixes for a
  couple of regressions introduced in 5.2:

   - Fix a race on bootup with RDMA device renaming and srp. SRP also
     needs to rename its internal sys files

   - Fix a memory leak in hns

   - Don't leak resources in efa on certain error unwinds

   - Don't panic in certain error unwinds in ib_register_device

   - Various small user visible bug fix patches for the hfi and efa
     drivers

   - Fix the 32 bit compilation break"

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma:
  RDMA/efa: Remove MAYEXEC flag check from mmap flow
  mlx5: avoid 64-bit division
  IB/hfi1: Validate page aligned for a given virtual address
  IB/{qib, hfi1, rdmavt}: Correct ibv_devinfo max_mr value
  IB/hfi1: Insure freeze_work work_struct is canceled on shutdown
  IB/rdmavt: Fix alloc_qpn() WARN_ON()
  RDMA/core: Fix panic when port_data isn't initialized
  RDMA/uverbs: Pass udata on uverbs error unwind
  RDMA/core: Clear out the udata before error unwind
  RDMA/hns: Fix PD memory leak for internal allocation
  RDMA/srp: Rename SRP sysfs name after IB device rename trigger
parents a02a532c 4f240dfe
Loading
Loading
Loading
Loading
+35 −14
Original line number Diff line number Diff line
@@ -409,29 +409,46 @@ static int rename_compat_devs(struct ib_device *device)

int ib_device_rename(struct ib_device *ibdev, const char *name)
{
	unsigned long index;
	void *client_data;
	int ret;

	down_write(&devices_rwsem);
	if (!strcmp(name, dev_name(&ibdev->dev))) {
		ret = 0;
		goto out;
		up_write(&devices_rwsem);
		return 0;
	}

	if (__ib_device_get_by_name(name)) {
		ret = -EEXIST;
		goto out;
		up_write(&devices_rwsem);
		return -EEXIST;
	}

	ret = device_rename(&ibdev->dev, name);
	if (ret)
		goto out;
	strlcpy(ibdev->name, name, IB_DEVICE_NAME_MAX);
	ret = rename_compat_devs(ibdev);
out:
	if (ret) {
		up_write(&devices_rwsem);
		return ret;
	}

	strlcpy(ibdev->name, name, IB_DEVICE_NAME_MAX);
	ret = rename_compat_devs(ibdev);

	downgrade_write(&devices_rwsem);
	down_read(&ibdev->client_data_rwsem);
	xan_for_each_marked(&ibdev->client_data, index, client_data,
			    CLIENT_DATA_REGISTERED) {
		struct ib_client *client = xa_load(&clients, index);

		if (!client || !client->rename)
			continue;

		client->rename(ibdev, client_data);
	}
	up_read(&ibdev->client_data_rwsem);
	up_read(&devices_rwsem);
	return 0;
}

static int alloc_name(struct ib_device *ibdev, const char *name)
{
	struct ib_device *device;
@@ -474,14 +491,15 @@ static void ib_device_release(struct device *device)

	free_netdevs(dev);
	WARN_ON(refcount_read(&dev->refcount));
	if (dev->port_data) {
		ib_cache_release_one(dev);
		ib_security_release_port_pkey_list(dev);
	xa_destroy(&dev->compat_devs);
	xa_destroy(&dev->client_data);
	if (dev->port_data)
		kfree_rcu(container_of(dev->port_data, struct ib_port_data_rcu,
				       pdata[0]),
			  rcu_head);
	}
	xa_destroy(&dev->compat_devs);
	xa_destroy(&dev->client_data);
	kfree_rcu(dev, rcu_head);
}

@@ -1935,6 +1953,9 @@ static void free_netdevs(struct ib_device *ib_dev)
	unsigned long flags;
	unsigned int port;

	if (!ib_dev->port_data)
		return;

	rdma_for_each_port (ib_dev, port) {
		struct ib_port_data *pdata = &ib_dev->port_data[port];
		struct net_device *ndev;
+2 −0
Original line number Diff line number Diff line
@@ -110,6 +110,8 @@ int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);
void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile);
void release_ufile_idr_uobject(struct ib_uverbs_file *ufile);

struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs);

/*
 * This is the runtime description of the uverbs API, used by the syscall
 * machinery to validate and dispatch calls.
+21 −9
Original line number Diff line number Diff line
@@ -174,6 +174,17 @@ static int uverbs_request_finish(struct uverbs_req_iter *iter)
	return 0;
}

/*
 * When calling a destroy function during an error unwind we need to pass in
 * the udata that is sanitized of all user arguments. Ie from the driver
 * perspective it looks like no udata was passed.
 */
struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs)
{
	attrs->driver_udata = (struct ib_udata){};
	return &attrs->driver_udata;
}

static struct ib_uverbs_completion_event_file *
_ib_uverbs_lookup_comp_file(s32 fd, struct uverbs_attr_bundle *attrs)
{
@@ -441,7 +452,7 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	ib_dealloc_pd_user(pd, &attrs->driver_udata);
	ib_dealloc_pd_user(pd, uverbs_get_cleared_udata(attrs));
	pd = NULL;
err_alloc:
	kfree(pd);
@@ -644,7 +655,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
	}

err_dealloc_xrcd:
	ib_dealloc_xrcd(xrcd, &attrs->driver_udata);
	ib_dealloc_xrcd(xrcd, uverbs_get_cleared_udata(attrs));

err:
	uobj_alloc_abort(&obj->uobject, attrs);
@@ -767,7 +778,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	ib_dereg_mr_user(mr, &attrs->driver_udata);
	ib_dereg_mr_user(mr, uverbs_get_cleared_udata(attrs));

err_put:
	uobj_put_obj_read(pd);
@@ -1042,7 +1053,7 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
	return obj;

err_cb:
	ib_destroy_cq(cq);
	ib_destroy_cq_user(cq, uverbs_get_cleared_udata(attrs));

err_file:
	if (ev_file)
@@ -1478,7 +1489,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,

	return uobj_alloc_commit(&obj->uevent.uobject, attrs);
err_cb:
	ib_destroy_qp(qp);
	ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs));

err_put:
	if (!IS_ERR(xrcd_uobj))
@@ -1611,7 +1622,7 @@ static int ib_uverbs_open_qp(struct uverbs_attr_bundle *attrs)
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);

err_destroy:
	ib_destroy_qp(qp);
	ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs));
err_xrcd:
	uobj_put_read(xrcd_uobj);
err_put:
@@ -2453,7 +2464,8 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs)
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
	rdma_destroy_ah_user(ah, RDMA_DESTROY_AH_SLEEPABLE,
			     uverbs_get_cleared_udata(attrs));

err_put:
	uobj_put_obj_read(pd);
@@ -2964,7 +2976,7 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);

err_copy:
	ib_destroy_wq(wq, &attrs->driver_udata);
	ib_destroy_wq(wq, uverbs_get_cleared_udata(attrs));
err_put_cq:
	uobj_put_obj_read(cq);
err_put_pd:
@@ -3464,7 +3476,7 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);

err_copy:
	ib_destroy_srq_user(srq, &attrs->driver_udata);
	ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs));

err_free:
	kfree(srq);
+1 −1
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(

	return 0;
err_cq:
	ib_destroy_cq(cq);
	ib_destroy_cq_user(cq, uverbs_get_cleared_udata(attrs));

err_event_file:
	if (ev_file)
+1 −1
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)(
	return 0;

err_dereg:
	ib_dereg_mr_user(mr, &attrs->driver_udata);
	ib_dereg_mr_user(mr, uverbs_get_cleared_udata(attrs));

	return ret;
}
Loading