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