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

Commit 26630e8a authored by Sagi Grimberg's avatar Sagi Grimberg Committed by Doug Ledford
Browse files

IB/srp: Split srp_map_sg



This is a preparation patch for the new registration API
conversion. It splits srp_map_sg per registration strategy
(srp_map_sg[fmr|fr|dma]. On its own it adds some code duplication,
but it makes the API switch easier to comprehend.

Signed-off-by: default avatarSagi Grimberg <sagig@mellanox.com>
Tested-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 9ddc8737
Loading
Loading
Loading
Loading
+106 −51
Original line number Diff line number Diff line
@@ -1286,6 +1286,17 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
	if (state->fmr.next >= state->fmr.end)
		return -ENOMEM;

	WARN_ON_ONCE(!dev->use_fmr);

	if (state->npages == 0)
		return 0;

	if (state->npages == 1 && target->global_mr) {
		srp_map_desc(state, state->base_dma_addr, state->dma_len,
			     target->global_mr->rkey);
		goto reset_state;
	}

	fmr = ib_fmr_pool_map_phys(ch->fmr_pool, state->pages,
				   state->npages, io_addr);
	if (IS_ERR(fmr))
@@ -1297,6 +1308,10 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
	srp_map_desc(state, state->base_dma_addr & ~dev->mr_page_mask,
		     state->dma_len, fmr->fmr->rkey);

reset_state:
	state->npages = 0;
	state->dma_len = 0;

	return 0;
}

@@ -1309,10 +1324,22 @@ static int srp_map_finish_fr(struct srp_map_state *state,
	struct ib_fast_reg_wr wr;
	struct srp_fr_desc *desc;
	u32 rkey;
	int err;

	if (state->fr.next >= state->fr.end)
		return -ENOMEM;

	WARN_ON_ONCE(!dev->use_fast_reg);

	if (state->npages == 0)
		return 0;

	if (state->npages == 1 && target->global_mr) {
		srp_map_desc(state, state->base_dma_addr, state->dma_len,
			     target->global_mr->rkey);
		goto reset_state;
	}

	desc = srp_fr_pool_get(ch->fr_pool);
	if (!desc)
		return -ENOMEM;
@@ -1342,7 +1369,15 @@ static int srp_map_finish_fr(struct srp_map_state *state,
	srp_map_desc(state, state->base_dma_addr, state->dma_len,
		     desc->mr->rkey);

	return ib_post_send(ch->qp, &wr.wr, &bad_wr);
	err = ib_post_send(ch->qp, &wr.wr, &bad_wr);
	if (err)
		return err;

reset_state:
	state->npages = 0;
	state->dma_len = 0;

	return 0;
}

static int srp_finish_mapping(struct srp_map_state *state,
@@ -1350,26 +1385,9 @@ static int srp_finish_mapping(struct srp_map_state *state,
{
	struct srp_target_port *target = ch->target;
	struct srp_device *dev = target->srp_host->srp_dev;
	int ret = 0;

	WARN_ON_ONCE(!dev->use_fast_reg && !dev->use_fmr);

	if (state->npages == 0)
		return 0;

	if (state->npages == 1 && target->global_mr)
		srp_map_desc(state, state->base_dma_addr, state->dma_len,
			     target->global_mr->rkey);
	else
		ret = dev->use_fast_reg ? srp_map_finish_fr(state, ch) :
	return dev->use_fast_reg ? srp_map_finish_fr(state, ch) :
				   srp_map_finish_fmr(state, ch);

	if (ret == 0) {
		state->npages = 0;
		state->dma_len = 0;
	}

	return ret;
}

static int srp_map_sg_entry(struct srp_map_state *state,
@@ -1415,47 +1433,79 @@ static int srp_map_sg_entry(struct srp_map_state *state,
	return ret;
}

static int srp_map_sg(struct srp_map_state *state, struct srp_rdma_ch *ch,
static int srp_map_sg_fmr(struct srp_map_state *state, struct srp_rdma_ch *ch,
			  struct srp_request *req, struct scatterlist *scat,
			  int count)
{
	struct srp_target_port *target = ch->target;
	struct srp_device *dev = target->srp_host->srp_dev;
	struct scatterlist *sg;
	int i, ret;

	state->desc = req->indirect_desc;
	state->pages = req->map_page;
	if (dev->use_fast_reg) {
		state->fr.next = req->fr_list;
		state->fr.end = req->fr_list + target->cmd_sg_cnt;
	} else if (dev->use_fmr) {
	state->fmr.next = req->fmr_list;
		state->fmr.end = req->fmr_list + target->cmd_sg_cnt;
	state->fmr.end = req->fmr_list + ch->target->cmd_sg_cnt;

	for_each_sg(scat, sg, count, i) {
		ret = srp_map_sg_entry(state, ch, sg, i);
		if (ret)
			return ret;
	}

	if (dev->use_fast_reg || dev->use_fmr) {
	ret = srp_finish_mapping(state, ch);
	if (ret)
		return ret;

	req->nmdesc = state->nmdesc;

	return 0;
}

static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch,
			 struct srp_request *req, struct scatterlist *scat,
			 int count)
{
	struct scatterlist *sg;
	int i, ret;

	state->desc = req->indirect_desc;
	state->pages = req->map_page;
	state->fmr.next = req->fmr_list;
	state->fmr.end = req->fmr_list + ch->target->cmd_sg_cnt;

	for_each_sg(scat, sg, count, i) {
		ret = srp_map_sg_entry(state, ch, sg, i);
		if (ret)
				goto out;
			return ret;
	}

	ret = srp_finish_mapping(state, ch);
	if (ret)
			goto out;
	} else {
		return ret;

	req->nmdesc = state->nmdesc;

	return 0;
}

static int srp_map_sg_dma(struct srp_map_state *state, struct srp_rdma_ch *ch,
			  struct srp_request *req, struct scatterlist *scat,
			  int count)
{
	struct srp_target_port *target = ch->target;
	struct srp_device *dev = target->srp_host->srp_dev;
	struct scatterlist *sg;
	int i;

	state->desc = req->indirect_desc;
	for_each_sg(scat, sg, count, i) {
		srp_map_desc(state, ib_sg_dma_address(dev->dev, sg),
			     ib_sg_dma_len(dev->dev, sg),
			     target->global_mr->rkey);
	}
	}

	req->nmdesc = state->nmdesc;
	ret = 0;

out:
	return ret;
	return 0;
}

/*
@@ -1563,7 +1613,12 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
				   target->indirect_size, DMA_TO_DEVICE);

	memset(&state, 0, sizeof(state));
	srp_map_sg(&state, ch, req, scat, count);
	if (dev->use_fast_reg)
		srp_map_sg_fr(&state, ch, req, scat, count);
	else if (dev->use_fmr)
		srp_map_sg_fmr(&state, ch, req, scat, count);
	else
		srp_map_sg_dma(&state, ch, req, scat, count);

	/* We've mapped the request, now pull as much of the indirect
	 * descriptor table as we can into the command buffer. If this