IB/ehca: Support large page MRs

Add support for MR pages larger than 4K on eHCA2. This reduces
firmware memory consumption. If enabled via the mr_largepage module
parameter, the MR page size will be determined based on the MR length
and the hardware capabilities -- if the MR is >= 16M, 16M pages are
used, for example.

Signed-off-by: Joachim Fenkes <fenkes@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by Hoang-Nam Nguyen and committed by Roland Dreier 5bb7d929 23f1b384

+357 -63
+9
drivers/infiniband/hw/ehca/ehca_classes.h
··· 100 struct ehca_sma_attr saved_attr; 101 }; 102 103 struct ehca_shca { 104 struct ib_device ib_device; 105 struct ibmebus_dev *ibmebus_dev; ··· 120 struct h_galpas galpas; 121 struct mutex modify_mutex; 122 u64 hca_cap; 123 int max_mtu; 124 }; 125 ··· 213 enum ehca_mr_flag flags; 214 u32 num_kpages; /* number of kernel pages */ 215 u32 num_hwpages; /* number of hw pages to form MR */ 216 int acl; /* ACL (stored here for usage in reregister) */ 217 u64 *start; /* virtual start address (stored here for */ 218 /* usage in reregister) */ ··· 248 enum ehca_mr_pgi_type type; 249 u64 num_kpages; 250 u64 kpage_cnt; 251 u64 num_hwpages; /* number of hw pages */ 252 u64 hwpage_cnt; /* counter for hw pages */ 253 u64 next_hwpage; /* next hw page in buffer/chunk/listelem */
··· 100 struct ehca_sma_attr saved_attr; 101 }; 102 103 + #define HCA_CAP_MR_PGSIZE_4K 1 104 + #define HCA_CAP_MR_PGSIZE_64K 2 105 + #define HCA_CAP_MR_PGSIZE_1M 4 106 + #define HCA_CAP_MR_PGSIZE_16M 8 107 + 108 struct ehca_shca { 109 struct ib_device ib_device; 110 struct ibmebus_dev *ibmebus_dev; ··· 115 struct h_galpas galpas; 116 struct mutex modify_mutex; 117 u64 hca_cap; 118 + /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */ 119 + u32 hca_cap_mr_pgsize; 120 int max_mtu; 121 }; 122 ··· 206 enum ehca_mr_flag flags; 207 u32 num_kpages; /* number of kernel pages */ 208 u32 num_hwpages; /* number of hw pages to form MR */ 209 + u64 hwpage_size; /* hw page size used for this MR */ 210 int acl; /* ACL (stored here for usage in reregister) */ 211 u64 *start; /* virtual start address (stored here for */ 212 /* usage in reregister) */ ··· 240 enum ehca_mr_pgi_type type; 241 u64 num_kpages; 242 u64 kpage_cnt; 243 + u64 hwpage_size; /* hw page size used for this MR */ 244 u64 num_hwpages; /* number of hw pages */ 245 u64 hwpage_cnt; /* counter for hw pages */ 246 u64 next_hwpage; /* next hw page in buffer/chunk/listelem */
+17 -1
drivers/infiniband/hw/ehca/ehca_main.c
··· 63 int ehca_poll_all_eqs = 1; 64 int ehca_static_rate = -1; 65 int ehca_scaling_code = 0; 66 67 module_param_named(open_aqp1, ehca_open_aqp1, int, 0); 68 module_param_named(debug_level, ehca_debug_level, int, 0); ··· 73 module_param_named(port_act_time, ehca_port_act_time, int, 0); 74 module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0); 75 module_param_named(static_rate, ehca_static_rate, int, 0); 76 - module_param_named(scaling_code, ehca_scaling_code, int, 0); 77 78 MODULE_PARM_DESC(open_aqp1, 79 "AQP1 on startup (0: no (default), 1: yes)"); ··· 97 "set permanent static rate (default: disabled)"); 98 MODULE_PARM_DESC(scaling_code, 99 "set scaling code (0: disabled/default, 1: enabled)"); 100 101 DEFINE_RWLOCK(ehca_qp_idr_lock); 102 DEFINE_RWLOCK(ehca_cq_idr_lock); ··· 299 for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++) 300 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) 301 ehca_gen_dbg(" %s", hca_cap_descr[i].descr); 302 303 port = (struct hipz_query_port *)rblock; 304 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); ··· 597 } 598 static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); 599 600 static struct attribute *ehca_dev_attrs[] = { 601 &dev_attr_adapter_handle.attr, 602 &dev_attr_num_ports.attr, ··· 621 &dev_attr_cur_mw.attr, 622 &dev_attr_max_pd.attr, 623 &dev_attr_max_ah.attr, 624 NULL 625 }; 626
··· 63 int ehca_poll_all_eqs = 1; 64 int ehca_static_rate = -1; 65 int ehca_scaling_code = 0; 66 + int ehca_mr_largepage = 0; 67 68 module_param_named(open_aqp1, ehca_open_aqp1, int, 0); 69 module_param_named(debug_level, ehca_debug_level, int, 0); ··· 72 module_param_named(port_act_time, ehca_port_act_time, int, 0); 73 module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0); 74 module_param_named(static_rate, ehca_static_rate, int, 0); 75 + module_param_named(scaling_code, ehca_scaling_code, int, 0); 76 + module_param_named(mr_largepage, ehca_mr_largepage, int, 0); 77 78 MODULE_PARM_DESC(open_aqp1, 79 "AQP1 on startup (0: no (default), 1: yes)"); ··· 95 "set permanent static rate (default: disabled)"); 96 MODULE_PARM_DESC(scaling_code, 97 "set scaling code (0: disabled/default, 1: enabled)"); 98 + MODULE_PARM_DESC(mr_largepage, 99 + "use large page for MR (0: use PAGE_SIZE (default), " 100 + "1: use large page depending on MR size"); 101 102 DEFINE_RWLOCK(ehca_qp_idr_lock); 103 DEFINE_RWLOCK(ehca_cq_idr_lock); ··· 294 for (i = 0; i < ARRAY_SIZE(hca_cap_descr); i++) 295 if (EHCA_BMASK_GET(hca_cap_descr[i].mask, shca->hca_cap)) 296 ehca_gen_dbg(" %s", hca_cap_descr[i].descr); 297 + 298 + shca->hca_cap_mr_pgsize = rblock->memory_page_size_supported; 299 300 port = (struct hipz_query_port *)rblock; 301 h_ret = hipz_h_query_port(shca->ipz_hca_handle, 1, port); ··· 590 } 591 static DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL); 592 593 + static ssize_t ehca_show_mr_largepage(struct device *dev, 594 + struct device_attribute *attr, 595 + char *buf) 596 + { 597 + return sprintf(buf, "%d\n", ehca_mr_largepage); 598 + } 599 + static DEVICE_ATTR(mr_largepage, S_IRUGO, ehca_show_mr_largepage, NULL); 600 + 601 static struct attribute *ehca_dev_attrs[] = { 602 &dev_attr_adapter_handle.attr, 603 &dev_attr_num_ports.attr, ··· 606 &dev_attr_cur_mw.attr, 607 &dev_attr_max_pd.attr, 608 &dev_attr_max_ah.attr, 609 + &dev_attr_mr_largepage.attr, 610 NULL 611 }; 612
+311 -60
drivers/infiniband/hw/ehca/ehca_mrmw.c
··· 5 * 6 * Authors: Dietmar Decker <ddecker@de.ibm.com> 7 * Christoph Raisch <raisch@de.ibm.com> 8 * 9 * Copyright (c) 2005 IBM Corporation 10 * ··· 56 57 static struct kmem_cache *mr_cache; 58 static struct kmem_cache *mw_cache; 59 60 static struct ehca_mr *ehca_mr_new(void) 61 { ··· 239 struct ehca_mr_pginfo pginfo; 240 u32 num_kpages; 241 u32 num_hwpages; 242 243 num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size, 244 PAGE_SIZE); 245 - num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + 246 - size, EHCA_PAGESIZE); 247 memset(&pginfo, 0, sizeof(pginfo)); 248 pginfo.type = EHCA_MR_PGI_PHYS; 249 pginfo.num_kpages = num_kpages; 250 pginfo.num_hwpages = num_hwpages; 251 pginfo.u.phy.num_phys_buf = num_phys_buf; 252 pginfo.u.phy.phys_buf_array = phys_buf_array; 253 - pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) / 254 - EHCA_PAGESIZE); 255 256 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, 257 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, ··· 295 int ret; 296 u32 num_kpages; 297 u32 num_hwpages; 298 299 if (!pd) { 300 ehca_gen_err("bad pd=%p", pd); ··· 346 347 /* determine number of MR pages */ 348 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE); 349 - num_hwpages = NUM_CHUNKS((virt % EHCA_PAGESIZE) + length, 350 - EHCA_PAGESIZE); 351 352 /* register MR on HCA */ 353 memset(&pginfo, 0, sizeof(pginfo)); 354 pginfo.type = EHCA_MR_PGI_USER; 355 pginfo.num_kpages = num_kpages; 356 pginfo.num_hwpages = num_hwpages; 357 pginfo.u.usr.region = e_mr->umem; 358 - pginfo.next_hwpage = e_mr->umem->offset / EHCA_PAGESIZE; 359 pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk, 360 (&e_mr->umem->chunk_list), 361 list); ··· 379 ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, 380 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, 381 &e_mr->ib.ib_mr.rkey); 382 if (ret) { 383 ib_mr = ERR_PTR(ret); 384 goto reg_user_mr_exit2; ··· 517 new_pd = container_of(mr->pd, struct ehca_pd, ib_pd); 518 519 if (mr_rereg_mask & IB_MR_REREG_TRANS) { 520 new_start = iova_start; /* change address */ 521 /* check physical buffer list and calculate size */ 522 ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array, ··· 535 } 536 num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) + 537 new_size, PAGE_SIZE); 538 - num_hwpages = NUM_CHUNKS(((u64)new_start % EHCA_PAGESIZE) + 539 - new_size, EHCA_PAGESIZE); 540 memset(&pginfo, 0, sizeof(pginfo)); 541 pginfo.type = EHCA_MR_PGI_PHYS; 542 pginfo.num_kpages = num_kpages; 543 pginfo.num_hwpages = num_hwpages; 544 pginfo.u.phy.num_phys_buf = num_phys_buf; 545 pginfo.u.phy.phys_buf_array = phys_buf_array; 546 - pginfo.next_hwpage = (((u64)iova_start & ~PAGE_MASK) / 547 - EHCA_PAGESIZE); 548 } 549 if (mr_rereg_mask & IB_MR_REREG_ACCESS) 550 new_acl = mr_access_flags; ··· 777 int ret; 778 u32 tmp_lkey, tmp_rkey; 779 struct ehca_mr_pginfo pginfo; 780 781 /* check other parameters */ 782 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) && ··· 807 ib_fmr = ERR_PTR(-EINVAL); 808 goto alloc_fmr_exit0; 809 } 810 - if (((1 << fmr_attr->page_shift) != EHCA_PAGESIZE) && 811 - ((1 << fmr_attr->page_shift) != PAGE_SIZE)) { 812 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x", 813 fmr_attr->page_shift); 814 ib_fmr = ERR_PTR(-EINVAL); ··· 824 825 /* register MR on HCA */ 826 memset(&pginfo, 0, sizeof(pginfo)); 827 ret = ehca_reg_mr(shca, e_fmr, NULL, 828 fmr_attr->max_pages * (1 << fmr_attr->page_shift), 829 mr_access_flags, e_pd, &pginfo, ··· 838 } 839 840 /* successful */ 841 e_fmr->fmr_page_size = 1 << fmr_attr->page_shift; 842 e_fmr->fmr_max_pages = fmr_attr->max_pages; 843 e_fmr->fmr_max_maps = fmr_attr->max_maps; ··· 896 memset(&pginfo, 0, sizeof(pginfo)); 897 pginfo.type = EHCA_MR_PGI_FMR; 898 pginfo.num_kpages = list_len; 899 - pginfo.num_hwpages = list_len * (e_fmr->fmr_page_size / EHCA_PAGESIZE); 900 pginfo.u.fmr.page_list = page_list; 901 - pginfo.next_hwpage = ((iova & (e_fmr->fmr_page_size-1)) / 902 - EHCA_PAGESIZE); 903 pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size; 904 905 ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova, ··· 1040 struct ehca_mr_hipzout_parms hipzout; 1041 1042 ehca_mrmw_map_acl(acl, &hipz_acl); 1043 - ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1044 if (ehca_use_hp_mr == 1) 1045 hipz_acl |= 0x00000001; 1046 ··· 1063 /* successful registration */ 1064 e_mr->num_kpages = pginfo->num_kpages; 1065 e_mr->num_hwpages = pginfo->num_hwpages; 1066 e_mr->start = iova_start; 1067 e_mr->size = size; 1068 e_mr->acl = acl; ··· 1106 u32 i; 1107 u64 *kpage; 1108 1109 kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 1110 if (!kpage) { 1111 ehca_err(&shca->ib_device, "kpage alloc failed"); ··· 1116 goto ehca_reg_mr_rpages_exit0; 1117 } 1118 1119 - /* max 512 pages per shot */ 1120 for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) { 1121 1122 if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { ··· 1129 ret = ehca_set_pagebuf(pginfo, rnum, kpage); 1130 if (ret) { 1131 ehca_err(&shca->ib_device, "ehca_set_pagebuf " 1132 - "bad rc, ret=%x rnum=%x kpage=%p", 1133 - ret, rnum, kpage); 1134 goto ehca_reg_mr_rpages_exit1; 1135 } 1136 ··· 1145 } else 1146 rpage = *kpage; 1147 1148 - h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, e_mr, 1149 - 0, /* pagesize 4k */ 1150 - 0, rpage, rnum); 1151 1152 if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { 1153 /* ··· 1212 struct ehca_mr_hipzout_parms hipzout; 1213 1214 ehca_mrmw_map_acl(acl, &hipz_acl); 1215 - ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1216 1217 kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 1218 if (!kpage) { ··· 1263 */ 1264 e_mr->num_kpages = pginfo->num_kpages; 1265 e_mr->num_hwpages = pginfo->num_hwpages; 1266 e_mr->start = iova_start; 1267 e_mr->size = size; 1268 e_mr->acl = acl; ··· 1350 1351 /* set some MR values */ 1352 e_mr->flags = save_mr.flags; 1353 e_mr->fmr_page_size = save_mr.fmr_page_size; 1354 e_mr->fmr_max_pages = save_mr.fmr_max_pages; 1355 e_mr->fmr_max_maps = save_mr.fmr_max_maps; 1356 e_mr->fmr_map_cnt = save_mr.fmr_map_cnt; 1357 1358 ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl, 1359 - e_pd, pginfo, lkey, rkey); 1360 if (ret) { 1361 u32 offset = (u64)(&e_mr->flags) - (u64)e_mr; 1362 memcpy(&e_mr->flags, &(save_mr.flags), ··· 1438 1439 /* set some MR values */ 1440 e_fmr->flags = save_fmr.flags; 1441 e_fmr->fmr_page_size = save_fmr.fmr_page_size; 1442 e_fmr->fmr_max_pages = save_fmr.fmr_max_pages; 1443 e_fmr->fmr_max_maps = save_fmr.fmr_max_maps; ··· 1447 1448 memset(&pginfo, 0, sizeof(pginfo)); 1449 pginfo.type = EHCA_MR_PGI_FMR; 1450 - pginfo.num_kpages = 0; 1451 - pginfo.num_hwpages = 0; 1452 ret = ehca_reg_mr(shca, e_fmr, NULL, 1453 (e_fmr->fmr_max_pages * e_fmr->fmr_page_size), 1454 e_fmr->acl, e_pd, &pginfo, &tmp_lkey, ··· 1455 u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr; 1456 memcpy(&e_fmr->flags, &(save_mr.flags), 1457 sizeof(struct ehca_mr) - offset); 1458 - goto ehca_unmap_one_fmr_exit0; 1459 } 1460 1461 ehca_unmap_one_fmr_exit0: ··· 1482 struct ehca_mr_hipzout_parms hipzout; 1483 1484 ehca_mrmw_map_acl(acl, &hipz_acl); 1485 - ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1486 1487 h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, 1488 (u64)iova_start, hipz_acl, e_pd->fw_pd, ··· 1501 /* successful registration */ 1502 e_newmr->num_kpages = e_origmr->num_kpages; 1503 e_newmr->num_hwpages = e_origmr->num_hwpages; 1504 e_newmr->start = iova_start; 1505 e_newmr->size = e_origmr->size; 1506 e_newmr->acl = acl; ··· 1534 struct ib_phys_buf ib_pbuf; 1535 u32 num_kpages; 1536 u32 num_hwpages; 1537 1538 e_mr = ehca_mr_new(); 1539 if (!e_mr) { ··· 1551 ib_pbuf.size = size_maxmr; 1552 num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr, 1553 PAGE_SIZE); 1554 - num_hwpages = NUM_CHUNKS(((u64)iova_start % EHCA_PAGESIZE) + size_maxmr, 1555 - EHCA_PAGESIZE); 1556 1557 memset(&pginfo, 0, sizeof(pginfo)); 1558 pginfo.type = EHCA_MR_PGI_PHYS; 1559 pginfo.num_kpages = num_kpages; 1560 pginfo.num_hwpages = num_hwpages; 1561 pginfo.u.phy.num_phys_buf = 1; 1562 pginfo.u.phy.phys_buf_array = &ib_pbuf; 1563 ··· 1608 struct ehca_mr_hipzout_parms hipzout; 1609 1610 ehca_mrmw_map_acl(acl, &hipz_acl); 1611 - ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1612 1613 h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, 1614 (u64)iova_start, hipz_acl, e_pd->fw_pd, ··· 1624 /* successful registration */ 1625 e_newmr->num_kpages = e_origmr->num_kpages; 1626 e_newmr->num_hwpages = e_origmr->num_hwpages; 1627 e_newmr->start = iova_start; 1628 e_newmr->size = e_origmr->size; 1629 e_newmr->acl = acl; ··· 1770 u64 pgaddr; 1771 u32 i = 0; 1772 u32 j = 0; 1773 1774 /* loop over desired chunk entries */ 1775 chunk = pginfo->u.usr.next_chunk; ··· 1782 << PAGE_SHIFT ; 1783 *kpage = phys_to_abs(pgaddr + 1784 (pginfo->next_hwpage * 1785 - EHCA_PAGESIZE)); 1786 if ( !(*kpage) ) { 1787 ehca_gen_err("pgaddr=%lx " 1788 "chunk->page_list[i]=%lx " ··· 1795 (pginfo->hwpage_cnt)++; 1796 (pginfo->next_hwpage)++; 1797 kpage++; 1798 - if (pginfo->next_hwpage % 1799 - (PAGE_SIZE / EHCA_PAGESIZE) == 0) { 1800 (pginfo->kpage_cnt)++; 1801 (pginfo->u.usr.next_nmap)++; 1802 pginfo->next_hwpage = 0; 1803 i++; 1804 } 1805 j++; 1806 if (j >= number) break; 1807 } ··· 1973 /* loop over desired phys_buf_array entries */ 1974 while (i < number) { 1975 pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf; 1976 - num_hw = NUM_CHUNKS((pbuf->addr % EHCA_PAGESIZE) + 1977 - pbuf->size, EHCA_PAGESIZE); 1978 - offs_hw = (pbuf->addr & ~PAGE_MASK) / EHCA_PAGESIZE; 1979 while (pginfo->next_hwpage < offs_hw + num_hw) { 1980 /* sanity check */ 1981 if ((pginfo->kpage_cnt >= pginfo->num_kpages) || ··· 1992 return -EFAULT; 1993 } 1994 *kpage = phys_to_abs( 1995 - (pbuf->addr & EHCA_PAGEMASK) 1996 - + (pginfo->next_hwpage * EHCA_PAGESIZE)); 1997 if ( !(*kpage) && pbuf->addr ) { 1998 - ehca_gen_err("pbuf->addr=%lx " 1999 - "pbuf->size=%lx " 2000 "next_hwpage=%lx", pbuf->addr, 2001 - pbuf->size, 2002 - pginfo->next_hwpage); 2003 return -EFAULT; 2004 } 2005 (pginfo->hwpage_cnt)++; 2006 (pginfo->next_hwpage)++; 2007 - if (pginfo->next_hwpage % 2008 - (PAGE_SIZE / EHCA_PAGESIZE) == 0) 2009 - (pginfo->kpage_cnt)++; 2010 kpage++; 2011 i++; 2012 if (i >= number) break; ··· 2032 /* loop over desired page_list entries */ 2033 fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem; 2034 for (i = 0; i < number; i++) { 2035 - *kpage = phys_to_abs((*fmrlist & EHCA_PAGEMASK) + 2036 - pginfo->next_hwpage * EHCA_PAGESIZE); 2037 if ( !(*kpage) ) { 2038 ehca_gen_err("*fmrlist=%lx fmrlist=%p " 2039 "next_listelem=%lx next_hwpage=%lx", ··· 2043 return -EFAULT; 2044 } 2045 (pginfo->hwpage_cnt)++; 2046 - (pginfo->next_hwpage)++; 2047 - kpage++; 2048 - if (pginfo->next_hwpage % 2049 - (pginfo->u.fmr.fmr_pgsize / EHCA_PAGESIZE) == 0) { 2050 - (pginfo->kpage_cnt)++; 2051 - (pginfo->u.fmr.next_listelem)++; 2052 - fmrlist++; 2053 - pginfo->next_hwpage = 0; 2054 } 2055 } 2056 return ret; 2057 } ··· 2091 ret = ehca_set_pagebuf_phys(pginfo, number, kpage); 2092 break; 2093 case EHCA_MR_PGI_USER: 2094 - ret = ehca_set_pagebuf_user1(pginfo, number, kpage); 2095 break; 2096 case EHCA_MR_PGI_FMR: 2097 ret = ehca_set_pagebuf_fmr(pginfo, number, kpage); ··· 2146 /*----------------------------------------------------------------------*/ 2147 2148 /* sets page size in hipz access control for MR/MW. */ 2149 - void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl) /*INOUT*/ 2150 { 2151 - return; /* HCA supports only 4k */ 2152 } /* end ehca_mrmw_set_pgsize_hipz_acl() */ 2153 2154 /*----------------------------------------------------------------------*/
··· 5 * 6 * Authors: Dietmar Decker <ddecker@de.ibm.com> 7 * Christoph Raisch <raisch@de.ibm.com> 8 + * Hoang-Nam Nguyen <hnguyen@de.ibm.com> 9 * 10 * Copyright (c) 2005 IBM Corporation 11 * ··· 55 56 static struct kmem_cache *mr_cache; 57 static struct kmem_cache *mw_cache; 58 + 59 + enum ehca_mr_pgsize { 60 + EHCA_MR_PGSIZE4K = 0x1000L, 61 + EHCA_MR_PGSIZE64K = 0x10000L, 62 + EHCA_MR_PGSIZE1M = 0x100000L, 63 + EHCA_MR_PGSIZE16M = 0x1000000L 64 + }; 65 + 66 + extern int ehca_mr_largepage; 67 + 68 + static u32 ehca_encode_hwpage_size(u32 pgsize) 69 + { 70 + u32 idx = 0; 71 + pgsize >>= 12; 72 + /* 73 + * map mr page size into hw code: 74 + * 0, 1, 2, 3 for 4K, 64K, 1M, 64M 75 + */ 76 + while (!(pgsize & 1)) { 77 + idx++; 78 + pgsize >>= 4; 79 + } 80 + return idx; 81 + } 82 + 83 + static u64 ehca_get_max_hwpage_size(struct ehca_shca *shca) 84 + { 85 + if (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M) 86 + return EHCA_MR_PGSIZE16M; 87 + return EHCA_MR_PGSIZE4K; 88 + } 89 90 static struct ehca_mr *ehca_mr_new(void) 91 { ··· 207 struct ehca_mr_pginfo pginfo; 208 u32 num_kpages; 209 u32 num_hwpages; 210 + u64 hw_pgsize; 211 212 num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size, 213 PAGE_SIZE); 214 + /* for kernel space we try most possible pgsize */ 215 + hw_pgsize = ehca_get_max_hwpage_size(shca); 216 + num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size, 217 + hw_pgsize); 218 memset(&pginfo, 0, sizeof(pginfo)); 219 pginfo.type = EHCA_MR_PGI_PHYS; 220 pginfo.num_kpages = num_kpages; 221 + pginfo.hwpage_size = hw_pgsize; 222 pginfo.num_hwpages = num_hwpages; 223 pginfo.u.phy.num_phys_buf = num_phys_buf; 224 pginfo.u.phy.phys_buf_array = phys_buf_array; 225 + pginfo.next_hwpage = 226 + ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize; 227 228 ret = ehca_reg_mr(shca, e_mr, iova_start, size, mr_access_flags, 229 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, ··· 259 int ret; 260 u32 num_kpages; 261 u32 num_hwpages; 262 + u64 hwpage_size; 263 264 if (!pd) { 265 ehca_gen_err("bad pd=%p", pd); ··· 309 310 /* determine number of MR pages */ 311 num_kpages = NUM_CHUNKS((virt % PAGE_SIZE) + length, PAGE_SIZE); 312 + /* select proper hw_pgsize */ 313 + if (ehca_mr_largepage && 314 + (shca->hca_cap_mr_pgsize & HCA_CAP_MR_PGSIZE_16M)) { 315 + if (length <= EHCA_MR_PGSIZE4K 316 + && PAGE_SIZE == EHCA_MR_PGSIZE4K) 317 + hwpage_size = EHCA_MR_PGSIZE4K; 318 + else if (length <= EHCA_MR_PGSIZE64K) 319 + hwpage_size = EHCA_MR_PGSIZE64K; 320 + else if (length <= EHCA_MR_PGSIZE1M) 321 + hwpage_size = EHCA_MR_PGSIZE1M; 322 + else 323 + hwpage_size = EHCA_MR_PGSIZE16M; 324 + } else 325 + hwpage_size = EHCA_MR_PGSIZE4K; 326 + ehca_dbg(pd->device, "hwpage_size=%lx", hwpage_size); 327 328 + reg_user_mr_fallback: 329 + num_hwpages = NUM_CHUNKS((virt % hwpage_size) + length, hwpage_size); 330 /* register MR on HCA */ 331 memset(&pginfo, 0, sizeof(pginfo)); 332 pginfo.type = EHCA_MR_PGI_USER; 333 + pginfo.hwpage_size = hwpage_size; 334 pginfo.num_kpages = num_kpages; 335 pginfo.num_hwpages = num_hwpages; 336 pginfo.u.usr.region = e_mr->umem; 337 + pginfo.next_hwpage = e_mr->umem->offset / hwpage_size; 338 pginfo.u.usr.next_chunk = list_prepare_entry(pginfo.u.usr.next_chunk, 339 (&e_mr->umem->chunk_list), 340 list); ··· 326 ret = ehca_reg_mr(shca, e_mr, (u64 *)virt, length, mr_access_flags, 327 e_pd, &pginfo, &e_mr->ib.ib_mr.lkey, 328 &e_mr->ib.ib_mr.rkey); 329 + if (ret == -EINVAL && pginfo.hwpage_size > PAGE_SIZE) { 330 + ehca_warn(pd->device, "failed to register mr " 331 + "with hwpage_size=%lx", hwpage_size); 332 + ehca_info(pd->device, "try to register mr with " 333 + "kpage_size=%lx", PAGE_SIZE); 334 + /* 335 + * this means kpages are not contiguous for a hw page 336 + * try kernel page size as fallback solution 337 + */ 338 + hwpage_size = PAGE_SIZE; 339 + goto reg_user_mr_fallback; 340 + } 341 if (ret) { 342 ib_mr = ERR_PTR(ret); 343 goto reg_user_mr_exit2; ··· 452 new_pd = container_of(mr->pd, struct ehca_pd, ib_pd); 453 454 if (mr_rereg_mask & IB_MR_REREG_TRANS) { 455 + u64 hw_pgsize = ehca_get_max_hwpage_size(shca); 456 + 457 new_start = iova_start; /* change address */ 458 /* check physical buffer list and calculate size */ 459 ret = ehca_mr_chk_buf_and_calc_size(phys_buf_array, ··· 468 } 469 num_kpages = NUM_CHUNKS(((u64)new_start % PAGE_SIZE) + 470 new_size, PAGE_SIZE); 471 + num_hwpages = NUM_CHUNKS(((u64)new_start % hw_pgsize) + 472 + new_size, hw_pgsize); 473 memset(&pginfo, 0, sizeof(pginfo)); 474 pginfo.type = EHCA_MR_PGI_PHYS; 475 pginfo.num_kpages = num_kpages; 476 + pginfo.hwpage_size = hw_pgsize; 477 pginfo.num_hwpages = num_hwpages; 478 pginfo.u.phy.num_phys_buf = num_phys_buf; 479 pginfo.u.phy.phys_buf_array = phys_buf_array; 480 + pginfo.next_hwpage = 481 + ((u64)iova_start & ~(hw_pgsize - 1)) / hw_pgsize; 482 } 483 if (mr_rereg_mask & IB_MR_REREG_ACCESS) 484 new_acl = mr_access_flags; ··· 709 int ret; 710 u32 tmp_lkey, tmp_rkey; 711 struct ehca_mr_pginfo pginfo; 712 + u64 hw_pgsize; 713 714 /* check other parameters */ 715 if (((mr_access_flags & IB_ACCESS_REMOTE_WRITE) && ··· 738 ib_fmr = ERR_PTR(-EINVAL); 739 goto alloc_fmr_exit0; 740 } 741 + hw_pgsize = ehca_get_max_hwpage_size(shca); 742 + if ((1 << fmr_attr->page_shift) != hw_pgsize) { 743 ehca_err(pd->device, "unsupported fmr_attr->page_shift=%x", 744 fmr_attr->page_shift); 745 ib_fmr = ERR_PTR(-EINVAL); ··· 755 756 /* register MR on HCA */ 757 memset(&pginfo, 0, sizeof(pginfo)); 758 + /* 759 + * pginfo.num_hwpages==0, ie register_rpages() will not be called 760 + * but deferred to map_phys_fmr() 761 + */ 762 ret = ehca_reg_mr(shca, e_fmr, NULL, 763 fmr_attr->max_pages * (1 << fmr_attr->page_shift), 764 mr_access_flags, e_pd, &pginfo, ··· 765 } 766 767 /* successful */ 768 + e_fmr->hwpage_size = hw_pgsize; 769 e_fmr->fmr_page_size = 1 << fmr_attr->page_shift; 770 e_fmr->fmr_max_pages = fmr_attr->max_pages; 771 e_fmr->fmr_max_maps = fmr_attr->max_maps; ··· 822 memset(&pginfo, 0, sizeof(pginfo)); 823 pginfo.type = EHCA_MR_PGI_FMR; 824 pginfo.num_kpages = list_len; 825 + pginfo.hwpage_size = e_fmr->hwpage_size; 826 + pginfo.num_hwpages = 827 + list_len * e_fmr->fmr_page_size / pginfo.hwpage_size; 828 pginfo.u.fmr.page_list = page_list; 829 + pginfo.next_hwpage = 830 + (iova & (e_fmr->fmr_page_size-1)) / pginfo.hwpage_size; 831 pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size; 832 833 ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova, ··· 964 struct ehca_mr_hipzout_parms hipzout; 965 966 ehca_mrmw_map_acl(acl, &hipz_acl); 967 + ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl); 968 if (ehca_use_hp_mr == 1) 969 hipz_acl |= 0x00000001; 970 ··· 987 /* successful registration */ 988 e_mr->num_kpages = pginfo->num_kpages; 989 e_mr->num_hwpages = pginfo->num_hwpages; 990 + e_mr->hwpage_size = pginfo->hwpage_size; 991 e_mr->start = iova_start; 992 e_mr->size = size; 993 e_mr->acl = acl; ··· 1029 u32 i; 1030 u64 *kpage; 1031 1032 + if (!pginfo->num_hwpages) /* in case of fmr */ 1033 + return 0; 1034 + 1035 kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 1036 if (!kpage) { 1037 ehca_err(&shca->ib_device, "kpage alloc failed"); ··· 1036 goto ehca_reg_mr_rpages_exit0; 1037 } 1038 1039 + /* max MAX_RPAGES ehca mr pages per register call */ 1040 for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) { 1041 1042 if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { ··· 1049 ret = ehca_set_pagebuf(pginfo, rnum, kpage); 1050 if (ret) { 1051 ehca_err(&shca->ib_device, "ehca_set_pagebuf " 1052 + "bad rc, ret=%x rnum=%x kpage=%p", 1053 + ret, rnum, kpage); 1054 goto ehca_reg_mr_rpages_exit1; 1055 } 1056 ··· 1065 } else 1066 rpage = *kpage; 1067 1068 + h_ret = hipz_h_register_rpage_mr( 1069 + shca->ipz_hca_handle, e_mr, 1070 + ehca_encode_hwpage_size(pginfo->hwpage_size), 1071 + 0, rpage, rnum); 1072 1073 if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) { 1074 /* ··· 1131 struct ehca_mr_hipzout_parms hipzout; 1132 1133 ehca_mrmw_map_acl(acl, &hipz_acl); 1134 + ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl); 1135 1136 kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL); 1137 if (!kpage) { ··· 1182 */ 1183 e_mr->num_kpages = pginfo->num_kpages; 1184 e_mr->num_hwpages = pginfo->num_hwpages; 1185 + e_mr->hwpage_size = pginfo->hwpage_size; 1186 e_mr->start = iova_start; 1187 e_mr->size = size; 1188 e_mr->acl = acl; ··· 1268 1269 /* set some MR values */ 1270 e_mr->flags = save_mr.flags; 1271 + e_mr->hwpage_size = save_mr.hwpage_size; 1272 e_mr->fmr_page_size = save_mr.fmr_page_size; 1273 e_mr->fmr_max_pages = save_mr.fmr_max_pages; 1274 e_mr->fmr_max_maps = save_mr.fmr_max_maps; 1275 e_mr->fmr_map_cnt = save_mr.fmr_map_cnt; 1276 1277 ret = ehca_reg_mr(shca, e_mr, iova_start, size, acl, 1278 + e_pd, pginfo, lkey, rkey); 1279 if (ret) { 1280 u32 offset = (u64)(&e_mr->flags) - (u64)e_mr; 1281 memcpy(&e_mr->flags, &(save_mr.flags), ··· 1355 1356 /* set some MR values */ 1357 e_fmr->flags = save_fmr.flags; 1358 + e_fmr->hwpage_size = save_fmr.hwpage_size; 1359 e_fmr->fmr_page_size = save_fmr.fmr_page_size; 1360 e_fmr->fmr_max_pages = save_fmr.fmr_max_pages; 1361 e_fmr->fmr_max_maps = save_fmr.fmr_max_maps; ··· 1363 1364 memset(&pginfo, 0, sizeof(pginfo)); 1365 pginfo.type = EHCA_MR_PGI_FMR; 1366 ret = ehca_reg_mr(shca, e_fmr, NULL, 1367 (e_fmr->fmr_max_pages * e_fmr->fmr_page_size), 1368 e_fmr->acl, e_pd, &pginfo, &tmp_lkey, ··· 1373 u32 offset = (u64)(&e_fmr->flags) - (u64)e_fmr; 1374 memcpy(&e_fmr->flags, &(save_mr.flags), 1375 sizeof(struct ehca_mr) - offset); 1376 } 1377 1378 ehca_unmap_one_fmr_exit0: ··· 1401 struct ehca_mr_hipzout_parms hipzout; 1402 1403 ehca_mrmw_map_acl(acl, &hipz_acl); 1404 + ehca_mrmw_set_pgsize_hipz_acl(e_origmr->hwpage_size, &hipz_acl); 1405 1406 h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, 1407 (u64)iova_start, hipz_acl, e_pd->fw_pd, ··· 1420 /* successful registration */ 1421 e_newmr->num_kpages = e_origmr->num_kpages; 1422 e_newmr->num_hwpages = e_origmr->num_hwpages; 1423 + e_newmr->hwpage_size = e_origmr->hwpage_size; 1424 e_newmr->start = iova_start; 1425 e_newmr->size = e_origmr->size; 1426 e_newmr->acl = acl; ··· 1452 struct ib_phys_buf ib_pbuf; 1453 u32 num_kpages; 1454 u32 num_hwpages; 1455 + u64 hw_pgsize; 1456 1457 e_mr = ehca_mr_new(); 1458 if (!e_mr) { ··· 1468 ib_pbuf.size = size_maxmr; 1469 num_kpages = NUM_CHUNKS(((u64)iova_start % PAGE_SIZE) + size_maxmr, 1470 PAGE_SIZE); 1471 + hw_pgsize = ehca_get_max_hwpage_size(shca); 1472 + num_hwpages = NUM_CHUNKS(((u64)iova_start % hw_pgsize) + size_maxmr, 1473 + hw_pgsize); 1474 1475 memset(&pginfo, 0, sizeof(pginfo)); 1476 pginfo.type = EHCA_MR_PGI_PHYS; 1477 pginfo.num_kpages = num_kpages; 1478 pginfo.num_hwpages = num_hwpages; 1479 + pginfo.hwpage_size = hw_pgsize; 1480 pginfo.u.phy.num_phys_buf = 1; 1481 pginfo.u.phy.phys_buf_array = &ib_pbuf; 1482 ··· 1523 struct ehca_mr_hipzout_parms hipzout; 1524 1525 ehca_mrmw_map_acl(acl, &hipz_acl); 1526 + ehca_mrmw_set_pgsize_hipz_acl(e_origmr->hwpage_size, &hipz_acl); 1527 1528 h_ret = hipz_h_register_smr(shca->ipz_hca_handle, e_newmr, e_origmr, 1529 (u64)iova_start, hipz_acl, e_pd->fw_pd, ··· 1539 /* successful registration */ 1540 e_newmr->num_kpages = e_origmr->num_kpages; 1541 e_newmr->num_hwpages = e_origmr->num_hwpages; 1542 + e_newmr->hwpage_size = e_origmr->hwpage_size; 1543 e_newmr->start = iova_start; 1544 e_newmr->size = e_origmr->size; 1545 e_newmr->acl = acl; ··· 1684 u64 pgaddr; 1685 u32 i = 0; 1686 u32 j = 0; 1687 + int hwpages_per_kpage = PAGE_SIZE / pginfo->hwpage_size; 1688 1689 /* loop over desired chunk entries */ 1690 chunk = pginfo->u.usr.next_chunk; ··· 1695 << PAGE_SHIFT ; 1696 *kpage = phys_to_abs(pgaddr + 1697 (pginfo->next_hwpage * 1698 + pginfo->hwpage_size)); 1699 if ( !(*kpage) ) { 1700 ehca_gen_err("pgaddr=%lx " 1701 "chunk->page_list[i]=%lx " ··· 1708 (pginfo->hwpage_cnt)++; 1709 (pginfo->next_hwpage)++; 1710 kpage++; 1711 + if (pginfo->next_hwpage % hwpages_per_kpage == 0) { 1712 (pginfo->kpage_cnt)++; 1713 (pginfo->u.usr.next_nmap)++; 1714 pginfo->next_hwpage = 0; 1715 i++; 1716 } 1717 + j++; 1718 + if (j >= number) break; 1719 + } 1720 + if ((pginfo->u.usr.next_nmap >= chunk->nmap) && 1721 + (j >= number)) { 1722 + pginfo->u.usr.next_nmap = 0; 1723 + prev_chunk = chunk; 1724 + break; 1725 + } else if (pginfo->u.usr.next_nmap >= chunk->nmap) { 1726 + pginfo->u.usr.next_nmap = 0; 1727 + prev_chunk = chunk; 1728 + } else if (j >= number) 1729 + break; 1730 + else 1731 + prev_chunk = chunk; 1732 + } 1733 + pginfo->u.usr.next_chunk = 1734 + list_prepare_entry(prev_chunk, 1735 + (&(pginfo->u.usr.region->chunk_list)), 1736 + list); 1737 + return ret; 1738 + } 1739 + 1740 + /* 1741 + * check given pages for contiguous layout 1742 + * last page addr is returned in prev_pgaddr for further check 1743 + */ 1744 + static int ehca_check_kpages_per_ate(struct scatterlist *page_list, 1745 + int start_idx, int end_idx, 1746 + u64 *prev_pgaddr) 1747 + { 1748 + int t; 1749 + for (t = start_idx; t <= end_idx; t++) { 1750 + u64 pgaddr = page_to_pfn(page_list[t].page) << PAGE_SHIFT; 1751 + ehca_gen_dbg("chunk_page=%lx value=%016lx", pgaddr, 1752 + *(u64 *)abs_to_virt(phys_to_abs(pgaddr))); 1753 + if (pgaddr - PAGE_SIZE != *prev_pgaddr) { 1754 + ehca_gen_err("uncontiguous page found pgaddr=%lx " 1755 + "prev_pgaddr=%lx page_list_i=%x", 1756 + pgaddr, *prev_pgaddr, t); 1757 + return -EINVAL; 1758 + } 1759 + *prev_pgaddr = pgaddr; 1760 + } 1761 + return 0; 1762 + } 1763 + 1764 + /* PAGE_SIZE < pginfo->hwpage_size */ 1765 + static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, 1766 + u32 number, 1767 + u64 *kpage) 1768 + { 1769 + int ret = 0; 1770 + struct ib_umem_chunk *prev_chunk; 1771 + struct ib_umem_chunk *chunk; 1772 + u64 pgaddr, prev_pgaddr; 1773 + u32 i = 0; 1774 + u32 j = 0; 1775 + int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE; 1776 + int nr_kpages = kpages_per_hwpage; 1777 + 1778 + /* loop over desired chunk entries */ 1779 + chunk = pginfo->u.usr.next_chunk; 1780 + prev_chunk = pginfo->u.usr.next_chunk; 1781 + list_for_each_entry_continue( 1782 + chunk, (&(pginfo->u.usr.region->chunk_list)), list) { 1783 + for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) { 1784 + if (nr_kpages == kpages_per_hwpage) { 1785 + pgaddr = ( page_to_pfn(chunk->page_list[i].page) 1786 + << PAGE_SHIFT ); 1787 + *kpage = phys_to_abs(pgaddr); 1788 + if ( !(*kpage) ) { 1789 + ehca_gen_err("pgaddr=%lx i=%x", 1790 + pgaddr, i); 1791 + ret = -EFAULT; 1792 + return ret; 1793 + } 1794 + /* 1795 + * The first page in a hwpage must be aligned; 1796 + * the first MR page is exempt from this rule. 1797 + */ 1798 + if (pgaddr & (pginfo->hwpage_size - 1)) { 1799 + if (pginfo->hwpage_cnt) { 1800 + ehca_gen_err( 1801 + "invalid alignment " 1802 + "pgaddr=%lx i=%x " 1803 + "mr_pgsize=%lx", 1804 + pgaddr, i, 1805 + pginfo->hwpage_size); 1806 + ret = -EFAULT; 1807 + return ret; 1808 + } 1809 + /* first MR page */ 1810 + pginfo->kpage_cnt = 1811 + (pgaddr & 1812 + (pginfo->hwpage_size - 1)) >> 1813 + PAGE_SHIFT; 1814 + nr_kpages -= pginfo->kpage_cnt; 1815 + *kpage = phys_to_abs( 1816 + pgaddr & 1817 + ~(pginfo->hwpage_size - 1)); 1818 + } 1819 + ehca_gen_dbg("kpage=%lx chunk_page=%lx " 1820 + "value=%016lx", *kpage, pgaddr, 1821 + *(u64 *)abs_to_virt( 1822 + phys_to_abs(pgaddr))); 1823 + prev_pgaddr = pgaddr; 1824 + i++; 1825 + pginfo->kpage_cnt++; 1826 + pginfo->u.usr.next_nmap++; 1827 + nr_kpages--; 1828 + if (!nr_kpages) 1829 + goto next_kpage; 1830 + continue; 1831 + } 1832 + if (i + nr_kpages > chunk->nmap) { 1833 + ret = ehca_check_kpages_per_ate( 1834 + chunk->page_list, i, 1835 + chunk->nmap - 1, &prev_pgaddr); 1836 + if (ret) return ret; 1837 + pginfo->kpage_cnt += chunk->nmap - i; 1838 + pginfo->u.usr.next_nmap += chunk->nmap - i; 1839 + nr_kpages -= chunk->nmap - i; 1840 + break; 1841 + } 1842 + 1843 + ret = ehca_check_kpages_per_ate(chunk->page_list, i, 1844 + i + nr_kpages - 1, 1845 + &prev_pgaddr); 1846 + if (ret) return ret; 1847 + i += nr_kpages; 1848 + pginfo->kpage_cnt += nr_kpages; 1849 + pginfo->u.usr.next_nmap += nr_kpages; 1850 + next_kpage: 1851 + nr_kpages = kpages_per_hwpage; 1852 + (pginfo->hwpage_cnt)++; 1853 + kpage++; 1854 j++; 1855 if (j >= number) break; 1856 } ··· 1750 /* loop over desired phys_buf_array entries */ 1751 while (i < number) { 1752 pbuf = pginfo->u.phy.phys_buf_array + pginfo->u.phy.next_buf; 1753 + num_hw = NUM_CHUNKS((pbuf->addr % pginfo->hwpage_size) + 1754 + pbuf->size, pginfo->hwpage_size); 1755 + offs_hw = (pbuf->addr & ~(pginfo->hwpage_size - 1)) / 1756 + pginfo->hwpage_size; 1757 while (pginfo->next_hwpage < offs_hw + num_hw) { 1758 /* sanity check */ 1759 if ((pginfo->kpage_cnt >= pginfo->num_kpages) || ··· 1768 return -EFAULT; 1769 } 1770 *kpage = phys_to_abs( 1771 + (pbuf->addr & ~(pginfo->hwpage_size - 1)) + 1772 + (pginfo->next_hwpage * pginfo->hwpage_size)); 1773 if ( !(*kpage) && pbuf->addr ) { 1774 + ehca_gen_err("pbuf->addr=%lx pbuf->size=%lx " 1775 "next_hwpage=%lx", pbuf->addr, 1776 + pbuf->size, pginfo->next_hwpage); 1777 return -EFAULT; 1778 } 1779 (pginfo->hwpage_cnt)++; 1780 (pginfo->next_hwpage)++; 1781 + if (PAGE_SIZE >= pginfo->hwpage_size) { 1782 + if (pginfo->next_hwpage % 1783 + (PAGE_SIZE / pginfo->hwpage_size) == 0) 1784 + (pginfo->kpage_cnt)++; 1785 + } else 1786 + pginfo->kpage_cnt += pginfo->hwpage_size / 1787 + PAGE_SIZE; 1788 kpage++; 1789 i++; 1790 if (i >= number) break; ··· 1806 /* loop over desired page_list entries */ 1807 fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem; 1808 for (i = 0; i < number; i++) { 1809 + *kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) + 1810 + pginfo->next_hwpage * pginfo->hwpage_size); 1811 if ( !(*kpage) ) { 1812 ehca_gen_err("*fmrlist=%lx fmrlist=%p " 1813 "next_listelem=%lx next_hwpage=%lx", ··· 1817 return -EFAULT; 1818 } 1819 (pginfo->hwpage_cnt)++; 1820 + if (pginfo->u.fmr.fmr_pgsize >= pginfo->hwpage_size) { 1821 + if (pginfo->next_hwpage % 1822 + (pginfo->u.fmr.fmr_pgsize / 1823 + pginfo->hwpage_size) == 0) { 1824 + (pginfo->kpage_cnt)++; 1825 + (pginfo->u.fmr.next_listelem)++; 1826 + fmrlist++; 1827 + pginfo->next_hwpage = 0; 1828 + } else 1829 + (pginfo->next_hwpage)++; 1830 + } else { 1831 + unsigned int cnt_per_hwpage = pginfo->hwpage_size / 1832 + pginfo->u.fmr.fmr_pgsize; 1833 + unsigned int j; 1834 + u64 prev = *kpage; 1835 + /* check if adrs are contiguous */ 1836 + for (j = 1; j < cnt_per_hwpage; j++) { 1837 + u64 p = phys_to_abs(fmrlist[j] & 1838 + ~(pginfo->hwpage_size - 1)); 1839 + if (prev + pginfo->u.fmr.fmr_pgsize != p) { 1840 + ehca_gen_err("uncontiguous fmr pages " 1841 + "found prev=%lx p=%lx " 1842 + "idx=%x", prev, p, i + j); 1843 + return -EINVAL; 1844 + } 1845 + prev = p; 1846 + } 1847 + pginfo->kpage_cnt += cnt_per_hwpage; 1848 + pginfo->u.fmr.next_listelem += cnt_per_hwpage; 1849 + fmrlist += cnt_per_hwpage; 1850 } 1851 + kpage++; 1852 } 1853 return ret; 1854 } ··· 1842 ret = ehca_set_pagebuf_phys(pginfo, number, kpage); 1843 break; 1844 case EHCA_MR_PGI_USER: 1845 + ret = PAGE_SIZE >= pginfo->hwpage_size ? 1846 + ehca_set_pagebuf_user1(pginfo, number, kpage) : 1847 + ehca_set_pagebuf_user2(pginfo, number, kpage); 1848 break; 1849 case EHCA_MR_PGI_FMR: 1850 ret = ehca_set_pagebuf_fmr(pginfo, number, kpage); ··· 1895 /*----------------------------------------------------------------------*/ 1896 1897 /* sets page size in hipz access control for MR/MW. */ 1898 + void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl) /*INOUT*/ 1899 { 1900 + *hipz_acl |= (ehca_encode_hwpage_size(pgsize) << 24); 1901 } /* end ehca_mrmw_set_pgsize_hipz_acl() */ 1902 1903 /*----------------------------------------------------------------------*/
+1 -1
drivers/infiniband/hw/ehca/ehca_mrmw.h
··· 111 void ehca_mrmw_map_acl(int ib_acl, 112 u32 *hipz_acl); 113 114 - void ehca_mrmw_set_pgsize_hipz_acl(u32 *hipz_acl); 115 116 void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl, 117 int *ib_acl);
··· 111 void ehca_mrmw_map_acl(int ib_acl, 112 u32 *hipz_acl); 113 114 + void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl); 115 116 void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl, 117 int *ib_acl);
+19 -1
drivers/infiniband/hw/ehca/hcp_if.c
··· 427 { 428 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES, 429 adapter_handle.handle, /* r4 */ 430 - queue_type | pagesize << 8, /* r5 */ 431 resource_handle, /* r6 */ 432 logical_address_of_page, /* r7 */ 433 count, /* r8 */ ··· 725 u64 ret; 726 u64 outs[PLPAR_HCALL9_BUFSIZE]; 727 728 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, 729 adapter_handle.handle, /* r4 */ 730 5, /* r5 */ ··· 750 const u64 logical_address_of_page, 751 const u64 count) 752 { 753 u64 ret; 754 755 if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) { 756 ehca_gen_err("logical_address_of_page not on a 4k boundary "
··· 427 { 428 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES, 429 adapter_handle.handle, /* r4 */ 430 + (u64)queue_type | ((u64)pagesize) << 8, 431 + /* r5 */ 432 resource_handle, /* r6 */ 433 logical_address_of_page, /* r7 */ 434 count, /* r8 */ ··· 724 u64 ret; 725 u64 outs[PLPAR_HCALL9_BUFSIZE]; 726 727 + ehca_gen_dbg("kernel PAGE_SIZE=%x access_ctrl=%016x " 728 + "vaddr=%lx length=%lx", 729 + (u32)PAGE_SIZE, access_ctrl, vaddr, length); 730 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs, 731 adapter_handle.handle, /* r4 */ 732 5, /* r5 */ ··· 746 const u64 logical_address_of_page, 747 const u64 count) 748 { 749 + extern int ehca_debug_level; 750 u64 ret; 751 + 752 + if (unlikely(ehca_debug_level >= 2)) { 753 + if (count > 1) { 754 + u64 *kpage; 755 + int i; 756 + kpage = (u64 *)abs_to_virt(logical_address_of_page); 757 + for (i = 0; i < count; i++) 758 + ehca_gen_dbg("kpage[%d]=%p", 759 + i, (void *)kpage[i]); 760 + } else 761 + ehca_gen_dbg("kpage=%p", 762 + (void *)logical_address_of_page); 763 + } 764 765 if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) { 766 ehca_gen_err("logical_address_of_page not on a 4k boundary "