1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/ib/ibtl/impl/ibtl.h> 30 31 /* 32 * ibtl_mem.c 33 * These routines implement all of the Memory Region verbs and the alloc/ 34 * query/free Memory Window verbs at the TI interface. 35 */ 36 37 static char ibtl_mem[] = "ibtl_mem"; 38 39 /* 40 * Function: 41 * ibt_register_mr() 42 * Input: 43 * hca_hdl - HCA Handle. 44 * pd - Protection Domain Handle. 45 * mem_attr - Requested memory region attributes. 46 * Output: 47 * mr_hdl_p - The returned IBT memory region handle. 48 * mem_desc - Returned memory descriptor. 49 * Returns: 50 * IBT_SUCCESS 51 * IBT_CHAN_HDL_INVALID 52 * IBT_MR_VA_INVALID 53 * IBT_MR_LEN_INVALID 54 * IBT_MR_ACCESS_REQ_INVALID 55 * IBT_PD_HDL_INVALID 56 * IBT_INSUFF_RESOURCE 57 * Description: 58 * Prepares a virtually addressed memory region for use by a HCA. A 59 * description of the registered memory suitable for use in Work Requests 60 * (WRs) is returned in the ibt_mr_desc_t parameter. 61 */ 62 ibt_status_t 63 ibt_register_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, ibt_mr_attr_t *mem_attr, 64 ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc) 65 { 66 ib_vaddr_t vaddr; 67 ibt_status_t status; 68 69 IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_mr(%p, %p, %p)", 70 hca_hdl, pd, mem_attr); 71 72 vaddr = mem_attr->mr_vaddr; 73 74 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_mr( 75 IBTL_HCA2CIHCA(hca_hdl), pd, mem_attr, IBTL_HCA2CLNT(hca_hdl), 76 mr_hdl_p, mem_desc); 77 if (status == IBT_SUCCESS) { 78 mem_desc->md_vaddr = vaddr; 79 mutex_enter(&hca_hdl->ha_mutex); 80 hca_hdl->ha_mr_cnt++; 81 mutex_exit(&hca_hdl->ha_mutex); 82 } 83 84 return (status); 85 } 86 87 88 /* 89 * Function: 90 * ibt_register_buf() 91 * Input: 92 * hca_hdl HCA Handle. 93 * pd Protection Domain Handle. 94 * mem_bpattr Memory Registration attributes (IOVA and flags). 95 * bp A pointer to a buf(9S) struct. 96 * Output: 97 * mr_hdl_p The returned IBT memory region handle. 98 * mem_desc Returned memory descriptor. 99 * Returns: 100 * IBT_SUCCESS 101 * IBT_CHAN_HDL_INVALID 102 * IBT_MR_VA_INVALID 103 * IBT_MR_LEN_INVALID 104 * IBT_MR_ACCESS_REQ_INVALID 105 * IBT_PD_HDL_INVALID 106 * IBT_INSUFF_RESOURCE 107 * Description: 108 * Prepares a memory region described by a buf(9S) struct for use by a HCA. 109 * A description of the registered memory suitable for use in 110 * Work Requests (WRs) is returned in the ibt_mr_desc_t parameter. 111 */ 112 ibt_status_t 113 ibt_register_buf(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, 114 ibt_smr_attr_t *mem_bpattr, struct buf *bp, ibt_mr_hdl_t *mr_hdl_p, 115 ibt_mr_desc_t *mem_desc) 116 { 117 ibt_status_t status; 118 119 IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_buf(%p, %p, %p, %p)", 120 hca_hdl, pd, mem_bpattr, bp); 121 122 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_buf( 123 IBTL_HCA2CIHCA(hca_hdl), pd, mem_bpattr, bp, IBTL_HCA2CLNT(hca_hdl), 124 mr_hdl_p, mem_desc); 125 if (status == IBT_SUCCESS) { 126 mutex_enter(&hca_hdl->ha_mutex); 127 hca_hdl->ha_mr_cnt++; 128 mutex_exit(&hca_hdl->ha_mutex); 129 } 130 131 return (status); 132 } 133 134 135 /* 136 * Function: 137 * ibt_query_mr() 138 * Input: 139 * hca_hdl - HCA Handle. 140 * mr_hdl - The IBT Memory Region handle. 141 * Output: 142 * attr - The pointer to Memory region attributes structure. 143 * Returns: 144 * IBT_SUCCESS 145 * IBT_CHAN_HDL_INVALID 146 * IBT_MR_HDL_INVALID 147 * Description: 148 * Retrieves information about a specified memory region. 149 */ 150 ibt_status_t 151 ibt_query_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl, 152 ibt_mr_query_attr_t *attr) 153 { 154 IBTF_DPRINTF_L3(ibtl_mem, "ibt_query_mr(%p, %p)", hca_hdl, mr_hdl); 155 156 return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_query_mr( 157 IBTL_HCA2CIHCA(hca_hdl), mr_hdl, attr)); 158 } 159 160 161 /* 162 * Function: 163 * ibt_deregister_mr() 164 * Input: 165 * hca_hdl - HCA Handle. 166 * mr_hdl - The IBT Memory Region handle. 167 * Output: 168 * none. 169 * Returns: 170 * IBT_SUCCESS 171 * IBT_CHAN_HDL_INVALID 172 * IBT_MR_HDL_INVALID 173 * IBT_MR_IN_USE 174 * Description: 175 * De-register the registered memory region. Remove a memory region from a 176 * HCA translation table, and free all resources associated with the 177 * memory region. 178 */ 179 ibt_status_t 180 ibt_deregister_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl) 181 { 182 ibt_status_t status; 183 184 IBTF_DPRINTF_L3(ibtl_mem, "ibt_deregister_mr(%p, %p)", hca_hdl, mr_hdl); 185 186 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_deregister_mr( 187 IBTL_HCA2CIHCA(hca_hdl), mr_hdl); 188 if (status == IBT_SUCCESS) { 189 mutex_enter(&hca_hdl->ha_mutex); 190 hca_hdl->ha_mr_cnt--; 191 mutex_exit(&hca_hdl->ha_mutex); 192 } 193 return (status); 194 } 195 196 197 /* 198 * Function: 199 * ibt_reregister_mr() 200 * Input: 201 * hca_hdl - HCA Handle. 202 * mr_hdl - The IBT Memory Region handle. 203 * pd - Optional Protection Domain Handle. 204 * mem_attr - Requested memory region attributes. 205 * Output: 206 * mr_hdl_p - The reregistered IBT memory region handle. 207 * mem_desc - Returned memory descriptor for the new memory region. 208 * Returns: 209 * IBT_SUCCESS 210 * IBT_CHAN_HDL_INVALID 211 * IBT_MR_HDL_INVALID 212 * IBT_MR_VA_INVALID 213 * IBT_MR_LEN_INVALID 214 * IBT_MR_ACCESS_REQ_INVALID 215 * IBT_PD_HDL_INVALID 216 * IBT_INSUFF_RESOURCE 217 * IBT_MR_IN_USE 218 * Description: 219 * Modify the attributes of an existing memory region. 220 */ 221 ibt_status_t 222 ibt_reregister_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl, ibt_pd_hdl_t pd, 223 ibt_mr_attr_t *mem_attr, ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc) 224 { 225 ibt_status_t status; 226 ib_vaddr_t vaddr = mem_attr->mr_vaddr; 227 228 IBTF_DPRINTF_L3(ibtl_mem, "ibt_reregister_mr(%p, %p, %p, %p)", 229 hca_hdl, mr_hdl, pd, mem_attr); 230 231 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_reregister_mr( 232 IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_attr, 233 IBTL_HCA2CLNT(hca_hdl), mr_hdl_p, mem_desc); 234 235 if (status == IBT_SUCCESS) 236 mem_desc->md_vaddr = vaddr; 237 else if (!(status == IBT_MR_IN_USE || status == IBT_HCA_HDL_INVALID || 238 status == IBT_MR_HDL_INVALID)) { 239 240 IBTF_DPRINTF_L2(ibtl_mem, "ibt_reregister_mr: " 241 "Re-registration Failed: %d", status); 242 243 /* we lost one memory region resource */ 244 mutex_enter(&hca_hdl->ha_mutex); 245 hca_hdl->ha_mr_cnt--; 246 mutex_exit(&hca_hdl->ha_mutex); 247 } 248 249 return (status); 250 } 251 252 253 /* 254 * Function: 255 * ibt_reregister_buf() 256 * Input: 257 * hca_hdl HCA Handle. 258 * mr_hdl The IBT Memory Region handle. 259 * pd Optional Protection Domain Handle. 260 * mem_bpattr Memory Registration attributes (IOVA and flags). 261 * bp A pointer to a buf(9S) struct. 262 * Output: 263 * mr_hdl_p The reregistered IBT memory region handle. 264 * mem_desc Returned memory descriptor for the new memory region. 265 * Returns: 266 * IBT_SUCCESS 267 * IBT_CHAN_HDL_INVALID 268 * IBT_MR_HDL_INVALID 269 * IBT_MR_VA_INVALID 270 * IBT_MR_LEN_INVALID 271 * IBT_MR_ACCESS_REQ_INVALID 272 * IBT_PD_HDL_INVALID 273 * IBT_INSUFF_RESOURCE 274 * IBT_MR_IN_USE 275 * Description: 276 * Modify the attributes of an existing memory region as described by a 277 * buf(9S) struct for use by a HCA. A description of the registered 278 * memory suitable for use in Work Requests (WRs) is returned in the 279 * ibt_mr_desc_t parameter. 280 */ 281 ibt_status_t 282 ibt_reregister_buf(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl, 283 ibt_pd_hdl_t pd, ibt_smr_attr_t *mem_bpattr, struct buf *bp, 284 ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc) 285 { 286 ibt_status_t status; 287 288 IBTF_DPRINTF_L3(ibtl_mem, "ibt_reregister_buf(%p, %p, %p, %p, %p)", 289 hca_hdl, mr_hdl, pd, mem_bpattr, bp); 290 291 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_reregister_buf( 292 IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_bpattr, bp, 293 IBTL_HCA2CLNT(hca_hdl), mr_hdl_p, mem_desc); 294 295 if (!(status == IBT_SUCCESS || status == IBT_MR_IN_USE || 296 status == IBT_HCA_HDL_INVALID || status == IBT_MR_HDL_INVALID)) { 297 298 IBTF_DPRINTF_L2(ibtl_mem, "ibt_reregister_buf: " 299 "Re-registration Mem Failed: %d", status); 300 301 /* we lost one memory region resource */ 302 mutex_enter(&hca_hdl->ha_mutex); 303 hca_hdl->ha_mr_cnt--; 304 mutex_exit(&hca_hdl->ha_mutex); 305 } 306 return (status); 307 } 308 309 310 /* 311 * Function: 312 * ibt_register_shared_mr() 313 * Input: 314 * hca_hdl - HCA Handle. 315 * mr_hdl - The IBT Memory Region handle. 316 * pd - Protection Domain Handle. 317 * mem_sattr - Requested memory region shared attributes. 318 * Output: 319 * mr_hdl_p - The reregistered IBT memory region handle. 320 * mem_desc - Returned memory descriptor for the new memory region. 321 * Returns: 322 * IBT_SUCCESS 323 * IBT_INSUFF_RESOURCE 324 * IBT_CHAN_HDL_INVALID 325 * IBT_MR_HDL_INVALID 326 * IBT_PD_HDL_INVALID 327 * IBT_MR_ACCESS_REQ_INVALID 328 * Description: 329 * Given an existing memory region, a new memory region associated with 330 * the same physical locations is created. 331 */ 332 ibt_status_t 333 ibt_register_shared_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl, 334 ibt_pd_hdl_t pd, ibt_smr_attr_t *mem_sattr, ibt_mr_hdl_t *mr_hdl_p, 335 ibt_mr_desc_t *mem_desc) 336 { 337 ibt_status_t status; 338 339 IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_shared_mr(%p, %p, %p, %p)", 340 hca_hdl, mr_hdl, pd, mem_sattr); 341 342 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_shared_mr( 343 IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_sattr, 344 IBTL_HCA2CLNT(hca_hdl), mr_hdl_p, mem_desc); 345 if (status == IBT_SUCCESS) { 346 mutex_enter(&hca_hdl->ha_mutex); 347 hca_hdl->ha_mr_cnt++; 348 mutex_exit(&hca_hdl->ha_mutex); 349 } 350 return (status); 351 } 352 353 /* 354 * Function: 355 * ibt_sync_mr() 356 * Input: 357 * hca_hdl - HCA Handle. 358 * mr_segments - A pointer to an array of ibt_mr_sync_t that describes 359 * the memory regions to sync. 360 * num_segments - The length of the mr_segments array. 361 * Output: 362 * NONE 363 * Returns: 364 * IBT_SUCCESS 365 * IBT_HCA_HDL_INVALID 366 * IBT_MR_HDL_INVALID 367 * IBT_INVALID_PARAM 368 * IBT_MR_VA_INVALID 369 * IBT_MR_LEN_INVALID 370 * Description: 371 * Make memory changes visible to incoming RDMA reads, or make the affects 372 * of an incoming RDMA writes visible to the consumer. 373 */ 374 ibt_status_t 375 ibt_sync_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_sync_t *mr_segments, 376 size_t num_segments) 377 378 { 379 IBTF_DPRINTF_L3(ibtl_mem, "ibt_sync_mr(%p, %p, %d)", hca_hdl, 380 mr_segments, num_segments); 381 382 return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_sync_mr( 383 IBTL_HCA2CIHCA(hca_hdl), mr_segments, num_segments)); 384 } 385 386 387 /* 388 * Function: 389 * ibt_alloc_mw() 390 * Input: 391 * hca_hdl - HCA Handle. 392 * pd - Protection Domain Handle. 393 * flags - Memory Window alloc flags. 394 * Output: 395 * mw_hdl_p - The returned IBT Memory Window handle. 396 * rkey - The IBT R_Key handle. 397 * Returns: 398 * IBT_SUCCESS 399 * IBT_INSUFF_RESOURCE 400 * IBT_CHAN_HDL_INVALID 401 * IBT_PD_HDL_INVALID 402 * Description: 403 * Allocate a memory window from the HCA. 404 */ 405 ibt_status_t 406 ibt_alloc_mw(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, ibt_mw_flags_t flags, 407 ibt_mw_hdl_t *mw_hdl_p, ibt_rkey_t *rkey) 408 { 409 ibt_status_t status; 410 411 IBTF_DPRINTF_L3(ibtl_mem, "ibt_alloc_mw(%p, %p, 0x%x)", 412 hca_hdl, pd, flags); 413 414 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_mw( 415 IBTL_HCA2CIHCA(hca_hdl), pd, flags, mw_hdl_p, rkey); 416 417 /* 418 * XXX - We should be able to allocate state and have a IBTF Memory 419 * Window Handle. Memory Windows are meant to be rebound on the fly 420 * (using a post) to make them fast. It is expected that alloc memory 421 * window will be done in a relatively static manner. But, we don't have 422 * a good reason to have local MW state at this point, so we won't. 423 */ 424 if (status == IBT_SUCCESS) { 425 mutex_enter(&hca_hdl->ha_mutex); 426 hca_hdl->ha_mw_cnt++; 427 mutex_exit(&hca_hdl->ha_mutex); 428 } 429 return (status); 430 } 431 432 433 /* 434 * Function: 435 * ibt_query_mw() 436 * Input: 437 * hca_hdl - HCA Handle. 438 * mw_hdl - The IBT Memory Window handle. 439 * Output: 440 * pd - Protection Domain Handle. 441 * rkey - The IBT R_Key handle. 442 * Returns: 443 * IBT_SUCCESS 444 * IBT_CHAN_HDL_INVALID 445 * IBT_MW_HDL_INVALID 446 * Description: 447 * Retrieves information about a specified memory region. 448 */ 449 ibt_status_t 450 ibt_query_mw(ibt_hca_hdl_t hca_hdl, ibt_mw_hdl_t mw_hdl, 451 ibt_mw_query_attr_t *mw_attr_p) 452 { 453 IBTF_DPRINTF_L3(ibtl_mem, "ibt_query_mw(%p, %p)", hca_hdl, mw_hdl); 454 455 return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_query_mw( 456 IBTL_HCA2CIHCA(hca_hdl), mw_hdl, mw_attr_p)); 457 } 458 459 460 /* 461 * Function: 462 * ibt_free_mw() 463 * Input: 464 * hca_hdl - HCA Handle 465 * mw_hdl - The IBT Memory Window handle. 466 * Output: 467 * none. 468 * Returns: 469 * IBT_SUCCESS 470 * IBT_CHAN_HDL_INVALID 471 * IBT_MW_HDL_INVALID 472 * Description: 473 * De-allocate the Memory Window. 474 */ 475 ibt_status_t 476 ibt_free_mw(ibt_hca_hdl_t hca_hdl, ibt_mw_hdl_t mw_hdl) 477 { 478 ibt_status_t status; 479 480 IBTF_DPRINTF_L3(ibtl_mem, "ibt_free_mw(%p, %p)", hca_hdl, mw_hdl); 481 482 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_free_mw( 483 IBTL_HCA2CIHCA(hca_hdl), mw_hdl); 484 485 if (status == IBT_SUCCESS) { 486 mutex_enter(&hca_hdl->ha_mutex); 487 hca_hdl->ha_mw_cnt--; 488 mutex_exit(&hca_hdl->ha_mutex); 489 } 490 return (status); 491 } 492 493 494 /* 495 * Function: 496 * ibt_map_mem_area() 497 * Input: 498 * hca_hdl HCA Handle 499 * va_attrs A pointer to an ibt_va_attr_t that describes the 500 * VA to be translated. 501 * paddr_list_len The number of entries in the 'paddr_list_p' array. 502 * Output: 503 * paddr_list_p Array of ibt_phys_buf_t (allocated by the caller), 504 * in which the physical buffers that map the virtual 505 * buffer are returned. 506 * num_paddr_p The actual number of ibt_phys_buf_t that were 507 * returned in the 'paddr_list_p' array. 508 * ma_hdl_p Memory Area Handle. 509 * Returns: 510 * IBT_SUCCESS 511 * Description: 512 * Translate a kernel virtual address range into HCA physical addresses. 513 * A set of physical addresses, that can be used with "Reserved L_Key", 514 * register physical, and "Fast Registration Work Request" operations 515 * is returned. 516 */ 517 ibt_status_t 518 ibt_map_mem_area(ibt_hca_hdl_t hca_hdl, ibt_va_attr_t *va_attrs, 519 uint_t paddr_list_len, ibt_phys_buf_t *paddr_list_p, uint_t *num_paddr_p, 520 size_t *paddr_bufsz_p, ib_memlen_t *paddr_offset_p, ibt_ma_hdl_t *ma_hdl_p) 521 { 522 ibt_status_t status; 523 524 IBTF_DPRINTF_L3(ibtl_mem, "ibt_map_mem_area(%p, %p, %d)", 525 hca_hdl, va_attrs, paddr_list_len); 526 527 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_map_mem_area( 528 IBTL_HCA2CIHCA(hca_hdl), va_attrs, 529 NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */ 530 paddr_list_len, paddr_list_p, num_paddr_p, paddr_bufsz_p, 531 paddr_offset_p, ma_hdl_p); 532 if (status == IBT_SUCCESS) { 533 mutex_enter(&hca_hdl->ha_mutex); 534 hca_hdl->ha_ma_cnt++; 535 mutex_exit(&hca_hdl->ha_mutex); 536 } 537 538 return (status); 539 } 540 541 542 /* 543 * Function: 544 * ibt_unmap_mem_area() 545 * Input: 546 * hca_hdl HCA Handle 547 * ma_hdl Memory Area Handle. 548 * Output: 549 * None. 550 * Returns: 551 * IBT_SUCCESS 552 * Description: 553 * Un pin physical pages pinned during an ibt_map_mem_area() call. 554 */ 555 ibt_status_t 556 ibt_unmap_mem_area(ibt_hca_hdl_t hca_hdl, ibt_ma_hdl_t ma_hdl) 557 { 558 ibt_status_t status; 559 560 IBTF_DPRINTF_L3(ibtl_mem, "ibt_unmap_mem_area(%p, %p)", 561 hca_hdl, ma_hdl); 562 563 status = (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_unmap_mem_area( 564 IBTL_HCA2CIHCA(hca_hdl), ma_hdl)); 565 if (status == IBT_SUCCESS) { 566 mutex_enter(&hca_hdl->ha_mutex); 567 hca_hdl->ha_ma_cnt--; 568 mutex_exit(&hca_hdl->ha_mutex); 569 } 570 571 return (status); 572 } 573 574 575 /* 576 * Function: 577 * ibt_alloc_lkey() 578 * Input: 579 * hca_hdl HCA Handle 580 * pd A protection domain handle. 581 * flags Access control. 582 * phys_buf_list_sz Requested size of Physical Buffer List (PBL) 583 * resources to be allocated. 584 * Output: 585 * mr_hdl_p The returned IBT memory region handle. 586 * mem_desc_p Returned memory descriptor. 587 * Returns: 588 * IBT_SUCCESS 589 * Description: 590 * Allocates physical buffer list resources for use in memory 591 * registrations. 592 */ 593 ibt_status_t 594 ibt_alloc_lkey(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, ibt_lkey_flags_t flags, 595 uint_t phys_buf_list_sz, ibt_mr_hdl_t *mr_hdl_p, 596 ibt_pmr_desc_t *mem_desc_p) 597 { 598 ibt_status_t status; 599 600 IBTF_DPRINTF_L3(ibtl_mem, "ibt_alloc_lkey(%p, %p, 0x%X, %d)", 601 hca_hdl, pd, flags, phys_buf_list_sz); 602 603 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_lkey( 604 IBTL_HCA2CIHCA(hca_hdl), pd, flags, phys_buf_list_sz, mr_hdl_p, 605 mem_desc_p); 606 if (status == IBT_SUCCESS) { 607 mutex_enter(&hca_hdl->ha_mutex); 608 hca_hdl->ha_mr_cnt++; 609 mutex_exit(&hca_hdl->ha_mutex); 610 } 611 612 return (status); 613 } 614 615 616 /* 617 * Function: 618 * ibt_register_phys_mr() 619 * Input: 620 * hca_hdl HCA Handle 621 * pd A protection domain handle. 622 * mem_pattr Requested memory region physical attributes. 623 * Output: 624 * mr_hdl_p The returned IBT memory region handle. 625 * mem_desc_p Returned memory descriptor. 626 * Returns: 627 * IBT_SUCCESS 628 * Description: 629 * Prepares a physically addressed memory region for use by a HCA. 630 */ 631 ibt_status_t 632 ibt_register_phys_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, 633 ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p, 634 ibt_pmr_desc_t *mem_desc_p) 635 { 636 ibt_status_t status; 637 638 IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_phys_mr(%p, %p, %p)", 639 hca_hdl, pd, mem_pattr); 640 641 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_physical_mr( 642 IBTL_HCA2CIHCA(hca_hdl), pd, mem_pattr, 643 NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */ 644 mr_hdl_p, mem_desc_p); 645 if (status == IBT_SUCCESS) { 646 mutex_enter(&hca_hdl->ha_mutex); 647 hca_hdl->ha_mr_cnt++; 648 mutex_exit(&hca_hdl->ha_mutex); 649 } 650 651 return (status); 652 } 653 654 655 /* 656 * Function: 657 * ibt_reregister_phys_mr() 658 * Input: 659 * hca_hdl HCA Handle 660 * mr_hdl The IBT memory region handle. 661 * pd A protection domain handle. 662 * mem_pattr Requested memory region physical attributes. 663 * Output: 664 * mr_hdl_p The returned IBT memory region handle. 665 * mem_desc_p Returned memory descriptor. 666 * Returns: 667 * IBT_SUCCESS 668 * Description: 669 * Prepares a physically addressed memory region for use by a HCA. 670 */ 671 ibt_status_t 672 ibt_reregister_phys_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl, 673 ibt_pd_hdl_t pd, ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p, 674 ibt_pmr_desc_t *mem_desc_p) 675 { 676 ibt_status_t status; 677 678 IBTF_DPRINTF_L3(ibtl_mem, "ibt_reregister_phys_mr(%p, %p, %p, %p)", 679 hca_hdl, mr_hdl, pd, mem_pattr); 680 681 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_reregister_physical_mr( 682 IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_pattr, 683 NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */ 684 mr_hdl_p, mem_desc_p); 685 686 if (!(status == IBT_SUCCESS || status == IBT_MR_IN_USE || 687 status == IBT_HCA_HDL_INVALID || status == IBT_MR_HDL_INVALID)) { 688 IBTF_DPRINTF_L2(ibtl_mem, "ibt_reregister_phys_mr: " 689 "Re-registration Mem Failed: %d", status); 690 691 /* we lost one memory region resource */ 692 mutex_enter(&hca_hdl->ha_mutex); 693 hca_hdl->ha_mr_cnt--; 694 mutex_exit(&hca_hdl->ha_mutex); 695 696 } 697 return (status); 698 } 699 700 701 /* 702 * Fast Memory Registration (FMR). 703 * 704 * ibt_create_fmr_pool 705 * Not fast-path. 706 * ibt_create_fmr_pool() verifies that the HCA supports FMR and allocates 707 * and initializes an "FMR pool". This pool contains state specific to 708 * this registration, including the watermark setting to determine when 709 * to sync, and the total number of FMR regions available within this pool. 710 * 711 */ 712 ibt_status_t 713 ibt_create_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, 714 ibt_fmr_pool_attr_t *fmr_params, ibt_fmr_pool_hdl_t *fmr_pool_p) 715 { 716 ibt_status_t status; 717 718 IBTF_DPRINTF_L3(ibtl_mem, "ibt_create_fmr_pool(%p, %p, %p)", 719 hca_hdl, pd, fmr_params); 720 721 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_create_fmr_pool( 722 IBTL_HCA2CIHCA(hca_hdl), pd, fmr_params, fmr_pool_p); 723 if (status != IBT_SUCCESS) { 724 *fmr_pool_p = NULL; 725 return (status); 726 } 727 728 /* Update the FMR resource count */ 729 mutex_enter(&hca_hdl->ha_mutex); 730 hca_hdl->ha_fmr_pool_cnt++; 731 mutex_exit(&hca_hdl->ha_mutex); 732 733 return (status); 734 } 735 736 737 /* 738 * ibt_destroy_fmr_pool 739 * ibt_destroy_fmr_pool() deallocates all of the FMR regions in a specific 740 * pool. All state and information regarding the pool are destroyed and 741 * returned as free space once again. No more use of FMR regions in this 742 * pool are possible without a subsequent call to ibt_create_fmr_pool(). 743 */ 744 ibt_status_t 745 ibt_destroy_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_fmr_pool_hdl_t fmr_pool) 746 { 747 ibt_status_t status; 748 749 IBTF_DPRINTF_L3(ibtl_mem, "ibt_destroy_fmr_pool(%p, %p)", 750 hca_hdl, fmr_pool); 751 752 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_destroy_fmr_pool( 753 IBTL_HCA2CIHCA(hca_hdl), fmr_pool); 754 if (status != IBT_SUCCESS) { 755 IBTF_DPRINTF_L2(ibtl_mem, "ibt_destroy_fmr_pool: " 756 "CI FMR Pool destroy failed (%d)", status); 757 return (status); 758 } 759 760 mutex_enter(&hca_hdl->ha_mutex); 761 hca_hdl->ha_fmr_pool_cnt--; 762 mutex_exit(&hca_hdl->ha_mutex); 763 764 return (status); 765 } 766 767 /* 768 * ibt_flush_fmr_pool 769 * ibt_flush_fmr_pool forces a flush to occur. At the client's request, 770 * any unmapped FMR regions (See 'ibt_deregister_mr())') are returned to 771 * a free state. This function allows for an asynchronous cleanup of 772 * formerly used FMR regions. Sync operation is also performed internally 773 * by HCA driver, when 'watermark' settings for the number of free FMR 774 * regions left in the "pool" is reached. 775 */ 776 ibt_status_t 777 ibt_flush_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_fmr_pool_hdl_t fmr_pool) 778 { 779 IBTF_DPRINTF_L3(ibtl_mem, "ibt_flush_fmr_pool(%p, %p)", 780 hca_hdl, fmr_pool); 781 782 return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_flush_fmr_pool( 783 IBTL_HCA2CIHCA(hca_hdl), fmr_pool)); 784 } 785 786 /* 787 * ibt_register_physical_fmr 788 * ibt_register_physical_fmr() assigns a "free" entry from the FMR Pool. 789 * It first consults the "FMR cache" to see if this is a duplicate memory 790 * registration to something already in use. If not, then a free entry 791 * in the "pool" is marked used. 792 */ 793 ibt_status_t 794 ibt_register_physical_fmr(ibt_hca_hdl_t hca_hdl, ibt_fmr_pool_hdl_t fmr_pool, 795 ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p, 796 ibt_pmr_desc_t *mem_desc_p) 797 { 798 IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_physical_fmr(%p, %p, %p, %p)", 799 hca_hdl, fmr_pool, mem_pattr, mem_desc_p); 800 801 return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_physical_fmr( 802 IBTL_HCA2CIHCA(hca_hdl), fmr_pool, mem_pattr, 803 NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */ 804 mr_hdl_p, mem_desc_p)); 805 } 806 807 /* 808 * ibt_deregister_fmr 809 * The ibt_deregister_fmr un-maps the resources reserved from the FMR 810 * pool by ibt_register_physical_fmr(). The ibt_deregister_fmr() will 811 * mark the region as free in the FMR Pool. 812 */ 813 ibt_status_t 814 ibt_deregister_fmr(ibt_hca_hdl_t hca, ibt_mr_hdl_t mr_hdl) 815 { 816 IBTF_DPRINTF_L3(ibtl_mem, "ibt_deregister_fmr(%p, %p)", hca, mr_hdl); 817 818 return (IBTL_HCA2CIHCAOPS_P(hca)->ibc_deregister_fmr( 819 IBTL_HCA2CIHCA(hca), mr_hdl)); 820 } 821