Commit e0477b34 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

RDMA: Explicitly pass in the dma_device to ib_register_device

The code in setup_dma_device has become rather convoluted, move all of
this to the drivers. Drives now pass in a DMA capable struct device which
will be used to setup DMA, or drivers must fully configure the ibdev for
DMA and pass in NULL.

Other than setting the masks in rvt all drivers were doing this already
anyhow.

mthca, mlx4 and mlx5 were already setting up maximum DMA segment size for
DMA based on their hardweare limits in:
__mthca_init_one()
  dma_set_max_seg_size (1G)

__mlx4_init_one()
  dma_set_max_seg_size (1G)

mlx5_pci_init()
  set_dma_caps()
    dma_set_max_seg_size (2G)

Other non software drivers (except usnic) were extended to UINT_MAX [1, 2]
instead of 2G as was before.

[1] https://lore.kernel.org/linux-rdma/20200924114940.GE9475@nvidia.com/
[2] https://lore.kernel.org/linux-rdma/20200924114940.GE9475@nvidia.com/

Link: https://lore.kernel.org/r/20201008082752.275846-1-leon@kernel.org
Link: https://lore.kernel.org/r/6b2ed339933d066622d5715903870676d8cc523a.1602590106.git.mchehab+huawei@kernel.org


Suggested-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarParav Pandit <parav@nvidia.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 9a40401c
Loading
Loading
Loading
Loading
+22 −53
Original line number Diff line number Diff line
@@ -1177,58 +1177,23 @@ out:
	return ret;
}

static void setup_dma_device(struct ib_device *device)
{
	struct device *parent = device->dev.parent;

	WARN_ON_ONCE(device->dma_device);

#ifdef CONFIG_DMA_OPS
	if (device->dev.dma_ops) {
		/*
		 * The caller provided custom DMA operations. Copy the
		 * DMA-related fields that are used by e.g. dma_alloc_coherent()
		 * into device->dev.
		 */
		device->dma_device = &device->dev;
		if (!device->dev.dma_mask) {
			if (parent)
				device->dev.dma_mask = parent->dma_mask;
			else
				WARN_ON_ONCE(true);
		}
		if (!device->dev.coherent_dma_mask) {
			if (parent)
				device->dev.coherent_dma_mask =
					parent->coherent_dma_mask;
			else
				WARN_ON_ONCE(true);
		}
	} else
#endif /* CONFIG_DMA_OPS */
static void setup_dma_device(struct ib_device *device,
			     struct device *dma_device)
{
	/*
		 * The caller did not provide custom DMA operations. Use the
		 * DMA mapping operations of the parent device.
	 * If the caller does not provide a DMA capable device then the IB
	 * device will be used. In this case the caller should fully setup the
	 * ibdev for DMA. This usually means using dma_virt_ops.
	 */
		WARN_ON_ONCE(!parent);
		device->dma_device = parent;
	}

	if (!device->dev.dma_parms) {
		if (parent) {
			/*
			 * The caller did not provide DMA parameters, so
			 * 'parent' probably represents a PCI device. The PCI
			 * core sets the maximum segment size to 64
			 * KB. Increase this parameter to 2 GB.
			 */
			device->dev.dma_parms = parent->dma_parms;
			dma_set_max_seg_size(device->dma_device, SZ_2G);
		} else {
			WARN_ON_ONCE(true);
		}
#ifdef CONFIG_DMA_VIRT_OPS
	if (!dma_device) {
		device->dev.dma_ops = &dma_virt_ops;
		dma_device = &device->dev;
	}
#endif
	WARN_ON(!dma_device);
	device->dma_device = dma_device;
	WARN_ON(!device->dma_device->dma_parms);
}

/*
@@ -1241,7 +1206,6 @@ static int setup_device(struct ib_device *device)
	struct ib_udata uhw = {.outlen = 0, .inlen = 0};
	int ret;

	setup_dma_device(device);
	ib_device_check_mandatory(device);

	ret = setup_port_data(device);
@@ -1355,6 +1319,9 @@ static void prevent_dealloc_device(struct ib_device *ib_dev)
 * @device: Device to register
 * @name: unique string device name. This may include a '%' which will
 * 	  cause a unique index to be added to the passed device name.
 * @dma_device: pointer to a DMA-capable device. If %NULL, then the IB
 *	        device will be used. In this case the caller should fully
 *		setup the ibdev for DMA. This usually means using dma_virt_ops.
 *
 * Low-level drivers use ib_register_device() to register their
 * devices with the IB core.  All registered clients will receive a
@@ -1365,7 +1332,8 @@ static void prevent_dealloc_device(struct ib_device *ib_dev)
 * asynchronously then the device pointer may become freed as soon as this
 * function returns.
 */
int ib_register_device(struct ib_device *device, const char *name)
int ib_register_device(struct ib_device *device, const char *name,
		       struct device *dma_device)
{
	int ret;

@@ -1373,6 +1341,7 @@ int ib_register_device(struct ib_device *device, const char *name)
	if (ret)
		return ret;

	setup_dma_device(device, dma_device);
	ret = setup_device(device);
	if (ret)
		return ret;
+2 −1
Original line number Diff line number Diff line
@@ -736,7 +736,8 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
	if (ret)
		return ret;

	return ib_register_device(ibdev, "bnxt_re%d");
	dma_set_max_seg_size(&rdev->en_dev->pdev->dev, UINT_MAX);
	return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev);
}

static void bnxt_re_dev_remove(struct bnxt_re_dev *rdev)
+3 −1
Original line number Diff line number Diff line
@@ -570,7 +570,9 @@ void c4iw_register_device(struct work_struct *work)
	ret = set_netdevs(&dev->ibdev, &dev->rdev);
	if (ret)
		goto err_dealloc_ctx;
	ret = ib_register_device(&dev->ibdev, "cxgb4_%d");
	dma_set_max_seg_size(&dev->rdev.lldi.pdev->dev, UINT_MAX);
	ret = ib_register_device(&dev->ibdev, "cxgb4_%d",
				 &dev->rdev.lldi.pdev->dev);
	if (ret)
		goto err_dealloc_ctx;
	return;
+2 −2
Original line number Diff line number Diff line
@@ -331,7 +331,7 @@ static int efa_ib_device_add(struct efa_dev *dev)

	ib_set_device_ops(&dev->ibdev, &efa_dev_ops);

	err = ib_register_device(&dev->ibdev, "efa_%d");
	err = ib_register_device(&dev->ibdev, "efa_%d", &pdev->dev);
	if (err)
		goto err_release_doorbell_bar;

@@ -418,7 +418,7 @@ static int efa_device_init(struct efa_com_dev *edev, struct pci_dev *pdev)
			err);
		return err;
	}

	dma_set_max_seg_size(&pdev->dev, UINT_MAX);
	return 0;
}

+2 −1
Original line number Diff line number Diff line
@@ -549,7 +549,8 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
		if (ret)
			return ret;
	}
	ret = ib_register_device(ib_dev, "hns_%d");
	dma_set_max_seg_size(dev, UINT_MAX);
	ret = ib_register_device(ib_dev, "hns_%d", dev);
	if (ret) {
		dev_err(dev, "ib_register_device failed!\n");
		return ret;
Loading