Skip to content

Commit 330179f

Browse files
Bart Van Asschedledford
authored andcommitted
IB/srp: Register the indirect data buffer descriptor
Instead of always using the global rkey for the indirect data buffer descriptor, register that descriptor with the HCA if the kernel module parameter register_always has been set to Y. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
1 parent 002f156 commit 330179f

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

drivers/infiniband/ulp/srp/ib_srp.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,18 +1453,58 @@ static int srp_map_sg(struct srp_map_state *state, struct srp_rdma_ch *ch,
14531453
return ret;
14541454
}
14551455

1456+
/*
1457+
* Register the indirect data buffer descriptor with the HCA.
1458+
*
1459+
* Note: since the indirect data buffer descriptor has been allocated with
1460+
* kmalloc() it is guaranteed that this buffer is a physically contiguous
1461+
* memory buffer.
1462+
*/
1463+
static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,
1464+
void **next_mr, void **end_mr, u32 idb_len,
1465+
__be32 *idb_rkey)
1466+
{
1467+
struct srp_target_port *target = ch->target;
1468+
struct srp_device *dev = target->srp_host->srp_dev;
1469+
struct srp_map_state state;
1470+
struct srp_direct_buf idb_desc;
1471+
u64 idb_pages[1];
1472+
int ret;
1473+
1474+
memset(&state, 0, sizeof(state));
1475+
memset(&idb_desc, 0, sizeof(idb_desc));
1476+
state.gen.next = next_mr;
1477+
state.gen.end = end_mr;
1478+
state.desc = &idb_desc;
1479+
state.pages = idb_pages;
1480+
state.pages[0] = (req->indirect_dma_addr &
1481+
dev->mr_page_mask);
1482+
state.npages = 1;
1483+
state.base_dma_addr = req->indirect_dma_addr;
1484+
state.dma_len = idb_len;
1485+
ret = srp_finish_mapping(&state, ch);
1486+
if (ret < 0)
1487+
goto out;
1488+
1489+
*idb_rkey = idb_desc.key;
1490+
1491+
out:
1492+
return ret;
1493+
}
1494+
14561495
static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
14571496
struct srp_request *req)
14581497
{
14591498
struct srp_target_port *target = ch->target;
14601499
struct scatterlist *scat;
14611500
struct srp_cmd *cmd = req->cmd->buf;
1462-
int len, nents, count;
1501+
int len, nents, count, ret;
14631502
struct srp_device *dev;
14641503
struct ib_device *ibdev;
14651504
struct srp_map_state state;
14661505
struct srp_indirect_buf *indirect_hdr;
1467-
u32 table_len;
1506+
u32 idb_len, table_len;
1507+
__be32 idb_rkey;
14681508
u8 fmt;
14691509

14701510
if (!scsi_sglist(scmnd) || scmnd->sc_data_direction == DMA_NONE)
@@ -1546,6 +1586,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
15461586

15471587
count = min(state.ndesc, target->cmd_sg_cnt);
15481588
table_len = state.ndesc * sizeof (struct srp_direct_buf);
1589+
idb_len = sizeof(struct srp_indirect_buf) + table_len;
15491590

15501591
fmt = SRP_DATA_DESC_INDIRECT;
15511592
len = sizeof(struct srp_cmd) + sizeof (struct srp_indirect_buf);
@@ -1554,8 +1595,18 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch,
15541595
memcpy(indirect_hdr->desc_list, req->indirect_desc,
15551596
count * sizeof (struct srp_direct_buf));
15561597

1598+
if (register_always && (dev->use_fast_reg || dev->use_fmr)) {
1599+
ret = srp_map_idb(ch, req, state.gen.next, state.gen.end,
1600+
idb_len, &idb_rkey);
1601+
if (ret < 0)
1602+
return ret;
1603+
req->nmdesc++;
1604+
} else {
1605+
idb_rkey = target->rkey;
1606+
}
1607+
15571608
indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr);
1558-
indirect_hdr->table_desc.key = cpu_to_be32(target->rkey);
1609+
indirect_hdr->table_desc.key = idb_rkey;
15591610
indirect_hdr->table_desc.len = cpu_to_be32(table_len);
15601611
indirect_hdr->len = cpu_to_be32(state.total_len);
15611612

drivers/infiniband/ulp/srp/ib_srp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ struct srp_map_state {
288288
struct srp_fr_desc **next;
289289
struct srp_fr_desc **end;
290290
} fr;
291+
struct {
292+
void **next;
293+
void **end;
294+
} gen;
291295
};
292296
struct srp_direct_buf *desc;
293297
u64 *pages;

0 commit comments

Comments
 (0)