daplt.h revision 9517:b4839b0aa7a4
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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#ifndef _DAPL_H_ 28#define _DAPL_H_ 29 30#ifdef __cplusplus 31extern "C" { 32#endif 33 34#define DAPLKA_VERSION (1) 35#define DAPLKA_TQ_NTHREADS 16 36#define DAPLKA_STATE_DETACHED 0x0000 37#define DAPLKA_STATE_ATTACHED 0x0001 38 39/* 40 * HCA structure 41 */ 42typedef struct daplka_hca { 43 ib_guid_t hca_guid; 44 ibt_hca_hdl_t hca_hdl; 45 ibt_hca_attr_t hca_attr; 46 uint32_t hca_nports; 47 ibt_hca_portinfo_t *hca_ports; 48 size_t hca_pinfosz; 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; 55 int hca_ref_cnt; 56 struct daplka_hca *hca_next; 57} daplka_hca_t; 58_NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_hca)) 59 60/* 61 * Per-Device instance state information. 62 */ 63typedef 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; 69} daplka_t; 70 71/* 72 * generic hash table 73 */ 74typedef struct daplka_hash_entry { 75 uint64_t he_hkey; 76 void *he_objp; 77 struct daplka_hash_entry *he_next; 78} daplka_hash_entry_t; 79 80typedef struct daplka_hash_bucket { 81 uint32_t hb_count; 82 daplka_hash_entry_t *hb_entries; 83} daplka_hash_bucket_t; 84 85typedef struct daplka_hash_table { 86 boolean_t ht_initialized; 87 uint32_t ht_count; 88 uint32_t ht_nbuckets; 89 uint64_t ht_next_hkey; 90 krwlock_t ht_table_lock; 91 kmutex_t ht_key_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)) 104 105/* 106 * resource structure header 107 */ 108typedef struct daplka_resource { 109 uint_t rs_type; 110 minor_t rs_rnum; 111 kmutex_t rs_reflock; 112 uint32_t rs_refcnt; 113 uint32_t rs_charged; 114 int (*rs_free)(struct daplka_resource *); 115} daplka_resource_t; 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)) 120 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 131 132typedef 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)) 137 138/* 139 * Various states IA can be in, this is primarily for handling race 140 * between MW allocation and MR cleanup callback. 141 */ 142typedef enum daplka_ia_state_e { 143 DAPLKA_IA_INIT = 0, 144 DAPLKA_IA_MW_ALLOC_IN_PROGRESS, 145 DAPLKA_IA_MW_FREEZE_IN_PROGRESS, 146 DAPLKA_IA_MW_FROZEN 147} daplka_ia_state_t; 148 149typedef struct daplka_ia_resource { 150 daplka_resource_t header; 151 kmutex_t ia_lock; 152 kcondvar_t ia_cv; 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; 157 uint8_t ia_port_num; 158 uint32_t ia_port_pkey; 159 pid_t ia_pid; 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)) 180 181typedef struct daplka_pd_resource { 182 daplka_resource_t header; 183 daplka_hca_t *pd_hca; 184 ibt_hca_hdl_t pd_hca_hdl; 185 ibt_pd_hdl_t pd_hdl; 186} daplka_pd_resource_t; 187_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_pd_resource)) 188 189/* 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. 193 * 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. 198 */ 199typedef 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) &\ 204 0xffff)) 205 206/* 207 * daplka_evd_cme_t defines connection manager events that can be 208 * chained to the daplka_evd_cme_list_t. 209 */ 210typedef 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; 222} daplka_evd_cme_t; 223_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_evd_cme_s)) 224 225typedef 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; 231 232/* 233 * daplka_evd_event_t defines elements in the event list - this is 234 * used for both async as well as connection manager events 235 */ 236typedef struct daplka_evd_event_s { 237 struct daplka_evd_event_s *ee_next; 238 union { 239 dapl_ib_async_event_t aev; 240 daplka_evd_cme_t cmev; 241 } ee_event; 242#define ee_aev ee_event.aev 243#define ee_cmev ee_event.cmev 244} daplka_evd_event_t; 245 246typedef 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; 252 253typedef struct daplka_evd_resource { 254 daplka_resource_t header; 255 kmutex_t evd_lock; 256 kcondvar_t evd_cv; 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; 267 uint64_t evd_cookie; 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)) 282 283typedef struct daplka_srq_resource { 284 daplka_resource_t header; 285 kmutex_t srq_lock; 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)) 293 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 303 304typedef struct daplka_ep_resource { 305 daplka_resource_t header; 306 kmutex_t ep_lock; 307 kcondvar_t ep_cv; 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; 317 uint32_t ep_state; 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]; 322 ib_gid_t ep_sgid; 323 ib_gid_t ep_dgid; 324} daplka_ep_resource_t; 325_NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_ep_resource)) 326 327typedef 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)) 332 333typedef 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; 338 ibt_mr_hdl_t mr_hdl; 339 ibt_mr_attr_t mr_attr; 340 ibt_mr_desc_t mr_desc; 341 kmutex_t mr_lock; 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)) 348 349typedef 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; 354 ibt_mw_hdl_t mw_hdl; 355 kmutex_t mw_lock; 356} daplka_mw_resource_t; 357_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_mw_resource)) 358 359/* 360 * This describes the elements in a connection pending list that each SP 361 * maintains. Fields are protected using the sp_lock. 362 */ 363typedef enum { 364 DAPLKA_SPCP_INIT = 0, 365 DAPLKA_SPCP_PENDING 366} daplka_spcp_state_t; 367 368typedef 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} daplka_sp_conn_pend_t; 374 375#define DAPLKA_DEFAULT_SP_BACKLOG 256 376typedef struct daplka_sp_resource { 377 daplka_resource_t header; 378 kmutex_t sp_lock; 379 ibt_srv_hdl_t sp_srv_hdl; 380 ibt_sbind_hdl_t sp_bind_hdl; 381 uint64_t sp_cookie; /* userland sp pointer */ 382 int sp_backlog_size; /* # elements backlog */ 383 daplka_sp_conn_pend_t *sp_backlog; /* pending conn backlog array */ 384 daplka_evd_resource_t *sp_evd_res; 385 ib_svc_id_t sp_conn_qual; 386 uint64_t sp_global_hkey; 387 uid_t sp_ruid; 388} daplka_sp_resource_t; 389_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_sp_resource)) 390_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_sp_conn_pend_s)) 391_NOTE(MUTEX_PROTECTS_DATA(daplka_sp_resource::sp_lock, 392 daplka_sp_resource::sp_backlog)) 393 394typedef struct daplka_cno_resource { 395 daplka_resource_t header; 396 kmutex_t cno_lock; 397 kcondvar_t cno_cv; 398 uint64_t cno_evd_cookie; 399} daplka_cno_resource_t; 400_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_cno_resource)) 401_NOTE(MUTEX_PROTECTS_DATA(daplka_cno_resource::cno_lock, 402 daplka_cno_resource::cno_cv 403 daplka_cno_resource::cno_evd_cookie)) 404 405#define DAPLKA_SMR_FREED 0x0000 406#define DAPLKA_SMR_TRANSITIONING 0x0001 407#define DAPLKA_SMR_READY 0x0002 408typedef struct daplka_shared_mr { 409 avl_node_t smr_node; 410 uint32_t smr_refcnt; 411 uint32_t smr_state; 412 daplka_mr_resource_t *smr_mr_list; 413 kcondvar_t smr_cv; 414 dapl_mr_cookie_t smr_cookie; 415} daplka_shared_mr_t; 416_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_shared_mr)) 417_NOTE(SCHEME_PROTECTS_DATA("daplka", daplka_shared_mr::smr_mr_list)) 418 419/* 420 * resource table data structures 421 */ 422#define DAPLKA_RC_BLKSZ 16 423#define DAPLKA_RC_RESERVED 0xff 424typedef struct daplka_resource_blk { 425 int daplka_rcblk_avail; 426 daplka_resource_t *daplka_rcblk_blks[DAPLKA_RC_BLKSZ]; 427} daplka_resource_blk_t; 428 429struct daplka_resource_table { 430 krwlock_t daplka_rct_lock; 431 int daplka_rc_len; 432 int daplka_rc_sz; 433 int daplka_rc_cnt; 434 ushort_t daplka_rc_flag; 435 daplka_resource_blk_t **daplka_rc_root; 436}; 437_NOTE(DATA_READABLE_WITHOUT_LOCK(daplka_resource_table)) 438_NOTE(RWLOCK_PROTECTS_DATA(daplka_resource_table::daplka_rct_lock, 439 daplka_resource_table::daplka_rc_root)) 440 441#ifdef __cplusplus 442} 443#endif 444 445#endif /* _DAPL_H_ */ 446