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

Commit 84e39eeb authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull second round of rdma updates from Doug Ledford:
 "This can be split out into just two categories:

   - fixes to the RDMA R/W API in regards to SG list length limits
     (about 5 patches)

   - fixes/features for the Intel hfi1 driver (everything else)

  The hfi1 driver is still being brought to full feature support by
  Intel, and they have a lot of people working on it, so that amounts to
  almost the entirety of this pull request"

* tag 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (84 commits)
  IB/hfi1: Add cache evict LRU list
  IB/hfi1: Fix memory leak during unexpected shutdown
  IB/hfi1: Remove unneeded mm argument in remove function
  IB/hfi1: Consistently call ops->remove outside spinlock
  IB/hfi1: Use evict mmu rb operation
  IB/hfi1: Add evict operation to the mmu rb handler
  IB/hfi1: Fix TID caching actions
  IB/hfi1: Make the cache handler own its rb tree root
  IB/hfi1: Make use of mm consistent
  IB/hfi1: Fix user SDMA racy user request claim
  IB/hfi1: Fix error condition that needs to clean up
  IB/hfi1: Release node on insert failure
  IB/hfi1: Validate SDMA user iovector count
  IB/hfi1: Validate SDMA user request index
  IB/hfi1: Use the same capability state for all shared contexts
  IB/hfi1: Prevent null pointer dereference
  IB/hfi1: Rename TID mmu_rb_* functions
  IB/hfi1: Remove unneeded empty check in hfi1_mmu_rb_unregister()
  IB/hfi1: Restructure hfi1_file_open
  IB/hfi1: Make iovec loop index easy to understand
  ...
parents 0cda6113 7c41765d
Loading
Loading
Loading
Loading
+11 −13
Original line number Original line Diff line number Diff line
@@ -58,19 +58,13 @@ static inline bool rdma_rw_io_needs_mr(struct ib_device *dev, u8 port_num,
	return false;
	return false;
}
}


static inline u32 rdma_rw_max_sge(struct ib_device *dev,
		enum dma_data_direction dir)
{
	return dir == DMA_TO_DEVICE ?
		dev->attrs.max_sge : dev->attrs.max_sge_rd;
}

static inline u32 rdma_rw_fr_page_list_len(struct ib_device *dev)
static inline u32 rdma_rw_fr_page_list_len(struct ib_device *dev)
{
{
	/* arbitrary limit to avoid allocating gigantic resources */
	/* arbitrary limit to avoid allocating gigantic resources */
	return min_t(u32, dev->attrs.max_fast_reg_page_list_len, 256);
	return min_t(u32, dev->attrs.max_fast_reg_page_list_len, 256);
}
}


/* Caller must have zero-initialized *reg. */
static int rdma_rw_init_one_mr(struct ib_qp *qp, u8 port_num,
static int rdma_rw_init_one_mr(struct ib_qp *qp, u8 port_num,
		struct rdma_rw_reg_ctx *reg, struct scatterlist *sg,
		struct rdma_rw_reg_ctx *reg, struct scatterlist *sg,
		u32 sg_cnt, u32 offset)
		u32 sg_cnt, u32 offset)
@@ -114,6 +108,7 @@ static int rdma_rw_init_mr_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
		u8 port_num, struct scatterlist *sg, u32 sg_cnt, u32 offset,
		u8 port_num, struct scatterlist *sg, u32 sg_cnt, u32 offset,
		u64 remote_addr, u32 rkey, enum dma_data_direction dir)
		u64 remote_addr, u32 rkey, enum dma_data_direction dir)
{
{
	struct rdma_rw_reg_ctx *prev = NULL;
	u32 pages_per_mr = rdma_rw_fr_page_list_len(qp->pd->device);
	u32 pages_per_mr = rdma_rw_fr_page_list_len(qp->pd->device);
	int i, j, ret = 0, count = 0;
	int i, j, ret = 0, count = 0;


@@ -125,7 +120,6 @@ static int rdma_rw_init_mr_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
	}
	}


	for (i = 0; i < ctx->nr_ops; i++) {
	for (i = 0; i < ctx->nr_ops; i++) {
		struct rdma_rw_reg_ctx *prev = i ? &ctx->reg[i - 1] : NULL;
		struct rdma_rw_reg_ctx *reg = &ctx->reg[i];
		struct rdma_rw_reg_ctx *reg = &ctx->reg[i];
		u32 nents = min(sg_cnt, pages_per_mr);
		u32 nents = min(sg_cnt, pages_per_mr);


@@ -162,9 +156,13 @@ static int rdma_rw_init_mr_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
		sg_cnt -= nents;
		sg_cnt -= nents;
		for (j = 0; j < nents; j++)
		for (j = 0; j < nents; j++)
			sg = sg_next(sg);
			sg = sg_next(sg);
		prev = reg;
		offset = 0;
		offset = 0;
	}
	}


	if (prev)
		prev->wr.wr.next = NULL;

	ctx->type = RDMA_RW_MR;
	ctx->type = RDMA_RW_MR;
	return count;
	return count;


@@ -181,7 +179,8 @@ static int rdma_rw_init_map_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
		u64 remote_addr, u32 rkey, enum dma_data_direction dir)
		u64 remote_addr, u32 rkey, enum dma_data_direction dir)
{
{
	struct ib_device *dev = qp->pd->device;
	struct ib_device *dev = qp->pd->device;
	u32 max_sge = rdma_rw_max_sge(dev, dir);
	u32 max_sge = dir == DMA_TO_DEVICE ? qp->max_write_sge :
		      qp->max_read_sge;
	struct ib_sge *sge;
	struct ib_sge *sge;
	u32 total_len = 0, i, j;
	u32 total_len = 0, i, j;


@@ -205,11 +204,10 @@ static int rdma_rw_init_map_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
			rdma_wr->wr.opcode = IB_WR_RDMA_READ;
			rdma_wr->wr.opcode = IB_WR_RDMA_READ;
		rdma_wr->remote_addr = remote_addr + total_len;
		rdma_wr->remote_addr = remote_addr + total_len;
		rdma_wr->rkey = rkey;
		rdma_wr->rkey = rkey;
		rdma_wr->wr.num_sge = nr_sge;
		rdma_wr->wr.sg_list = sge;
		rdma_wr->wr.sg_list = sge;


		for (j = 0; j < nr_sge; j++, sg = sg_next(sg)) {
		for (j = 0; j < nr_sge; j++, sg = sg_next(sg)) {
			rdma_wr->wr.num_sge++;

			sge->addr = ib_sg_dma_address(dev, sg) + offset;
			sge->addr = ib_sg_dma_address(dev, sg) + offset;
			sge->length = ib_sg_dma_len(dev, sg) - offset;
			sge->length = ib_sg_dma_len(dev, sg) - offset;
			sge->lkey = qp->pd->local_dma_lkey;
			sge->lkey = qp->pd->local_dma_lkey;
@@ -220,8 +218,8 @@ static int rdma_rw_init_map_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp,
			offset = 0;
			offset = 0;
		}
		}


		if (i + 1 < ctx->nr_ops)
		rdma_wr->wr.next = i + 1 < ctx->nr_ops ?
			rdma_wr->wr.next = &ctx->map.wrs[i + 1].wr;
			&ctx->map.wrs[i + 1].wr : NULL;
	}
	}


	ctx->type = RDMA_RW_MULTI_WR;
	ctx->type = RDMA_RW_MULTI_WR;
+9 −0
Original line number Original line Diff line number Diff line
@@ -825,6 +825,15 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
		}
		}
	}
	}


	/*
	 * Note: all hw drivers guarantee that max_send_sge is lower than
	 * the device RDMA WRITE SGE limit but not all hw drivers ensure that
	 * max_send_sge <= max_sge_rd.
	 */
	qp->max_write_sge = qp_init_attr->cap.max_send_sge;
	qp->max_read_sge = min_t(u32, qp_init_attr->cap.max_send_sge,
				 device->attrs.max_sge_rd);

	return qp;
	return qp;
}
}
EXPORT_SYMBOL(ib_create_qp);
EXPORT_SYMBOL(ib_create_qp);
+2 −1
Original line number Original line Diff line number Diff line
config INFINIBAND_HFI1
config INFINIBAND_HFI1
	tristate "Intel OPA Gen1 support"
	tristate "Intel OPA Gen1 support"
	depends on X86_64 && INFINIBAND_RDMAVT
	depends on X86_64 && INFINIBAND_RDMAVT && I2C
	select MMU_NOTIFIER
	select MMU_NOTIFIER
	select CRC32
	select CRC32
	select I2C_ALGOBIT
	---help---
	---help---
	This is a low-level driver for Intel OPA Gen1 adapter.
	This is a low-level driver for Intel OPA Gen1 adapter.
config HFI1_DEBUG_SDMA_ORDER
config HFI1_DEBUG_SDMA_ORDER
+1 −1
Original line number Original line Diff line number Diff line
@@ -10,7 +10,7 @@ obj-$(CONFIG_INFINIBAND_HFI1) += hfi1.o
hfi1-y := affinity.o chip.o device.o driver.o efivar.o \
hfi1-y := affinity.o chip.o device.o driver.o efivar.o \
	eprom.o file_ops.o firmware.o \
	eprom.o file_ops.o firmware.o \
	init.o intr.o mad.o mmu_rb.o pcie.o pio.o pio_copy.o platform.o \
	init.o intr.o mad.o mmu_rb.o pcie.o pio.o pio_copy.o platform.o \
	qp.o qsfp.o rc.o ruc.o sdma.o sysfs.o trace.o twsi.o \
	qp.o qsfp.o rc.o ruc.o sdma.o sysfs.o trace.o \
	uc.o ud.o user_exp_rcv.o user_pages.o user_sdma.o verbs.o \
	uc.o ud.o user_exp_rcv.o user_pages.o user_sdma.o verbs.o \
	verbs_txreq.o
	verbs_txreq.o
hfi1-$(CONFIG_DEBUG_FS) += debugfs.o
hfi1-$(CONFIG_DEBUG_FS) += debugfs.o
Loading