xref: /onnv-gate/usr/src/uts/common/io/ib/ibtl/ibtl_cq.c (revision 12965:b65a8427f8fe)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
58580SBill.Taylor@Sun.COM  * Common Development and Distribution License (the "License").
68580SBill.Taylor@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
2212574SWilliam.Taylor@Oracle.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate #include <sys/ib/ibtl/impl/ibtl.h>
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate  * ibtl_cq.c
290Sstevel@tonic-gate  *	These routines implement (most of) the verbs related to
300Sstevel@tonic-gate  *	Completion Queues.
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate 
330Sstevel@tonic-gate /*
340Sstevel@tonic-gate  * Globals
350Sstevel@tonic-gate  */
360Sstevel@tonic-gate 
370Sstevel@tonic-gate static char ibtf_cq[] = "ibtl_cq";
380Sstevel@tonic-gate 
390Sstevel@tonic-gate /*
400Sstevel@tonic-gate  * This file contains code for the  TI CQ calls
410Sstevel@tonic-gate  */
420Sstevel@tonic-gate 
430Sstevel@tonic-gate /*
440Sstevel@tonic-gate  * ibt_alloc_cq_sched() - Reserve CQ scheduling class resources
450Sstevel@tonic-gate  *
460Sstevel@tonic-gate  *	chan	    - IBT Channel Handle.
470Sstevel@tonic-gate  *	load	    - Expected CQ load in class, 0 = unspecified
480Sstevel@tonic-gate  *      sched_hdl_p - Returned scheduling handle.
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate ibt_status_t
ibt_alloc_cq_sched(ibt_hca_hdl_t hca_hdl,ibt_cq_sched_attr_t * attr,ibt_sched_hdl_t * sched_hdl_p)510Sstevel@tonic-gate ibt_alloc_cq_sched(ibt_hca_hdl_t hca_hdl, ibt_cq_sched_attr_t *attr,
520Sstevel@tonic-gate     ibt_sched_hdl_t *sched_hdl_p)
530Sstevel@tonic-gate {
540Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_alloc_cq_sched(%p, %p, %p)",
550Sstevel@tonic-gate 	    hca_hdl, attr, sched_hdl_p);
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 	return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_cq_sched(
58*12965SWilliam.Taylor@Oracle.COM 	    IBTL_HCA2CIHCA(hca_hdl), attr, sched_hdl_p));
590Sstevel@tonic-gate }
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 
620Sstevel@tonic-gate /*
630Sstevel@tonic-gate  * ibt_free_cq_sched() - Free CQ scheduling class resources
640Sstevel@tonic-gate  *
650Sstevel@tonic-gate  *	chan	  - IBT Channel Handle.
660Sstevel@tonic-gate  *      sched_hdl - Scheduling handle returned from ibt_alloc_cq_sched.
670Sstevel@tonic-gate  *	load	  - CQ load being removed.
680Sstevel@tonic-gate  */
690Sstevel@tonic-gate ibt_status_t
ibt_free_cq_sched(ibt_hca_hdl_t hca_hdl,ibt_sched_hdl_t sched_hdl)70*12965SWilliam.Taylor@Oracle.COM ibt_free_cq_sched(ibt_hca_hdl_t hca_hdl, ibt_sched_hdl_t sched_hdl)
710Sstevel@tonic-gate {
72*12965SWilliam.Taylor@Oracle.COM 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_free_cq_sched(%p, %p)",
73*12965SWilliam.Taylor@Oracle.COM 	    hca_hdl, sched_hdl);
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_free_cq_sched(
76*12965SWilliam.Taylor@Oracle.COM 	    IBTL_HCA2CIHCA(hca_hdl), sched_hdl));
770Sstevel@tonic-gate }
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 
800Sstevel@tonic-gate /*
810Sstevel@tonic-gate  *
820Sstevel@tonic-gate  * ibt_alloc_cq() - Allocate a completion queue
830Sstevel@tonic-gate  */
840Sstevel@tonic-gate ibt_status_t
ibt_alloc_cq(ibt_hca_hdl_t hca_hdl,ibt_cq_attr_t * cq_attr,ibt_cq_hdl_t * ibt_cq_p,uint32_t * real_size)850Sstevel@tonic-gate ibt_alloc_cq(ibt_hca_hdl_t hca_hdl, ibt_cq_attr_t *cq_attr,
860Sstevel@tonic-gate     ibt_cq_hdl_t *ibt_cq_p, uint32_t *real_size)
870Sstevel@tonic-gate {
880Sstevel@tonic-gate 	ibt_status_t 		status;
890Sstevel@tonic-gate 	ibt_cq_hdl_t		ibt_cq;
900Sstevel@tonic-gate 
910Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_alloc_cq(%p, %p)",
920Sstevel@tonic-gate 	    hca_hdl, cq_attr);
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	ibt_cq = kmem_zalloc(sizeof (struct ibtl_cq_s), KM_SLEEP);
960Sstevel@tonic-gate 	*ibt_cq_p = ibt_cq;
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq->cq_in_thread))
990Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq->cq_ibc_cq_hdl))
1000Sstevel@tonic-gate 	_NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq->cq_hca))
1010Sstevel@tonic-gate 	/*
1020Sstevel@tonic-gate 	 * Set the following values before creating CI CQ, to avoid race
1030Sstevel@tonic-gate 	 * conditions on async callback.
1040Sstevel@tonic-gate 	 */
1050Sstevel@tonic-gate 	ibt_cq->cq_hca = hca_hdl;
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	ibtl_qp_flow_control_enter();
1080Sstevel@tonic-gate 	status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_cq(
1090Sstevel@tonic-gate 	    IBTL_HCA2CIHCA(hca_hdl), ibt_cq, cq_attr, &ibt_cq->cq_ibc_cq_hdl,
1100Sstevel@tonic-gate 	    real_size);
1110Sstevel@tonic-gate 	ibtl_qp_flow_control_exit();
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
1140Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cq, "ibt_alloc_cq: "
1150Sstevel@tonic-gate 		    "CI CQ handle allocation failed: status = %d", status);
1160Sstevel@tonic-gate 		kmem_free(ibt_cq, sizeof (struct ibtl_cq_s));
1170Sstevel@tonic-gate 		*ibt_cq_p = NULL;
1180Sstevel@tonic-gate 		return (status);
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 	if (cq_attr->cq_flags & IBT_CQ_HANDLER_IN_THREAD) {
1220Sstevel@tonic-gate 		ibt_cq->cq_in_thread = 1;
1230Sstevel@tonic-gate 		/* We may want additional CQ threads now. */
1240Sstevel@tonic-gate 		ibtl_another_cq_handler_in_thread();
1250Sstevel@tonic-gate 	}
1260Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq->cq_in_thread))
1270Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq->cq_ibc_cq_hdl))
1280Sstevel@tonic-gate 	_NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq->cq_hca))
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	mutex_init(&ibt_cq->cq_mutex, NULL, MUTEX_DEFAULT, NULL);
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	/* Update the cq resource count */
13312574SWilliam.Taylor@Oracle.COM 	atomic_inc_32(&hca_hdl->ha_cq_cnt);
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	return (IBT_SUCCESS);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate /*
1400Sstevel@tonic-gate  * ibt_free_cq() - Free a completion queue
1410Sstevel@tonic-gate  *
1420Sstevel@tonic-gate  */
1430Sstevel@tonic-gate ibt_status_t
ibt_free_cq(ibt_cq_hdl_t ibt_cq)1440Sstevel@tonic-gate ibt_free_cq(ibt_cq_hdl_t ibt_cq)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate 	ibt_status_t	status;
1470Sstevel@tonic-gate 	ibtl_hca_t	*ibt_hca = ibt_cq->cq_hca;
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_free_cq(%p)", ibt_cq);
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 	ibtl_free_cq_check(ibt_cq);
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	status = ((IBTL_CQ2CIHCAOPS_P(ibt_cq))->ibc_free_cq)
1540Sstevel@tonic-gate 	    (IBTL_CQ2CIHCA(ibt_cq), ibt_cq->cq_ibc_cq_hdl);
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	if (status != IBT_SUCCESS) {
1570Sstevel@tonic-gate 		IBTF_DPRINTF_L2(ibtf_cq, "ibt_free_cq: "
1580Sstevel@tonic-gate 		    "CI CQ handle de-allocation failed: status = %d", status);
1590Sstevel@tonic-gate 		return (status);
1600Sstevel@tonic-gate 	}
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 	/* mutex_destroy(&ibt_cq->cq_mutex); */
1630Sstevel@tonic-gate 	ibtl_free_cq_async_check(ibt_cq);
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	/* Update the cq resource count */
16612574SWilliam.Taylor@Oracle.COM 	atomic_dec_32(&ibt_hca->ha_cq_cnt);
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	return (status);
1690Sstevel@tonic-gate }
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate /*
1730Sstevel@tonic-gate  * ibt_query_cq() - Returns the size of the cq
1740Sstevel@tonic-gate  */
1750Sstevel@tonic-gate ibt_status_t
ibt_query_cq(ibt_cq_hdl_t ibt_cq,uint32_t * entries_p,uint_t * count_p,uint_t * usec_p,ibt_cq_handler_id_t * hid_p)1768580SBill.Taylor@Sun.COM ibt_query_cq(ibt_cq_hdl_t ibt_cq, uint32_t *entries_p, uint_t *count_p,
1778580SBill.Taylor@Sun.COM     uint_t *usec_p, ibt_cq_handler_id_t *hid_p)
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_query_cq(%p)", ibt_cq);
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	return (IBTL_CQ2CIHCAOPS_P(ibt_cq)->ibc_query_cq(IBTL_CQ2CIHCA(ibt_cq),
1828580SBill.Taylor@Sun.COM 	    ibt_cq->cq_ibc_cq_hdl, entries_p, count_p, usec_p, hid_p));
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate /*
1870Sstevel@tonic-gate  *  ibt_resize_cq() - Change the size of a cq.
1880Sstevel@tonic-gate  */
1890Sstevel@tonic-gate ibt_status_t
ibt_resize_cq(ibt_cq_hdl_t ibt_cq,uint32_t new_sz,uint32_t * real_sz)1900Sstevel@tonic-gate ibt_resize_cq(ibt_cq_hdl_t ibt_cq, uint32_t new_sz, uint32_t *real_sz)
1910Sstevel@tonic-gate {
1920Sstevel@tonic-gate 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_resize_cq(%p, %d)", ibt_cq, new_sz);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 	return (IBTL_CQ2CIHCAOPS_P(ibt_cq)->ibc_resize_cq(IBTL_CQ2CIHCA(ibt_cq),
1950Sstevel@tonic-gate 	    ibt_cq->cq_ibc_cq_hdl, new_sz, real_sz));
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate 
1988580SBill.Taylor@Sun.COM ibt_status_t
ibt_modify_cq(ibt_cq_hdl_t ibt_cq,uint_t count,uint_t usec,ibt_cq_handler_id_t hid)1998580SBill.Taylor@Sun.COM ibt_modify_cq(ibt_cq_hdl_t ibt_cq, uint_t count, uint_t usec,
2008580SBill.Taylor@Sun.COM     ibt_cq_handler_id_t hid)
2018580SBill.Taylor@Sun.COM {
2028580SBill.Taylor@Sun.COM 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_modify_cq(%p, %d, %d, %d)", ibt_cq, count,
2038580SBill.Taylor@Sun.COM 	    usec, hid);
2048580SBill.Taylor@Sun.COM 
2058580SBill.Taylor@Sun.COM 	return (IBTL_CQ2CIHCAOPS_P(ibt_cq)->ibc_modify_cq(IBTL_CQ2CIHCA(ibt_cq),
2068580SBill.Taylor@Sun.COM 	    ibt_cq->cq_ibc_cq_hdl, count, usec, hid));
2078580SBill.Taylor@Sun.COM }
2088580SBill.Taylor@Sun.COM 
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate /*
2110Sstevel@tonic-gate  * ibt_poll_cq()
2120Sstevel@tonic-gate  *      Poll the specified CQ for a work request (WR) completion. If a CQ
2130Sstevel@tonic-gate  *      contains a completed WR, the completed WR at the head of the CQ is
2140Sstevel@tonic-gate  *      returned.
2150Sstevel@tonic-gate  *
2160Sstevel@tonic-gate  *      ibt_cq                  The CQ handle.
2170Sstevel@tonic-gate  *
2180Sstevel@tonic-gate  *      work_completions        An array of work completions.
2190Sstevel@tonic-gate  *
2200Sstevel@tonic-gate  *      num_wc                  Size of the Work completion array. The
2210Sstevel@tonic-gate  *                              requested number of completions.
2220Sstevel@tonic-gate  *
2230Sstevel@tonic-gate  *      num_polled              The actual number of completions returned.
2240Sstevel@tonic-gate  *
2250Sstevel@tonic-gate  */
2260Sstevel@tonic-gate ibt_status_t
ibt_poll_cq(ibt_cq_hdl_t ibt_cq,ibt_wc_t * work_completions,uint_t num_wc,uint_t * num_polled)2270Sstevel@tonic-gate ibt_poll_cq(ibt_cq_hdl_t ibt_cq, ibt_wc_t *work_completions, uint_t num_wc,
2280Sstevel@tonic-gate     uint_t *num_polled)
2290Sstevel@tonic-gate {
2300Sstevel@tonic-gate 	IBTF_DPRINTF_L4(ibtf_cq, "ibt_poll_cq(%p)", ibt_cq);
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 	return (IBTL_CQ2CIHCAOPS_P(ibt_cq)->ibc_poll_cq(IBTL_CQ2CIHCA(ibt_cq),
2330Sstevel@tonic-gate 	    ibt_cq->cq_ibc_cq_hdl, work_completions, num_wc, num_polled));
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_cq_s::cq_clnt_private))
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate /*
2390Sstevel@tonic-gate  * ibt_set_cq_private - Sets the private data on a given CQ
2400Sstevel@tonic-gate  *
2410Sstevel@tonic-gate  *      ibt_cq          The ibt_cq_hdl_t of the allocated CQ.
2420Sstevel@tonic-gate  *      clnt_private    The client private data.
2430Sstevel@tonic-gate  */
2440Sstevel@tonic-gate void
ibt_set_cq_private(ibt_cq_hdl_t ibt_cq,void * clnt_private)2450Sstevel@tonic-gate ibt_set_cq_private(ibt_cq_hdl_t ibt_cq, void *clnt_private)
2460Sstevel@tonic-gate {
2470Sstevel@tonic-gate 	ibt_cq->cq_clnt_private = clnt_private;
2480Sstevel@tonic-gate }
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate /*
2520Sstevel@tonic-gate  * ibt_get_cq_private - Retrieves the private data for a given CQ
2530Sstevel@tonic-gate  *
2540Sstevel@tonic-gate  *      ibt_cq          The ibt_cq_hdl_t of the allocated CQ.
2550Sstevel@tonic-gate  */
2560Sstevel@tonic-gate void *
ibt_get_cq_private(ibt_cq_hdl_t ibt_cq)2570Sstevel@tonic-gate ibt_get_cq_private(ibt_cq_hdl_t ibt_cq)
2580Sstevel@tonic-gate {
2590Sstevel@tonic-gate 	return (ibt_cq->cq_clnt_private);
2600Sstevel@tonic-gate }
261*12965SWilliam.Taylor@Oracle.COM 
262*12965SWilliam.Taylor@Oracle.COM /*
263*12965SWilliam.Taylor@Oracle.COM  * ibt_query_cq_handler_id - Retrieves the attributes of a cq_handler_id.
264*12965SWilliam.Taylor@Oracle.COM  */
265*12965SWilliam.Taylor@Oracle.COM ibt_status_t
ibt_query_cq_handler_id(ibt_hca_hdl_t hca_hdl,ibt_cq_handler_id_t hid,ibt_cq_handler_attr_t * attrs)266*12965SWilliam.Taylor@Oracle.COM ibt_query_cq_handler_id(ibt_hca_hdl_t hca_hdl,
267*12965SWilliam.Taylor@Oracle.COM     ibt_cq_handler_id_t hid, ibt_cq_handler_attr_t *attrs)
268*12965SWilliam.Taylor@Oracle.COM {
269*12965SWilliam.Taylor@Oracle.COM 	IBTF_DPRINTF_L3(ibtf_cq, "ibt_query_cq_handler(%p, %d, %p)",
270*12965SWilliam.Taylor@Oracle.COM 	    hca_hdl, hid, attrs);
271*12965SWilliam.Taylor@Oracle.COM 
272*12965SWilliam.Taylor@Oracle.COM 	return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_query_cq_handler_id(
273*12965SWilliam.Taylor@Oracle.COM 	    IBTL_HCA2CIHCA(hca_hdl), hid, attrs));
274*12965SWilliam.Taylor@Oracle.COM }
275