IB/ehca: Assure 4K alignment for firmware control blocks

Assure 4K alignment for firmware control blocks in 64K page mode,
because kzalloc()'s result address might not be 4K aligned if 64K
pages are enabled. Thus, we introduce wrappers called
ehca_{alloc,free}_fw_ctrlblock(), which use a slab cache for objects
with 4K length and 4K alignment in order to alloc/free firmware
control blocks in 64K page mode. In 4K page mode those wrappers just
are defines of get_zeroed_page() and free_page().

Signed-off-by: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by Hoang-Nam Nguyen and committed by Roland Dreier 7e28db5d 40eb0066

+81 -35
+9 -8
drivers/infiniband/hw/ehca/ehca_hca.c
··· 40 40 */ 41 41 42 42 #include "ehca_tools.h" 43 + #include "ehca_iverbs.h" 43 44 #include "hcp_if.h" 44 45 45 46 int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) ··· 50 49 ib_device); 51 50 struct hipz_query_hca *rblock; 52 51 53 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 52 + rblock = ehca_alloc_fw_ctrlblock(); 54 53 if (!rblock) { 55 54 ehca_err(&shca->ib_device, "Can't allocate rblock memory."); 56 55 return -ENOMEM; ··· 97 96 = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); 98 97 99 98 query_device1: 100 - kfree(rblock); 99 + ehca_free_fw_ctrlblock(rblock); 101 100 102 101 return ret; 103 102 } ··· 110 109 ib_device); 111 110 struct hipz_query_port *rblock; 112 111 113 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 112 + rblock = ehca_alloc_fw_ctrlblock(); 114 113 if (!rblock) { 115 114 ehca_err(&shca->ib_device, "Can't allocate rblock memory."); 116 115 return -ENOMEM; ··· 163 162 props->active_speed = 0x1; 164 163 165 164 query_port1: 166 - kfree(rblock); 165 + ehca_free_fw_ctrlblock(rblock); 167 166 168 167 return ret; 169 168 } ··· 179 178 return -EINVAL; 180 179 } 181 180 182 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 181 + rblock = ehca_alloc_fw_ctrlblock(); 183 182 if (!rblock) { 184 183 ehca_err(&shca->ib_device, "Can't allocate rblock memory."); 185 184 return -ENOMEM; ··· 194 193 memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); 195 194 196 195 query_pkey1: 197 - kfree(rblock); 196 + ehca_free_fw_ctrlblock(rblock); 198 197 199 198 return ret; 200 199 } ··· 212 211 return -EINVAL; 213 212 } 214 213 215 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 214 + rblock = ehca_alloc_fw_ctrlblock(); 216 215 if (!rblock) { 217 216 ehca_err(&shca->ib_device, "Can't allocate rblock memory."); 218 217 return -ENOMEM; ··· 228 227 memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); 229 228 230 229 query_gid1: 231 - kfree(rblock); 230 + ehca_free_fw_ctrlblock(rblock); 232 231 233 232 return ret; 234 233 }
+8 -9
drivers/infiniband/hw/ehca/ehca_irq.c
··· 45 45 #include "ehca_tools.h" 46 46 #include "hcp_if.h" 47 47 #include "hipz_fns.h" 48 + #include "ipz_pt_fn.h" 48 49 49 50 #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) 50 51 #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) ··· 138 137 u64 *rblock; 139 138 unsigned long block_count; 140 139 141 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 140 + rblock = ehca_alloc_fw_ctrlblock(); 142 141 if (!rblock) { 143 142 ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); 144 143 ret = -ENOMEM; 145 144 goto error_data1; 146 145 } 147 146 147 + /* rblock must be 4K aligned and should be 4K large */ 148 148 ret = hipz_h_error_data(shca->ipz_hca_handle, 149 149 resource, 150 150 rblock, 151 151 &block_count); 152 152 153 - if (ret == H_R_STATE) { 153 + if (ret == H_R_STATE) 154 154 ehca_err(&shca->ib_device, 155 155 "No error data is available: %lx.", resource); 156 - } 157 156 else if (ret == H_SUCCESS) { 158 157 int length; 159 158 160 159 length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); 161 160 162 - if (length > PAGE_SIZE) 163 - length = PAGE_SIZE; 161 + if (length > EHCA_PAGESIZE) 162 + length = EHCA_PAGESIZE; 164 163 165 164 print_error_data(shca, data, rblock, length); 166 - } 167 - else { 165 + } else 168 166 ehca_err(&shca->ib_device, 169 167 "Error data could not be fetched: %lx", resource); 170 - } 171 168 172 - kfree(rblock); 169 + ehca_free_fw_ctrlblock(rblock); 173 170 174 171 error_data1: 175 172 return ret;
+8
drivers/infiniband/hw/ehca/ehca_iverbs.h
··· 179 179 180 180 int ehca_munmap(unsigned long addr, size_t len); 181 181 182 + #ifdef CONFIG_PPC_64K_PAGES 183 + void *ehca_alloc_fw_ctrlblock(void); 184 + void ehca_free_fw_ctrlblock(void *ptr); 185 + #else 186 + #define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL)) 187 + #define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) 188 + #endif 189 + 182 190 #endif
+47 -9
drivers/infiniband/hw/ehca/ehca_main.c
··· 40 40 * POSSIBILITY OF SUCH DAMAGE. 41 41 */ 42 42 43 + #ifdef CONFIG_PPC_64K_PAGES 44 + #include <linux/slab.h> 45 + #endif 43 46 #include "ehca_classes.h" 44 47 #include "ehca_iverbs.h" 45 48 #include "ehca_mrmw.h" ··· 52 49 MODULE_LICENSE("Dual BSD/GPL"); 53 50 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); 54 51 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); 55 - MODULE_VERSION("SVNEHCA_0017"); 52 + MODULE_VERSION("SVNEHCA_0018"); 56 53 57 54 int ehca_open_aqp1 = 0; 58 55 int ehca_debug_level = 0; ··· 97 94 DEFINE_IDR(ehca_qp_idr); 98 95 DEFINE_IDR(ehca_cq_idr); 99 96 97 + 100 98 static struct list_head shca_list; /* list of all registered ehcas */ 101 99 static spinlock_t shca_list_lock; 102 100 103 101 static struct timer_list poll_eqs_timer; 102 + 103 + #ifdef CONFIG_PPC_64K_PAGES 104 + static struct kmem_cache *ctblk_cache = NULL; 105 + 106 + void *ehca_alloc_fw_ctrlblock(void) 107 + { 108 + void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL); 109 + if (!ret) 110 + ehca_gen_err("Out of memory for ctblk"); 111 + return ret; 112 + } 113 + 114 + void ehca_free_fw_ctrlblock(void *ptr) 115 + { 116 + if (ptr) 117 + kmem_cache_free(ctblk_cache, ptr); 118 + 119 + } 120 + #endif 104 121 105 122 static int ehca_create_slab_caches(void) 106 123 { ··· 156 133 goto create_slab_caches5; 157 134 } 158 135 136 + #ifdef CONFIG_PPC_64K_PAGES 137 + ctblk_cache = kmem_cache_create("ehca_cache_ctblk", 138 + EHCA_PAGESIZE, H_CB_ALIGNMENT, 139 + SLAB_HWCACHE_ALIGN, 140 + NULL, NULL); 141 + if (!ctblk_cache) { 142 + ehca_gen_err("Cannot create ctblk SLAB cache."); 143 + ehca_cleanup_mrmw_cache(); 144 + goto create_slab_caches5; 145 + } 146 + #endif 159 147 return 0; 160 148 161 149 create_slab_caches5: ··· 191 157 ehca_cleanup_qp_cache(); 192 158 ehca_cleanup_cq_cache(); 193 159 ehca_cleanup_pd_cache(); 160 + #ifdef CONFIG_PPC_64K_PAGES 161 + if (ctblk_cache) 162 + kmem_cache_destroy(ctblk_cache); 163 + #endif 194 164 } 195 165 196 166 #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) ··· 206 168 u64 h_ret; 207 169 struct hipz_query_hca *rblock; 208 170 209 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 171 + rblock = ehca_alloc_fw_ctrlblock(); 210 172 if (!rblock) { 211 173 ehca_gen_err("Cannot allocate rblock memory."); 212 174 return -ENOMEM; ··· 249 211 shca->sport[1].rate = IB_RATE_30_GBPS; 250 212 251 213 num_ports1: 252 - kfree(rblock); 214 + ehca_free_fw_ctrlblock(rblock); 253 215 return ret; 254 216 } 255 217 ··· 258 220 int ret = 0; 259 221 struct hipz_query_hca *rblock; 260 222 261 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 223 + rblock = ehca_alloc_fw_ctrlblock(); 262 224 if (!rblock) { 263 225 ehca_err(&shca->ib_device, "Can't allocate rblock memory."); 264 226 return -ENOMEM; ··· 273 235 memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); 274 236 275 237 init_node_guid1: 276 - kfree(rblock); 238 + ehca_free_fw_ctrlblock(rblock); 277 239 return ret; 278 240 } 279 241 ··· 469 431 \ 470 432 shca = dev->driver_data; \ 471 433 \ 472 - rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); \ 434 + rblock = ehca_alloc_fw_ctrlblock(); \ 473 435 if (!rblock) { \ 474 436 dev_err(dev, "Can't allocate rblock memory."); \ 475 437 return 0; \ ··· 477 439 \ 478 440 if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ 479 441 dev_err(dev, "Can't query device properties"); \ 480 - kfree(rblock); \ 442 + ehca_free_fw_ctrlblock(rblock); \ 481 443 return 0; \ 482 444 } \ 483 445 \ 484 446 data = rblock->name; \ 485 - kfree(rblock); \ 447 + ehca_free_fw_ctrlblock(rblock); \ 486 448 \ 487 449 if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ 488 450 return snprintf(buf, 256, "1\n"); \ ··· 790 752 int ret; 791 753 792 754 printk(KERN_INFO "eHCA Infiniband Device Driver " 793 - "(Rel.: SVNEHCA_0017)\n"); 755 + "(Rel.: SVNEHCA_0018)\n"); 794 756 idr_init(&ehca_qp_idr); 795 757 idr_init(&ehca_cq_idr); 796 758 spin_lock_init(&ehca_qp_idr_lock);
+4 -4
drivers/infiniband/hw/ehca/ehca_mrmw.c
··· 1013 1013 u32 i; 1014 1014 u64 *kpage; 1015 1015 1016 - kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 1016 + kpage = ehca_alloc_fw_ctrlblock(); 1017 1017 if (!kpage) { 1018 1018 ehca_err(&shca->ib_device, "kpage alloc failed"); 1019 1019 ret = -ENOMEM; ··· 1092 1092 1093 1093 1094 1094 ehca_reg_mr_rpages_exit1: 1095 - kfree(kpage); 1095 + ehca_free_fw_ctrlblock(kpage); 1096 1096 ehca_reg_mr_rpages_exit0: 1097 1097 if (ret) 1098 1098 ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " ··· 1124 1124 ehca_mrmw_map_acl(acl, &hipz_acl); 1125 1125 ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); 1126 1126 1127 - kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 1127 + kpage = ehca_alloc_fw_ctrlblock(); 1128 1128 if (!kpage) { 1129 1129 ehca_err(&shca->ib_device, "kpage alloc failed"); 1130 1130 ret = -ENOMEM; ··· 1181 1181 } 1182 1182 1183 1183 ehca_rereg_mr_rereg1_exit1: 1184 - kfree(kpage); 1184 + ehca_free_fw_ctrlblock(kpage); 1185 1185 ehca_rereg_mr_rereg1_exit0: 1186 1186 if ( ret && (ret != -EAGAIN) ) 1187 1187 ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x "
+5 -5
drivers/infiniband/hw/ehca/ehca_qp.c
··· 811 811 unsigned long spl_flags = 0; 812 812 813 813 /* do query_qp to obtain current attr values */ 814 - mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); 815 - if (mqpcb == NULL) { 814 + mqpcb = ehca_alloc_fw_ctrlblock(); 815 + if (!mqpcb) { 816 816 ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " 817 817 "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); 818 818 return -ENOMEM; ··· 1225 1225 } 1226 1226 1227 1227 modify_qp_exit1: 1228 - kfree(mqpcb); 1228 + ehca_free_fw_ctrlblock(mqpcb); 1229 1229 1230 1230 return ret; 1231 1231 } ··· 1277 1277 return -EINVAL; 1278 1278 } 1279 1279 1280 - qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL ); 1280 + qpcb = ehca_alloc_fw_ctrlblock(); 1281 1281 if (!qpcb) { 1282 1282 ehca_err(qp->device,"Out of memory for qpcb " 1283 1283 "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); ··· 1401 1401 ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); 1402 1402 1403 1403 query_qp_exit1: 1404 - kfree(qpcb); 1404 + ehca_free_fw_ctrlblock(qpcb); 1405 1405 1406 1406 return ret; 1407 1407 }