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

Commit 57b0be9c authored by Bart Van Assche's avatar Bart Van Assche Committed by Doug Ledford
Browse files

IB/srp: Fix srp_map_sg_fr()



After dma_map_sg() has been called the return value of that function
must be used as the number of elements in the scatterlist instead of
scsi_sg_count().

Fixes: commit f7f7aab1 ("IB/srp: Convert to new registration API")
Reported-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Cc: stable <stable@vger.kernel.org> # v4.4+
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Sebastian Parschauer <sebastian.riemer@profitbricks.com>
Reviewed-by: default avatarSagi Grimberg <sagig@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent a745f4f4
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -1313,7 +1313,7 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
}

static int srp_map_finish_fr(struct srp_map_state *state,
			     struct srp_rdma_ch *ch)
			     struct srp_rdma_ch *ch, int sg_nents)
{
	struct srp_target_port *target = ch->target;
	struct srp_device *dev = target->srp_host->srp_dev;
@@ -1328,10 +1328,10 @@ static int srp_map_finish_fr(struct srp_map_state *state,

	WARN_ON_ONCE(!dev->use_fast_reg);

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

	if (state->sg_nents == 1 && target->global_mr) {
	if (sg_nents == 1 && target->global_mr) {
		srp_map_desc(state, sg_dma_address(state->sg),
			     sg_dma_len(state->sg),
			     target->global_mr->rkey);
@@ -1345,8 +1345,7 @@ static int srp_map_finish_fr(struct srp_map_state *state,
	rkey = ib_inc_rkey(desc->mr->rkey);
	ib_update_fast_reg_key(desc->mr, rkey);

	n = ib_map_mr_sg(desc->mr, state->sg, state->sg_nents,
			 dev->mr_page_size);
	n = ib_map_mr_sg(desc->mr, state->sg, sg_nents, dev->mr_page_size);
	if (unlikely(n < 0))
		return n;

@@ -1452,16 +1451,15 @@ static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch,
	state->fr.next = req->fr_list;
	state->fr.end = req->fr_list + ch->target->cmd_sg_cnt;
	state->sg = scat;
	state->sg_nents = scsi_sg_count(req->scmnd);

	while (state->sg_nents) {
	while (count) {
		int i, n;

		n = srp_map_finish_fr(state, ch);
		n = srp_map_finish_fr(state, ch, count);
		if (unlikely(n < 0))
			return n;

		state->sg_nents -= n;
		count -= n;
		for (i = 0; i < n; i++)
			state->sg = sg_next(state->sg);
	}
@@ -1521,13 +1519,12 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,

	if (dev->use_fast_reg) {
		state.sg = idb_sg;
		state.sg_nents = 1;
		sg_set_buf(idb_sg, req->indirect_desc, idb_len);
		idb_sg->dma_address = req->indirect_dma_addr; /* hack! */
#ifdef CONFIG_NEED_SG_DMA_LENGTH
		idb_sg->dma_length = idb_sg->length;	      /* hack^2 */
#endif
		ret = srp_map_finish_fr(&state, ch);
		ret = srp_map_finish_fr(&state, ch, 1);
		if (ret < 0)
			return ret;
	} else if (dev->use_fmr) {
+1 −4
Original line number Diff line number Diff line
@@ -300,10 +300,7 @@ struct srp_map_state {
	dma_addr_t		base_dma_addr;
	u32			dma_len;
	u32			total_len;
	union {
	unsigned int		npages;
		int		sg_nents;
	};
	unsigned int		nmdesc;
	unsigned int		ndesc;
};