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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright (c) 2005 SilverStorm Technologies, Inc. All rights reserved. 27 * 28 * This software is available to you under a choice of one of two 29 * licenses. You may choose to be licensed under the terms of the GNU 30 * General Public License (GPL) Version 2, available from the file 31 * COPYING in the main directory of this source tree, or the 32 * OpenIB.org BSD license below: 33 * 34 * Redistribution and use in source and binary forms, with or 35 * without modification, are permitted provided that the following 36 * conditions are met: 37 * 38 * - Redistributions of source code must retain the above 39 * copyright notice, this list of conditions and the following 40 * disclaimer. 41 * 42 * - Redistributions in binary form must reproduce the above 43 * copyright notice, this list of conditions and the following 44 * disclaimer in the documentation and/or other materials 45 * provided with the distribution. 46 * 47 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 48 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 49 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 50 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 51 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 52 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 53 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 54 * SOFTWARE. 55 * 56 */ 57 /* 58 * Sun elects to include this software in Sun product 59 * under the OpenIB BSD license. 60 * 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 63 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 65 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 66 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 67 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 68 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 69 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 70 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 71 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 72 * POSSIBILITY OF SUCH DAMAGE. 73 */ 74 75 #include <sys/ib/clients/rds/rdsib_cm.h> 76 #include <sys/ib/clients/rds/rdsib_ib.h> 77 #include <sys/ib/clients/rds/rdsib_buf.h> 78 #include <sys/ib/clients/rds/rdsib_ep.h> 79 #include <sys/ib/clients/rds/rds_kstat.h> 80 81 /* 82 * This File contains the buffer management code 83 */ 84 85 #define DUMP_USER_PARAMS() \ 86 RDS_DPRINTF3(LABEL, "MaxNodes = %d", MaxNodes); \ 87 RDS_DPRINTF3(LABEL, "UserBufferSize = %d", UserBufferSize); \ 88 RDS_DPRINTF3(LABEL, "RdsPktSize = %d", RdsPktSize); \ 89 RDS_DPRINTF3(LABEL, "MaxDataSendBuffers = %d", MaxDataSendBuffers); \ 90 RDS_DPRINTF3(LABEL, "MaxDataRecvBuffers = %d", MaxDataRecvBuffers); \ 91 RDS_DPRINTF3(LABEL, "MaxCtrlSendBuffers = %d", MaxCtrlSendBuffers); \ 92 RDS_DPRINTF3(LABEL, "MaxCtrlRecvBuffers = %d", MaxCtrlRecvBuffers); \ 93 RDS_DPRINTF3(LABEL, "DataRecvBufferLWM = %d", DataRecvBufferLWM); \ 94 RDS_DPRINTF3(LABEL, "PendingRxPktsHWM = %d", PendingRxPktsHWM); \ 95 RDS_DPRINTF3(LABEL, "MinRnrRetry = %d", MinRnrRetry) 96 97 uint_t rds_nbuffers_to_putback; 98 99 static void 100 rds_free_mblk(char *arg) 101 { 102 rds_buf_t *bp = (rds_buf_t *)(uintptr_t)arg; 103 104 /* Free the recv buffer */ 105 RDS_DPRINTF4("rds_free_mblk", "Enter: BP(%p)", bp); 106 ASSERT(bp->buf_state == RDS_RCVBUF_ONSOCKQ); 107 rds_free_recv_buf(bp, 1); 108 RDS_DECR_RXPKTS_PEND(1); 109 RDS_DPRINTF4("rds_free_mblk", "Return: BP(%p)", bp); 110 } 111 112 void 113 rds_free_recv_caches(rds_state_t *statep) 114 { 115 rds_hca_t *hcap; 116 int ret; 117 118 RDS_DPRINTF4("rds_free_recv_caches", "Enter"); 119 120 mutex_enter(&rds_dpool.pool_lock); 121 if (rds_dpool.pool_memp == NULL) { 122 RDS_DPRINTF2("rds_free_recv_caches", "Caches are empty"); 123 mutex_exit(&rds_dpool.pool_lock); 124 return; 125 } 126 127 /* 128 * All buffers must have been freed as all sessions are closed 129 * and destroyed 130 */ 131 ASSERT(rds_dpool.pool_nbusy == 0); 132 RDS_DPRINTF2("rds_free_recv_caches", "Data Pool has " 133 "pending buffers: %d", rds_dpool.pool_nbusy); 134 while (rds_dpool.pool_nbusy != 0) { 135 mutex_exit(&rds_dpool.pool_lock); 136 delay(drv_sectohz(1)); 137 mutex_enter(&rds_dpool.pool_lock); 138 } 139 140 hcap = statep->rds_hcalistp; 141 while (hcap != NULL) { 142 if (hcap->hca_mrhdl != NULL) { 143 ret = ibt_deregister_mr(hcap->hca_hdl, 144 hcap->hca_mrhdl); 145 if (ret == IBT_SUCCESS) { 146 hcap->hca_mrhdl = NULL; 147 hcap->hca_lkey = 0; 148 hcap->hca_rkey = 0; 149 } else { 150 RDS_DPRINTF2(LABEL, "ibt_deregister_mr " 151 "failed: %d, mrhdl: 0x%p", ret, 152 hcap->hca_mrhdl); 153 } 154 } 155 hcap = hcap->hca_nextp; 156 } 157 158 kmem_free(rds_dpool.pool_bufmemp, (rds_dpool.pool_nbuffers + 159 rds_cpool.pool_nbuffers) * sizeof (rds_buf_t)); 160 rds_dpool.pool_bufmemp = NULL; 161 162 kmem_free(rds_dpool.pool_memp, rds_dpool.pool_memsize); 163 rds_dpool.pool_memp = NULL; 164 165 mutex_exit(&rds_dpool.pool_lock); 166 167 RDS_DPRINTF4("rds_free_recv_caches", "Return"); 168 } 169 170 int 171 rds_init_recv_caches(rds_state_t *statep) 172 { 173 uint8_t *mp; 174 rds_buf_t *bp; 175 rds_hca_t *hcap; 176 uint32_t nsessions; 177 uint_t ix; 178 uint_t nctrlrx; 179 uint8_t *memp; 180 uint_t memsize, nbuf; 181 rds_buf_t *bufmemp; 182 ibt_mr_attr_t mem_attr; 183 ibt_mr_desc_t mem_desc; 184 int ret; 185 186 RDS_DPRINTF4("rds_init_recv_caches", "Enter"); 187 188 DUMP_USER_PARAMS(); 189 190 mutex_enter(&rds_dpool.pool_lock); 191 if (rds_dpool.pool_memp != NULL) { 192 RDS_DPRINTF2("rds_init_recv_caches", "Pools are already " 193 "initialized"); 194 mutex_exit(&rds_dpool.pool_lock); 195 return (0); 196 } 197 198 /* 199 * High water mark for the receive buffers in the system. If the 200 * number of buffers used crosses this mark then all sockets in 201 * would be stalled. The port quota for the sockets is set based 202 * on this limit. 203 */ 204 rds_rx_pkts_pending_hwm = (PendingRxPktsHWM * NDataRX)/100; 205 206 rds_nbuffers_to_putback = min(MaxCtrlRecvBuffers, MaxDataRecvBuffers); 207 208 /* nsessions can never be less than 1 */ 209 nsessions = MaxNodes - 1; 210 nctrlrx = (nsessions + 1) * MaxCtrlRecvBuffers * 2; 211 212 RDS_DPRINTF3(LABEL, "Number of Possible Sessions: %d", nsessions); 213 214 /* Add the hdr */ 215 RdsPktSize = UserBufferSize + RDS_DATA_HDR_SZ; 216 217 memsize = (NDataRX * RdsPktSize) + (nctrlrx * RDS_CTRLPKT_SIZE); 218 nbuf = NDataRX + nctrlrx; 219 RDS_DPRINTF3(LABEL, "RDS Buffer Pool Memory: %lld", memsize); 220 RDS_DPRINTF3(LABEL, "Total Buffers: %d", nbuf); 221 222 memp = (uint8_t *)kmem_zalloc(memsize, KM_NOSLEEP); 223 if (memp == NULL) { 224 RDS_DPRINTF1(LABEL, "RDS Memory allocation failed"); 225 mutex_exit(&rds_dpool.pool_lock); 226 return (-1); 227 } 228 229 RDS_DPRINTF3(LABEL, "RDS Buffer Entries Memory: %lld", 230 nbuf * sizeof (rds_buf_t)); 231 232 /* allocate memory for buffer entries */ 233 bufmemp = (rds_buf_t *)kmem_zalloc(nbuf * sizeof (rds_buf_t), 234 KM_SLEEP); 235 236 /* register the memory with all HCAs */ 237 mem_attr.mr_vaddr = (ib_vaddr_t)(uintptr_t)memp; 238 mem_attr.mr_len = memsize; 239 mem_attr.mr_as = NULL; 240 mem_attr.mr_flags = IBT_MR_ENABLE_LOCAL_WRITE; 241 242 rw_enter(&statep->rds_hca_lock, RW_WRITER); 243 244 hcap = statep->rds_hcalistp; 245 while (hcap != NULL) { 246 if (hcap->hca_state != RDS_HCA_STATE_OPEN) { 247 hcap = hcap->hca_nextp; 248 continue; 249 } 250 251 ret = ibt_register_mr(hcap->hca_hdl, hcap->hca_pdhdl, 252 &mem_attr, &hcap->hca_mrhdl, &mem_desc); 253 if (ret != IBT_SUCCESS) { 254 RDS_DPRINTF2(LABEL, "ibt_register_mr failed: %d", ret); 255 hcap = statep->rds_hcalistp; 256 while ((hcap) && (hcap->hca_mrhdl != NULL)) { 257 ret = ibt_deregister_mr(hcap->hca_hdl, 258 hcap->hca_mrhdl); 259 if (ret == IBT_SUCCESS) { 260 hcap->hca_mrhdl = NULL; 261 hcap->hca_lkey = 0; 262 hcap->hca_rkey = 0; 263 } else { 264 RDS_DPRINTF2(LABEL, "ibt_deregister_mr " 265 "failed: %d, mrhdl: 0x%p", ret, 266 hcap->hca_mrhdl); 267 } 268 hcap = hcap->hca_nextp; 269 } 270 kmem_free(bufmemp, nbuf * sizeof (rds_buf_t)); 271 kmem_free(memp, memsize); 272 rw_exit(&statep->rds_hca_lock); 273 mutex_exit(&rds_dpool.pool_lock); 274 return (-1); 275 } 276 277 hcap->hca_state = RDS_HCA_STATE_MEM_REGISTERED; 278 hcap->hca_lkey = mem_desc.md_lkey; 279 hcap->hca_rkey = mem_desc.md_rkey; 280 281 hcap = hcap->hca_nextp; 282 } 283 rw_exit(&statep->rds_hca_lock); 284 285 /* Initialize data pool */ 286 rds_dpool.pool_memp = memp; 287 rds_dpool.pool_memsize = memsize; 288 rds_dpool.pool_bufmemp = bufmemp; 289 rds_dpool.pool_nbuffers = NDataRX; 290 rds_dpool.pool_nbusy = 0; 291 rds_dpool.pool_nfree = NDataRX; 292 293 /* chain the buffers */ 294 mp = memp; 295 bp = bufmemp; 296 for (ix = 0; ix < NDataRX; ix++) { 297 bp[ix].buf_nextp = &bp[ix + 1]; 298 bp[ix].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 299 bp[ix].buf_state = RDS_RCVBUF_FREE; 300 bp[ix].buf_frtn.free_func = rds_free_mblk; 301 bp[ix].buf_frtn.free_arg = (char *)&bp[ix]; 302 mp = mp + RdsPktSize; 303 } 304 bp[NDataRX - 1].buf_nextp = NULL; 305 rds_dpool.pool_headp = &bp[0]; 306 rds_dpool.pool_tailp = &bp[NDataRX - 1]; 307 308 /* Initialize ctrl pool */ 309 rds_cpool.pool_nbuffers = nctrlrx; 310 rds_cpool.pool_nbusy = 0; 311 rds_cpool.pool_nfree = nctrlrx; 312 313 /* chain the buffers */ 314 for (ix = NDataRX; ix < nbuf - 1; ix++) { 315 bp[ix].buf_nextp = &bp[ix + 1]; 316 bp[ix].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 317 mp = mp + RDS_CTRLPKT_SIZE; 318 } 319 bp[nbuf - 1].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 320 bp[nbuf - 1].buf_nextp = NULL; 321 rds_cpool.pool_headp = &bp[NDataRX]; 322 rds_cpool.pool_tailp = &bp[nbuf - 1]; 323 324 mutex_exit(&rds_dpool.pool_lock); 325 326 RDS_DPRINTF3(LABEL, "rdsmemp start: %p end: %p", memp, mp); 327 RDS_DPRINTF4("rds_init_recv_caches", "Return"); 328 return (0); 329 } 330 331 rds_hca_t *rds_lkup_hca(ib_guid_t hca_guid); 332 333 void 334 rds_free_send_pool(rds_ep_t *ep) 335 { 336 rds_bufpool_t *pool; 337 rds_hca_t *hcap; 338 int ret; 339 340 pool = &ep->ep_sndpool; 341 342 mutex_enter(&pool->pool_lock); 343 if (pool->pool_memp == NULL) { 344 mutex_exit(&pool->pool_lock); 345 RDS_DPRINTF2("rds_free_send_pool", 346 "EP(%p) DOUBLE Free on Send Pool", ep); 347 return; 348 } 349 350 /* get the hcap for the HCA hosting this channel */ 351 hcap = rds_lkup_hca(ep->ep_hca_guid); 352 if (hcap == NULL) { 353 RDS_DPRINTF2("rds_free_send_pool", "HCA (0x%llx) not found", 354 ep->ep_hca_guid); 355 } else { 356 ret = ibt_deregister_mr(hcap->hca_hdl, ep->ep_snd_mrhdl); 357 if (ret != IBT_SUCCESS) { 358 RDS_DPRINTF2(LABEL, 359 "ibt_deregister_mr failed: %d, mrhdl: 0x%p", 360 ret, ep->ep_snd_mrhdl); 361 } 362 363 if (ep->ep_ack_addr) { 364 ret = ibt_deregister_mr(hcap->hca_hdl, ep->ep_ackhdl); 365 if (ret != IBT_SUCCESS) { 366 RDS_DPRINTF2(LABEL, 367 "ibt_deregister_mr ackhdl failed: %d, " 368 "mrhdl: 0x%p", ret, ep->ep_ackhdl); 369 } 370 371 kmem_free((void *)ep->ep_ack_addr, sizeof (uintptr_t)); 372 ep->ep_ack_addr = NULL; 373 } 374 } 375 376 kmem_free(pool->pool_memp, pool->pool_memsize); 377 kmem_free(pool->pool_bufmemp, 378 pool->pool_nbuffers * sizeof (rds_buf_t)); 379 pool->pool_memp = NULL; 380 pool->pool_bufmemp = NULL; 381 mutex_exit(&pool->pool_lock); 382 } 383 384 int 385 rds_init_send_pool(rds_ep_t *ep, ib_guid_t hca_guid) 386 { 387 uint8_t *mp; 388 rds_buf_t *bp; 389 rds_hca_t *hcap; 390 uint_t ix, rcv_len; 391 ibt_mr_attr_t mem_attr; 392 ibt_mr_desc_t mem_desc; 393 uint8_t *memp; 394 rds_buf_t *bufmemp; 395 uintptr_t ack_addr = NULL; 396 uint_t memsize; 397 uint_t nbuf; 398 rds_bufpool_t *spool; 399 rds_data_hdr_t *pktp; 400 int ret; 401 402 RDS_DPRINTF2("rds_init_send_pool", "Enter"); 403 404 spool = &ep->ep_sndpool; 405 406 ASSERT(spool->pool_memp == NULL); 407 ASSERT(ep->ep_hca_guid == 0); 408 409 /* get the hcap for the HCA hosting this channel */ 410 hcap = rds_get_hcap(rdsib_statep, hca_guid); 411 if (hcap == NULL) { 412 RDS_DPRINTF2("rds_init_send_pool", "HCA (0x%llx) not found", 413 hca_guid); 414 return (-1); 415 } 416 417 if (ep->ep_type == RDS_EP_TYPE_DATA) { 418 spool->pool_nbuffers = MaxDataSendBuffers; 419 spool->pool_nbusy = 0; 420 spool->pool_nfree = MaxDataSendBuffers; 421 memsize = (MaxDataSendBuffers * RdsPktSize) + 422 sizeof (uintptr_t); 423 rcv_len = RdsPktSize; 424 } else { 425 spool->pool_nbuffers = MaxCtrlSendBuffers; 426 spool->pool_nbusy = 0; 427 spool->pool_nfree = MaxCtrlSendBuffers; 428 memsize = MaxCtrlSendBuffers * RDS_CTRLPKT_SIZE; 429 rcv_len = RDS_CTRLPKT_SIZE; 430 } 431 nbuf = spool->pool_nbuffers; 432 433 RDS_DPRINTF3(LABEL, "RDS Send Pool Memory: %lld", memsize); 434 435 memp = (uint8_t *)kmem_zalloc(memsize, KM_NOSLEEP); 436 if (memp == NULL) { 437 RDS_DPRINTF1(LABEL, "RDS Send Memory allocation failed"); 438 return (-1); 439 } 440 441 RDS_DPRINTF3(LABEL, "RDS Buffer Entries Memory: %lld", 442 nbuf * sizeof (rds_buf_t)); 443 444 /* allocate memory for buffer entries */ 445 bufmemp = (rds_buf_t *)kmem_zalloc(nbuf * sizeof (rds_buf_t), 446 KM_SLEEP); 447 448 if (ep->ep_type == RDS_EP_TYPE_DATA) { 449 ack_addr = (uintptr_t)kmem_zalloc(sizeof (uintptr_t), KM_SLEEP); 450 451 /* register the memory with the HCA for this channel */ 452 mem_attr.mr_vaddr = (ib_vaddr_t)ack_addr; 453 mem_attr.mr_len = sizeof (uintptr_t); 454 mem_attr.mr_as = NULL; 455 mem_attr.mr_flags = IBT_MR_SLEEP | IBT_MR_ENABLE_LOCAL_WRITE | 456 IBT_MR_ENABLE_REMOTE_WRITE; 457 458 ret = ibt_register_mr(hcap->hca_hdl, hcap->hca_pdhdl, 459 &mem_attr, &ep->ep_ackhdl, &mem_desc); 460 if (ret != IBT_SUCCESS) { 461 RDS_DPRINTF2("rds_init_send_pool", 462 "EP(%p): ibt_register_mr for ack failed: %d", 463 ep, ret); 464 kmem_free(memp, memsize); 465 kmem_free(bufmemp, nbuf * sizeof (rds_buf_t)); 466 kmem_free((void *)ack_addr, sizeof (uintptr_t)); 467 return (-1); 468 } 469 ep->ep_ack_rkey = mem_desc.md_rkey; 470 ep->ep_ack_addr = ack_addr; 471 } 472 473 /* register the memory with the HCA for this channel */ 474 mem_attr.mr_vaddr = (ib_vaddr_t)(uintptr_t)memp; 475 mem_attr.mr_len = memsize; 476 mem_attr.mr_as = NULL; 477 mem_attr.mr_flags = IBT_MR_SLEEP | IBT_MR_ENABLE_LOCAL_WRITE; 478 479 ret = ibt_register_mr(hcap->hca_hdl, hcap->hca_pdhdl, 480 &mem_attr, &ep->ep_snd_mrhdl, &mem_desc); 481 if (ret != IBT_SUCCESS) { 482 RDS_DPRINTF2("rds_init_send_pool", "EP(%p): ibt_register_mr " 483 "failed: %d", ep, ret); 484 kmem_free(memp, memsize); 485 kmem_free(bufmemp, nbuf * sizeof (rds_buf_t)); 486 if (ack_addr != NULL) 487 kmem_free((void *)ack_addr, sizeof (uintptr_t)); 488 return (-1); 489 } 490 ep->ep_snd_lkey = mem_desc.md_lkey; 491 492 493 /* Initialize the pool */ 494 spool->pool_memp = memp; 495 spool->pool_memsize = memsize; 496 spool->pool_bufmemp = bufmemp; 497 spool->pool_sqpoll_pending = B_FALSE; 498 499 /* chain the buffers and initialize them */ 500 mp = memp; 501 bp = bufmemp; 502 503 if (ep->ep_type == RDS_EP_TYPE_DATA) { 504 for (ix = 0; ix < nbuf - 1; ix++) { 505 bp[ix].buf_nextp = &bp[ix + 1]; 506 bp[ix].buf_ep = ep; 507 bp[ix].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 508 bp[ix].buf_ds.ds_key = ep->ep_snd_lkey; 509 bp[ix].buf_state = RDS_SNDBUF_FREE; 510 pktp = (rds_data_hdr_t *)(uintptr_t)mp; 511 pktp->dh_bufid = (uintptr_t)&bp[ix]; 512 mp = mp + rcv_len; 513 } 514 bp[nbuf - 1].buf_nextp = NULL; 515 bp[nbuf - 1].buf_ep = ep; 516 bp[nbuf - 1].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 517 bp[nbuf - 1].buf_ds.ds_key = ep->ep_snd_lkey; 518 bp[nbuf - 1].buf_state = RDS_SNDBUF_FREE; 519 pktp = (rds_data_hdr_t *)(uintptr_t)mp; 520 pktp->dh_bufid = (uintptr_t)&bp[nbuf - 1]; 521 522 spool->pool_headp = &bp[0]; 523 spool->pool_tailp = &bp[nbuf - 1]; 524 525 mp = mp + rcv_len; 526 ep->ep_ackds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 527 ep->ep_ackds.ds_key = ep->ep_snd_lkey; 528 ep->ep_ackds.ds_len = sizeof (uintptr_t); 529 530 *(uintptr_t *)ep->ep_ack_addr = (uintptr_t)spool->pool_tailp; 531 } else { 532 /* control send pool */ 533 for (ix = 0; ix < nbuf - 1; ix++) { 534 bp[ix].buf_nextp = &bp[ix + 1]; 535 bp[ix].buf_ep = ep; 536 bp[ix].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 537 bp[ix].buf_ds.ds_key = ep->ep_snd_lkey; 538 bp[ix].buf_state = RDS_SNDBUF_FREE; 539 mp = mp + rcv_len; 540 } 541 bp[nbuf - 1].buf_nextp = NULL; 542 bp[nbuf - 1].buf_ep = ep; 543 bp[nbuf - 1].buf_ds.ds_va = (ib_vaddr_t)(uintptr_t)mp; 544 bp[nbuf - 1].buf_ds.ds_key = ep->ep_snd_lkey; 545 bp[nbuf - 1].buf_state = RDS_SNDBUF_FREE; 546 spool->pool_headp = &bp[0]; 547 spool->pool_tailp = &bp[nbuf - 1]; 548 } 549 550 RDS_DPRINTF3(LABEL, "rdsmemp start: %p end: %p", memp, mp); 551 RDS_DPRINTF2("rds_init_send_pool", "Return"); 552 553 return (0); 554 } 555 556 int 557 rds_reinit_send_pool(rds_ep_t *ep, ib_guid_t hca_guid) 558 { 559 rds_buf_t *bp; 560 rds_hca_t *hcap; 561 ibt_mr_attr_t mem_attr; 562 ibt_mr_desc_t mem_desc; 563 rds_bufpool_t *spool; 564 int ret; 565 566 RDS_DPRINTF2("rds_reinit_send_pool", "Enter: EP(%p)", ep); 567 568 spool = &ep->ep_sndpool; 569 ASSERT(spool->pool_memp != NULL); 570 571 /* deregister the send pool memory from the previous HCA */ 572 hcap = rds_get_hcap(rdsib_statep, ep->ep_hca_guid); 573 if (hcap == NULL) { 574 RDS_DPRINTF2("rds_reinit_send_pool", "HCA (0x%llx) not found", 575 ep->ep_hca_guid); 576 } else { 577 if (ep->ep_snd_mrhdl != NULL) { 578 (void) ibt_deregister_mr(hcap->hca_hdl, 579 ep->ep_snd_mrhdl); 580 ep->ep_snd_mrhdl = NULL; 581 ep->ep_snd_lkey = 0; 582 } 583 584 if ((ep->ep_type == RDS_EP_TYPE_DATA) && 585 (ep->ep_ackhdl != NULL)) { 586 (void) ibt_deregister_mr(hcap->hca_hdl, ep->ep_ackhdl); 587 ep->ep_ackhdl = NULL; 588 ep->ep_ack_rkey = 0; 589 } 590 591 ep->ep_hca_guid = NULL; 592 } 593 594 /* get the hcap for the new HCA */ 595 hcap = rds_get_hcap(rdsib_statep, hca_guid); 596 if (hcap == NULL) { 597 RDS_DPRINTF2("rds_reinit_send_pool", "HCA (0x%llx) not found", 598 hca_guid); 599 return (-1); 600 } 601 602 /* register the send memory */ 603 mem_attr.mr_vaddr = (ib_vaddr_t)(uintptr_t)spool->pool_memp; 604 mem_attr.mr_len = spool->pool_memsize; 605 mem_attr.mr_as = NULL; 606 mem_attr.mr_flags = IBT_MR_SLEEP | IBT_MR_ENABLE_LOCAL_WRITE; 607 608 ret = ibt_register_mr(hcap->hca_hdl, hcap->hca_pdhdl, 609 &mem_attr, &ep->ep_snd_mrhdl, &mem_desc); 610 if (ret != IBT_SUCCESS) { 611 RDS_DPRINTF2("rds_reinit_send_pool", 612 "EP(%p): ibt_register_mr failed: %d", ep, ret); 613 return (-1); 614 } 615 ep->ep_snd_lkey = mem_desc.md_lkey; 616 617 /* register the acknowledgement space */ 618 if (ep->ep_type == RDS_EP_TYPE_DATA) { 619 mem_attr.mr_vaddr = (ib_vaddr_t)ep->ep_ack_addr; 620 mem_attr.mr_len = sizeof (uintptr_t); 621 mem_attr.mr_as = NULL; 622 mem_attr.mr_flags = IBT_MR_SLEEP | IBT_MR_ENABLE_LOCAL_WRITE | 623 IBT_MR_ENABLE_REMOTE_WRITE; 624 625 ret = ibt_register_mr(hcap->hca_hdl, hcap->hca_pdhdl, 626 &mem_attr, &ep->ep_ackhdl, &mem_desc); 627 if (ret != IBT_SUCCESS) { 628 RDS_DPRINTF2("rds_reinit_send_pool", 629 "EP(%p): ibt_register_mr for ack failed: %d", 630 ep, ret); 631 (void) ibt_deregister_mr(hcap->hca_hdl, 632 ep->ep_snd_mrhdl); 633 ep->ep_snd_mrhdl = NULL; 634 ep->ep_snd_lkey = 0; 635 return (-1); 636 } 637 ep->ep_ack_rkey = mem_desc.md_rkey; 638 639 /* update the LKEY in the acknowledgement WR */ 640 ep->ep_ackds.ds_key = ep->ep_snd_lkey; 641 } 642 643 /* update the LKEY in each buffer */ 644 bp = spool->pool_headp; 645 while (bp) { 646 bp->buf_ds.ds_key = ep->ep_snd_lkey; 647 bp = bp->buf_nextp; 648 } 649 650 ep->ep_hca_guid = hca_guid; 651 652 RDS_DPRINTF2("rds_reinit_send_pool", "Return: EP(%p)", ep); 653 654 return (0); 655 } 656 657 void 658 rds_free_recv_pool(rds_ep_t *ep) 659 { 660 rds_bufpool_t *pool; 661 662 if (ep->ep_type == RDS_EP_TYPE_DATA) { 663 pool = &rds_dpool; 664 } else { 665 pool = &rds_cpool; 666 } 667 668 mutex_enter(&ep->ep_rcvpool.pool_lock); 669 if (ep->ep_rcvpool.pool_nfree != 0) { 670 rds_free_buf(pool, ep->ep_rcvpool.pool_headp, 671 ep->ep_rcvpool.pool_nfree); 672 ep->ep_rcvpool.pool_nfree = 0; 673 ep->ep_rcvpool.pool_headp = NULL; 674 ep->ep_rcvpool.pool_tailp = NULL; 675 } 676 mutex_exit(&ep->ep_rcvpool.pool_lock); 677 } 678 679 int 680 rds_init_recv_pool(rds_ep_t *ep) 681 { 682 rds_bufpool_t *rpool; 683 rds_qp_t *recvqp; 684 685 recvqp = &ep->ep_recvqp; 686 rpool = &ep->ep_rcvpool; 687 if (ep->ep_type == RDS_EP_TYPE_DATA) { 688 recvqp->qp_depth = MaxDataRecvBuffers; 689 recvqp->qp_level = 0; 690 recvqp->qp_lwm = (DataRecvBufferLWM * MaxDataRecvBuffers)/100; 691 recvqp->qp_taskqpending = B_FALSE; 692 693 rpool->pool_nbuffers = MaxDataRecvBuffers; 694 rpool->pool_nbusy = 0; 695 rpool->pool_nfree = 0; 696 } else { 697 recvqp->qp_depth = MaxCtrlRecvBuffers; 698 recvqp->qp_level = 0; 699 recvqp->qp_lwm = (CtrlRecvBufferLWM * MaxCtrlRecvBuffers)/100; 700 recvqp->qp_taskqpending = B_FALSE; 701 702 rpool->pool_nbuffers = MaxCtrlRecvBuffers; 703 rpool->pool_nbusy = 0; 704 rpool->pool_nfree = 0; 705 } 706 707 return (0); 708 } 709 710 /* Free buffers to the global pool, either cpool or dpool */ 711 void 712 rds_free_buf(rds_bufpool_t *pool, rds_buf_t *bp, uint_t nbuf) 713 { 714 uint_t ix; 715 716 RDS_DPRINTF4("rds_free_buf", "Enter"); 717 718 ASSERT(nbuf != 0); 719 720 mutex_enter(&pool->pool_lock); 721 722 if (pool->pool_nfree != 0) { 723 pool->pool_tailp->buf_nextp = bp; 724 } else { 725 pool->pool_headp = bp; 726 } 727 728 if (nbuf == 1) { 729 ASSERT(bp->buf_state == RDS_RCVBUF_FREE); 730 bp->buf_ep = NULL; 731 bp->buf_nextp = NULL; 732 pool->pool_tailp = bp; 733 } else { 734 for (ix = 1; ix < nbuf; ix++) { 735 ASSERT(bp->buf_state == RDS_RCVBUF_FREE); 736 bp->buf_ep = NULL; 737 bp = bp->buf_nextp; 738 } 739 ASSERT(bp->buf_state == RDS_RCVBUF_FREE); 740 bp->buf_ep = NULL; 741 bp->buf_nextp = NULL; 742 pool->pool_tailp = bp; 743 } 744 /* tail is always the last buffer */ 745 pool->pool_tailp->buf_nextp = NULL; 746 747 pool->pool_nfree += nbuf; 748 pool->pool_nbusy -= nbuf; 749 750 mutex_exit(&pool->pool_lock); 751 752 RDS_DPRINTF4("rds_free_buf", "Return"); 753 } 754 755 /* Get buffers from the global pools, either cpool or dpool */ 756 rds_buf_t * 757 rds_get_buf(rds_bufpool_t *pool, uint_t nbuf, uint_t *nret) 758 { 759 rds_buf_t *bp = NULL, *bp1; 760 uint_t ix; 761 762 RDS_DPRINTF4("rds_get_buf", "Enter"); 763 764 mutex_enter(&pool->pool_lock); 765 766 RDS_DPRINTF3("rds_get_buf", "Available: %d Needed: %d", 767 pool->pool_nfree, nbuf); 768 769 if (nbuf < pool->pool_nfree) { 770 *nret = nbuf; 771 772 bp1 = pool->pool_headp; 773 for (ix = 1; ix < nbuf; ix++) { 774 bp1 = bp1->buf_nextp; 775 } 776 777 bp = pool->pool_headp; 778 pool->pool_headp = bp1->buf_nextp; 779 bp1->buf_nextp = NULL; 780 781 pool->pool_nfree -= nbuf; 782 pool->pool_nbusy += nbuf; 783 } else if (nbuf >= pool->pool_nfree) { 784 *nret = pool->pool_nfree; 785 786 bp = pool->pool_headp; 787 788 pool->pool_headp = NULL; 789 pool->pool_tailp = NULL; 790 791 pool->pool_nbusy += pool->pool_nfree; 792 pool->pool_nfree = 0; 793 } 794 795 mutex_exit(&pool->pool_lock); 796 797 RDS_DPRINTF4("rds_get_buf", "Return"); 798 799 return (bp); 800 } 801 802 boolean_t 803 rds_is_recvq_empty(rds_ep_t *ep, boolean_t wait) 804 { 805 rds_qp_t *recvqp; 806 rds_bufpool_t *rpool; 807 boolean_t ret = B_TRUE; 808 809 recvqp = &ep->ep_recvqp; 810 mutex_enter(&recvqp->qp_lock); 811 RDS_DPRINTF2("rds_is_recvq_empty", "EP(%p): QP has %d WRs", 812 ep, recvqp->qp_level); 813 if (wait) { 814 /* wait until the RQ is empty */ 815 while (recvqp->qp_level != 0) { 816 /* wait one second and try again */ 817 mutex_exit(&recvqp->qp_lock); 818 delay(drv_sectohz(1)); 819 mutex_enter(&recvqp->qp_lock); 820 } 821 } else if (recvqp->qp_level != 0) { 822 ret = B_FALSE; 823 } 824 mutex_exit(&recvqp->qp_lock); 825 826 rpool = &ep->ep_rcvpool; 827 mutex_enter(&rpool->pool_lock); 828 829 /* 830 * During failovers/reconnects, the app may still have some buffers 831 * on thier socket queues. Waiting here for those buffers may 832 * cause a hang. It seems ok for those buffers to get freed later. 833 */ 834 if (rpool->pool_nbusy != 0) { 835 RDS_DPRINTF2("rds_is_recvq_empty", "EP(%p): " 836 "There are %d pending buffers on sockqs", ep, 837 rpool->pool_nbusy); 838 ret = B_FALSE; 839 } 840 mutex_exit(&rpool->pool_lock); 841 842 return (ret); 843 } 844 845 boolean_t 846 rds_is_sendq_empty(rds_ep_t *ep, uint_t wait) 847 { 848 rds_bufpool_t *spool; 849 rds_buf_t *bp; 850 boolean_t ret1 = B_TRUE; 851 852 /* check if all the sends completed */ 853 spool = &ep->ep_sndpool; 854 mutex_enter(&spool->pool_lock); 855 RDS_DPRINTF2("rds_is_sendq_empty", "EP(%p): " 856 "Send Pool contains: %d", ep, spool->pool_nbusy); 857 if (wait) { 858 while (spool->pool_nbusy != 0) { 859 if (rds_no_interrupts) { 860 /* wait one second and try again */ 861 delay(drv_sectohz(1)); 862 rds_poll_send_completions(ep->ep_sendcq, ep, 863 B_TRUE); 864 } else { 865 /* wait one second and try again */ 866 mutex_exit(&spool->pool_lock); 867 delay(drv_sectohz(1)); 868 mutex_enter(&spool->pool_lock); 869 } 870 } 871 872 if ((wait == 2) && (ep->ep_type == RDS_EP_TYPE_DATA)) { 873 rds_buf_t *ackbp; 874 rds_buf_t *prev_ackbp; 875 876 /* 877 * If the last one is acknowledged then everything 878 * is acknowledged 879 */ 880 bp = spool->pool_tailp; 881 ackbp = *(rds_buf_t **)ep->ep_ack_addr; 882 prev_ackbp = ackbp; 883 RDS_DPRINTF2("rds_is_sendq_empty", "EP(%p): " 884 "Checking for acknowledgements", ep); 885 while (bp != ackbp) { 886 RDS_DPRINTF2("rds_is_sendq_empty", 887 "EP(%p) BP(0x%p/0x%p) last " 888 "sent/acknowledged", ep, bp, ackbp); 889 mutex_exit(&spool->pool_lock); 890 delay(drv_sectohz(1)); 891 mutex_enter(&spool->pool_lock); 892 893 bp = spool->pool_tailp; 894 ackbp = *(rds_buf_t **)ep->ep_ack_addr; 895 if (ackbp == prev_ackbp) { 896 RDS_DPRINTF2("rds_is_sendq_empty", 897 "There has been no progress," 898 "give up and proceed"); 899 break; 900 } 901 prev_ackbp = ackbp; 902 } 903 } 904 } else if (spool->pool_nbusy != 0) { 905 ret1 = B_FALSE; 906 } 907 mutex_exit(&spool->pool_lock); 908 909 /* check if all the rdma acks completed */ 910 mutex_enter(&ep->ep_lock); 911 RDS_DPRINTF2("rds_is_sendq_empty", "EP(%p): " 912 "Outstanding RDMA Acks: %d", ep, ep->ep_rdmacnt); 913 if (wait) { 914 while (ep->ep_rdmacnt != 0) { 915 if (rds_no_interrupts) { 916 /* wait one second and try again */ 917 delay(drv_sectohz(1)); 918 rds_poll_send_completions(ep->ep_sendcq, ep, 919 B_FALSE); 920 } else { 921 /* wait one second and try again */ 922 mutex_exit(&ep->ep_lock); 923 delay(drv_sectohz(1)); 924 mutex_enter(&ep->ep_lock); 925 } 926 } 927 } else if (ep->ep_rdmacnt != 0) { 928 ret1 = B_FALSE; 929 } 930 mutex_exit(&ep->ep_lock); 931 932 return (ret1); 933 } 934 935 /* Get buffers from the send pool */ 936 rds_buf_t * 937 rds_get_send_buf(rds_ep_t *ep, uint_t nbuf) 938 { 939 rds_buf_t *bp = NULL, *bp1; 940 rds_bufpool_t *spool; 941 uint_t waittime = rds_waittime_ms * 1000; 942 uint_t ix; 943 int ret; 944 945 RDS_DPRINTF4("rds_get_send_buf", "Enter: EP(%p) Buffers requested: %d", 946 ep, nbuf); 947 948 spool = &ep->ep_sndpool; 949 mutex_enter(&spool->pool_lock); 950 951 if (rds_no_interrupts) { 952 if ((spool->pool_sqpoll_pending == B_FALSE) && 953 (spool->pool_nbusy > 954 (spool->pool_nbuffers * rds_poll_percent_full)/100)) { 955 spool->pool_sqpoll_pending = B_TRUE; 956 mutex_exit(&spool->pool_lock); 957 rds_poll_send_completions(ep->ep_sendcq, ep, B_FALSE); 958 mutex_enter(&spool->pool_lock); 959 spool->pool_sqpoll_pending = B_FALSE; 960 } 961 } 962 963 if (spool->pool_nfree < nbuf) { 964 /* wait for buffers to become available */ 965 spool->pool_cv_count += nbuf; 966 ret = cv_reltimedwait_sig(&spool->pool_cv, &spool->pool_lock, 967 drv_usectohz(waittime), TR_CLOCK_TICK); 968 /* ret = cv_wait_sig(&spool->pool_cv, &spool->pool_lock); */ 969 if (ret == 0) { 970 /* signal pending */ 971 spool->pool_cv_count -= nbuf; 972 mutex_exit(&spool->pool_lock); 973 return (NULL); 974 } 975 976 spool->pool_cv_count -= nbuf; 977 } 978 979 /* Have the number of buffers needed */ 980 if (spool->pool_nfree > nbuf) { 981 bp = spool->pool_headp; 982 983 if (ep->ep_type == RDS_EP_TYPE_DATA) { 984 rds_buf_t *ackbp; 985 ackbp = *(rds_buf_t **)ep->ep_ack_addr; 986 987 /* check if all the needed buffers are acknowledged */ 988 bp1 = bp; 989 for (ix = 0; ix < nbuf; ix++) { 990 if ((bp1 == ackbp) || 991 (bp1->buf_state != RDS_SNDBUF_FREE)) { 992 /* 993 * The buffer is not yet signalled or 994 * is not yet acknowledged 995 */ 996 RDS_DPRINTF5("rds_get_send_buf", 997 "EP(%p) Buffer (%p) not yet " 998 "acked/completed", ep, bp1); 999 mutex_exit(&spool->pool_lock); 1000 return (NULL); 1001 } 1002 1003 bp1 = bp1->buf_nextp; 1004 } 1005 } 1006 1007 /* mark the buffers as pending */ 1008 bp1 = bp; 1009 for (ix = 1; ix < nbuf; ix++) { 1010 ASSERT(bp1->buf_state == RDS_SNDBUF_FREE); 1011 bp1->buf_state = RDS_SNDBUF_PENDING; 1012 bp1 = bp1->buf_nextp; 1013 } 1014 ASSERT(bp1->buf_state == RDS_SNDBUF_FREE); 1015 bp1->buf_state = RDS_SNDBUF_PENDING; 1016 1017 spool->pool_headp = bp1->buf_nextp; 1018 bp1->buf_nextp = NULL; 1019 if (spool->pool_headp == NULL) 1020 spool->pool_tailp = NULL; 1021 spool->pool_nfree -= nbuf; 1022 spool->pool_nbusy += nbuf; 1023 } 1024 mutex_exit(&spool->pool_lock); 1025 1026 RDS_DPRINTF4("rds_get_send_buf", "Return: EP(%p) Buffers requested: %d", 1027 ep, nbuf); 1028 1029 return (bp); 1030 } 1031 1032 #define RDS_MIN_BUF_TO_WAKE_THREADS 10 1033 1034 void 1035 rds_free_send_buf(rds_ep_t *ep, rds_buf_t *headp, rds_buf_t *tailp, uint_t nbuf, 1036 boolean_t lock) 1037 { 1038 rds_bufpool_t *spool; 1039 rds_buf_t *tmp; 1040 1041 RDS_DPRINTF4("rds_free_send_buf", "Enter"); 1042 1043 ASSERT(nbuf != 0); 1044 1045 if (tailp == NULL) { 1046 if (nbuf > 1) { 1047 tmp = headp; 1048 while (tmp->buf_nextp) { 1049 tmp = tmp->buf_nextp; 1050 } 1051 tailp = tmp; 1052 } else { 1053 tailp = headp; 1054 } 1055 } 1056 1057 spool = &ep->ep_sndpool; 1058 1059 if (lock == B_FALSE) { 1060 /* lock is not held outside */ 1061 mutex_enter(&spool->pool_lock); 1062 } 1063 1064 if (spool->pool_nfree) { 1065 spool->pool_tailp->buf_nextp = headp; 1066 } else { 1067 spool->pool_headp = headp; 1068 } 1069 spool->pool_tailp = tailp; 1070 1071 spool->pool_nfree += nbuf; 1072 spool->pool_nbusy -= nbuf; 1073 1074 if ((spool->pool_cv_count > 0) && 1075 (spool->pool_nfree > RDS_MIN_BUF_TO_WAKE_THREADS)) { 1076 if (spool->pool_nfree >= spool->pool_cv_count) 1077 cv_broadcast(&spool->pool_cv); 1078 else 1079 cv_signal(&spool->pool_cv); 1080 } 1081 1082 if (lock == B_FALSE) { 1083 mutex_exit(&spool->pool_lock); 1084 } 1085 1086 RDS_DPRINTF4("rds_free_send_buf", "Return"); 1087 } 1088 1089 void 1090 rds_free_recv_buf(rds_buf_t *bp, uint_t nbuf) 1091 { 1092 rds_ep_t *ep; 1093 rds_bufpool_t *rpool; 1094 rds_buf_t *bp1; 1095 uint_t ix; 1096 1097 RDS_DPRINTF4("rds_free_recv_buf", "Enter"); 1098 1099 ASSERT(nbuf != 0); 1100 1101 ep = bp->buf_ep; 1102 rpool = &ep->ep_rcvpool; 1103 1104 mutex_enter(&rpool->pool_lock); 1105 1106 /* Add the buffers to the local pool */ 1107 if (rpool->pool_tailp == NULL) { 1108 ASSERT(rpool->pool_headp == NULL); 1109 ASSERT(rpool->pool_nfree == 0); 1110 rpool->pool_headp = bp; 1111 bp1 = bp; 1112 for (ix = 1; ix < nbuf; ix++) { 1113 if (bp1->buf_state == RDS_RCVBUF_ONSOCKQ) { 1114 rpool->pool_nbusy--; 1115 } 1116 bp1->buf_state = RDS_RCVBUF_FREE; 1117 bp1 = bp1->buf_nextp; 1118 } 1119 bp1->buf_nextp = NULL; 1120 if (bp->buf_state == RDS_RCVBUF_ONSOCKQ) { 1121 rpool->pool_nbusy--; 1122 } 1123 bp->buf_state = RDS_RCVBUF_FREE; 1124 rpool->pool_tailp = bp1; 1125 rpool->pool_nfree += nbuf; 1126 } else { 1127 bp1 = bp; 1128 for (ix = 1; ix < nbuf; ix++) { 1129 if (bp1->buf_state == RDS_RCVBUF_ONSOCKQ) { 1130 rpool->pool_nbusy--; 1131 } 1132 bp1->buf_state = RDS_RCVBUF_FREE; 1133 bp1 = bp1->buf_nextp; 1134 } 1135 bp1->buf_nextp = NULL; 1136 if (bp->buf_state == RDS_RCVBUF_ONSOCKQ) { 1137 rpool->pool_nbusy--; 1138 } 1139 bp->buf_state = RDS_RCVBUF_FREE; 1140 rpool->pool_tailp->buf_nextp = bp; 1141 rpool->pool_tailp = bp1; 1142 rpool->pool_nfree += nbuf; 1143 } 1144 1145 if (rpool->pool_nfree >= rds_nbuffers_to_putback) { 1146 bp = rpool->pool_headp; 1147 nbuf = rpool->pool_nfree; 1148 rpool->pool_headp = NULL; 1149 rpool->pool_tailp = NULL; 1150 rpool->pool_nfree = 0; 1151 mutex_exit(&rpool->pool_lock); 1152 1153 /* Free the buffers to the global pool */ 1154 if (ep->ep_type == RDS_EP_TYPE_DATA) { 1155 rds_free_buf(&rds_dpool, bp, nbuf); 1156 } else { 1157 rds_free_buf(&rds_cpool, bp, nbuf); 1158 } 1159 1160 return; 1161 } 1162 mutex_exit(&rpool->pool_lock); 1163 1164 RDS_DPRINTF4("rds_free_recv_buf", "Return"); 1165 }