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: Sagi Grimberg <sagig@mellanox.com> Tested-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
9ddc87374a
commit
26630e8a09
|
@ -1286,6 +1286,17 @@ static int srp_map_finish_fmr(struct srp_map_state *state,
|
||||||
if (state->fmr.next >= state->fmr.end)
|
if (state->fmr.next >= state->fmr.end)
|
||||||
return -ENOMEM;
|
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,
|
fmr = ib_fmr_pool_map_phys(ch->fmr_pool, state->pages,
|
||||||
state->npages, io_addr);
|
state->npages, io_addr);
|
||||||
if (IS_ERR(fmr))
|
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,
|
srp_map_desc(state, state->base_dma_addr & ~dev->mr_page_mask,
|
||||||
state->dma_len, fmr->fmr->rkey);
|
state->dma_len, fmr->fmr->rkey);
|
||||||
|
|
||||||
|
reset_state:
|
||||||
|
state->npages = 0;
|
||||||
|
state->dma_len = 0;
|
||||||
|
|
||||||
return 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 ib_fast_reg_wr wr;
|
||||||
struct srp_fr_desc *desc;
|
struct srp_fr_desc *desc;
|
||||||
u32 rkey;
|
u32 rkey;
|
||||||
|
int err;
|
||||||
|
|
||||||
if (state->fr.next >= state->fr.end)
|
if (state->fr.next >= state->fr.end)
|
||||||
return -ENOMEM;
|
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);
|
desc = srp_fr_pool_get(ch->fr_pool);
|
||||||
if (!desc)
|
if (!desc)
|
||||||
return -ENOMEM;
|
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,
|
srp_map_desc(state, state->base_dma_addr, state->dma_len,
|
||||||
desc->mr->rkey);
|
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,
|
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_target_port *target = ch->target;
|
||||||
struct srp_device *dev = target->srp_host->srp_dev;
|
struct srp_device *dev = target->srp_host->srp_dev;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
WARN_ON_ONCE(!dev->use_fast_reg && !dev->use_fmr);
|
return dev->use_fast_reg ? srp_map_finish_fr(state, ch) :
|
||||||
|
|
||||||
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) :
|
|
||||||
srp_map_finish_fmr(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,
|
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;
|
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 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)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = srp_finish_mapping(state, ch);
|
||||||
|
if (ret)
|
||||||
|
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,
|
struct srp_request *req, struct scatterlist *scat,
|
||||||
int count)
|
int count)
|
||||||
{
|
{
|
||||||
struct srp_target_port *target = ch->target;
|
struct srp_target_port *target = ch->target;
|
||||||
struct srp_device *dev = target->srp_host->srp_dev;
|
struct srp_device *dev = target->srp_host->srp_dev;
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
int i, ret;
|
int i;
|
||||||
|
|
||||||
state->desc = req->indirect_desc;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->use_fast_reg || dev->use_fmr) {
|
|
||||||
for_each_sg(scat, sg, count, i) {
|
|
||||||
ret = srp_map_sg_entry(state, ch, sg, i);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
ret = srp_finish_mapping(state, ch);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
} else {
|
|
||||||
for_each_sg(scat, sg, count, i) {
|
for_each_sg(scat, sg, count, i) {
|
||||||
srp_map_desc(state, ib_sg_dma_address(dev->dev, sg),
|
srp_map_desc(state, ib_sg_dma_address(dev->dev, sg),
|
||||||
ib_sg_dma_len(dev->dev, sg),
|
ib_sg_dma_len(dev->dev, sg),
|
||||||
target->global_mr->rkey);
|
target->global_mr->rkey);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
req->nmdesc = state->nmdesc;
|
req->nmdesc = state->nmdesc;
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
out:
|
return 0;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1563,7 +1613,12 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
|
||||||
target->indirect_size, DMA_TO_DEVICE);
|
target->indirect_size, DMA_TO_DEVICE);
|
||||||
|
|
||||||
memset(&state, 0, sizeof(state));
|
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
|
/* We've mapped the request, now pull as much of the indirect
|
||||||
* descriptor table as we can into the command buffer. If this
|
* descriptor table as we can into the command buffer. If this
|
||||||
|
|
Loading…
Reference in New Issue