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.
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.
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 * PURPOSE: Shared Receive Queue
32 * Description: Interfaces in this file are completely described in
33 * the DAPL 1.2 API, Chapter 6, section 5
38 #include "dapl_adapter_util.h"
39 #include "dapl_ia_util.h"
40 #include "dapl_srq_util.h"
41 #include "dapl_cookie.h"
46 * uDAPL: User Direct Access Program Library Version 1.2, 6.5.1
48 * creates an instance of a Shared Receive Queue (SRQ) that is provided
49 * to the Consumer as srq_handle.
61 * DAT_INSUFFICIENT_RESOURCES
63 * DAT_INVALID_PARAMETER
64 * DAT_MODEL_NOT_SUPPORTED
69 IN DAT_IA_HANDLE ia_handle
,
70 IN DAT_PZ_HANDLE pz_handle
,
71 IN DAT_SRQ_ATTR
*srq_attr
,
72 OUT DAT_SRQ_HANDLE
*srq_handle
)
76 DAT_SRQ_ATTR srq_attr_limit
;
77 DAT_RETURN dat_status
;
79 ia_ptr
= (DAPL_IA
*)ia_handle
;
80 dat_status
= DAT_SUCCESS
;
84 if (DAPL_BAD_HANDLE(ia_ptr
, DAPL_MAGIC_IA
)) {
85 dat_status
= DAT_ERROR(DAT_INVALID_HANDLE
,
86 DAT_INVALID_HANDLE_IA
);
90 if ((pz_handle
== NULL
) || DAPL_BAD_HANDLE(pz_handle
, DAPL_MAGIC_PZ
)) {
91 dat_status
= DAT_ERROR(DAT_INVALID_HANDLE
,
92 DAT_INVALID_HANDLE_PZ
);
96 if ((srq_attr
== NULL
) || ((uintptr_t)srq_attr
& 3)) {
97 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG3
);
101 if (srq_handle
== NULL
) {
102 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG4
);
106 if (srq_attr
->max_recv_dtos
== 0 || srq_attr
->max_recv_iov
== 0 ||
107 srq_attr
->low_watermark
!= DAT_SRQ_LW_DEFAULT
) {
108 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG3
);
112 /* Verify the attributes against the transport */
113 (void) dapl_os_memzero(&srq_attr_limit
, sizeof (DAT_SRQ_ATTR
));
114 dat_status
= dapls_ib_query_hca(ia_ptr
->hca_ptr
, NULL
, NULL
, NULL
,
116 if (dat_status
!= DAT_SUCCESS
) {
119 if (srq_attr
->max_recv_dtos
> srq_attr_limit
.max_recv_dtos
||
120 srq_attr
->max_recv_iov
> srq_attr_limit
.max_recv_iov
) {
121 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG3
);
126 srq_ptr
= dapl_srq_alloc(ia_ptr
, srq_attr
);
127 if (srq_ptr
== NULL
) {
128 dat_status
= DAT_ERROR(DAT_INSUFFICIENT_RESOURCES
,
129 DAT_RESOURCE_MEMORY
);
133 /* Take a reference on the PZ handle */
134 dapl_os_atomic_inc(&((DAPL_PZ
*)pz_handle
)->pz_ref_count
);
139 srq_ptr
->param
.ia_handle
= ia_handle
;
140 srq_ptr
->param
.srq_state
= DAT_SRQ_STATE_OPERATIONAL
;
141 srq_ptr
->param
.pz_handle
= pz_handle
;
142 srq_ptr
->param
.max_recv_dtos
= srq_attr
->max_recv_dtos
;
143 srq_ptr
->param
.max_recv_iov
= srq_attr
->max_recv_iov
;
144 srq_ptr
->param
.low_watermark
= DAT_SRQ_LW_DEFAULT
;
146 srq_ptr
->param
.available_dto_count
= DAT_VALUE_UNKNOWN
;
147 srq_ptr
->param
.outstanding_dto_count
= 0;
149 dat_status
= dapls_ib_srq_alloc(ia_ptr
, srq_ptr
);
150 if (dat_status
!= DAT_SUCCESS
) {
151 dapl_os_atomic_dec(&((DAPL_PZ
*)pz_handle
)->pz_ref_count
);
152 dapl_srq_dealloc(srq_ptr
);
155 /* Link it onto the IA */
156 dapl_ia_link_srq(ia_ptr
, srq_ptr
);
158 *srq_handle
= srq_ptr
;
166 * uDAPL: User Direct Access Program Library Version 1.2, 6.5.5
168 * destroys an instance of the SRQ. The SRQ cannot be destroyed if it is
185 IN DAT_SRQ_HANDLE srq_handle
)
189 DAT_SRQ_PARAM
*param
;
190 DAT_RETURN dat_status
= DAT_SUCCESS
;
192 if (DAPL_BAD_HANDLE(srq_handle
, DAPL_MAGIC_SRQ
)) {
193 dat_status
= DAT_ERROR(DAT_INVALID_HANDLE
,
194 DAT_INVALID_HANDLE_SRQ
);
198 srq_ptr
= (DAPL_SRQ
*)srq_handle
;
199 param
= &srq_ptr
->param
;
200 if (0 != srq_ptr
->srq_ref_count
) {
201 dapl_dbg_log(DAPL_DBG_TYPE_EP
,
202 "dapl_srq_free: Free SRQ: %p, refcnt %d\n",
203 srq_ptr
, srq_ptr
->srq_ref_count
);
204 dat_status
= DAT_ERROR(DAT_INVALID_HANDLE
,
205 DAT_INVALID_STATE_SRQ_IN_USE
);
209 ia_ptr
= srq_ptr
->header
.owner_ia
;
210 param
->srq_state
= DAT_SRQ_STATE_ERROR
;
212 dapls_ib_srq_free(ia_ptr
, srq_ptr
);
214 /* Remove link from the IA */
215 dapl_ia_unlink_srq(ia_ptr
, srq_ptr
);
217 dapl_os_assert(param
->pz_handle
!= NULL
);
218 dapl_os_atomic_dec(&((DAPL_PZ
*)param
->pz_handle
)->pz_ref_count
);
219 param
->pz_handle
= NULL
;
221 dapl_srq_dealloc(srq_ptr
);
230 * uDAPL: User Direct Access Program Library Version 1.2, 6.5.8
232 * posts the receive buffer that can be used for the incoming message into
233 * the local_iov by any connected EP that uses SRQ.
247 * DAT_INSUFFICIENT_RESOURCES
248 * DAT_INVALID_PARAMETER
249 * DAT_PROTECTION_VIOLATION
250 * DAT_PRIVILEGES_VIOLATION
255 IN DAT_SRQ_HANDLE srq_handle
,
256 IN DAT_COUNT num_segments
,
257 IN DAT_LMR_TRIPLET
*local_iov
,
258 IN DAT_DTO_COOKIE user_cookie
)
262 DAT_RETURN dat_status
;
264 dapl_dbg_log(DAPL_DBG_TYPE_API
,
265 "dapl_srq_post_recv (%p, %d, %p, %P)\n",
271 if (DAPL_BAD_HANDLE(srq_handle
, DAPL_MAGIC_SRQ
)) {
272 dat_status
= DAT_ERROR(DAT_INVALID_HANDLE
,
273 DAT_INVALID_HANDLE_SRQ
);
277 srq_ptr
= (DAPL_SRQ
*) srq_handle
;
280 * Synchronization ok since this buffer is only used for receive
281 * requests, which aren't allowed to race with each other.
283 dat_status
= dapls_dto_cookie_alloc(&srq_ptr
->recv_buffer
,
287 if (DAT_SUCCESS
!= dat_status
) {
292 * Invoke provider specific routine to post DTO
294 dat_status
= dapls_ib_post_srq(srq_ptr
, cookie
, num_segments
,
297 if (dat_status
!= DAT_SUCCESS
) {
298 dapls_cookie_dealloc(&srq_ptr
->recv_buffer
, cookie
);
300 dapl_os_atomic_inc(&srq_ptr
->recv_count
);
304 dapl_dbg_log(DAPL_DBG_TYPE_RTN
,
305 "dapl_srq_post_recv () returns 0x%x\n", dat_status
);
314 * uDAPL: User Direct Access Program Library Version 1.2, 6.5.6
316 * provides to the Consumer SRQ parameters. The Consumer passes in a pointer
317 * to the Consumer-allocated structures for SRQ parameters that the Provider
330 * DAT_INVALID_PARAMETER
335 IN DAT_SRQ_HANDLE srq_handle
,
336 IN DAT_SRQ_PARAM_MASK srq_param_mask
,
337 OUT DAT_SRQ_PARAM
*srq_param
)
340 DAT_RETURN dat_status
;
342 dat_status
= DAT_SUCCESS
;
344 if (srq_param_mask
& ~DAT_SRQ_FIELD_ALL
) {
345 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG2
);
349 if (NULL
== srq_param
) {
350 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG3
);
355 if (DAPL_BAD_HANDLE(srq_handle
, DAPL_MAGIC_SRQ
)) {
356 dat_status
= DAT_ERROR(DAT_INVALID_HANDLE
, 0);
360 srq_ptr
= (DAPL_SRQ
*)srq_handle
;
361 /* Do a struct copy */
362 *srq_param
= srq_ptr
->param
;
363 /* update the outstanding dto count */
364 srq_param
->outstanding_dto_count
= srq_ptr
->recv_count
;
373 * uDAPL: User Direct Access Program Library Version 1.2, 6.5.4
375 * sets the low watermark value for SRQ and arms SRQ for generating an
376 * asynchronous event for low watermark. An asynchronous event will be
377 * generated when the number of buffers on SRQ is below the low watermark
378 * for the first time. This may happen during this call or when an
379 * associated EP takes a buffer from the SRQ.
391 * DAT_INVALID_PARAMETER
392 * DAT_MODEL_NOT_SUPPORTED
398 IN DAT_SRQ_HANDLE srq_handle
,
399 IN DAT_COUNT low_watermark
)
401 return (DAT_MODEL_NOT_SUPPORTED
);
407 * uDAPL: User Direct Access Program Library Version 1.2, 6.5.7
409 * modifies the size of the queue of SRQ. Resizing of SRQ shall not cause
410 * any incoming messages on any of the EPs that use the SRQ to be lost.
422 * DAT_INVALID_PARAMETER
423 * DAT_INSUFFICIENT_RESOURCES
430 IN DAT_SRQ_HANDLE srq_handle
,
431 IN DAT_COUNT srq_max_recv_dtos
)
434 DAT_SRQ_ATTR srq_attr_limit
;
435 DAPL_COOKIE_BUFFER new_cb
;
436 DAT_RETURN dat_status
;
439 srq_ptr
= (DAPL_SRQ
*)srq_handle
;
440 dat_status
= DAT_SUCCESS
;
442 if (DAPL_BAD_HANDLE(srq_handle
, DAPL_MAGIC_SRQ
)) {
443 return (DAT_ERROR(DAT_INVALID_HANDLE
, DAT_HANDLE_TYPE_SRQ
));
446 /* can't shrink below the number of outstanding recvs */
447 if (srq_max_recv_dtos
< srq_ptr
->recv_count
) {
448 return (DAT_ERROR(DAT_INVALID_STATE
, 0));
452 * shrinking SRQs is not supported on tavor return success without
455 if (srq_max_recv_dtos
<= srq_ptr
->param
.max_recv_dtos
) {
456 return (DAT_SUCCESS
);
459 /* Verify the attributes against the transport */
460 (void) dapl_os_memzero(&srq_attr_limit
, sizeof (DAT_SRQ_ATTR
));
461 dat_status
= dapls_ib_query_hca(srq_ptr
->header
.owner_ia
->hca_ptr
,
462 NULL
, NULL
, NULL
, &srq_attr_limit
);
463 if (dat_status
!= DAT_SUCCESS
) {
467 if (srq_max_recv_dtos
> srq_attr_limit
.max_recv_dtos
) {
468 dat_status
= DAT_ERROR(DAT_INVALID_PARAMETER
, DAT_INVALID_ARG2
);
472 dat_status
= dapls_cb_resize(&srq_ptr
->recv_buffer
, srq_max_recv_dtos
,
474 if (dat_status
!= DAT_SUCCESS
) {
478 dat_status
= dapls_ib_srq_resize(srq_ptr
, srq_max_recv_dtos
);
479 if (dat_status
!= DAT_SUCCESS
) {
483 dapls_cb_free(&srq_ptr
->recv_buffer
);
484 srq_ptr
->recv_buffer
= new_cb
; /* struct copy */
485 srq_ptr
->param
.max_recv_dtos
= srq_max_recv_dtos
;
487 return (DAT_SUCCESS
);
489 dapls_cb_free(&new_cb
);