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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
34 #define DAPLKA_VERSION (1)
35 #define DAPLKA_TQ_NTHREADS 16
36 #define DAPLKA_STATE_DETACHED 0x0000
37 #define DAPLKA_STATE_ATTACHED 0x0001
42 typedef struct daplka_hca
{
44 ibt_hca_hdl_t hca_hdl
;
45 ibt_hca_attr_t hca_attr
;
47 ibt_hca_portinfo_t
*hca_ports
;
49 uint32_t hca_qp_count
;
50 uint32_t hca_cq_count
;
51 uint32_t hca_pd_count
;
52 uint32_t hca_mw_count
;
53 uint32_t hca_mr_count
;
54 uint32_t hca_srq_count
;
56 struct daplka_hca
*hca_next
;
58 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_hca
))
61 * Per-Device instance state information.
63 typedef struct daplka
{
64 kmutex_t daplka_mutex
;
65 dev_info_t
*daplka_dip
;
66 ibt_clnt_hdl_t daplka_clnt_hdl
;
67 daplka_hca_t
*daplka_hca_list_head
;
68 uint32_t daplka_status
;
74 typedef struct daplka_hash_entry
{
77 struct daplka_hash_entry
*he_next
;
78 } daplka_hash_entry_t
;
80 typedef struct daplka_hash_bucket
{
82 daplka_hash_entry_t
*hb_entries
;
83 } daplka_hash_bucket_t
;
85 typedef struct daplka_hash_table
{
86 boolean_t ht_initialized
;
89 uint64_t ht_next_hkey
;
90 krwlock_t ht_table_lock
;
92 daplka_hash_bucket_t
*ht_buckets
;
93 void (*ht_free_func
)(void *);
94 void (*ht_lookup_func
)(void *);
95 } daplka_hash_table_t
;
96 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_hash_entry
))
97 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_hash_bucket
))
98 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_hash_table
))
99 _NOTE(MUTEX_PROTECTS_DATA(daplka_hash_table::ht_key_lock
,
100 daplka_hash_table::ht_next_hkey
))
101 _NOTE(RWLOCK_PROTECTS_DATA(daplka_hash_table::ht_table_lock
,
102 daplka_hash_table::ht_buckets
103 daplka_hash_table::ht_count
))
106 * resource structure header
108 typedef struct daplka_resource
{
114 int (*rs_free
)(struct daplka_resource
*);
116 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_resource
))
117 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_resource::rs_charged
))
118 _NOTE(MUTEX_PROTECTS_DATA(daplka_resource::rs_reflock
,
119 daplka_resource::rs_refcnt
))
121 #define DAPLKA_EP_HTBL_SZ 128
122 #define DAPLKA_MR_HTBL_SZ 64
123 #define DAPLKA_MW_HTBL_SZ 64
124 #define DAPLKA_PD_HTBL_SZ 32
125 #define DAPLKA_SP_HTBL_SZ 32
126 #define DAPLKA_EVD_HTBL_SZ 32
127 #define DAPLKA_G_SP_HTBL_SZ 512
128 #define DAPLKA_TIMER_HTBL_SZ 512
129 #define DAPLKA_CNO_HTBL_SZ 16
130 #define DAPLKA_SRQ_HTBL_SZ 32
132 typedef struct daplka_async_evd_hkey_s
{
133 struct daplka_async_evd_hkey_s
*aeh_next
;
134 uint64_t aeh_evd_hkey
;
135 } daplka_async_evd_hkey_t
;
136 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_async_evd_hkey_s
))
139 * Various states IA can be in, this is primarily for handling race
140 * between MW allocation and MR cleanup callback.
142 typedef enum daplka_ia_state_e
{
144 DAPLKA_IA_MW_ALLOC_IN_PROGRESS
,
145 DAPLKA_IA_MW_FREEZE_IN_PROGRESS
,
149 typedef struct daplka_ia_resource
{
150 daplka_resource_t header
;
153 daplka_ia_state_t ia_state
;
154 ibt_hca_hdl_t ia_hca_hdl
;
155 ib_gid_t ia_hca_sgid
;
156 daplka_hca_t
*ia_hca
;
158 uint32_t ia_port_pkey
;
160 uint32_t ia_mw_alloccnt
; /* # mw allocs in progress */
161 daplka_async_evd_hkey_t
*ia_async_evd_hkeys
; /* hash key of async evd */
162 daplka_hash_table_t ia_ep_htbl
;
163 daplka_hash_table_t ia_mr_htbl
;
164 daplka_hash_table_t ia_mw_htbl
;
165 daplka_hash_table_t ia_pd_htbl
;
166 daplka_hash_table_t ia_evd_htbl
;
167 daplka_hash_table_t ia_sp_htbl
;
168 daplka_hash_table_t ia_cno_htbl
;
169 daplka_hash_table_t ia_srq_htbl
;
170 uint8_t ia_sadata
[DAPL_ATS_NBYTES
]; /* SA data */
171 boolean_t ia_ar_registered
;
172 } daplka_ia_resource_t
;
173 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_ia_resource
))
174 _NOTE(MUTEX_PROTECTS_DATA(daplka_ia_resource::ia_lock
,
175 daplka_ia_resource::ia_cv
176 daplka_ia_resource::ia_async_evd_hkeys
177 daplka_ia_resource::ia_mw_alloccnt
178 daplka_ia_resource::ia_state
179 daplka_async_evd_hkey_s
))
181 typedef struct daplka_pd_resource
{
182 daplka_resource_t header
;
183 daplka_hca_t
*pd_hca
;
184 ibt_hca_hdl_t pd_hca_hdl
;
186 } daplka_pd_resource_t
;
187 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_pd_resource
))
190 * Passive side EP cookies - this is generated at the connection request
191 * time and unique for every CR. It gets associated with the EP that
192 * is passed to the CR accept.
194 * daplka_psep_cookie contains the following information
195 * - 48 bit timestamp (unit = 1/10us)
196 * - 16 bit index in the psp backlog array corr to this CR event
197 * this makes it unique for every CR.
199 typedef uint64_t daplka_psep_cookie_t
;
200 #define DAPLKA_CREATE_PSEP_COOKIE(index) \
201 ((uint64_t)((gethrtime()/100)<<16 | (index)))
202 #define DAPLKA_GET_PSEP_INDEX(cookie) \
203 ((uint16_t)((uint64_t)(cookie) &\
207 * daplka_evd_cme_t defines connection manager events that can be
208 * chained to the daplka_evd_cme_list_t.
210 typedef struct daplka_evd_cme_s
{
211 dapl_ib_cm_event_type_t ec_cm_ev_type
;
212 /* ec_cm_cookie is the SP(passive)/EP(active) cookie */
213 uint64_t ec_cm_cookie
;
214 /* ec_cm_ev_session_id is the cookie for DEFER processing */
215 void *ec_cm_ev_session_id
;
216 /* true - passive side event, false - active side event */
217 boolean_t ec_cm_is_passive
;
218 daplka_psep_cookie_t ec_cm_psep_cookie
;
219 ib_gid_t ec_cm_req_prim_addr
; /* requestor gid */
220 ibt_priv_data_len_t ec_cm_ev_priv_data_len
;
221 void *ec_cm_ev_priv_data
;
223 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_evd_cme_s
))
225 typedef enum daplka_evd_event_type_e
{
226 DAPLKA_EVD_NO_EVENTS
= 0x00,
227 DAPLKA_EVD_ULAND_EVENTS
= 0x01, /* userland events ie. CQ or SE */
228 DAPLKA_EVD_CM_EVENTS
= 0x02,
229 DAPLKA_EVD_ASYNC_EVENTS
= 0x04
230 } daplka_evd_event_type_t
;
233 * daplka_evd_event_t defines elements in the event list - this is
234 * used for both async as well as connection manager events
236 typedef struct daplka_evd_event_s
{
237 struct daplka_evd_event_s
*ee_next
;
239 dapl_ib_async_event_t aev
;
240 daplka_evd_cme_t cmev
;
242 #define ee_aev ee_event.aev
243 #define ee_cmev ee_event.cmev
244 } daplka_evd_event_t
;
246 typedef struct daplka_evd_event_list_s
{
247 daplka_evd_event_type_t eel_event_type
;
248 uint32_t eel_num_elements
;
249 daplka_evd_event_t
*eel_head
;
250 daplka_evd_event_t
*eel_tail
;
251 } daplka_evd_event_list_t
;
253 typedef struct daplka_evd_resource
{
254 daplka_resource_t header
;
257 DAT_EVD_FLAGS evd_flags
;
258 daplka_evd_event_type_t evd_newevents
; /* DAPLKA_EVD_*_EVENTS */
259 ibt_cq_hdl_t evd_cq_hdl
;
260 uint32_t evd_cq_real_size
;
261 daplka_evd_event_list_t evd_cr_events
; /* connect request event */
262 daplka_evd_event_list_t evd_conn_events
; /* connection events */
263 daplka_evd_event_list_t evd_async_events
; /* aysnc events list */
264 ibt_hca_hdl_t evd_hca_hdl
;
265 daplka_hca_t
*evd_hca
;
266 uint32_t evd_waiters
;
268 struct daplka_cno_resource
*evd_cno_res
;
269 } daplka_evd_resource_t
;
270 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_evd_event_s
))
271 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_evd_event_s
))
272 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_evd_event_list_s
))
273 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_evd_resource
))
274 _NOTE(MUTEX_PROTECTS_DATA(daplka_evd_resource::evd_lock
,
275 daplka_evd_resource::evd_cv
276 daplka_evd_resource::evd_flags
277 daplka_evd_resource::evd_newevents
278 daplka_evd_resource::evd_cr_events
279 daplka_evd_resource::evd_conn_events
280 daplka_evd_resource::evd_async_events
281 daplka_evd_resource::evd_waiters
))
283 typedef struct daplka_srq_resource
{
284 daplka_resource_t header
;
286 daplka_hca_t
*srq_hca
;
287 ibt_hca_hdl_t srq_hca_hdl
;
288 daplka_pd_resource_t
*srq_pd_res
;
289 ibt_srq_hdl_t srq_hdl
;
290 uint32_t srq_real_size
;
291 } daplka_srq_resource_t
;
292 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_srq_resource
))
294 #define DAPLKA_EP_STATE_CLOSED 0x0001
295 #define DAPLKA_EP_STATE_CONNECTING 0x0002
296 #define DAPLKA_EP_STATE_ACCEPTING 0x0003
297 #define DAPLKA_EP_STATE_CONNECTED 0x0004
298 #define DAPLKA_EP_STATE_DISCONNECTING 0x0005
299 #define DAPLKA_EP_STATE_ABORTING 0x0006
300 #define DAPLKA_EP_STATE_DISCONNECTED 0x0007
301 #define DAPLKA_EP_STATE_TRANSITIONING 0x0008
302 #define DAPLKA_EP_STATE_FREED 0x0009
304 typedef struct daplka_ep_resource
{
305 daplka_resource_t header
;
308 uint64_t ep_cookie
; /* userland ep pointer */
309 daplka_hca_t
*ep_hca
;
310 ibt_channel_hdl_t ep_chan_hdl
;
311 daplka_evd_resource_t
*ep_snd_evd
;
312 daplka_evd_resource_t
*ep_rcv_evd
;
313 daplka_evd_resource_t
*ep_conn_evd
;
314 daplka_evd_resource_t
*ep_bind_evd
;
315 daplka_pd_resource_t
*ep_pd_res
;
316 daplka_srq_resource_t
*ep_srq_res
;
318 uint64_t ep_timer_hkey
;
319 daplka_psep_cookie_t ep_psep_cookie
; /* passive side ep cookie */
320 ibt_priv_data_len_t ep_priv_len
;
321 uint8_t ep_priv_data
[IBT_REP_PRIV_DATA_SZ
];
324 } daplka_ep_resource_t
;
325 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_ep_resource
))
327 typedef struct daplka_timer_info
{
328 daplka_ep_resource_t
*ti_ep_res
;
329 timeout_id_t ti_tmo_id
;
330 } daplka_timer_info_t
;
331 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_timer_info
))
333 typedef struct daplka_mr_resource
{
334 daplka_resource_t header
;
335 daplka_pd_resource_t
*mr_pd_res
;
336 daplka_hca_t
*mr_hca
;
337 ibt_hca_hdl_t mr_hca_hdl
;
339 ibt_mr_attr_t mr_attr
;
340 ibt_mr_desc_t mr_desc
;
342 struct daplka_mr_resource
*mr_next
;
343 struct daplka_shared_mr
*mr_shared_mr
;
344 } daplka_mr_resource_t
;
345 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_mr_resource
))
346 _NOTE(MUTEX_PROTECTS_DATA(daplka_mr_resource::mr_lock
,
347 daplka_mr_resource::mr_shared_mr
))
349 typedef struct daplka_mw_resource
{
350 daplka_resource_t header
;
351 daplka_pd_resource_t
*mw_pd_res
;
352 daplka_hca_t
*mw_hca
;
353 ibt_hca_hdl_t mw_hca_hdl
;
356 } daplka_mw_resource_t
;
357 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_mw_resource
))
360 * This describes the elements in a connection pending list that each SP
361 * maintains. Fields are protected using the sp_lock.
364 DAPLKA_SPCP_INIT
= 0,
366 } daplka_spcp_state_t
;
368 typedef struct daplka_sp_conn_pend_s
{
369 daplka_spcp_state_t spcp_state
;
370 void *spcp_sid
; /* session id for cm_proceed */
371 uint32_t spcp_req_len
; /* used by cr_handoff */
372 char spcp_req_data
[DAPL_MAX_PRIVATE_DATA_SIZE
];
373 uint8_t spcp_rdma_ra_out
;
374 uint8_t spcp_rdma_ra_in
;
375 } daplka_sp_conn_pend_t
;
377 #define DAPLKA_DEFAULT_SP_BACKLOG 256
378 typedef struct daplka_sp_resource
{
379 daplka_resource_t header
;
381 ibt_srv_hdl_t sp_srv_hdl
;
382 ibt_sbind_hdl_t sp_bind_hdl
;
383 uint64_t sp_cookie
; /* userland sp pointer */
384 int sp_backlog_size
; /* # elements backlog */
385 daplka_sp_conn_pend_t
*sp_backlog
; /* pending conn backlog array */
386 daplka_evd_resource_t
*sp_evd_res
;
387 ib_svc_id_t sp_conn_qual
;
388 uint64_t sp_global_hkey
;
390 } daplka_sp_resource_t
;
391 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_sp_resource
))
392 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_sp_conn_pend_s
))
393 _NOTE(MUTEX_PROTECTS_DATA(daplka_sp_resource::sp_lock
,
394 daplka_sp_resource::sp_backlog
))
396 typedef struct daplka_cno_resource
{
397 daplka_resource_t header
;
400 uint64_t cno_evd_cookie
;
401 } daplka_cno_resource_t
;
402 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_cno_resource
))
403 _NOTE(MUTEX_PROTECTS_DATA(daplka_cno_resource::cno_lock
,
404 daplka_cno_resource::cno_cv
405 daplka_cno_resource::cno_evd_cookie
))
407 #define DAPLKA_SMR_FREED 0x0000
408 #define DAPLKA_SMR_TRANSITIONING 0x0001
409 #define DAPLKA_SMR_READY 0x0002
410 typedef struct daplka_shared_mr
{
414 daplka_mr_resource_t
*smr_mr_list
;
416 dapl_mr_cookie_t smr_cookie
;
417 } daplka_shared_mr_t
;
418 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_shared_mr
))
419 _NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_shared_mr::smr_mr_list
))
422 * resource table data structures
424 #define DAPLKA_RC_BLKSZ 16
425 #define DAPLKA_RC_RESERVED 0xff
426 typedef struct daplka_resource_blk
{
427 int daplka_rcblk_avail
;
428 daplka_resource_t
*daplka_rcblk_blks
[DAPLKA_RC_BLKSZ
];
429 } daplka_resource_blk_t
;
431 struct daplka_resource_table
{
432 krwlock_t daplka_rct_lock
;
436 ushort_t daplka_rc_flag
;
437 daplka_resource_blk_t
**daplka_rc_root
;
439 _NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_resource_table
))
440 _NOTE(RWLOCK_PROTECTS_DATA(daplka_resource_table::daplka_rct_lock
,
441 daplka_resource_table::daplka_rc_root
))
447 #endif /* _DAPL_H_ */