summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/iser/iser_memory.c
diff options
context:
space:
mode:
authorErez Zilber <erezz@voltaire.com>2006-09-11 12:22:30 +0300
committerRoland Dreier <rolandd@cisco.com>2006-09-22 15:22:51 -0700
commit8dfa0876d3dde5f9c1818a4c35caaabc3ddba78b (patch)
treeca68e1f128305185c8cb807e15ab67b36b2be2a5 /drivers/infiniband/ulp/iser/iser_memory.c
parent8072ec2f8f6790df91e85d833e672c9c30a7ab3c (diff)
downloadtalos-obmc-linux-8dfa0876d3dde5f9c1818a4c35caaabc3ddba78b.tar.gz
talos-obmc-linux-8dfa0876d3dde5f9c1818a4c35caaabc3ddba78b.zip
IB/iser: make FMR "page size" be 4K and not PAGE_SIZE
As iser is able to use at most one rdma operation for the execution of a scsi command, and registration of the sg associated with scsi command has its restrictions, the code checks if an sg is "aligned for rdma". Alignment for rdma is measured in "fmr page" units whose possible resolutions are different between HCAs and can be smaller, equal or bigger to the system page size. When the system page size is bigger than 4KB (eg the default with ia64 kernels) there a bigger chance that an sg would be aligned for rdma if the fmr page size is 4KB. Change the code to create FMR whose pages are of size 4KB and to take that into account when processing the 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.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 53af9567632e..bcef0d31f756 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -42,6 +42,7 @@
#include "iscsi_iser.h"
#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */
+
/**
* Decrements the reference count for the
* registered buffer & releases it
@@ -239,7 +240,7 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
int i;
/* compute the offset of first element */
- page_vec->offset = (u64) sg[0].offset;
+ page_vec->offset = (u64) sg[0].offset & ~MASK_4K;
for (i = 0; i < data->dma_nents; i++) {
total_sz += sg_dma_len(&sg[i]);
@@ -247,21 +248,30 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
first_addr = sg_dma_address(&sg[i]);
last_addr = first_addr + sg_dma_len(&sg[i]);
- start_aligned = !(first_addr & ~PAGE_MASK);
- end_aligned = !(last_addr & ~PAGE_MASK);
+ start_aligned = !(first_addr & ~MASK_4K);
+ end_aligned = !(last_addr & ~MASK_4K);
/* continue to collect page fragments till aligned or SG ends */
while (!end_aligned && (i + 1 < data->dma_nents)) {
i++;
total_sz += sg_dma_len(&sg[i]);
last_addr = sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]);
- end_aligned = !(last_addr & ~PAGE_MASK);
+ end_aligned = !(last_addr & ~MASK_4K);
}
- first_addr = first_addr & PAGE_MASK;
-
- for (page = first_addr; page < last_addr; page += PAGE_SIZE)
- page_vec->pages[cur_page++] = page;
+ /* handle the 1st page in the 1st DMA element */
+ if (cur_page == 0) {
+ page = first_addr & MASK_4K;
+ page_vec->pages[cur_page] = page;
+ cur_page++;
+ page += SIZE_4K;
+ } else
+ page = first_addr;
+
+ for (; page < last_addr; page += SIZE_4K) {
+ page_vec->pages[cur_page] = page;
+ cur_page++;
+ }
}
page_vec->data_size = total_sz;
@@ -269,8 +279,7 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
return cur_page;
}
-#define MASK_4K ((1UL << 12) - 1) /* 0xFFF */
-#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & MASK_4K) == 0)
+#define IS_4K_ALIGNED(addr) ((((unsigned long)addr) & ~MASK_4K) == 0)
/**
* iser_data_buf_aligned_len - Tries to determine the maximal correctly aligned
@@ -352,7 +361,7 @@ static void iser_page_vec_build(struct iser_data_buf *data,
page_vec->length = page_vec_len;
- if (page_vec_len * PAGE_SIZE < page_vec->data_size) {
+ if (page_vec_len * SIZE_4K < page_vec->data_size) {
iser_err("page_vec too short to hold this SG\n");
iser_data_buf_dump(data);
iser_dump_page_vec(page_vec);
OpenPOWER on IntegriCloud