IB/ehca: Only use MR large pages for hugetlb regions
authorJoachim Fenkes <fenkes@de.ibm.com>
Thu, 13 Sep 2007 16:16:20 +0000 (18:16 +0200)
committerRoland Dreier <rolandd@cisco.com>
Wed, 10 Oct 2007 02:59:13 +0000 (19:59 -0700)
...because, on virtualized hardware like System p, we can't be sure
that the physical pages behind them are contiguous otherwise.

Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
drivers/infiniband/hw/ehca/ehca_mrmw.c

index e925e84c9bc711c3c5d982270b1e12dd013e4498..da88738265edd23893b136540148a29db3902f09 100644 (file)
@@ -51,6 +51,7 @@
 
 #define NUM_CHUNKS(length, chunk_size) \
        (((length) + (chunk_size - 1)) / (chunk_size))
+
 /* max number of rpages (per hcall register_rpages) */
 #define MAX_RPAGES 512
 
@@ -64,6 +65,11 @@ enum ehca_mr_pgsize {
        EHCA_MR_PGSIZE16M = 0x1000000L
 };
 
+#define EHCA_MR_PGSHIFT4K  12
+#define EHCA_MR_PGSHIFT64K 16
+#define EHCA_MR_PGSHIFT1M  20
+#define EHCA_MR_PGSHIFT16M 24
+
 static u32 ehca_encode_hwpage_size(u32 pgsize)
 {
        u32 idx = 0;
@@ -347,17 +353,16 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        /* select proper hw_pgsize */
        if (ehca_mr_largepage &&
            (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) {
-               if (length <= EHCA_MR_PGSIZE4K
-                   && PAGE_SIZE == EHCA_MR_PGSIZE4K)
-                       hwpage_size = EHCA_MR_PGSIZE4K;
-               else if (length <= EHCA_MR_PGSIZE64K)
-                       hwpage_size = EHCA_MR_PGSIZE64K;
-               else if (length <= EHCA_MR_PGSIZE1M)
-                       hwpage_size = EHCA_MR_PGSIZE1M;
-               else
-                       hwpage_size = EHCA_MR_PGSIZE16M;
+               int page_shift = PAGE_SHIFT;
+               if (e_mr->umem->hugetlb) {
+                       /* determine page_shift, clamp between 4K and 16M */
+                       page_shift = (fls64(length - 1) + 3) & ~3;
+                       page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
+                                        EHCA_MR_PGSHIFT16M);
+               }
+               hwpage_size = 1UL << page_shift;
        } else
-               hwpage_size = EHCA_MR_PGSIZE4K;
+               hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */
        ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size);
 
 reg_user_mr_fallback: