aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorJoachim Fenkes <fenkes@de.ibm.com>2007-10-16 11:31:14 -0400
committerRoland Dreier <rolandd@cisco.com>2007-10-18 00:47:24 -0400
commitabc39d3672d8af4bf6c943faf85fa8877caccf7e (patch)
treec90456ddae53b1ce39cd604404d3810e3b499a27 /drivers/infiniband
parent8c08d50d4fc52a9367c356ebbeb194c30fbc7ac8 (diff)
IB/ehca: Change meaning of hca_cap_mr_pgsize
ehca_shca.hca_cap_mr_pgsize now contains all supported page sizes ORed together. This makes some checks easier to code and understand, plus we can return this value verbatim in query_hca(), fixing a problem with SRP (reported by Anton Blanchard -- thanks!). Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c18
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c38
4 files changed, 36 insertions, 22 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 0f7a55d35ea7..365bc5dfcc88 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -323,7 +323,6 @@ extern int ehca_static_rate;
323extern int ehca_port_act_time; 323extern int ehca_port_act_time;
324extern int ehca_use_hp_mr; 324extern int ehca_use_hp_mr;
325extern int ehca_scaling_code; 325extern int ehca_scaling_code;
326extern int ehca_mr_largepage;
327 326
328struct ipzu_queue_resp { 327struct ipzu_queue_resp {
329 u32 qe_size; /* queue entry size */ 328 u32 qe_size; /* queue entry size */
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index 4aa3ffa6a19f..15806d140461 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -77,6 +77,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
77 } 77 }
78 78
79 memset(props, 0, sizeof(struct ib_device_attr)); 79 memset(props, 0, sizeof(struct ib_device_attr));
80 props->page_size_cap = shca->hca_cap_mr_pgsize;
80 props->fw_ver = rblock->hw_ver; 81 props->fw_ver = rblock->hw_ver;
81 props->max_mr_size = rblock->max_mr_size; 82 props->max_mr_size = rblock->max_mr_size;
82 props->vendor_id = rblock->vendor_id >> 8; 83 props->vendor_id = rblock->vendor_id >> 8;
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 403467f66fe6..d477dc3b4760 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -260,13 +260,20 @@ static struct cap_descr {
260 { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" }, 260 { HCA_CAP_MINI_QP, "HCA_CAP_MINI_QP" },
261}; 261};
262 262
263int ehca_sense_attributes(struct ehca_shca *shca) 263static int ehca_sense_attributes(struct ehca_shca *shca)
264{ 264{
265 int i, ret = 0; 265 int i, ret = 0;
266 u64 h_ret; 266 u64 h_ret;
267 struct hipz_query_hca *rblock; 267 struct hipz_query_hca *rblock;
268 struct hipz_query_port *port; 268 struct hipz_query_port *port;
269 269
270 static const u32 pgsize_map[] = {
271 HCA_CAP_MR_PGSIZE_4K, 0x1000,
272 HCA_CAP_MR_PGSIZE_64K, 0x10000,
273 HCA_CAP_MR_PGSIZE_1M, 0x100000,
274 HCA_CAP_MR_PGSIZE_16M, 0x1000000,
275 };
276
270 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 277 rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
271 if (!rblock) { 278 if (!rblock) {
272 ehca_gen_err("Cannot allocate rblock memory."); 279 ehca_gen_err("Cannot allocate rblock memory.");
@@ -329,8 +336,15 @@ int ehca_sense_attributes(struct ehca_shca *shca)
329 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) 336 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap))
330 ehca_gen_dbg(" %s", hca_cap_descr[i].descr); 337 ehca_gen_dbg(" %s", hca_cap_descr[i].descr);
331 338
332 shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported; 339 /* translate supported MR page sizes; always support 4K */
340 shca->hca_cap_mr_pgsize = EHCA_PAGESIZE;
341 if (ehca_mr_largepage) { /* support extra sizes only if enabled */
342 for (i = 0; i < ARRAY_SIZE(pgsize_map); i += 2)
343 if (rblock->memory_page_size_supported & pgsize_map[i])
344 shca->hca_cap_mr_pgsize |= pgsize_map[i + 1];
345 }
333 346
347 /* query max MTU from first port -- it's the same for all ports */
334 port = (struct hipz_query_port *)rblock; 348 port = (struct hipz_query_port *)rblock;
335 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); 349 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port);
336 if (h_ret != H_SUCCESS) { 350 if (h_ret != H_SUCCESS) {
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index b9a788c4fdd1..bb9791555f49 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -79,9 +79,7 @@ static u32 ehca_encode_hwpage_size(u32 pgsize)
79 79
80static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca) 80static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca)
81{ 81{
82 if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M) 82 return 1UL << ilog2(shca->hca_cap_mr_pgsize);
83 return EHCA_MR_PGSIZE16M;
84 return EHCA_MR_PGSIZE4K;
85} 83}
86 84
87static struct ehca_mr *ehca_mr_new(void) 85static struct ehca_mr *ehca_mr_new(void)
@@ -288,7 +286,7 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
288 container_of(pd->device, struct ehca_shca, ib_device); 286 container_of(pd->device, struct ehca_shca, ib_device);
289 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd); 287 struct ehca_pd *e_pd = container_of(pd, struct ehca_pd, ib_pd);
290 struct ehca_mr_pginfo pginfo; 288 struct ehca_mr_pginfo pginfo;
291 int ret; 289 int ret, page_shift;
292 u32 num_kpages; 290 u32 num_kpages;
293 u32 num_hwpages; 291 u32 num_hwpages;
294 u64 hwpage_size; 292 u64 hwpage_size;
@@ -343,19 +341,20 @@ struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
343 /* determine number of MR pages */ 341 /* determine number of MR pages */
344 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE); 342 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE);
345 /* select proper hw_pgsize */ 343 /* select proper hw_pgsize */
346 if (ehca_mr_largepage && 344 page_shift = PAGE_SHIFT;
347 (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) { 345 if (e_mr->umem->hugetlb) {
348 int page_shift = PAGE_SHIFT; 346 /* determine page_shift, clamp between 4K and 16M */
349 if (e_mr->umem->hugetlb) { 347 page_shift = (fls64(length - 1) + 3) & ~3;
350 /* determine page_shift, clamp between 4K and 16M */ 348 page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K),
351 page_shift = (fls64(length - 1) + 3) & ~3; 349 EHCA_MR_PGSHIFT16M);
352 page_shift = min(max(page_shift, EHCA_MR_PGSHIFT4K), 350 }
353 EHCA_MR_PGSHIFT16M); 351 hwpage_size = 1UL << page_shift;
354 } 352
355 hwpage_size = 1UL << page_shift; 353 /* now that we have the desired page size, shift until it's
356 } else 354 * supported, too. 4K is always supported, so this terminates.
357 hwpage_size = EHCA_MR_PGSIZE4K; /* ehca1 only supports 4k */ 355 */
358 ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size); 356 while (!(hwpage_size & shca->hca_cap_mr_pgsize))
357 hwpage_size >>= 4;
359 358
360reg_user_mr_fallback: 359reg_user_mr_fallback:
361 num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size); 360 num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size);
@@ -801,8 +800,9 @@ struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
801 ib_fmr = ERR_PTR(-EINVAL); 800 ib_fmr = ERR_PTR(-EINVAL);
802 goto alloc_fmr_exit0; 801 goto alloc_fmr_exit0;
803 } 802 }
804 hw_pgsize = ehca_get_max_hwpage_size(shca); 803
805 if ((1 << fmr_attr->page_shift) != hw_pgsize) { 804 hw_pgsize = 1 << fmr_attr->page_shift;
805 if (!(hw_pgsize & shca->hca_cap_mr_pgsize)) {
806 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x", 806 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x",
807 fmr_attr->page_shift); 807 fmr_attr->page_shift);
808 ib_fmr = ERR_PTR(-EINVAL); 808 ib_fmr = ERR_PTR(-EINVAL);