Print this page
8368 remove warlock leftovers from usr/src/uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_utils.c
+++ new/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_utils.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * ibcm_utils.c
28 28 *
29 29 * contains internal lookup functions of IB CM module
30 30 * along with some other miscellaneous stuff
31 31 *
32 32 * TBD:
33 33 * 1. Code needed to ensure that if any clients are using a service then
34 34 * don't de-register it.
35 35 */
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
36 36
37 37 #include <sys/ib/mgt/ibcm/ibcm_impl.h>
38 38 #include <sys/ddi.h>
39 39
40 40
41 41 /* statics */
42 42 static vmem_t *ibcm_local_sid_arena;
43 43 static vmem_t *ibcm_ip_sid_arena;
44 44 static ib_svc_id_t ibcm_local_sid_seed;
45 45 static ib_com_id_t ibcm_local_cid_seed;
46 -_NOTE(READ_ONLY_DATA({ibcm_local_sid_arena ibcm_local_sid_seed
47 - ibcm_ip_sid_arena ibcm_local_cid_seed}))
48 46 static void ibcm_delete_state_from_avl(ibcm_state_data_t *statep);
49 47 static void ibcm_init_conn_trace(ibcm_state_data_t *statep);
50 48 static void ibcm_fini_conn_trace(ibcm_state_data_t *statep);
51 49 static void ibcm_dump_conn_trbuf(void *statep, char *line_prefix,
52 50 char *buf, int buf_size);
53 51 extern ibt_status_t ibcm_get_node_rec(ibmf_saa_handle_t, sa_node_record_t *,
54 52 uint64_t c_mask, void *, size_t *);
55 53
56 54 /*
57 55 * ibcm_lookup_msg:
58 56 *
59 57 * Retrieves an existing state structure or creates a new one if none found.
60 58 * This function is used during
61 59 * Passive connection side for INCOMING REQ/REJ/RTU/MRA/DREQ/DREP/LAP msgs
62 60 * Active connection side for INCOMING REP/REJ/MRA/DREQ/DREP/APR msgs
63 61 * Active side CM for outgoing REQ message.
64 62 *
65 63 * NOTE: Only return IBCM_LOOKUP_FAIL if lookup failed to find a match.
66 64 *
67 65 * Arguments are:-
68 66 * event_type - type of message
69 67 * incoming REQ, REP, REJ, MRA, RTU
70 68 * remote_qpn - Remote QP number
71 69 * comid - local/remote comid
72 70 * remote_hca_guid - Remote HCA GUID
73 71 * hcap - HCA entry ptr
74 72 * rstatep - return statep pointer
75 73 *
76 74 * Return Values:
77 75 * IBCM_LOOKUP_NEW - new statep allocated
78 76 * IBCM_LOOKUP_EXISTS - found an existing entry
79 77 * IBCM_LOOKUP_FAIL - No lookup entry found
80 78 * IBCM_MEMORY_FAILURE - Memory allocs failed
81 79 */
82 80 ibcm_status_t
83 81 ibcm_lookup_msg(ibcm_event_type_t event_type, ib_com_id_t comid,
84 82 ib_qpn_t remote_qpn, ib_guid_t remote_hca_guid, ibcm_hca_info_t *hcap,
85 83 ibcm_state_data_t **rstatep)
86 84 {
87 85 avl_index_t where;
88 86 ibcm_state_data_t *sp;
89 87
90 88 IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: event = 0x%x, comid = 0x%x",
91 89 event_type, comid);
92 90 IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: rem_qpn = 0x%lX, "
93 91 "rem_hca_guid = 0x%llX", remote_qpn, remote_hca_guid);
94 92
95 93 ASSERT(rw_lock_held(&hcap->hca_state_rwlock));
96 94
97 95 /*
98 96 * Lookup in "hca_passive_tree" for IBCM_INCOMING_REQ and
99 97 * IBCM_INCOMING_REP_STALE;
100 98 *
101 99 * Lookup in "hca_passive_comid_tree" for IBCM_INCOMING_REQ_STALE
102 100 *
103 101 * All other lookups in "hca_active_tree".
104 102 *
105 103 * NOTE: "hca_active_tree" lookups are based on the local comid.
106 104 * "hca_passive_state_tree" lookups are based on remote QPN
107 105 * and remote hca GUID.
108 106 *
109 107 * Call avl_find to lookup in the respective tree and save result in
110 108 * "sp". If "sp" is null it implies that no match was found. If so,
111 109 * allocate a new ibcm_state_data_t and insert it into the AVL tree(s).
112 110 */
113 111 if ((event_type == IBCM_INCOMING_REQ) ||
114 112 (event_type == IBCM_INCOMING_REP_STALE)) {
115 113 ibcm_passive_node_info_t info;
116 114
117 115 info.info_qpn = remote_qpn;
118 116 info.info_hca_guid = remote_hca_guid;
119 117
120 118 /* Lookup based on Remote QPN and Remote GUID in Passive Tree */
121 119 sp = avl_find(&hcap->hca_passive_tree, &info, &where);
122 120 } else if ((event_type == IBCM_INCOMING_REQ_STALE) ||
123 121 (event_type == IBCM_INCOMING_REJ_RCOMID)) {
124 122 ibcm_passive_comid_node_info_t info;
125 123
126 124 info.info_comid = comid;
127 125 info.info_hca_guid = remote_hca_guid;
128 126
129 127 /* Lookup based on Remote COMID in Passive Tree */
130 128 sp = avl_find(&hcap->hca_passive_comid_tree, &info, &where);
131 129 } else { /* any other event including IBCM_OUTGOING_REQ */
132 130 /* Lookup based on Local comid in Active Tree */
133 131 sp = avl_find(&hcap->hca_active_tree, &comid, &where);
134 132 }
135 133
136 134 /* matching entry found !! */
137 135 if (sp != NULL) {
138 136 IBTF_DPRINTF_L4(cmlog, "ibcm_lookup_msg: match found "
139 137 "statep = %p", sp);
140 138 if (event_type == IBCM_INCOMING_REQ)
141 139 kmem_free(*rstatep, sizeof (ibcm_state_data_t));
142 140 *rstatep = sp; /* return the matched statep */
143 141
144 142 mutex_enter(&(sp->state_mutex));
145 143 IBCM_REF_CNT_INCR(sp); /* increment the ref count */
146 144 mutex_exit(&(sp->state_mutex));
147 145
148 146 return (IBCM_LOOKUP_EXISTS);
149 147 }
150 148
151 149 /*
152 150 * If we came here then it implies that CM didn't
153 151 * find a matching entry. We will create a new entry in avl tree,
154 152 * if event_type is INCOMING/OUTGOING REQ, REQ_STALE/REP_STALE.
155 153 * statep is created for INCOMING/OUTGOING REQ.
156 154 * For all other event_types we return lookup failure
157 155 */
158 156 if (!((event_type == IBCM_INCOMING_REQ) ||
159 157 (event_type == IBCM_INCOMING_REQ_STALE) ||
160 158 (event_type == IBCM_INCOMING_REP_STALE) ||
161 159 (event_type == IBCM_OUTGOING_REQ))) {
162 160 IBTF_DPRINTF_L2(cmlog, "ibcm_lookup_msg: failed for "
163 161 "event type %x remote_comid = 0x%x",
164 162 event_type, comid);
↓ open down ↓ |
107 lines elided |
↑ open up ↑ |
165 163
166 164 return (IBCM_LOOKUP_FAIL);
167 165 }
168 166
169 167 if ((event_type == IBCM_INCOMING_REQ) ||
170 168 (event_type == IBCM_OUTGOING_REQ)) {
171 169
172 170 /* fill in the new ibcm_state_data */
173 171 sp = *rstatep;
174 172
175 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp))
176 -
177 173 /* initialize statep */
178 174 mutex_init(&sp->state_mutex, NULL, MUTEX_DEFAULT, NULL);
179 175 cv_init(&sp->block_client_cv, NULL, CV_DRIVER, NULL);
180 176 cv_init(&sp->block_mad_cv, NULL, CV_DRIVER, NULL);
181 177
182 178 sp->hcap = hcap;
183 179 IBCM_REF_CNT_INCR(sp);
184 180 sp->local_comid = comid;
185 181
186 182 if (ibcm_enable_trace != 0)
187 183 ibcm_init_conn_trace(sp);
188 184
189 185 if (event_type == IBCM_INCOMING_REQ) { /* Passive side */
190 186 sp->state = IBCM_STATE_REQ_RCVD;
191 187 sp->clnt_proceed = IBCM_BLOCK;
192 188 sp->close_nocb_state = IBCM_UNBLOCK;
193 189 sp->remote_hca_guid = remote_hca_guid;
194 190 sp->remote_qpn = remote_qpn;
195 -
196 191 } else if (event_type == IBCM_OUTGOING_REQ) { /* Active side */
197 192 sp->close_nocb_state = IBCM_UNBLOCK;
198 193 sp->state = IBCM_STATE_IDLE;
199 194 }
200 -
201 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp))
202 -
203 195 } else {
204 196 sp = *rstatep; /* for incoming REQ/REP STALE only */
205 197 }
206 198
207 199 if ((event_type == IBCM_INCOMING_REQ) ||
208 200 (event_type == IBCM_INCOMING_REP_STALE)) {
209 201
210 202 /* First, insert a new "sp" into "hca_passive_tree" @ "where" */
211 203 avl_insert(&(hcap->hca_passive_tree), (void *)sp, where);
212 204
213 205 if (event_type == IBCM_INCOMING_REQ) { /* Only INCOMING_REQ */
214 206 /*
215 207 * We have to do an avl_find() to figure out
216 208 * "where" to insert the statep into the active tree.
217 209 *
218 210 * CM doesn't care for avl_find's retval.
219 211 */
220 212 (void) avl_find(&hcap->hca_active_tree,
221 213 &sp->local_comid, &where);
222 214
223 215 /* Next, insert the "sp" into "hca_active_tree" */
224 216 avl_insert(&hcap->hca_active_tree, (void *)sp, where);
225 217 }
226 218 } else if (event_type == IBCM_INCOMING_REQ_STALE) {
227 219 avl_insert(&(hcap->hca_passive_comid_tree), (void *)sp, where);
228 220 } else { /* IBCM_OUTGOING_REQ */
229 221 /* Insert the new sp only into "hca_active_tree", @ "where" */
230 222 avl_insert(&(hcap->hca_active_tree), (void *)sp, where);
231 223 }
232 224
233 225 return (IBCM_LOOKUP_NEW); /* return new lookup */
234 226 }
235 227
236 228
237 229 /*
238 230 * ibcm_active_node_compare:
239 231 * - AVL active tree node compare
240 232 *
241 233 * Arguments:
242 234 * p1 : pointer to local comid
243 235 * p2 : pointer to passed ibcm_state_data_t
244 236 *
245 237 * Return values:
246 238 * 0 : match found
247 239 * -1 : no match but insert to left side of the tree
248 240 * +1 : no match but insert to right side of the tree
249 241 */
250 242 int
251 243 ibcm_active_node_compare(const void *p1, const void *p2)
252 244 {
253 245 ib_com_id_t *local_comid = (ib_com_id_t *)p1;
254 246 ibcm_state_data_t *statep = (ibcm_state_data_t *)p2;
255 247
256 248 IBTF_DPRINTF_L5(cmlog, "ibcm_active_node_compare: "
257 249 "comid: 0x%x, statep: 0x%p", *local_comid, statep);
258 250
259 251 if (*local_comid > statep->local_comid) {
260 252 return (+1);
261 253 } else if (*local_comid < statep->local_comid) {
262 254 return (-1);
263 255 } else {
264 256 return (0);
265 257 }
266 258 }
267 259
268 260
269 261 /*
270 262 * ibcm_passive_node_compare:
271 263 * - AVL passive tree node compare (passive side)
272 264 *
273 265 * Arguments:
274 266 * p1 : pointer to ibcm_passive_node_info (remote qpn and remote guid)
275 267 * p2 : pointer to passed ibcm_state_data_t
276 268 *
277 269 * Return values:
278 270 * 0 : match found
279 271 * -1 : no match but insert to left side of the tree
280 272 * +1 : no match but insert to right side of the tree
281 273 */
282 274 int
283 275 ibcm_passive_node_compare(const void *p1, const void *p2)
284 276 {
285 277 ibcm_state_data_t *statep = (ibcm_state_data_t *)p2;
286 278 ibcm_passive_node_info_t *infop = (ibcm_passive_node_info_t *)p1;
287 279
288 280 IBTF_DPRINTF_L5(cmlog, "ibcm_passive_node_compare: "
289 281 "statep: 0x%p, p1: 0x%p", statep, p1);
290 282
291 283 /*
292 284 * PASSIVE SIDE: (REQ, REP, MRA, REJ)
293 285 * always search by active COMID
294 286 */
295 287 if (infop->info_qpn > statep->remote_qpn) {
296 288 return (+1);
297 289 } else if (infop->info_qpn < statep->remote_qpn) {
298 290 return (-1);
299 291 } else {
300 292 if (infop->info_hca_guid < statep->remote_hca_guid) {
301 293 return (-1);
302 294 } else if (infop->info_hca_guid > statep->remote_hca_guid) {
303 295 return (+1);
304 296 } else {
305 297 return (0);
306 298 }
307 299 }
308 300 }
309 301
310 302 /*
311 303 * ibcm_passive_comid_node_compare:
312 304 * - AVL passive comid tree node compare (passive side)
313 305 *
314 306 * Arguments:
315 307 * p1 : pointer to ibcm_passive_comid_node_info
316 308 * (remote comid and remote guid)
317 309 * p2 : pointer to passed ibcm_state_data_t
318 310 *
319 311 * Return values:
320 312 * 0 : match found
321 313 * -1 : no match but insert to left side of the tree
322 314 * +1 : no match but insert to right side of the tree
323 315 */
324 316 int
325 317 ibcm_passive_comid_node_compare(const void *p1, const void *p2)
326 318 {
327 319 ibcm_state_data_t *statep = (ibcm_state_data_t *)p2;
328 320 ibcm_passive_comid_node_info_t *infop =
329 321 (ibcm_passive_comid_node_info_t *)p1;
330 322
331 323 IBTF_DPRINTF_L5(cmlog, "ibcm_passive_comid_node_compare: "
332 324 "statep: 0x%p, p1: 0x%p", statep, p1);
333 325
334 326 if (infop->info_comid > statep->remote_comid) {
335 327 return (+1);
336 328 } else if (infop->info_comid < statep->remote_comid) {
337 329 return (-1);
338 330 } else {
339 331 if (infop->info_hca_guid < statep->remote_hca_guid) {
340 332 return (-1);
341 333 } else if (infop->info_hca_guid > statep->remote_hca_guid) {
342 334 return (+1);
343 335 } else {
344 336 return (0);
345 337 }
346 338 }
347 339 }
348 340
349 341
350 342 void
351 343 ibcm_delete_state_from_avl(ibcm_state_data_t *statep)
352 344 {
353 345 avl_index_t a_where = 0;
354 346 avl_index_t p_where = 0;
355 347 avl_index_t pcomid_where = 0;
356 348 ibcm_hca_info_t *hcap;
357 349 ibcm_state_data_t *active_nodep, *passive_nodep;
358 350 ibcm_state_data_t *passive_comid_nodep;
359 351 ibcm_passive_node_info_t info;
360 352 ibcm_passive_comid_node_info_t info_comid;
361 353
362 354 IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_from_avl: statep 0x%p",
363 355 statep);
364 356
365 357 if (statep == NULL) {
366 358 IBTF_DPRINTF_L2(cmlog, "ibcm_delete_state_from_avl: statep"
367 359 " NULL");
368 360 return;
369 361 }
370 362
371 363 hcap = statep->hcap;
372 364
373 365 /*
374 366 * Once the avl tree lock is acquired, no other thread can increment
375 367 * ref cnt, until tree lock is exit'ed. Since the statep is removed
376 368 * from the avl's after acquiring lock below, no other thread can
377 369 * increment the ref cnt after acquiring the lock below
378 370 */
379 371
380 372 rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
381 373
382 374 /* Lookup based on Local comid in the active tree */
383 375 active_nodep = avl_find(&hcap->hca_active_tree, &(statep->local_comid),
384 376 &a_where);
385 377
386 378 /* Lookup based on Remote QPN and Remote GUID in the passive tree */
387 379 info.info_qpn = statep->remote_qpn;
388 380 info.info_hca_guid = statep->remote_hca_guid;
389 381 passive_nodep = avl_find(&hcap->hca_passive_tree, &info, &p_where);
390 382
391 383 /* Lookup based on Remote Comid and Remote GUID in the passive tree */
392 384 info_comid.info_comid = statep->remote_comid;
393 385 info_comid.info_hca_guid = statep->remote_hca_guid;
394 386 passive_comid_nodep = avl_find(&hcap->hca_passive_comid_tree,
395 387 &info_comid, &pcomid_where);
396 388
397 389 /* remove it from the tree, destroy record and the nodep */
398 390 if (active_nodep == statep) {
399 391 avl_remove(&hcap->hca_active_tree, active_nodep);
400 392 }
401 393
402 394 if (passive_nodep == statep) {
403 395 avl_remove(&hcap->hca_passive_tree, passive_nodep);
404 396 }
405 397
406 398 if (passive_comid_nodep == statep) {
407 399 avl_remove(&hcap->hca_passive_comid_tree, passive_comid_nodep);
408 400 }
409 401
410 402 rw_exit(&hcap->hca_state_rwlock);
411 403 }
412 404
413 405 /*
414 406 * ibcm_dealloc_state_data:
415 407 * Deallocates all buffers and the memory of state structure
416 408 * This routine can be called on statep that has ref_cnt of 0, and that is
417 409 * already deleted from the avl tree's
418 410 *
419 411 * Arguments are:-
420 412 * statep - statep to be deleted
421 413 *
422 414 * Return Values: NONE
423 415 */
424 416 void
425 417 ibcm_dealloc_state_data(ibcm_state_data_t *statep)
426 418 {
427 419 timeout_id_t timer_val;
428 420 int dump_trace;
429 421 IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_state_data: statep 0x%p", statep);
430 422
431 423 if (statep == NULL) {
432 424 IBTF_DPRINTF_L2(cmlog, "ibcm_dealloc_state_data: statep NULL");
433 425 return;
434 426 }
435 427
436 428 /* ref_cnt is 0 */
437 429 /* If timer is running - expire it */
438 430 mutex_enter(&statep->state_mutex);
439 431 timer_val = statep->timerid;
440 432 if (timer_val != 0) {
441 433 statep->timerid = 0;
442 434 mutex_exit(&statep->state_mutex);
443 435 (void) untimeout(timer_val);
444 436 } else
445 437 mutex_exit(&statep->state_mutex);
446 438
447 439 /* release the ref cnt on the associated ibmf qp */
448 440 if (statep->stored_reply_addr.cm_qp_entry != NULL)
449 441 ibcm_release_qp(statep->stored_reply_addr.cm_qp_entry);
450 442
451 443 if (statep->stored_msg != NULL)
452 444 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
453 445 &statep->stored_msg);
454 446
455 447 if (statep->dreq_msg != NULL)
456 448 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
457 449 &statep->dreq_msg);
458 450
459 451 if (statep->drep_msg != NULL)
460 452 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
461 453 &statep->drep_msg);
462 454
463 455 if (statep->mra_msg != NULL)
464 456 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
465 457 &statep->mra_msg);
466 458
467 459 if (statep->lapr_msg != NULL)
468 460 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
469 461 &statep->lapr_msg);
470 462
471 463 if (statep->defer_cm_msg != NULL)
472 464 kmem_free(statep->defer_cm_msg, IBCM_MSG_SIZE);
473 465
474 466 IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_state_data: done for sp = 0x%p",
475 467 statep);
476 468
477 469 /* Ensure the thread doing ref cnt decr releases the mutex */
478 470 mutex_enter(&statep->state_mutex);
479 471 dump_trace = statep->cm_retries > 0;
480 472 mutex_exit(&statep->state_mutex);
481 473
482 474 /*
483 475 * now call the mutex_destroy() and cv_destroy()
484 476 */
485 477 mutex_destroy(&statep->state_mutex);
486 478
487 479 cv_destroy(&statep->block_client_cv);
488 480 cv_destroy(&statep->block_mad_cv);
489 481
490 482 /* free the comid */
491 483 ibcm_free_comid(statep->hcap, statep->local_comid);
492 484
493 485 /* Decrement the resource on hcap */
494 486 ibcm_dec_hca_res_cnt(statep->hcap);
495 487
496 488 /* dump the trace data into ibtf_debug_buf */
497 489 if ((ibcm_enable_trace & 4) || dump_trace)
498 490 ibcm_dump_conn_trace(statep);
499 491
500 492 ibcm_fini_conn_trace(statep);
501 493
502 494 /* free the statep */
503 495 kmem_free(statep, sizeof (ibcm_state_data_t));
504 496 }
505 497
506 498 /*
507 499 * ibcm_delete_state_data:
508 500 * Deletes the state from avl trees, and tries to deallocate state
509 501 *
510 502 * Arguments are:-
511 503 * statep - statep to be deleted
512 504 *
513 505 * Return Values: NONE
514 506 */
515 507 void
516 508 ibcm_delete_state_data(ibcm_state_data_t *statep)
517 509 {
518 510 IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_data:");
519 511
520 512 ibcm_delete_state_from_avl(statep);
521 513
522 514 /* Must acquire the state mutex to set delete_state_data */
523 515 mutex_enter(&statep->state_mutex);
524 516 if (statep->ref_cnt > 0) {
525 517 statep->delete_state_data = B_TRUE;
526 518 IBTF_DPRINTF_L4(cmlog, "ibcm_delete_state_data: statep 0x%p "
527 519 "ref_cnt = %x", statep, statep->ref_cnt);
528 520 mutex_exit(&statep->state_mutex);
529 521 return;
530 522 }
531 523 mutex_exit(&statep->state_mutex);
532 524
533 525 ibcm_dealloc_state_data(statep);
534 526 }
535 527
536 528 /*
537 529 * ibcm_find_sidr_entry:
538 530 * Routines for CM SIDR state structure list manipulation.
539 531 * Finds an entry based on lid, gid and grh exists fields
540 532 *
541 533 * INPUTS:
542 534 * lid: LID of incoming SIDR REQ
543 535 * gid: GID of incoming SIDR REQ
544 536 * grh_exists: TRUE if GRH exists in the incoming SIDR REQ
545 537 * req_id: Request ID
546 538 * hcap: CM State table to search for SIDR state structure
547 539 * statep: Returns a valid state structure, if one exists based
548 540 * on lid, gid and grh_exists fields
549 541 * flag: IBCM_FLAG_LOOKUP - just lookup
550 542 * IBCM_FLAG_LOOKUP_AND_ADD - if lookup fails, add it.
551 543 * Return Values:
552 544 * IBCM_LOOKUP_EXISTS - found an existing entry
553 545 * IBCM_LOOKUP_FAIL - failed to find an entry
554 546 * IBCM_LOOKUP_NEW - created a new entry
555 547 */
556 548 ibcm_status_t
557 549 ibcm_find_sidr_entry(ibcm_sidr_srch_t *srch_param, ibcm_hca_info_t *hcap,
558 550 ibcm_ud_state_data_t **ud_statep, ibcm_lookup_flag_t flag)
559 551 {
560 552 ibcm_status_t status;
561 553 ibcm_ud_state_data_t *usp;
562 554
563 555 IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: srch_params are:"
564 556 "lid=%x, (%llX, %llX), grh: %x, id: %x",
565 557 srch_param->srch_lid, srch_param->srch_gid.gid_prefix,
566 558 srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
567 559 srch_param->srch_req_id);
568 560
569 561 if (flag == IBCM_FLAG_ADD) {
570 562 *ud_statep = ibcm_add_sidr_entry(srch_param, hcap);
571 563 return (IBCM_LOOKUP_NEW);
572 564 }
573 565
574 566 usp = hcap->hca_sidr_list; /* Point to the list */
575 567
576 568 /* traverse the list for a matching entry */
577 569 while (usp != NULL) {
578 570 IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: "
579 571 "lid=%x, (%llX, %llX), grh: %x, id: %x",
580 572 usp->ud_sidr_req_lid, usp->ud_sidr_req_gid.gid_prefix,
581 573 usp->ud_sidr_req_gid.gid_guid, usp->ud_grh_exists,
582 574 usp->ud_req_id);
583 575
584 576 if ((usp->ud_sidr_req_lid == srch_param->srch_lid) &&
585 577 ((srch_param->srch_gid.gid_prefix == 0) ||
586 578 (srch_param->srch_gid.gid_prefix ==
587 579 usp->ud_sidr_req_gid.gid_prefix)) &&
588 580 ((srch_param->srch_gid.gid_guid == 0) ||
589 581 (srch_param->srch_gid.gid_guid ==
590 582 usp->ud_sidr_req_gid.gid_guid)) &&
591 583 (srch_param->srch_req_id == usp->ud_req_id) &&
592 584 (usp->ud_grh_exists == srch_param->srch_grh_exists) &&
593 585 (usp->ud_mode == srch_param->srch_mode)) { /* found match */
594 586 *ud_statep = usp;
595 587 IBTF_DPRINTF_L5(cmlog, "ibcm_find_sidr_entry: "
596 588 "found usp = %p", usp);
597 589 mutex_enter(&usp->ud_state_mutex);
598 590 IBCM_UD_REF_CNT_INCR(usp);
599 591 mutex_exit(&usp->ud_state_mutex);
600 592
601 593 return (IBCM_LOOKUP_EXISTS);
602 594 }
603 595 usp = usp->ud_nextp;
604 596 }
605 597
606 598 /*
607 599 * If code came here --> it couldn't find a match.
608 600 * OR
609 601 * the "hcap->hca_sidr_list" was NULL
610 602 */
611 603 if (flag == IBCM_FLAG_LOOKUP) {
612 604 IBTF_DPRINTF_L3(cmlog, "ibcm_find_sidr_entry: no match found "
613 605 "lid=%x, (%llX, %llX), grh: %x, id: %x",
614 606 srch_param->srch_lid, srch_param->srch_gid.gid_prefix,
615 607 srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
616 608 srch_param->srch_req_id);
617 609 status = IBCM_LOOKUP_FAIL;
618 610 } else {
619 611 *ud_statep = ibcm_add_sidr_entry(srch_param, hcap);
620 612 status = IBCM_LOOKUP_NEW;
621 613 }
622 614
623 615 return (status);
624 616 }
625 617
626 618
627 619 /*
628 620 * ibcm_add_sidr_entry:
629 621 * Adds a SIDR entry. Called *ONLY* from ibcm_find_sidr_entry()
630 622 *
631 623 * INPUTS:
632 624 * lid: LID of incoming SIDR REQ
633 625 * gid: GID of incoming SIDR REQ
634 626 * grh_exists: TRUE if GRH exists in the incoming SIDR REQ
635 627 * req_id: Request ID
636 628 * hcap: CM State table to search for SIDR state structure
637 629 * Return Values: NONE
638 630 */
↓ open down ↓ |
426 lines elided |
↑ open up ↑ |
639 631 ibcm_ud_state_data_t *
640 632 ibcm_add_sidr_entry(ibcm_sidr_srch_t *srch_param, ibcm_hca_info_t *hcap)
641 633 {
642 634 ibcm_ud_state_data_t *ud_statep;
643 635
644 636 IBTF_DPRINTF_L5(cmlog, "ibcm_add_sidr_entry: lid=%x, guid=%llX, "
645 637 "grh = %x req_id = %x", srch_param->srch_lid,
646 638 srch_param->srch_gid.gid_guid, srch_param->srch_grh_exists,
647 639 srch_param->srch_req_id);
648 640
649 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
650 -
651 641 /* didn't find the entry - so create new */
652 642 ud_statep = kmem_zalloc(sizeof (ibcm_ud_state_data_t), KM_SLEEP);
653 643
654 644 mutex_init(&ud_statep->ud_state_mutex, NULL, MUTEX_DEFAULT, NULL);
655 645 cv_init(&ud_statep->ud_block_client_cv, NULL, CV_DRIVER, NULL);
656 646
657 647 /* Initialize some ud_statep fields */
658 648 mutex_enter(&ud_statep->ud_state_mutex);
659 649 ud_statep->ud_hcap = hcap;
660 650 ud_statep->ud_req_id = srch_param->srch_req_id;
661 651 ud_statep->ud_ref_cnt = 1;
662 652 ud_statep->ud_grh_exists = srch_param->srch_grh_exists;
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
663 653 ud_statep->ud_sidr_req_lid = srch_param->srch_lid;
664 654 ud_statep->ud_sidr_req_gid = srch_param->srch_gid;
665 655 ud_statep->ud_mode = srch_param->srch_mode;
666 656 ud_statep->ud_max_cm_retries = ibcm_max_retries;
667 657 mutex_exit(&ud_statep->ud_state_mutex);
668 658
669 659 /* Update the list */
670 660 ud_statep->ud_nextp = hcap->hca_sidr_list;
671 661 hcap->hca_sidr_list = ud_statep;
672 662
673 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
674 -
675 663 return (ud_statep);
676 664 }
677 665
678 666
679 667 /*
680 668 * ibcm_delete_ud_state_data:
681 669 * Deletes a given state structure
682 670 *
683 671 * Arguments are:-
684 672 * statep - statep to be deleted
685 673 *
686 674 * Return Values: NONE
687 675 */
688 676 void
689 677 ibcm_delete_ud_state_data(ibcm_ud_state_data_t *ud_statep)
690 678 {
691 679 ibcm_ud_state_data_t *prevp, *headp;
692 680 ibcm_hca_info_t *hcap;
693 681
694 682 IBTF_DPRINTF_L4(cmlog, "ibcm_delete_ud_state_data: ud_statep 0x%p",
695 683 ud_statep);
696 684
697 685 if (ud_statep == NULL || ud_statep->ud_hcap == NULL) {
698 686 IBTF_DPRINTF_L2(cmlog, "ibcm_delete_ud_state_data: "
699 687 "ud_statep or hcap is NULL");
700 688 return;
701 689 }
702 690
703 691 hcap = ud_statep->ud_hcap;
704 692
705 693 rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
706 694
707 695 /* Next, remove this from the HCA SIDR list */
708 696 if (hcap->hca_sidr_list != NULL) {
709 697 prevp = NULL;
710 698 headp = hcap->hca_sidr_list;
711 699
712 700 while (headp != NULL) {
713 701 /* delete the matching entry */
714 702 if (headp == ud_statep) {
715 703 if (prevp) {
716 704 prevp->ud_nextp = headp->ud_nextp;
717 705 } else {
718 706 prevp = headp->ud_nextp;
719 707 hcap->hca_sidr_list = prevp;
720 708 }
721 709 break;
722 710 }
723 711 prevp = headp;
724 712 headp = headp->ud_nextp;
725 713 }
726 714 }
727 715
728 716 rw_exit(&hcap->hca_sidr_list_lock);
729 717
730 718 /*
731 719 * While ref_cnt > 0
732 720 * - implies someone else is accessing the statep (possibly in
733 721 * a timeout function handler etc.)
734 722 * - don't delete statep unless they are done otherwise potentially
735 723 * one could access released memory and panic.
736 724 */
737 725 mutex_enter(&ud_statep->ud_state_mutex);
738 726 if (ud_statep->ud_ref_cnt > 0) {
739 727 ud_statep->ud_delete_state_data = B_TRUE;
740 728 IBTF_DPRINTF_L4(cmlog, "ibcm_delete_ud_state_data: "
741 729 "ud_statep 0x%p ud_ref_cnt = %x", ud_statep,
742 730 ud_statep->ud_ref_cnt);
743 731 mutex_exit(&ud_statep->ud_state_mutex);
744 732 return;
745 733 }
746 734 mutex_exit(&ud_statep->ud_state_mutex);
747 735
748 736 ibcm_dealloc_ud_state_data(ud_statep);
749 737 }
750 738
751 739 /*
752 740 * ibcm_ud_dealloc_state_data:
753 741 * Deallocates a given ud state structure
754 742 *
755 743 * Arguments are:-
756 744 * ud statep - ud statep to be deleted
757 745 *
758 746 * Return Values: NONE
759 747 */
760 748 void
761 749 ibcm_dealloc_ud_state_data(ibcm_ud_state_data_t *ud_statep)
762 750 {
763 751 timeout_id_t timer_val;
764 752
765 753 IBTF_DPRINTF_L4(cmlog, "ibcm_dealloc_ud_state_data: ud_statep 0x%p",
766 754 ud_statep);
767 755
768 756 /* If timer is running - expire it */
769 757 mutex_enter(&ud_statep->ud_state_mutex);
770 758 if (ud_statep->ud_timerid) {
771 759 timer_val = ud_statep->ud_timerid;
772 760 ud_statep->ud_timerid = 0;
773 761 mutex_exit(&ud_statep->ud_state_mutex);
774 762 (void) untimeout(timer_val);
775 763 IBTF_DPRINTF_L2(cmlog, "ibcm_dealloc_ud_state_data: "
776 764 "Unexpected timer id 0x%p ud_statep 0x%p", timer_val,
777 765 ud_statep);
778 766 } else
779 767 mutex_exit(&ud_statep->ud_state_mutex);
780 768
781 769 if (ud_statep->ud_stored_msg != NULL) {
782 770 (void) ibcm_free_out_msg(
783 771 ud_statep->ud_stored_reply_addr.ibmf_hdl,
784 772 &ud_statep->ud_stored_msg);
785 773 }
786 774
787 775 /* release the ref cnt on the associated ibmf qp */
788 776 ASSERT(ud_statep->ud_stored_reply_addr.cm_qp_entry != NULL);
789 777 ibcm_release_qp(ud_statep->ud_stored_reply_addr.cm_qp_entry);
790 778
791 779 /* Ensure the thread doing ref cnt decr releases the mutex */
792 780 mutex_enter(&ud_statep->ud_state_mutex);
793 781 mutex_exit(&ud_statep->ud_state_mutex);
794 782
795 783 /* now do the mutex_destroy() and cv_destroy() */
796 784 mutex_destroy(&ud_statep->ud_state_mutex);
797 785
798 786 cv_destroy(&ud_statep->ud_block_client_cv);
799 787
800 788 /* free the req id on SIDR REQ sender side */
801 789 if (ud_statep->ud_mode == IBCM_ACTIVE_MODE)
802 790 ibcm_free_reqid(ud_statep->ud_hcap, ud_statep->ud_req_id);
803 791
804 792 /* Decrement the resource on hcap */
805 793 ibcm_dec_hca_res_cnt(ud_statep->ud_hcap);
806 794
807 795 /* free the statep */
808 796 kmem_free(ud_statep, sizeof (ibcm_ud_state_data_t));
809 797 }
810 798
811 799
812 800 /*
813 801 * ibcm_init_ids:
814 802 * Create the vmem arenas for the various global ids
815 803 *
816 804 * Arguments are:-
↓ open down ↓ |
132 lines elided |
↑ open up ↑ |
817 805 * NONE
818 806 *
819 807 * Return Values: ibcm_status_t
820 808 */
821 809
822 810 ibcm_status_t
823 811 ibcm_init_ids(void)
824 812 {
825 813 timespec_t tv;
826 814
827 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_sid_arena))
828 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_ip_sid_arena))
829 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_sid_seed))
830 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_local_cid_seed))
831 -
832 815 ibcm_local_sid_arena = vmem_create("ibcm_local_sid",
833 816 (void *)IBCM_INITIAL_SID, IBCM_MAX_LOCAL_SIDS, 1, NULL, NULL, NULL,
834 817 0, VM_SLEEP | VMC_IDENTIFIER);
835 818
836 819 if (!ibcm_local_sid_arena)
837 820 return (IBCM_FAILURE);
838 821
839 822 ibcm_ip_sid_arena = vmem_create("ibcm_ip_sid", (void *)IBCM_INITIAL_SID,
840 823 IBCM_MAX_IP_SIDS, 1, NULL, NULL, NULL, 0,
841 824 VM_SLEEP | VMC_IDENTIFIER);
842 825
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
843 826 if (!ibcm_ip_sid_arena)
844 827 return (IBCM_FAILURE);
845 828
846 829 /* create a random starting value for local service ids */
847 830 gethrestime(&tv);
848 831 ibcm_local_sid_seed = ((uint64_t)tv.tv_sec << 20) & 0x007FFFFFFFF00000;
849 832 ASSERT((ibcm_local_sid_seed & IB_SID_AGN_MASK) == 0);
850 833 ibcm_local_sid_seed |= IB_SID_AGN_LOCAL;
851 834
852 835 ibcm_local_cid_seed = (ib_com_id_t)tv.tv_sec;
853 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_sid_arena))
854 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_sid_seed))
855 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_ip_sid_arena))
856 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_local_cid_seed))
857 836
858 837 return (IBCM_SUCCESS);
859 838 }
860 839
861 840
862 841 /*
863 842 * ibcm_init_hca_ids:
864 843 * Create the vmem arenas for the various hca level ids
865 844 *
866 845 * Arguments are:-
867 846 * hcap pointer to ibcm_hca_info_t
868 847 *
869 848 * Return Values: ibcm_status_t
870 849 */
871 850 ibcm_status_t
872 851 ibcm_init_hca_ids(ibcm_hca_info_t *hcap)
873 852 {
874 853 hcap->hca_comid_arena = vmem_create("ibcm_com_ids",
875 854 (void *)IBCM_INITIAL_COMID, IBCM_MAX_COMIDS,
876 855 1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
877 856
878 857 if (!hcap->hca_comid_arena)
879 858 return (IBCM_FAILURE);
880 859
881 860 hcap->hca_reqid_arena = vmem_create("ibcm_req_ids",
882 861 (void *)IBCM_INITIAL_REQID, IBCM_MAX_REQIDS,
883 862 1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
884 863
885 864 if (!hcap->hca_reqid_arena) {
886 865 vmem_destroy(hcap->hca_comid_arena);
887 866 return (IBCM_FAILURE);
888 867 }
889 868
890 869 return (IBCM_SUCCESS);
891 870 }
892 871
893 872 /*
894 873 * ibcm_free_ids:
895 874 * Destroy the vmem arenas for the various ids
896 875 *
897 876 * Arguments are:-
898 877 * NONE
899 878 *
900 879 * Return Values: NONE
901 880 */
902 881 void
903 882 ibcm_fini_ids(void)
904 883 {
905 884 /* All arenas shall be valid */
906 885 vmem_destroy(ibcm_local_sid_arena);
907 886 vmem_destroy(ibcm_ip_sid_arena);
908 887 }
909 888
910 889 /*
911 890 * ibcm_free_hca_ids:
912 891 * Destroy the vmem arenas for the various ids
913 892 *
914 893 * Arguments are:-
915 894 * hcap pointer to ibcm_hca_info_t
916 895 *
917 896 * Return Values: NONE
918 897 */
919 898 void
920 899 ibcm_fini_hca_ids(ibcm_hca_info_t *hcap)
921 900 {
922 901 /* All arenas shall be valid */
923 902 vmem_destroy(hcap->hca_comid_arena);
924 903 vmem_destroy(hcap->hca_reqid_arena);
925 904 }
926 905
927 906 /* Communication id management routines ie., allocate, free up comids */
928 907
929 908 /*
930 909 * ibcm_alloc_comid:
931 910 * Allocate a new communication id
932 911 *
933 912 * Arguments are:-
934 913 * hcap : pointer to ibcm_hca_info_t
935 914 * comid: pointer to the newly allocated communication id
936 915 *
937 916 * Return Values: ibt_status_t
938 917 */
939 918 ibcm_status_t
940 919 ibcm_alloc_comid(ibcm_hca_info_t *hcap, ib_com_id_t *comidp)
941 920 {
942 921 ib_com_id_t comid;
943 922
944 923 /* Use next fit, so least recently used com id is allocated */
945 924 comid = (ib_com_id_t)(uintptr_t)vmem_alloc(hcap->hca_comid_arena, 1,
946 925 VM_SLEEP | VM_NEXTFIT);
947 926
948 927 IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_comid: hcap 0x%p comid 0x%lX", hcap,
949 928 comid);
950 929
951 930 /*
952 931 * As comid is 32 bits, and maximum connections possible are 2^24
953 932 * per hca, comid allocation would never fail
954 933 */
955 934 *comidp = comid + ibcm_local_cid_seed;
956 935 if (comid == 0) {
957 936 IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_comid: hcap 0x%p"
958 937 "no more comids available", hcap);
959 938 return (IBCM_FAILURE);
960 939 }
961 940
962 941 return (IBCM_SUCCESS);
963 942 }
964 943
965 944 /*
966 945 * ibcm_free_comid:
967 946 * Releases the given Communication Id
968 947 *
969 948 * Arguments are:
970 949 * hcap : pointer to ibcm_hca_info_t
971 950 * comid : Communication id to be free'd
972 951 *
973 952 * Return Values: NONE
974 953 */
975 954 void
976 955 ibcm_free_comid(ibcm_hca_info_t *hcap, ib_com_id_t comid)
977 956 {
978 957 IBTF_DPRINTF_L4(cmlog, "ibcm_free_comid: hcap 0x%p"
979 958 "comid %x", hcap, comid);
980 959 comid -= ibcm_local_cid_seed;
981 960 vmem_free(hcap->hca_comid_arena, (void *)(uintptr_t)comid, 1);
982 961 }
983 962
984 963 /* Allocate and Free local service ids */
985 964
986 965 /*
987 966 * ibcm_alloc_local_sids:
988 967 * Create and destroy the vmem arenas for the service ids
989 968 *
990 969 * Arguments are:-
991 970 * Number of contiguous SIDs needed
992 971 *
993 972 * Return Values: starting SID
994 973 */
995 974 ib_svc_id_t
996 975 ibcm_alloc_local_sids(int num_sids)
997 976 {
998 977 ib_svc_id_t sid;
999 978
1000 979 sid = (ib_svc_id_t)(uintptr_t)vmem_alloc(ibcm_local_sid_arena,
1001 980 num_sids, VM_SLEEP | VM_NEXTFIT);
1002 981
1003 982 IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_local_sids: ServiceID 0x%llX "
1004 983 "num_sids %d", sid, num_sids);
1005 984 if (sid == 0) {
1006 985 IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_local_sids: "
1007 986 "no more local sids available");
1008 987 } else {
1009 988 ASSERT((ibcm_local_sid_seed & IB_SID_AGN_MASK) ==
1010 989 IB_SID_AGN_LOCAL);
1011 990 sid += ibcm_local_sid_seed;
1012 991 IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_local_sids: Success: "
1013 992 "allocated 0x%llX:%d", sid, num_sids);
1014 993 }
1015 994 return (sid);
1016 995 }
1017 996
1018 997 /*
1019 998 * ibcm_free_local_sids:
1020 999 * Releases the given Local service id
1021 1000 *
1022 1001 * Arguments are:
1023 1002 * num_sids: Number of local service id's to be free'd
1024 1003 * service_id: Starting local service id that needs to be free'd
1025 1004 *
1026 1005 * Return Values: NONE
1027 1006 */
1028 1007 void
1029 1008 ibcm_free_local_sids(ib_svc_id_t service_id, int num_sids)
1030 1009 {
1031 1010 service_id -= ibcm_local_sid_seed;
1032 1011 IBTF_DPRINTF_L4(cmlog, "ibcm_free_local_sids: "
1033 1012 "service_id 0x%llX num_sids %d", service_id, num_sids);
1034 1013 vmem_free(ibcm_local_sid_arena,
1035 1014 (void *)(uintptr_t)service_id, num_sids);
1036 1015 }
1037 1016
1038 1017 /*
1039 1018 * ibcm_alloc_ip_sid:
1040 1019 * Allocate a local IP SID.
1041 1020 */
1042 1021 ib_svc_id_t
1043 1022 ibcm_alloc_ip_sid()
1044 1023 {
1045 1024 ib_svc_id_t sid;
1046 1025
1047 1026 sid = (ib_svc_id_t)(uintptr_t)vmem_alloc(ibcm_ip_sid_arena, 1,
1048 1027 VM_SLEEP | VM_NEXTFIT);
1049 1028 if (sid == 0) {
1050 1029 IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_ip_sid: no more RDMA IP "
1051 1030 "SIDs available");
1052 1031 } else {
1053 1032 sid += IB_SID_IPADDR_PREFIX;
1054 1033 IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_ip_sid: Success: RDMA IP SID"
1055 1034 " allocated : 0x%016llX", sid);
1056 1035 }
1057 1036 return (sid);
1058 1037 }
1059 1038
1060 1039 /*
1061 1040 * ibcm_free_ip_sid:
1062 1041 * Releases the given IP Service ID
1063 1042 */
1064 1043 void
1065 1044 ibcm_free_ip_sid(ib_svc_id_t sid)
1066 1045 {
1067 1046 sid -= IB_SID_IPADDR_PREFIX;
1068 1047 vmem_free(ibcm_ip_sid_arena, (void *)(uintptr_t)sid, 1);
1069 1048 }
1070 1049
1071 1050
1072 1051 /* Allocate and free request id routines for SIDR */
1073 1052
1074 1053 /*
1075 1054 * ibcm_alloc_reqid:
1076 1055 * Allocate a new SIDR REQ request id
1077 1056 *
1078 1057 * Arguments are:-
1079 1058 * hcap : pointer to ibcm_hca_info_t
1080 1059 * *reqid : pointer to the new request id returned
1081 1060 *
1082 1061 * Return Values: ibcm_status_t
1083 1062 */
1084 1063 ibcm_status_t
1085 1064 ibcm_alloc_reqid(ibcm_hca_info_t *hcap, uint32_t *reqid)
1086 1065 {
1087 1066 /* Use next fit, so least recently used com id is allocated */
1088 1067 *reqid = (uint32_t)(uintptr_t)vmem_alloc(hcap->hca_reqid_arena, 1,
1089 1068 VM_SLEEP | VM_NEXTFIT);
1090 1069
1091 1070 IBTF_DPRINTF_L4(cmlog, "ibcm_alloc_reqid: hcap 0x%p reqid %x", hcap,
1092 1071 *reqid);
1093 1072 if (!(*reqid)) {
1094 1073 IBTF_DPRINTF_L2(cmlog, "ibcm_alloc_reqid: "
1095 1074 "no more req ids available");
1096 1075 return (IBCM_FAILURE);
1097 1076 }
1098 1077 return (IBCM_SUCCESS);
1099 1078 }
1100 1079
1101 1080 /*
1102 1081 * ibcm_free_reqid:
1103 1082 * Releases the given SIDR REQ request id
1104 1083 *
1105 1084 * Arguments are:
1106 1085 * hcap : pointer to ibcm_hca_info_t
1107 1086 * reqid : Request id to be free'd
1108 1087 *
1109 1088 * Return Values: NONE
1110 1089 */
1111 1090 void
1112 1091 ibcm_free_reqid(ibcm_hca_info_t *hcap, uint32_t reqid)
1113 1092 {
1114 1093 IBTF_DPRINTF_L4(cmlog, "ibcm_free_reqid: hcap 0x%p reqid %x", hcap,
1115 1094 reqid);
1116 1095 vmem_free(hcap->hca_reqid_arena, (void *)(uintptr_t)reqid, 1);
1117 1096 }
1118 1097
1119 1098 /*
1120 1099 * ibcm_generate_tranid:
1121 1100 * Generate a new transaction id based on args
1122 1101 *
1123 1102 * Arguments are:-
1124 1103 * event_type CM Message REQ/DREQ/LAP
1125 1104 * id 32 bit identifier
1126 1105 * cm_tran_priv CM private data to be filled in top 28 MSB bits of
1127 1106 * tran id
1128 1107 *
1129 1108 *
1130 1109 * Return Value: uint64_t
1131 1110 */
1132 1111 uint64_t
1133 1112 ibcm_generate_tranid(uint8_t event, uint32_t id, uint32_t cm_tran_priv)
1134 1113 {
1135 1114 /*
1136 1115 * copy comid to bits 31-0 of tran id,
1137 1116 * attr id to bits 35-32 of tran id,
1138 1117 * cm_priv to bits 63-36 of tran id
1139 1118 */
1140 1119 if (cm_tran_priv == 0)
1141 1120 /*
1142 1121 * The below ensures that no duplicate transaction id is
1143 1122 * generated atleast for next 6 months. Calculations:
1144 1123 * (2^28)/(1000 * 60 * 24 * 30) = 6 approx
1145 1124 */
1146 1125 cm_tran_priv = gethrtime() >> 20; /* ~time in ms */
1147 1126
1148 1127 return ((((uint64_t)cm_tran_priv << 36) | (uint64_t)event << 32) | id);
1149 1128 }
1150 1129
1151 1130 #ifdef DEBUG
1152 1131
1153 1132 /*
1154 1133 * ibcm_decode_tranid:
1155 1134 * Decodes a given transaction id, assuming certain format.
1156 1135 *
1157 1136 * Arguments are:-
1158 1137 * tran_id Transaction id to be decoded
1159 1138 * cm_tran_priv CM private data retrieved from transaction id
1160 1139 *
1161 1140 * Return Value: None
1162 1141 */
1163 1142 void
1164 1143 ibcm_decode_tranid(uint64_t tran_id, uint32_t *cm_tran_priv)
1165 1144 {
1166 1145 ib_com_id_t id;
1167 1146 ibcm_event_type_t event;
1168 1147
1169 1148 id = tran_id & 0xFFFFFFFF;
1170 1149 event = (tran_id >> 32) & 0xF;
1171 1150
1172 1151 IBTF_DPRINTF_L5(cmlog, "ibcm_decode_tranid: id = 0x%x, event = %x",
1173 1152 id, event);
1174 1153
1175 1154 if (cm_tran_priv) {
1176 1155 *cm_tran_priv = tran_id >> 36;
1177 1156 IBTF_DPRINTF_L5(cmlog, "ibcm_decode_tranid: "
1178 1157 "cm_tran_priv = %x", *cm_tran_priv);
1179 1158 }
1180 1159 }
1181 1160
1182 1161 #endif
1183 1162
1184 1163 /*
1185 1164 * Service ID entry create and lookup functions
1186 1165 */
1187 1166
1188 1167 /*
1189 1168 * ibcm_svc_compare:
1190 1169 * - AVL svc tree node compare
1191 1170 *
1192 1171 * Arguments:
1193 1172 * p1 : pointer to local comid
1194 1173 * p2 : pointer to passed ibcm_state_data_t
1195 1174 *
1196 1175 * Return values:
1197 1176 * 0 : match found
1198 1177 * -1 : no match but insert to left side of the tree
1199 1178 * +1 : no match but insert to right side of the tree
1200 1179 */
1201 1180 int
1202 1181 ibcm_svc_compare(const void *p1, const void *p2)
1203 1182 {
1204 1183 ibcm_svc_lookup_t *sidp = (ibcm_svc_lookup_t *)p1;
1205 1184 ibcm_svc_info_t *svcp = (ibcm_svc_info_t *)p2;
1206 1185 ib_svc_id_t start_sid = sidp->sid;
1207 1186 ib_svc_id_t end_sid = start_sid + sidp->num_sids - 1;
1208 1187
1209 1188 IBTF_DPRINTF_L5(cmlog, "ibcm_svc_compare: "
1210 1189 "sid: 0x%llx, numsids: %d, node_sid: 0x%llx node_num_sids: %d",
1211 1190 sidp->sid, sidp->num_sids, svcp->svc_id, svcp->svc_num_sids);
1212 1191
1213 1192 ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
1214 1193
1215 1194 if (svcp->svc_id > end_sid)
1216 1195 return (-1);
1217 1196 if (svcp->svc_id + svcp->svc_num_sids - 1 < start_sid)
1218 1197 return (+1);
1219 1198 return (0); /* means there is some overlap of SIDs */
1220 1199 }
1221 1200
1222 1201
1223 1202 /*
1224 1203 * ibcm_create_svc_entry:
1225 1204 * Make sure no conflicting entry exists, then allocate it.
1226 1205 * Fill in the critical "look up" details that are provided
1227 1206 * in the arguments before dropping the lock.
1228 1207 *
1229 1208 * Return values:
↓ open down ↓ |
363 lines elided |
↑ open up ↑ |
1230 1209 * Pointer to ibcm_svc_info_t, if created, otherwise NULL.
1231 1210 */
1232 1211 ibcm_svc_info_t *
1233 1212 ibcm_create_svc_entry(ib_svc_id_t sid, int num_sids)
1234 1213 {
1235 1214 ibcm_svc_info_t *svcp;
1236 1215 ibcm_svc_info_t *svcinfop;
1237 1216 ibcm_svc_lookup_t svc;
1238 1217 avl_index_t where = 0;
1239 1218
1240 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*svcinfop))
1241 -
1242 1219 /* assume success, and avoid kmem while holding the writer lock */
1243 1220 svcinfop = kmem_zalloc(sizeof (*svcinfop), KM_SLEEP);
1244 1221 svcinfop->svc_id = sid;
1245 1222 svcinfop->svc_num_sids = num_sids;
1246 1223
1247 1224 svc.sid = sid;
1248 1225 svc.num_sids = num_sids;
1249 1226
1250 1227 mutex_enter(&ibcm_svc_info_lock);
1251 -#ifdef __lock_lint
1252 - ibcm_svc_compare(NULL, NULL);
1253 -#endif
1254 1228 svcp = avl_find(&ibcm_svc_avl_tree, &svc, &where);
1255 1229 if (svcp != NULL) { /* overlab exists */
1256 1230 mutex_exit(&ibcm_svc_info_lock);
1257 1231 kmem_free(svcinfop, sizeof (*svcinfop));
1258 1232 return (NULL);
1259 1233 }
1260 1234 avl_insert(&ibcm_svc_avl_tree, (void *)svcinfop, where);
1261 1235 mutex_exit(&ibcm_svc_info_lock);
1262 1236
1263 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*svcinfop))
1264 -
1265 1237 return (svcinfop);
1266 1238 }
1267 1239
1268 1240 /*
1269 1241 * ibcm_find_svc_entry:
1270 1242 * Finds a ibcm_svc_info_t entry into the CM's global table.
1271 1243 * The search done here assumes the list is sorted by SID.
1272 1244 *
1273 1245 * Arguments are:
1274 1246 * sid - Service ID to look up
1275 1247 *
1276 1248 * Return values:
1277 1249 * Pointer to ibcm_svc_info_t, if found, otherwise NULL.
1278 1250 */
1279 1251 ibcm_svc_info_t *
1280 1252 ibcm_find_svc_entry(ib_svc_id_t sid)
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
1281 1253 {
1282 1254 ibcm_svc_info_t *svcp;
1283 1255 ibcm_svc_lookup_t svc;
1284 1256
1285 1257 IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: finding SID 0x%llX", sid);
1286 1258
1287 1259 ASSERT(MUTEX_HELD(&ibcm_svc_info_lock));
1288 1260
1289 1261 svc.sid = sid;
1290 1262 svc.num_sids = 1;
1291 -#ifdef __lock_lint
1292 - ibcm_svc_compare(NULL, NULL);
1293 -#endif
1294 1263 svcp = avl_find(&ibcm_svc_avl_tree, &svc, NULL);
1295 1264 if (svcp != NULL) {
1296 1265 IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: "
1297 1266 "found SID = 0x%llX", sid);
1298 1267 return (svcp); /* found it */
1299 1268 }
1300 1269 IBTF_DPRINTF_L3(cmlog, "ibcm_find_svc_entry: SID %llX not found", sid);
1301 1270 return (NULL);
1302 1271 }
1303 1272
1304 1273 /*
1305 1274 * ibcm_alloc_ibmf_msg:
1306 1275 * Allocate an ibmf message structure and the additional memory required for
1307 1276 * sending an outgoing CM mad. The ibmf message structure contains two
1308 1277 * ibmf_msg_bufs_t fields, one for the incoming MAD and one for the outgoing
1309 1278 * MAD. The CM must allocate the memory for the outgoing MAD. The msg_buf
1310 1279 * field has three buffers: the mad header, the class header, and the class
1311 1280 * data. To simplify the code and reduce the number of kmem_zalloc() calls,
1312 1281 * ibcm_alloc_ibmf_msg will allocate one buffer and set the pointers to the
1313 1282 * right offsets. No class header is needed so only the mad header and class
1314 1283 * data fields are used.
1315 1284 */
1316 1285 ibt_status_t
1317 1286 ibcm_alloc_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp,
1318 1287 uint8_t method)
1319 1288 {
1320 1289 ib_mad_hdr_t *output_mad_hdr;
1321 1290 int sa_retval;
1322 1291
1323 1292 if ((sa_retval =
1324 1293 ibmf_alloc_msg(ibmf_handle, IBMF_ALLOC_SLEEP, ibmf_msgpp)) !=
1325 1294 IBMF_SUCCESS) {
1326 1295 IBTF_DPRINTF_L1(cmlog, "ibcm_alloc_out_msg: "
1327 1296 "ibmf_alloc_msg failed with IBMF_ALLOC_SLEEP");
1328 1297 return (ibcm_ibmf_analyze_error(sa_retval));
1329 1298 }
1330 1299
1331 1300 (*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr = kmem_zalloc(
1332 1301 IBCM_MAD_SIZE, KM_SLEEP);
1333 1302
1334 1303 (*ibmf_msgpp)->im_msgbufs_send.im_bufs_cl_data_len = IBCM_MSG_SIZE;
1335 1304 (*ibmf_msgpp)->im_msgbufs_send.im_bufs_cl_data =
1336 1305 (uchar_t *)((*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr) +
1337 1306 IBCM_MAD_HDR_SIZE;
1338 1307
1339 1308 /* initialize generic CM MAD header fields */
1340 1309 output_mad_hdr = IBCM_OUT_HDRP((*ibmf_msgpp));
1341 1310 output_mad_hdr->BaseVersion = IBCM_MAD_BASE_VERSION;
1342 1311 output_mad_hdr->MgmtClass = MAD_MGMT_CLASS_COMM_MGT;
1343 1312 output_mad_hdr->ClassVersion = IBCM_MAD_CLASS_VERSION;
1344 1313 output_mad_hdr->R_Method = method;
1345 1314
1346 1315 return (IBT_SUCCESS);
1347 1316 }
1348 1317
1349 1318 /*
1350 1319 * ibcm_free_ibmf_msg:
1351 1320 * Frees the buffer and ibmf message associated with an outgoing CM message.
1352 1321 * This function should only be used to free messages created by
1353 1322 * ibcm_alloc_out_msg. Will return IBCM_FAILURE if the ibmf_free_msg() call
1354 1323 * fails and IBCM_SUCCESS otherwise.
1355 1324 */
1356 1325 ibcm_status_t
1357 1326 ibcm_free_out_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t **ibmf_msgpp)
1358 1327 {
1359 1328 int ibmf_status;
1360 1329
1361 1330 kmem_free((*ibmf_msgpp)->im_msgbufs_send.im_bufs_mad_hdr,
1362 1331 IBCM_MAD_SIZE);
1363 1332
1364 1333 if ((ibmf_status = ibmf_free_msg(ibmf_handle, ibmf_msgpp)) !=
1365 1334 IBMF_SUCCESS) {
1366 1335 IBTF_DPRINTF_L2(cmlog, "ibcm_free_out_msg: "
1367 1336 "ibmf_free_msg failed %d", ibmf_status);
1368 1337 return (IBCM_FAILURE);
1369 1338 } else
↓ open down ↓ |
66 lines elided |
↑ open up ↑ |
1370 1339 return (IBCM_SUCCESS);
1371 1340 }
1372 1341
1373 1342 ibcm_qp_list_t *
1374 1343 ibcm_find_qp(ibcm_hca_info_t *hcap, int port_no, ib_pkey_t pkey)
1375 1344 {
1376 1345 ibcm_qp_list_t *entry;
1377 1346 ibmf_qp_handle_t ibmf_qp;
1378 1347 int ibmf_status;
1379 1348
1380 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*entry))
1381 -
1382 1349 mutex_enter(&ibcm_qp_list_lock);
1383 1350
1384 1351 /*
1385 1352 * CM currently does not track port up and down status. If tracking of
1386 1353 * " port status" is added in the future, then CM could be optimized to
1387 1354 * re-use other ports on hcap, if the port associated with the above
1388 1355 * port_no is down. But, the issue of "reachability" needs to be
1389 1356 * handled, before selecting an alternative port different from above.
1390 1357 */
1391 1358 entry = hcap->hca_port_info[port_no-1].port_qplist;
1392 1359 while (entry != NULL) {
1393 1360 if (entry->qp_pkey == pkey) {
1394 1361 ++entry->qp_ref_cnt;
1395 1362 mutex_exit(&ibcm_qp_list_lock);
1396 1363 return (entry);
1397 1364 }
1398 1365 entry = entry->qp_next;
1399 1366 }
1400 1367
1401 1368 /*
1402 1369 * entry not found, attempt to alloc a qp
1403 1370 * This may be optimized in the future, to allocate ibmf qp's
1404 1371 * once the "CM mgmt pkeys" are precisely known.
1405 1372 */
1406 1373 ibmf_status = ibmf_alloc_qp(
1407 1374 hcap->hca_port_info[port_no-1].port_ibmf_hdl, pkey, IB_GSI_QKEY,
1408 1375 IBMF_ALT_QP_MAD_NO_RMPP, &ibmf_qp);
1409 1376
1410 1377 if (ibmf_status != IBMF_SUCCESS) {
1411 1378 mutex_exit(&ibcm_qp_list_lock);
1412 1379 IBTF_DPRINTF_L2(cmlog, "ibcm_find_qp: failed to alloc IBMF QP"
1413 1380 "for Pkey = %x port_no = %x status = %d hcaguid = %llXp",
1414 1381 pkey, port_no, ibmf_status, hcap->hca_guid);
1415 1382 /*
1416 1383 * This may be optimized in the future, so as CM would attempt
1417 1384 * to re-use other QP's whose ref cnt is 0 in the respective
1418 1385 * port_qplist, by doing an ibmf_modify_qp with pkey above.
1419 1386 */
1420 1387 return (NULL);
1421 1388 }
1422 1389
1423 1390 entry = kmem_alloc(sizeof (ibcm_qp_list_t), KM_SLEEP);
1424 1391 entry->qp_next = hcap->hca_port_info[port_no-1].port_qplist;
1425 1392 hcap->hca_port_info[port_no-1].port_qplist = entry;
1426 1393 entry->qp_cm = ibmf_qp;
1427 1394 entry->qp_ref_cnt = 1;
1428 1395 entry->qp_pkey = pkey;
1429 1396 entry->qp_port = &(hcap->hca_port_info[port_no-1]);
1430 1397
1431 1398 mutex_exit(&ibcm_qp_list_lock);
1432 1399
1433 1400 /* set-up the handler */
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
1434 1401 ibmf_status = ibmf_setup_async_cb(
1435 1402 hcap->hca_port_info[port_no-1].port_ibmf_hdl, ibmf_qp,
1436 1403 ibcm_recv_cb, entry, 0);
1437 1404
1438 1405 ASSERT(ibmf_status == IBMF_SUCCESS);
1439 1406
1440 1407 #ifdef DEBUG
1441 1408 ibcm_query_qp(hcap->hca_port_info[port_no-1].port_ibmf_hdl, ibmf_qp);
1442 1409 #endif
1443 1410
1444 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*entry))
1445 -
1446 1411 return (entry);
1447 1412 }
1448 1413
1449 1414 void
1450 1415 ibcm_release_qp(ibcm_qp_list_t *cm_qp_entry)
1451 1416 {
1452 1417 mutex_enter(&ibcm_qp_list_lock);
1453 1418 --cm_qp_entry->qp_ref_cnt;
1454 1419 ASSERT(cm_qp_entry->qp_ref_cnt >= 0);
1455 1420 mutex_exit(&ibcm_qp_list_lock);
1456 1421 }
1457 1422
1458 1423
1459 1424 /* called holding the ibcm_qp_list_lock mutex */
1460 1425 ibcm_status_t
1461 1426 ibcm_free_qp(ibcm_qp_list_t *cm_qp_entry)
1462 1427 {
1463 1428 int ibmf_status;
1464 1429
1465 1430 IBTF_DPRINTF_L5(cmlog, "ibcm_free_qp: qp_hdl %p ref_cnt %d pkey %x",
1466 1431 cm_qp_entry->qp_cm, cm_qp_entry->qp_ref_cnt, cm_qp_entry->qp_pkey);
1467 1432
1468 1433 /* check, there are no users of this ibmf qp */
1469 1434 if (cm_qp_entry->qp_ref_cnt != 0)
1470 1435 return (IBCM_FAILURE);
1471 1436
1472 1437 /* Tear down the receive callback */
1473 1438 ibmf_status = ibmf_tear_down_async_cb(
1474 1439 cm_qp_entry->qp_port->port_ibmf_hdl, cm_qp_entry->qp_cm, 0);
1475 1440 if (ibmf_status != IBMF_SUCCESS) {
1476 1441 IBTF_DPRINTF_L2(cmlog, "ibcm_free_qp: "
1477 1442 "ibmf_tear_down_async_cb failed %d port_num %d",
1478 1443 ibmf_status, cm_qp_entry->qp_port->port_num);
1479 1444 return (IBCM_FAILURE);
1480 1445 }
1481 1446
1482 1447 ibmf_status = ibmf_free_qp(cm_qp_entry->qp_port->port_ibmf_hdl,
1483 1448 &cm_qp_entry->qp_cm, 0);
1484 1449 if (ibmf_status != IBMF_SUCCESS) {
1485 1450 IBTF_DPRINTF_L2(cmlog, "ibcm_free_qp: ibmf_free_qp failed for"
1486 1451 " ibmf_status %d qp hdl %p port_no %x", ibmf_status,
1487 1452 cm_qp_entry->qp_cm, cm_qp_entry->qp_port->port_num);
1488 1453 return (IBCM_FAILURE);
1489 1454 }
1490 1455
1491 1456 return (IBCM_SUCCESS);
1492 1457 }
1493 1458
1494 1459 ibcm_status_t
1495 1460 ibcm_free_allqps(ibcm_hca_info_t *hcap, int port_no)
1496 1461 {
1497 1462 ibcm_qp_list_t *entry, *freed;
1498 1463 ibcm_status_t ibcm_status = IBCM_SUCCESS;
1499 1464
1500 1465 IBTF_DPRINTF_L5(cmlog, "ibcm_free_allqps: hcap %p port_no %d", hcap,
1501 1466 port_no);
1502 1467
1503 1468 mutex_enter(&ibcm_qp_list_lock);
1504 1469 entry = hcap->hca_port_info[port_no-1].port_qplist;
1505 1470 while ((entry != NULL) &&
1506 1471 ((ibcm_status = ibcm_free_qp(entry)) == IBCM_SUCCESS)) {
1507 1472 freed = entry;
1508 1473 entry = entry->qp_next;
1509 1474 kmem_free(freed, sizeof (ibcm_qp_list_t));
1510 1475 }
1511 1476
1512 1477 if (ibcm_status != IBCM_SUCCESS) /* sanity the linked list */
1513 1478 hcap->hca_port_info[port_no-1].port_qplist = entry;
1514 1479 else /* all ibmf qp's of port must have been free'd successfully */
1515 1480 hcap->hca_port_info[port_no-1].port_qplist = NULL;
1516 1481
1517 1482 mutex_exit(&ibcm_qp_list_lock);
1518 1483 return (ibcm_status);
1519 1484 }
1520 1485
1521 1486 /*
1522 1487 * ibt_bind_service() and ibt_get_paths() needs the following helper function
1523 1488 * to handle endianess in case of Service Data.
1524 1489 */
1525 1490 void
1526 1491 ibcm_swizzle_from_srv(ibt_srv_data_t *sb_data, uint8_t *service_bytes)
1527 1492 {
1528 1493 uint8_t *p8 = service_bytes;
1529 1494 uint16_t *p16;
1530 1495 uint32_t *p32;
1531 1496 uint64_t *p64;
1532 1497 int i;
1533 1498
1534 1499 for (i = 0; i < 16; i++)
1535 1500 *p8++ = sb_data->s_data8[i];
1536 1501
1537 1502 p16 = (uint16_t *)p8;
1538 1503 for (i = 0; i < 8; i++)
1539 1504 *p16++ = h2b16(sb_data->s_data16[i]);
1540 1505
1541 1506 p32 = (uint32_t *)p16;
1542 1507 for (i = 0; i < 4; i++)
1543 1508 *p32++ = h2b32(sb_data->s_data32[i]);
1544 1509
1545 1510 p64 = (uint64_t *)p32;
1546 1511 for (i = 0; i < 2; i++)
1547 1512 *p64++ = h2b64(sb_data->s_data64[i]);
1548 1513 }
1549 1514
1550 1515 void
1551 1516 ibcm_swizzle_to_srv(uint8_t *service_bytes, ibt_srv_data_t *sb_data)
1552 1517 {
1553 1518 uint8_t *p8 = service_bytes;
1554 1519 uint16_t *p16;
1555 1520 uint32_t *p32;
1556 1521 uint64_t *p64;
1557 1522 int i;
1558 1523
1559 1524 for (i = 0; i < 16; i++)
1560 1525 sb_data->s_data8[i] = *p8++;
1561 1526
1562 1527 p16 = (uint16_t *)p8;
1563 1528 for (i = 0; i < 8; i++)
1564 1529 sb_data->s_data16[i] = h2b16(*p16++);
1565 1530
1566 1531 p32 = (uint32_t *)p16;
1567 1532 for (i = 0; i < 4; i++)
1568 1533 sb_data->s_data32[i] = h2b32(*p32++);
1569 1534 p64 = (uint64_t *)p32;
1570 1535
1571 1536 for (i = 0; i < 2; i++)
1572 1537 sb_data->s_data64[i] = h2b64(*p64++);
1573 1538 }
↓ open down ↓ |
118 lines elided |
↑ open up ↑ |
1574 1539
1575 1540 /* Trace related functions */
1576 1541
1577 1542 void
1578 1543 ibcm_init_conn_trace(ibcm_state_data_t *sp)
1579 1544 {
1580 1545 IBTF_DPRINTF_L5(cmlog, "ibcm_init_conn_trace: statep %p", sp);
1581 1546
1582 1547 /* Initialize trace related fields */
1583 1548
1584 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp->conn_trace))
1585 1549 sp->conn_trace = kmem_zalloc(sizeof (ibcm_conn_trace_t), KM_SLEEP);
1586 1550 if ((ibcm_enable_trace & 1) == 0)
1587 1551 sp->conn_trace->conn_base_tm = gethrtime();
1588 1552 sp->conn_trace->conn_allocated_trcnt = ibcm_conn_max_trcnt;
1589 1553 sp->conn_trace->conn_trace_events =
1590 1554 kmem_zalloc(sp->conn_trace->conn_allocated_trcnt, KM_SLEEP);
1591 1555 sp->conn_trace->conn_trace_event_times =
1592 1556 kmem_zalloc(sp->conn_trace->conn_allocated_trcnt *
1593 1557 sizeof (tm_diff_type), KM_SLEEP);
1594 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp->conn_trace))
1595 1558 }
1596 1559
1597 1560 void
1598 1561 ibcm_fini_conn_trace(ibcm_state_data_t *statep)
1599 1562 {
1600 1563 IBTF_DPRINTF_L5(cmlog, "ibcm_fini_conn_trace: statep %p tracep %p",
1601 1564 statep, statep->conn_trace);
1602 1565
1603 1566 /* free the trace data */
1604 1567 if (statep->conn_trace) {
1605 1568 if (statep->conn_trace->conn_trace_events)
1606 1569 kmem_free(statep->conn_trace->conn_trace_events,
1607 1570 statep->conn_trace->conn_allocated_trcnt);
1608 1571 if (statep->conn_trace->conn_trace_event_times)
1609 1572 kmem_free(statep->conn_trace->conn_trace_event_times,
1610 1573 statep->conn_trace->conn_allocated_trcnt *
1611 1574 sizeof (tm_diff_type));
1612 1575
1613 1576 kmem_free(statep->conn_trace, sizeof (ibcm_conn_trace_t));
1614 1577 }
1615 1578 }
1616 1579
1617 1580 /* mostly used to profile connection establishment times with dtrace */
1618 1581 void
1619 1582 ibcm_established(hrtime_t time_diff)
1620 1583 {
1621 1584 if (time_diff > 1000000000LL) /* 1 second */
1622 1585 IBTF_DPRINTF_L2(cmlog, "slow connection time (%d seconds)",
1623 1586 (uint_t)(time_diff >> 30));
1624 1587 }
1625 1588
1626 1589 void
1627 1590 ibcm_insert_trace(void *statep, ibcm_state_rc_trace_qualifier_t event_qualifier)
1628 1591 {
1629 1592 ibcm_conn_trace_t *conn_trace;
1630 1593 uint8_t conn_trace_ind;
1631 1594 hrtime_t time_diff;
1632 1595 hrtime_t hrt;
1633 1596
1634 1597 if (!(((ibcm_state_data_t *)statep)->conn_trace))
1635 1598 return;
1636 1599
1637 1600 conn_trace = ((ibcm_state_data_t *)statep)->conn_trace;
1638 1601
1639 1602 if (!conn_trace->conn_trace_events)
1640 1603 return;
1641 1604
1642 1605 IBTF_DPRINTF_L5(cmlog, "ibcm_insert_trace: statep %p event %d",
1643 1606 statep, event_qualifier);
1644 1607
1645 1608 mutex_enter(&ibcm_trace_mutex);
1646 1609
1647 1610 /* No more trace memory available, hence return */
1648 1611 if (conn_trace->conn_trace_ind == conn_trace->conn_allocated_trcnt) {
1649 1612 mutex_exit(&ibcm_trace_mutex);
1650 1613 return;
1651 1614 } else
1652 1615 ++conn_trace->conn_trace_ind;
1653 1616
1654 1617 conn_trace_ind = conn_trace->conn_trace_ind - 1;
1655 1618
1656 1619 conn_trace->conn_trace_events[conn_trace_ind] = event_qualifier;
1657 1620
1658 1621 if ((ibcm_enable_trace & 1) == 0) {
1659 1622 hrt = gethrtime();
1660 1623 time_diff = hrt - conn_trace->conn_base_tm;
1661 1624 if (event_qualifier == IBCM_TRACE_CALLED_CONN_EST_EVENT)
1662 1625 ibcm_established(time_diff);
1663 1626 time_diff >>= 10;
1664 1627 if (time_diff >= TM_DIFF_MAX) {
1665 1628 /* RESET, future times are relative to new base time. */
1666 1629 conn_trace->conn_base_tm = hrt;
1667 1630 time_diff = 0;
1668 1631 }
1669 1632 conn_trace->conn_trace_event_times[conn_trace_ind] = time_diff;
1670 1633 }
1671 1634
1672 1635 mutex_exit(&ibcm_trace_mutex);
1673 1636
1674 1637 IBTF_DPRINTF_L5(cmlog, "ibcm_insert_trace: statep %p inserted event %d",
1675 1638 statep, event_qualifier);
1676 1639 }
1677 1640
1678 1641 void
1679 1642 ibcm_dump_conn_trace(void *statep)
1680 1643 {
1681 1644 IBTF_DPRINTF_L5(cmlog, "ibcm_dump_conn_trace: statep %p",
1682 1645 statep);
1683 1646
1684 1647 mutex_enter(&ibcm_trace_print_mutex);
1685 1648 ibcm_debug_buf[0] = '\0';
1686 1649 ibcm_dump_conn_trbuf(statep, "ibcm: ", ibcm_debug_buf,
1687 1650 IBCM_DEBUG_BUF_SIZE);
1688 1651 if (ibcm_debug_buf[0] != '\0')
1689 1652 IBTF_DPRINTF_L2(cmlog, "\n%s", ibcm_debug_buf);
1690 1653
1691 1654 #ifdef DEBUG
1692 1655
1693 1656 if (ibcm_test_mode > 1)
1694 1657 cmn_err(CE_CONT, "IBCM DEBUG TRACE:\n%s", ibcm_debug_buf);
1695 1658 #endif
1696 1659
1697 1660 mutex_exit(&ibcm_trace_print_mutex);
1698 1661 }
1699 1662
1700 1663 void
1701 1664 ibcm_dump_conn_trbuf(void *statep, char *line_prefix, char *buf, int buf_size)
1702 1665 {
1703 1666 ibcm_conn_trace_t *conn_trace;
1704 1667 int tr_ind;
1705 1668 ibcm_state_data_t *sp;
1706 1669 int cur_size = 0; /* size of item copied */
1707 1670 int rem_size; /* remaining size in trace buffer */
1708 1671 int next_data = 0; /* location where next item copied */
1709 1672
1710 1673 if ((buf == NULL) || (buf_size <= 0))
1711 1674 return;
1712 1675
1713 1676 sp = (ibcm_state_data_t *)statep;
1714 1677
1715 1678 if (!sp->conn_trace)
1716 1679 return;
1717 1680
1718 1681 conn_trace = sp->conn_trace;
1719 1682
1720 1683 if (!conn_trace->conn_trace_events)
1721 1684 return;
1722 1685
1723 1686 rem_size = buf_size;
1724 1687
1725 1688 /* Print connection level global data */
1726 1689
1727 1690 /* Print statep, local comid, local qpn */
1728 1691 cur_size = snprintf(&buf[next_data], rem_size, "%s%s0x%p\n%s%s0x%p\n"
1729 1692 "%s%s0x%x/%llx/%d\n%s%s0x%x\n%s%s0x%x/%llx\n%s%s0x%x\n%s%s%llu\n",
1730 1693 line_prefix, event_str[IBCM_DISPLAY_SID], (void *)sp,
1731 1694 line_prefix, event_str[IBCM_DISPLAY_CHAN], (void *)sp->channel,
1732 1695 line_prefix, event_str[IBCM_DISPLAY_LCID], sp->local_comid,
1733 1696 (longlong_t)sp->local_hca_guid, sp->prim_port,
1734 1697 line_prefix, event_str[IBCM_DISPLAY_LQPN], sp->local_qpn,
1735 1698 line_prefix, event_str[IBCM_DISPLAY_RCID], sp->remote_comid,
1736 1699 (longlong_t)sp->remote_hca_guid,
1737 1700 line_prefix, event_str[IBCM_DISPLAY_RQPN], sp->remote_qpn,
1738 1701 line_prefix, event_str[IBCM_DISPLAY_TM], conn_trace->conn_base_tm);
1739 1702
1740 1703 rem_size = rem_size - cur_size;
1741 1704 if (rem_size <= 0) {
1742 1705 buf[buf_size-1] = '\n';
1743 1706 return;
1744 1707 }
1745 1708
1746 1709 next_data = next_data + cur_size;
1747 1710
1748 1711 for (tr_ind = 0; tr_ind < conn_trace->conn_trace_ind; tr_ind++) {
1749 1712 cur_size = snprintf(&buf[next_data], rem_size,
1750 1713 "%s%sTM_DIFF %u\n", line_prefix,
1751 1714 event_str[conn_trace->conn_trace_events[tr_ind]],
1752 1715 conn_trace->conn_trace_event_times[tr_ind]);
1753 1716 rem_size = rem_size - cur_size;
1754 1717 if (rem_size <= 0) {
1755 1718 buf[buf_size-1] = '\n';
1756 1719 return;
1757 1720 }
1758 1721 next_data = next_data + cur_size;
1759 1722 }
1760 1723
1761 1724 buf[next_data] = '\0';
1762 1725 IBTF_DPRINTF_L5(cmlog, "ibcm_dump_conn_trbuf: statep %p "
1763 1726 "debug buf size %d bytes", statep, next_data);
1764 1727 }
1765 1728
1766 1729
1767 1730 #ifdef DEBUG
1768 1731
1769 1732 void
1770 1733 ibcm_query_qp(ibmf_handle_t ibmf_hdl, ibmf_qp_handle_t ibmf_qp)
1771 1734 {
1772 1735 uint8_t qp_port_num;
1773 1736 ib_qpn_t qp_num;
1774 1737 ib_pkey_t qp_pkey;
1775 1738 ib_qkey_t qp_qkey;
1776 1739 int ibmf_status;
1777 1740
1778 1741 if (ibmf_qp == IBMF_QP_HANDLE_DEFAULT) {
1779 1742 IBTF_DPRINTF_L4(cmlog, "ibcm_query_qp: QP1");
1780 1743 return;
1781 1744 }
1782 1745
1783 1746 ibmf_status =
1784 1747 ibmf_query_qp(ibmf_hdl, ibmf_qp, &qp_num, &qp_pkey, &qp_qkey,
1785 1748 &qp_port_num, 0);
1786 1749
1787 1750 ASSERT(ibmf_status == IBMF_SUCCESS);
1788 1751
1789 1752 IBTF_DPRINTF_L5(cmlog, "ibcm_query_qp: qpn %x qkey %x pkey %x port %d",
1790 1753 qp_num, qp_qkey, qp_pkey, qp_port_num);
1791 1754 }
1792 1755
1793 1756 /*
1794 1757 * ibcm_dump_raw_message:
1795 1758 * dumps 256 bytes of data of a raw message (REP/REQ/DREQ ...)
1796 1759 * (can be called from the kernel debugger w/ the message pointer)
1797 1760 *
1798 1761 * Arguments:
1799 1762 * msgp - the messages that needs to be dumped
1800 1763 *
1801 1764 * Return values: NONE
1802 1765 */
1803 1766 void
1804 1767 ibcm_dump_raw_message(uchar_t *c)
1805 1768 {
1806 1769 int i;
1807 1770
1808 1771 for (i = 0; i < IBCM_MAD_SIZE; i += 16) {
1809 1772 /* print in batches of 16 chars at a time */
1810 1773 IBTF_DPRINTF_L4(cmlog,
1811 1774 "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
1812 1775 c[i], c[i + 1], c[i + 2], c[i + 3], c[i + 4], c[i + 5],
1813 1776 c[i + 6], c[i + 7], c[i + 8], c[i + 9], c[i + 10],
1814 1777 c[i + 11], c[i + 12], c[i + 13], c[i + 14], c[i + 15]);
1815 1778 }
1816 1779 }
1817 1780
1818 1781
1819 1782 /*
1820 1783 * ibcm_dump_srv_rec:
1821 1784 * Dumps Service Records.
1822 1785 *
1823 1786 * Arguments:
1824 1787 * srv_rec - the pointer to sa_service_record_t struct.
1825 1788 *
1826 1789 * Return values: NONE
1827 1790 */
1828 1791 void
1829 1792 ibcm_dump_srvrec(sa_service_record_t *srv_rec)
1830 1793 {
1831 1794 uint8_t i;
1832 1795
1833 1796 IBTF_DPRINTF_L4(cmlog, "ibcm_dump_srvrec: Service Records");
1834 1797 IBTF_DPRINTF_L4(cmlog, "SID : 0x%016llX", srv_rec->ServiceID);
1835 1798 IBTF_DPRINTF_L4(cmlog, "Svc GID : 0x%016llX:0x%016llX",
1836 1799 srv_rec->ServiceGID.gid_prefix, srv_rec->ServiceGID.gid_guid);
1837 1800 IBTF_DPRINTF_L4(cmlog, "Svc PKey : 0x%X", srv_rec->ServiceP_Key);
1838 1801
1839 1802 IBTF_DPRINTF_L4(cmlog, "Svc Lease : 0x%lX", srv_rec->ServiceLease);
1840 1803 IBTF_DPRINTF_L4(cmlog, "Svc Key-hi: 0x%016llX", srv_rec->ServiceKey_hi);
1841 1804 IBTF_DPRINTF_L4(cmlog, "Svc Key-lo: 0x%016llX", srv_rec->ServiceKey_lo);
1842 1805 IBTF_DPRINTF_L4(cmlog, "Svc Name : %s", srv_rec->ServiceName);
1843 1806 IBTF_DPRINTF_L4(cmlog, "Svc Data : ");
1844 1807 for (i = 0; i < IB_SVC_DATA_LEN; i += 8) {
1845 1808 IBTF_DPRINTF_L4(cmlog,
1846 1809 "\t 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X",
1847 1810 srv_rec->ServiceData[i], srv_rec->ServiceData[i+1],
1848 1811 srv_rec->ServiceData[i+2], srv_rec->ServiceData[i+3],
1849 1812 srv_rec->ServiceData[i+4], srv_rec->ServiceData[i+5],
1850 1813 srv_rec->ServiceData[i+6], srv_rec->ServiceData[i+7]);
1851 1814 }
1852 1815 }
1853 1816
1854 1817
1855 1818 /*
1856 1819 * ibcm_dump_pathrec:
1857 1820 * Dumps Path Records.
1858 1821 *
1859 1822 * Arguments:
1860 1823 * path_rec - the pointer to sa_path_record_t struct.
1861 1824 *
1862 1825 * Return values: NONE
1863 1826 */
1864 1827 void
1865 1828 ibcm_dump_pathrec(sa_path_record_t *path_rec)
1866 1829 {
1867 1830 IBTF_DPRINTF_L5(cmlog, "Path Record:");
1868 1831 IBTF_DPRINTF_L5(cmlog, "SGID: (sn_prefix) %016llX",
1869 1832 path_rec->SGID.gid_prefix);
1870 1833 IBTF_DPRINTF_L5(cmlog, "SGID: (GUID) %016llX",
1871 1834 path_rec->SGID.gid_guid);
1872 1835 IBTF_DPRINTF_L5(cmlog, "DGID: (sn_prefix) %016llX",
1873 1836 path_rec->DGID.gid_prefix);
1874 1837 IBTF_DPRINTF_L5(cmlog, "DGID: (GUID) %016llX",
1875 1838 path_rec->DGID.gid_guid);
1876 1839 IBTF_DPRINTF_L5(cmlog, "SLID: %04X", path_rec->SLID);
1877 1840 IBTF_DPRINTF_L5(cmlog, "DLID: %04X", path_rec->DLID);
1878 1841 IBTF_DPRINTF_L5(cmlog, "Raw Traffic: %01X", path_rec->RawTraffic);
1879 1842 IBTF_DPRINTF_L5(cmlog, "Flow Label: %05X", path_rec->FlowLabel);
1880 1843 IBTF_DPRINTF_L5(cmlog, "Hop Limit: %02X", path_rec->HopLimit);
1881 1844 IBTF_DPRINTF_L5(cmlog, "TClass: %02X", path_rec->TClass);
1882 1845 IBTF_DPRINTF_L5(cmlog, "Reversible: %01X", path_rec->Reversible);
1883 1846 IBTF_DPRINTF_L5(cmlog, "Numb Paths: %02d", path_rec->NumbPath);
1884 1847 IBTF_DPRINTF_L5(cmlog, "P_Key: %04X", path_rec->P_Key);
1885 1848 IBTF_DPRINTF_L5(cmlog, "SL: %02X", path_rec->SL);
1886 1849 IBTF_DPRINTF_L5(cmlog, "Path MTU Selector: %01X",
1887 1850 path_rec->MtuSelector);
1888 1851 IBTF_DPRINTF_L5(cmlog, "Path MTU: %02X", path_rec->Mtu);
1889 1852 IBTF_DPRINTF_L5(cmlog, "Path Rate Selector:%01X",
1890 1853 path_rec->RateSelector);
1891 1854 IBTF_DPRINTF_L5(cmlog, "Path Rate: %02X", path_rec->Rate);
1892 1855 IBTF_DPRINTF_L5(cmlog, "Packet LT Selector:%01X",
1893 1856 path_rec->PacketLifeTimeSelector);
1894 1857 IBTF_DPRINTF_L5(cmlog, "Packet Life Time: %d (dec)",
1895 1858 path_rec->PacketLifeTime);
1896 1859 IBTF_DPRINTF_L5(cmlog, "Preference Bit: %02X", path_rec->Preference);
1897 1860 }
1898 1861
1899 1862 /*
1900 1863 * ibcm_dump_node_rec:
1901 1864 * Dumps Node Records.
1902 1865 *
1903 1866 * Arguments:
1904 1867 * nrec - the pointer to sa_node_record_t struct.
1905 1868 *
1906 1869 * Return values: NONE
1907 1870 */
1908 1871 void
1909 1872 ibcm_dump_noderec(sa_node_record_t *nrec)
1910 1873 {
1911 1874 IBTF_DPRINTF_L5(cmlog, "ibcm_dump_noderec: Node Info Record");
1912 1875 IBTF_DPRINTF_L5(cmlog, "LID : %04X", nrec->LID);
1913 1876 IBTF_DPRINTF_L5(cmlog, "Base Ver : %02X", nrec->NodeInfo.BaseVersion);
1914 1877 IBTF_DPRINTF_L5(cmlog, "Class Ver : %02X", nrec->NodeInfo.ClassVersion);
1915 1878 IBTF_DPRINTF_L5(cmlog, "Node Type : %02d", nrec->NodeInfo.NodeType);
1916 1879 IBTF_DPRINTF_L5(cmlog, "Num Ports : %02X", nrec->NodeInfo.NumPorts);
1917 1880 IBTF_DPRINTF_L5(cmlog, "SysImgGUID: %016llX",
1918 1881 nrec->NodeInfo.SystemImageGUID);
1919 1882 IBTF_DPRINTF_L5(cmlog, "NODE GUID : %016llX", nrec->NodeInfo.NodeGUID);
1920 1883 IBTF_DPRINTF_L5(cmlog, "Port GUID : %016llX", nrec->NodeInfo.PortGUID);
1921 1884 IBTF_DPRINTF_L5(cmlog, "PartionCap: %04X", nrec->NodeInfo.PartitionCap);
1922 1885 IBTF_DPRINTF_L5(cmlog, "Device ID : %04X", nrec->NodeInfo.DeviceID);
1923 1886 IBTF_DPRINTF_L5(cmlog, "Revision : %06X", nrec->NodeInfo.Revision);
1924 1887 IBTF_DPRINTF_L5(cmlog, "LocalPort#: %02X", nrec->NodeInfo.LocalPortNum);
1925 1888 IBTF_DPRINTF_L5(cmlog, "Vendor ID : %06X", nrec->NodeInfo.VendorID);
1926 1889 IBTF_DPRINTF_L5(cmlog, "Description: %s",
1927 1890 (char *)&nrec->NodeDescription);
1928 1891 }
1929 1892 #endif
1930 1893
1931 1894 /*
1932 1895 * ibcm_ibtl_node_info:
1933 1896 * Get the node record of the destination specified by lid via the HCA
1934 1897 * and port specified.
1935 1898 *
1936 1899 * Arguments:
1937 1900 * hca_guid - GUID of the local HCA.
1938 1901 * port - port in the HCA to be used.
1939 1902 * lid - destination LID
1940 1903 * node_info_p - pointer to the Node Info to be returned.
1941 1904 *
1942 1905 * Return values:
1943 1906 * IBT_SUCCESS : Got the node record sucessfully
1944 1907 * IBT_FILURE : Failed to get the node record.
1945 1908 */
1946 1909 ibt_status_t
1947 1910 ibcm_ibtl_node_info(ib_guid_t hca_guid, uint8_t port, ib_lid_t lid,
1948 1911 ibt_node_info_t *node_info_p)
1949 1912 {
1950 1913 sa_node_record_t nr_req, *nr_resp;
1951 1914 void *res_p;
1952 1915 ibmf_saa_handle_t saa_handle;
1953 1916 ibt_status_t ibt_status;
1954 1917 ibcm_hca_info_t *hcap;
1955 1918 uint_t num_rec;
1956 1919 size_t len;
1957 1920
1958 1921 IBTF_DPRINTF_L3(cmlog, "ibcm_ibtl_node_info: ENTER: port %x "
1959 1922 "guid %llx\n", port, hca_guid);
1960 1923
1961 1924 hcap = ibcm_find_hca_entry(hca_guid);
1962 1925 if (hcap == NULL) {
1963 1926 IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1964 1927 "HCA(%llX) info not found", hca_guid);
1965 1928 return (IBT_FAILURE);
1966 1929 }
1967 1930
1968 1931 /* Get SA Access Handle. */
1969 1932 saa_handle = ibcm_get_saa_handle(hcap, port);
1970 1933 if (saa_handle == NULL) {
1971 1934 IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1972 1935 "Port %d of HCA (%llX) is NOT ACTIVE", port, hca_guid);
1973 1936 ibcm_dec_hca_acc_cnt(hcap);
1974 1937 return (IBT_FAILURE);
1975 1938 }
1976 1939
1977 1940 /* Retrieve Node Records from SA Access. */
1978 1941 bzero(&nr_req, sizeof (sa_node_record_t));
1979 1942 nr_req.LID = lid;
1980 1943
1981 1944 ibt_status = ibcm_get_node_rec(saa_handle, &nr_req,
1982 1945 SA_NODEINFO_COMPMASK_NODELID, &res_p, &len);
1983 1946 if (ibt_status != IBT_SUCCESS) {
1984 1947 IBTF_DPRINTF_L2(cmlog, "ibcm_ibtl_node_info: "
1985 1948 "failed (%d) to get Node records", ibt_status);
↓ open down ↓ |
381 lines elided |
↑ open up ↑ |
1986 1949 ibcm_dec_hca_acc_cnt(hcap);
1987 1950 return (IBT_FAILURE);
1988 1951 }
1989 1952
1990 1953 num_rec = len/sizeof (sa_node_record_t);
1991 1954 nr_resp = (sa_node_record_t *)(uchar_t *)res_p;
1992 1955
1993 1956 if ((nr_resp != NULL) && (num_rec > 0)) {
1994 1957 IBCM_DUMP_NODE_REC(nr_resp);
1995 1958
1996 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
1997 - *node_info_p))
1998 -
1999 1959 node_info_p->n_sys_img_guid =
2000 1960 nr_resp->NodeInfo.SystemImageGUID;
2001 1961 node_info_p->n_node_guid =
2002 1962 nr_resp->NodeInfo.NodeGUID;
2003 1963 node_info_p->n_port_guid =
2004 1964 nr_resp->NodeInfo.PortGUID;
2005 1965 node_info_p->n_dev_id =
2006 1966 nr_resp->NodeInfo.DeviceID;
2007 1967 node_info_p->n_revision =
2008 1968 nr_resp->NodeInfo.Revision;
2009 1969 node_info_p->n_vendor_id =
2010 1970 nr_resp->NodeInfo.VendorID;
2011 1971 node_info_p->n_num_ports =
2012 1972 nr_resp->NodeInfo.NumPorts;
2013 1973 node_info_p->n_port_num =
2014 1974 nr_resp->NodeInfo.LocalPortNum;
2015 1975 node_info_p->n_node_type =
2016 1976 nr_resp->NodeInfo.NodeType;
2017 1977 (void) strncpy(node_info_p->n_description,
2018 1978 (char *)&nr_resp->NodeDescription, 64);
2019 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
2020 - *node_info_p))
2021 1979
2022 -
2023 1980 kmem_free(nr_resp, len);
2024 1981 }
2025 1982 ibcm_dec_hca_acc_cnt(hcap);
2026 1983 return (IBT_SUCCESS);
2027 1984 }
2028 1985
2029 1986 /*
2030 1987 * ibcm_ibmf_analyze_error:
2031 1988 * Checks IBMF status and determines appropriate ibt status.
2032 1989 *
2033 1990 * Arguments:
2034 1991 * ibmf_status - IBMF Status
2035 1992 *
2036 1993 * Return values:
2037 1994 * ibt_status_t
2038 1995 */
2039 1996 ibt_status_t
2040 1997 ibcm_ibmf_analyze_error(int ibmf_status)
2041 1998 {
2042 1999 if (ibt_check_failure(ibmf_status, NULL) != IBT_FAILURE_STANDARD) {
2043 2000 /*
2044 2001 * IBMF specific failure, return special error code
2045 2002 * to the client so that it can retrieve any associated ENA.
2046 2003 */
2047 2004 return (ibmf_status);
2048 2005 } else if (ibmf_status == IBMF_TRANS_TIMEOUT) {
2049 2006 return (IBT_IBMF_TIMEOUT);
2050 2007 } else {
2051 2008 /*
2052 2009 * IBMF failed for some other reason, invalid arguments etc.
2053 2010 * Analyze, log ENA with IBTF and obtain a special ibt_status_t
2054 2011 * that indicates IBMF failure.
2055 2012 */
2056 2013 if ((ibmf_status == IBMF_BAD_CLASS) ||
2057 2014 (ibmf_status == IBMF_BAD_HANDLE) ||
2058 2015 (ibmf_status == IBMF_BAD_QP_HANDLE) ||
2059 2016 (ibmf_status == IBMF_BAD_NODE) ||
2060 2017 (ibmf_status == IBMF_BAD_PORT) ||
2061 2018 (ibmf_status == IBMF_BAD_VERSION) ||
2062 2019 (ibmf_status == IBMF_BAD_FLAGS) ||
2063 2020 (ibmf_status == IBMF_BAD_SIZE) ||
2064 2021 (ibmf_status == IBMF_INVALID_GID) ||
2065 2022 (ibmf_status == IBMF_INVALID_ARG) ||
2066 2023 (ibmf_status == IBMF_INVALID_FIELD) ||
2067 2024 (ibmf_status == IBMF_UNSUPP_METHOD) ||
2068 2025 (ibmf_status == IBMF_UNSUPP_METHOD_ATTR)) {
2069 2026
2070 2027 /*
2071 2028 * These errors, we should not see...
2072 2029 * something really bad happened!.
2073 2030 */
2074 2031 IBTF_DPRINTF_L2(cmlog, "ibcm_ibmf_analyze_error: "
2075 2032 "Unexpected ERROR from IBMF - %d", ibmf_status);
2076 2033 }
2077 2034 return (ibt_get_module_failure(IBT_FAILURE_IBMF, 0));
2078 2035 }
2079 2036 }
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX