78
79
80 /*
81 *
82 * ibt_alloc_cq() - Allocate a completion queue
83 */
84 ibt_status_t
85 ibt_alloc_cq(ibt_hca_hdl_t hca_hdl, ibt_cq_attr_t *cq_attr,
86 ibt_cq_hdl_t *ibt_cq_p, uint32_t *real_size)
87 {
88 ibt_status_t status;
89 ibt_cq_hdl_t ibt_cq;
90
91 IBTF_DPRINTF_L3(ibtf_cq, "ibt_alloc_cq(%p, %p)",
92 hca_hdl, cq_attr);
93
94
95 ibt_cq = kmem_zalloc(sizeof (struct ibtl_cq_s), KM_SLEEP);
96 *ibt_cq_p = ibt_cq;
97
98 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq->cq_in_thread))
99 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq->cq_ibc_cq_hdl))
100 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibt_cq->cq_hca))
101 /*
102 * Set the following values before creating CI CQ, to avoid race
103 * conditions on async callback.
104 */
105 ibt_cq->cq_hca = hca_hdl;
106
107 ibtl_qp_flow_control_enter();
108 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_cq(
109 IBTL_HCA2CIHCA(hca_hdl), ibt_cq, cq_attr, &ibt_cq->cq_ibc_cq_hdl,
110 real_size);
111 ibtl_qp_flow_control_exit();
112
113 if (status != IBT_SUCCESS) {
114 IBTF_DPRINTF_L2(ibtf_cq, "ibt_alloc_cq: "
115 "CI CQ handle allocation failed: status = %d", status);
116 kmem_free(ibt_cq, sizeof (struct ibtl_cq_s));
117 *ibt_cq_p = NULL;
118 return (status);
119 }
120
121 if (cq_attr->cq_flags & IBT_CQ_HANDLER_IN_THREAD) {
122 ibt_cq->cq_in_thread = 1;
123 /* We may want additional CQ threads now. */
124 ibtl_another_cq_handler_in_thread();
125 }
126 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq->cq_in_thread))
127 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq->cq_ibc_cq_hdl))
128 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibt_cq->cq_hca))
129
130 mutex_init(&ibt_cq->cq_mutex, NULL, MUTEX_DEFAULT, NULL);
131
132 /* Update the cq resource count */
133 atomic_inc_32(&hca_hdl->ha_cq_cnt);
134
135 return (IBT_SUCCESS);
136 }
137
138
139 /*
140 * ibt_free_cq() - Free a completion queue
141 *
142 */
143 ibt_status_t
144 ibt_free_cq(ibt_cq_hdl_t ibt_cq)
145 {
146 ibt_status_t status;
147 ibtl_hca_t *ibt_hca = ibt_cq->cq_hca;
148
216 * ibt_cq The CQ handle.
217 *
218 * work_completions An array of work completions.
219 *
220 * num_wc Size of the Work completion array. The
221 * requested number of completions.
222 *
223 * num_polled The actual number of completions returned.
224 *
225 */
226 ibt_status_t
227 ibt_poll_cq(ibt_cq_hdl_t ibt_cq, ibt_wc_t *work_completions, uint_t num_wc,
228 uint_t *num_polled)
229 {
230 IBTF_DPRINTF_L4(ibtf_cq, "ibt_poll_cq(%p)", ibt_cq);
231
232 return (IBTL_CQ2CIHCAOPS_P(ibt_cq)->ibc_poll_cq(IBTL_CQ2CIHCA(ibt_cq),
233 ibt_cq->cq_ibc_cq_hdl, work_completions, num_wc, num_polled));
234 }
235
236 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_cq_s::cq_clnt_private))
237
238 /*
239 * ibt_set_cq_private - Sets the private data on a given CQ
240 *
241 * ibt_cq The ibt_cq_hdl_t of the allocated CQ.
242 * clnt_private The client private data.
243 */
244 void
245 ibt_set_cq_private(ibt_cq_hdl_t ibt_cq, void *clnt_private)
246 {
247 ibt_cq->cq_clnt_private = clnt_private;
248 }
249
250
251 /*
252 * ibt_get_cq_private - Retrieves the private data for a given CQ
253 *
254 * ibt_cq The ibt_cq_hdl_t of the allocated CQ.
255 */
256 void *
257 ibt_get_cq_private(ibt_cq_hdl_t ibt_cq)
|
78
79
80 /*
81 *
82 * ibt_alloc_cq() - Allocate a completion queue
83 */
84 ibt_status_t
85 ibt_alloc_cq(ibt_hca_hdl_t hca_hdl, ibt_cq_attr_t *cq_attr,
86 ibt_cq_hdl_t *ibt_cq_p, uint32_t *real_size)
87 {
88 ibt_status_t status;
89 ibt_cq_hdl_t ibt_cq;
90
91 IBTF_DPRINTF_L3(ibtf_cq, "ibt_alloc_cq(%p, %p)",
92 hca_hdl, cq_attr);
93
94
95 ibt_cq = kmem_zalloc(sizeof (struct ibtl_cq_s), KM_SLEEP);
96 *ibt_cq_p = ibt_cq;
97
98 /*
99 * Set the following values before creating CI CQ, to avoid race
100 * conditions on async callback.
101 */
102 ibt_cq->cq_hca = hca_hdl;
103
104 ibtl_qp_flow_control_enter();
105 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_cq(
106 IBTL_HCA2CIHCA(hca_hdl), ibt_cq, cq_attr, &ibt_cq->cq_ibc_cq_hdl,
107 real_size);
108 ibtl_qp_flow_control_exit();
109
110 if (status != IBT_SUCCESS) {
111 IBTF_DPRINTF_L2(ibtf_cq, "ibt_alloc_cq: "
112 "CI CQ handle allocation failed: status = %d", status);
113 kmem_free(ibt_cq, sizeof (struct ibtl_cq_s));
114 *ibt_cq_p = NULL;
115 return (status);
116 }
117
118 if (cq_attr->cq_flags & IBT_CQ_HANDLER_IN_THREAD) {
119 ibt_cq->cq_in_thread = 1;
120 /* We may want additional CQ threads now. */
121 ibtl_another_cq_handler_in_thread();
122 }
123
124 mutex_init(&ibt_cq->cq_mutex, NULL, MUTEX_DEFAULT, NULL);
125
126 /* Update the cq resource count */
127 atomic_inc_32(&hca_hdl->ha_cq_cnt);
128
129 return (IBT_SUCCESS);
130 }
131
132
133 /*
134 * ibt_free_cq() - Free a completion queue
135 *
136 */
137 ibt_status_t
138 ibt_free_cq(ibt_cq_hdl_t ibt_cq)
139 {
140 ibt_status_t status;
141 ibtl_hca_t *ibt_hca = ibt_cq->cq_hca;
142
210 * ibt_cq The CQ handle.
211 *
212 * work_completions An array of work completions.
213 *
214 * num_wc Size of the Work completion array. The
215 * requested number of completions.
216 *
217 * num_polled The actual number of completions returned.
218 *
219 */
220 ibt_status_t
221 ibt_poll_cq(ibt_cq_hdl_t ibt_cq, ibt_wc_t *work_completions, uint_t num_wc,
222 uint_t *num_polled)
223 {
224 IBTF_DPRINTF_L4(ibtf_cq, "ibt_poll_cq(%p)", ibt_cq);
225
226 return (IBTL_CQ2CIHCAOPS_P(ibt_cq)->ibc_poll_cq(IBTL_CQ2CIHCA(ibt_cq),
227 ibt_cq->cq_ibc_cq_hdl, work_completions, num_wc, num_polled));
228 }
229
230 /*
231 * ibt_set_cq_private - Sets the private data on a given CQ
232 *
233 * ibt_cq The ibt_cq_hdl_t of the allocated CQ.
234 * clnt_private The client private data.
235 */
236 void
237 ibt_set_cq_private(ibt_cq_hdl_t ibt_cq, void *clnt_private)
238 {
239 ibt_cq->cq_clnt_private = clnt_private;
240 }
241
242
243 /*
244 * ibt_get_cq_private - Retrieves the private data for a given CQ
245 *
246 * ibt_cq The ibt_cq_hdl_t of the allocated CQ.
247 */
248 void *
249 ibt_get_cq_private(ibt_cq_hdl_t ibt_cq)
|