aboutsummaryrefslogtreecommitdiff
path: root/drivers/infiniband/ulp/iser/iser_memory.c
diff options
context:
space:
mode:
authorErez Zilber <erezz@voltaire.com>2006-09-11 12:26:33 +0300
committerRoland Dreier <rolandd@cisco.com>2006-09-22 15:22:52 -0700
commitd81110285f7f6c07a0ce8f99a5ff158a647cd649 (patch)
tree7ecbae2d81a7464114a7d57e1a7d0230aaa21071 /drivers/infiniband/ulp/iser/iser_memory.c
parente981f1d4b8288072ba7cf6b7141cd4aefb404383 (diff)
IB/iser: Do not use FMR for a single dma entry sg
Fast Memory Registration (fmr) is used to register for rdma an sg whose elements are not linearly sequential after dma mapping. The IB verbs layer provides an "all dma memory MR (memory region)" which can be used for RDMA-ing a dma linearly sequential buffer. Change the code to use the dma mr instead of doing fmr when dma mapping produces a single dma entry sg. Signed-off-by: Erez Zilber <erezz@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/ulp/iser/iser_memory.c')
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 8fea0bce504..d0b03f42658 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -56,7 +56,7 @@ int iser_regd_buff_release(struct iser_regd_buf *regd_buf)
if ((atomic_read(&regd_buf->ref_count) == 0) ||
atomic_dec_and_test(&regd_buf->ref_count)) {
/* if we used the dma mr, unreg is just NOP */
- if (regd_buf->reg.rkey != 0)
+ if (regd_buf->reg.is_fmr)
iser_unreg_mem(&regd_buf->reg);
if (regd_buf->dma_addr) {
@@ -91,9 +91,9 @@ void iser_reg_single(struct iser_device *device,
BUG_ON(dma_mapping_error(dma_addr));
regd_buf->reg.lkey = device->mr->lkey;
- regd_buf->reg.rkey = 0; /* indicate there's no need to unreg */
regd_buf->reg.len = regd_buf->data_size;
regd_buf->reg.va = dma_addr;
+ regd_buf->reg.is_fmr = 0;
regd_buf->dma_addr = dma_addr;
regd_buf->direction = direction;
@@ -379,11 +379,13 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
enum iser_data_dir cmd_dir)
{
struct iser_conn *ib_conn = iser_ctask->iser_conn->ib_conn;
+ struct iser_device *device = ib_conn->device;
struct iser_data_buf *mem = &iser_ctask->data[cmd_dir];
struct iser_regd_buf *regd_buf;
int aligned_len;
int err;
int i;
+ struct scatterlist *sg;
regd_buf = &iser_ctask->rdma_regd[cmd_dir];
@@ -399,19 +401,37 @@ int iser_reg_rdma_mem(struct iscsi_iser_cmd_task *iser_ctask,
mem = &iser_ctask->data_copy[cmd_dir];
}
- iser_page_vec_build(mem, ib_conn->page_vec);
- err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg);
- if (err) {
- iser_data_buf_dump(mem);
- iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", mem->dma_nents,
- ntoh24(iser_ctask->desc.iscsi_header.dlength));
- iser_err("page_vec: data_size = 0x%x, length = %d, offset = 0x%x\n",
- ib_conn->page_vec->data_size, ib_conn->page_vec->length,
- ib_conn->page_vec->offset);
- for (i=0 ; i<ib_conn->page_vec->length ; i++) {
- iser_err("page_vec[%d] = 0x%lx\n", i, ib_conn->page_vec->pages[i]);
+ /* if there a single dma entry, FMR is not needed */
+ if (mem->dma_nents == 1) {
+ sg = (struct scatterlist *)mem->buf;
+
+ regd_buf->reg.lkey = device->mr->lkey;
+ regd_buf->reg.rkey = device->mr->rkey;
+ regd_buf->reg.len = sg_dma_len(&sg[0]);
+ regd_buf->reg.va = sg_dma_address(&sg[0]);
+ regd_buf->reg.is_fmr = 0;
+
+ iser_dbg("PHYSICAL Mem.register: lkey: 0x%08X rkey: 0x%08X "
+ "va: 0x%08lX sz: %ld]\n",
+ (unsigned int)regd_buf->reg.lkey,
+ (unsigned int)regd_buf->reg.rkey,
+ (unsigned long)regd_buf->reg.va,
+ (unsigned long)regd_buf->reg.len);
+ } else { /* use FMR for multiple dma entries */
+ iser_page_vec_build(mem, ib_conn->page_vec);
+ err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, &regd_buf->reg);
+ if (err) {
+ iser_data_buf_dump(mem);
+ iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", mem->dma_nents,
+ ntoh24(iser_ctask->desc.iscsi_header.dlength));
+ iser_err("page_vec: data_size = 0x%x, length = %d, offset = 0x%x\n",
+ ib_conn->page_vec->data_size, ib_conn->page_vec->length,
+ ib_conn->page_vec->offset);
+ for (i=0 ; i<ib_conn->page_vec->length ; i++)
+ iser_err("page_vec[%d] = 0x%llx\n", i,
+ (unsigned long long) ib_conn->page_vec->pages[i]);
+ return err;
}
- return err;
}
/* take a reference on this regd buf such that it will not be released *