xref: /illumos-gate/usr/src/uts/common/io/ib/ibtl/ibtl_srq.c (revision 24da5b34f49324ed742a340010ed5bd3d4e06625)
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 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/ib/ibtl/impl/ibtl.h>
29 
30 /*
31  * ibtl_srq.c
32  *	These routines implement (most of) the verbs related to
33  *	Shared Receive Queues.
34  */
35 
36 /*
37  * Globals
38  */
39 
40 static char ibtf_srq[] = "ibtl_srq";
41 
42 /*
43  * This file contains code for the TI SRQ calls
44  */
45 
46 /*
47  *
48  * ibt_alloc_srq() - Allocate a completion queue
49  */
50 ibt_status_t
51 ibt_alloc_srq(ibt_hca_hdl_t hca_hdl, ibt_srq_flags_t flags, ibt_pd_hdl_t pd,
52     ibt_srq_sizes_t *srq_sizes, ibt_srq_hdl_t *ibt_srq_p,
53     ibt_srq_sizes_t *real_sizes_p)
54 {
55 	ibt_status_t 		status;
56 	ibt_srq_hdl_t		ibt_srq;
57 
58 	IBTF_DPRINTF_L3(ibtf_srq, "ibt_alloc_srq(%p, %p)",
59 	    hca_hdl, srq_sizes);
60 
61 	ibt_srq = kmem_zalloc(sizeof (struct ibtl_srq_s), KM_SLEEP);
62 	*ibt_srq_p = ibt_srq;
63 
64 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_srq->srq_ibc_srq_hdl))
65 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_srq->srq_hca))
66 	/*
67 	 * Set the following values before creating CI SRQ, to avoid race
68 	 * conditions on async callback.
69 	 */
70 	ibt_srq->srq_hca = hca_hdl;
71 
72 	status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_srq(
73 	    IBTL_HCA2CIHCA(hca_hdl), flags, ibt_srq, pd, srq_sizes,
74 	    &ibt_srq->srq_ibc_srq_hdl, real_sizes_p);
75 
76 	if (status != IBT_SUCCESS) {
77 		IBTF_DPRINTF_L2(ibtf_srq, "ibt_alloc_srq: "
78 		    "CI SRQ handle allocation failed: status = %d", status);
79 		kmem_free(ibt_srq, sizeof (struct ibtl_srq_s));
80 		*ibt_srq_p = NULL;
81 		return (status);
82 	}
83 
84 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_srq->srq_ibc_srq_hdl))
85 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_srq->srq_hca))
86 
87 	/* Update the srq resource count */
88 	mutex_enter(&hca_hdl->ha_mutex);
89 	hca_hdl->ha_srq_cnt++;
90 	mutex_exit(&hca_hdl->ha_mutex);
91 
92 	return (IBT_SUCCESS);
93 }
94 
95 
96 /*
97  * ibt_free_srq() - Free a shared receive queue
98  *
99  */
100 ibt_status_t
101 ibt_free_srq(ibt_srq_hdl_t ibt_srq)
102 {
103 	ibt_status_t	status;
104 	ibtl_hca_t	*ibt_hca = ibt_srq->srq_hca;
105 
106 	IBTF_DPRINTF_L3(ibtf_srq, "ibt_free_srq(%p)", ibt_srq);
107 
108 	status = ((IBTL_SRQ2CIHCAOPS_P(ibt_srq))->ibc_free_srq)
109 	    (IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl);
110 
111 	if (status != IBT_SUCCESS) {
112 		IBTF_DPRINTF_L2(ibtf_srq, "ibt_free_srq: "
113 		    "CI SRQ handle de-allocation failed: status = %d", status);
114 		return (status);
115 	}
116 
117 	ibtl_free_srq_async_check(ibt_srq);
118 
119 	/* Update the srq resource count */
120 	mutex_enter(&ibt_hca->ha_mutex);
121 	ibt_hca->ha_srq_cnt--;
122 	mutex_exit(&ibt_hca->ha_mutex);
123 
124 	return (status);
125 }
126 
127 
128 /*
129  * ibt_query_srq() - Returns the size of the srq
130  */
131 ibt_status_t
132 ibt_query_srq(ibt_srq_hdl_t ibt_srq, ibt_pd_hdl_t *pd_p,
133     ibt_srq_sizes_t *sizes_p, uint_t *limit)
134 {
135 	IBTF_DPRINTF_L3(ibtf_srq, "ibt_query_srq(%p)", ibt_srq);
136 
137 	return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_query_srq(
138 	    IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl, pd_p,
139 	    sizes_p, limit));
140 }
141 
142 
143 /*
144  *  ibt_resize_srq() - Change the size of a srq.
145  */
146 ibt_status_t
147 ibt_modify_srq(ibt_srq_hdl_t ibt_srq, ibt_srq_modify_flags_t flags,
148     uint_t size, uint_t limit, uint_t *real_size_p)
149 {
150 	IBTF_DPRINTF_L3(ibtf_srq, "ibt_modify_srq(%p, %d, %d, %d)",
151 	    ibt_srq, flags, size, limit);
152 
153 	return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_modify_srq(
154 	    IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl,
155 	    flags, size, limit, real_size_p));
156 }
157 
158 
159 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_srq_s::srq_clnt_private))
160 
161 /*
162  * ibt_set_srq_private - Sets the private data on a given SRQ
163  *
164  *      ibt_srq          The ibt_srq_hdl_t of the allocated SRQ.
165  *      clnt_private    The client private data.
166  */
167 void
168 ibt_set_srq_private(ibt_srq_hdl_t ibt_srq, void *clnt_private)
169 {
170 	ibt_srq->srq_clnt_private = clnt_private;
171 }
172 
173 
174 /*
175  * ibt_get_srq_private - Retrieves the private data for a given SRQ
176  *
177  *      ibt_srq          The ibt_srq_hdl_t of the allocated SRQ.
178  */
179 void *
180 ibt_get_srq_private(ibt_srq_hdl_t ibt_srq)
181 {
182 	return (ibt_srq->srq_clnt_private);
183 }
184 
185 /*
186  * Function:
187  *	ibt_post_srq
188  * Input:
189  *	srq	- SRQ.
190  *	wr_list	- Address of array[size] of work requests.
191  *	size	- Number of work requests.
192  * Output:
193  *	posted	- Address to return the number of work requests
194  *		  successfully posted.  May be NULL.
195  * Description:
196  *	Post one or more receive work requests to the SRQ.
197  */
198 
199 ibt_status_t
200 ibt_post_srq(ibt_srq_hdl_t srq, ibt_recv_wr_t *wr_list, uint_t size,
201     uint_t *posted)
202 {
203 	IBTF_DPRINTF_L4(ibtf_srq, "ibt_post_srq(%p, %p, %d)",
204 	    srq, wr_list, size);
205 
206 	return (IBTL_SRQ2CIHCAOPS_P(srq)->ibc_post_srq(IBTL_SRQ2CIHCA(srq),
207 	    srq->srq_ibc_srq_hdl, wr_list, size, posted));
208 }
209