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_sm.c
+++ new/usr/src/uts/common/io/ib/mgt/ibcm/ibcm_sm.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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #include <sys/ib/mgt/ibcm/ibcm_impl.h>
26 26 #include <sys/callb.h>
27 27
28 28 /*
29 29 * ibcm_sm.c
30 30 * These routines implement the CM state machine (both ACTIVE and PASSIVE)
31 31 *
32 32 * Points to Note :
33 33 *
34 34 * o CM uses one ibcm_hca_info_t entry per HCA to store all the
35 35 * connection state data belonging to that HCA in the AVL trees, etc.,
36 36 *
37 37 * o There is one state structure per RC, referenced from three AVL trees
38 38 * ie. the HCA active AVL tree, and the HCA passive AVL tree and HCA
39 39 * passive comid tree
40 40 *
41 41 * o SIDR state structures are stored in a linked list
42 42 *
43 43 * o The term statep generally refers to RC, until explicitly mentioned
44 44 * in the notes below
45 45 *
46 46 * o Any thread that may access statep increments the ref_cnt. This ensures
47 47 * that statep is not deleted when it is still being accessed and modified
48 48 * by other threads
49 49 *
50 50 * o Any thread that may want to search the AVL tree(s) holds the hca state
51 51 * table reader lock. If it shall insert/delete a new state structure, then
52 52 * the lock held is writer lock.
53 53 *
54 54 * o Incrementing and Decrementing the ref_cnt can happen only after acquiring
55 55 * statep mutex
56 56 *
57 57 * o Deleting a statep can happen only by acquiring the hca state writer lock
58 58 * and statep mutex and if ref_cnt is zero.
59 59 *
60 60 * o Statep mutexes are used to decrease the hca state table lock holding
61 61 * times. thus increasing more number of threads that can access hca
62 62 * global data structures
63 63 *
64 64 * o Statep mutexes cannot be hold for long time. They are primarily used to
65 65 * check the state of statep, change it and exit the lock. Other threads
66 66 * checking this statep find statep's new state, and may exit without
67 67 * further processing (as the statep->state has changed).
68 68 *
69 69 * o Statep mutex must be held while setting and unsetting the timer id
70 70 * values and during untimeout
71 71 *
72 72 * Re-stating, the overall purpose of these various locks are:
73 73 * - Minimize the time state table locks are held
74 74 * - Writer locks are held only while inserting/deleting into trees,
75 75 * so multiple readers can traverse data structures in parallel
76 76 * - Minimize the time statep mutex held, so other threads entering the same
77 77 * statep mutex are not held for long
78 78 *
79 79 * The CM state machine logic ensures that the statep is valid and exists
80 80 * when timeout callback (ibcm_timeout_cb) is called. This is ensured by
81 81 * cancelling timeouts on state changes, where appropriate
82 82 *
83 83 *
84 84 * The timeout processing is handled in the context in which the
85 85 * timeout callback is invoked.
86 86 *
87 87 * The CM STATE MACHINE logic flow:
88 88 *
89 89 * On an incoming MAD:-
90 90 *
91 91 * IBMF -> ibcm_process_incoming_mad
92 92 * Verify and branch to one of the below connection state routines.
93 93 * The callback arg from ibmf has the pointer to ibcm_hca_info_t
94 94 *
95 95 * 1. INCOMING REQ MAD
96 96 *
97 97 * Acquire hca state table WRITER lock
98 98 * Do lookup in passive AVL tree by remote qpn and remote hca guid
99 99 *
100 100 * If (new lookup)
101 101 *
102 102 * create new statep, initialize key fields
103 103 * obtain new local com id, insert into hca state AVL tree
104 104 * release hca state table WRITER lock
105 105 *
106 106 * Initialize remaining fields
107 107 * If invalid service id,
108 108 * send a REJ reply,
109 109 * decr ref_cnt holding state mutex
110 110 * If existing peer conn, check guids, and break the tie
111 111 * Call the cep state transition function
112 112 * Send an RTU/REJ reply
113 113 * Check and handle for any incoming REJ's during REQ RCVD state
114 114 *
115 115 * else if (existing lookup)
116 116 *
117 117 * increment refcnt holding state mutex
118 118 * release hca state table WRITER lock
119 119 *
120 120 * re-acquire the statep mutex
121 121 * if (statep->state is REP SENT/REJ SENT/ MRA SENT)
122 122 * resend the mad
123 123 * else if established
124 124 * handle the stale detection
125 125 * else
126 126 * drop the mad (no processing required)
127 127 * decr statep->ref_cnt, release state mutex
128 128 *
129 129 *
130 130 * 2. INCOMING REP MAD
131 131 *
132 132 * Acquire hca state READER lock
133 133 * Do lookup in hca state tree by local com id
134 134 * Release hca state table READER lock
135 135 *
136 136 * if lookup does not exist
137 137 * return
138 138 *
139 139 * if look up exists
140 140 * incr statep->ref_cnt holding state mutex
141 141 *
142 142 * acquire the statep lock
143 143 * if (state == ESTABLISHED or REJ SENt or MRA REP SENT)
144 144 * resend the MAD
145 145 * release state mutex, cancel req sent timer
146 146 * decrement ref_cnt holding the statep lock
147 147 * return
148 148 *
149 149 * if (state == REQ_SENT or REP_WAIT)
150 150 * first, change state to REP_RCVD
151 151 * release statep lock
152 152 * cancel timers
153 153 * lookup in the passive tree by remote qpn and remote hca guid
154 154 * if entry already exists
155 155 * handle the stale detection
156 156 * else
157 157 * add to the passive tree
158 158 *
159 159 * Initialize fields of statep
160 160 * Call the qp state transition function
161 161 * Post RTU/REJ reply
162 162 * Acquire the state mutex
163 163 * decrement the ref cnt
164 164 * release the statep lock
165 165 *
166 166 * 3. INCOMING MRA
167 167 *
168 168 * Acquire hca state table READER lock
169 169 * Do lookup in active hca state tree by local com id
170 170 * Release hca state table READER lock
171 171 *
172 172 * If lookup does not exist
173 173 * return
174 174 *
175 175 * if look up exists
176 176 * incr statep->ref_cnt holding state mutex
177 177 *
178 178 * acquire state mutex
179 179 * if (state is REQ_SENT or REP_SENT)
180 180 * change state to REP WAIT or MRA REP RCVD
181 181 * release state mutex
182 182 * cancel the current timer
183 183 *
184 184 * reacquire state mutex
185 185 * if (state is REP_WAIT or MRA_REP_RCVD)
186 186 * set new timer, using service timeout for the first timeout
187 187 * decr ref cnt, release state mutex
188 188 *
189 189 * 4. INCOMING RTU
190 190 *
191 191 * Acquire hca state table READER lock
192 192 * Do lookup in active hca state tree by local com id
193 193 * Release hca state table READER lock
194 194 *
195 195 * If lookup does not exist
196 196 * return
197 197 *
198 198 * if look up exists
199 199 * incr statep->ref_cnt holding state mutex
200 200 *
201 201 * acquire statep mutex
202 202 * if (state == REP_SENT or MRA REP RCVD))
203 203 * change state to ESTABLISHED
204 204 * release statep mutex
205 205 * cancel timer
206 206 *
207 207 * Change QP state
208 208 *
209 209 * acquire the statep mutex
210 210 * decrement the ref count
211 211 * release statep mutex
212 212 *
213 213 * 5. INCOMING REJ
214 214 *
215 215 * Acquire hca state table READER lock
216 216 * Do lookup in active hca state tree by local com id
217 217 * Release hca state table READER lock
218 218 *
219 219 * If lookup does not exist
220 220 * return
221 221 *
222 222 * if look up exists
223 223 * incr statep->ref_cnt holding state mutex
224 224 *
225 225 * if (state == REQ RCVD or REP RCVD MRA_SENT or MRA_REP_SNET)
226 226 * set statep->delete = true
227 227 * decrement the ref_cnt
228 228 * release statep mutex;
229 229 *
230 230 * else if (state == REQ_SENT or REP SENT or MRA REP Rcvd)
231 231 * state = IBCM_STATE_DELETE
232 232 * Cancel running timers
233 233 * decrement the ref_cnt
234 234 * release state mutex
235 235 * Call the client QP handler
236 236 * delete the state data
237 237 *
238 238 * 6. INCOMING DREQ
239 239 *
240 240 * Acquire hca state table READER lock
241 241 * Do lookup in active hca state tree by local com id
242 242 * Release hca state table READER lock
243 243 *
244 244 * If lookup does not exist
245 245 * return
246 246 *
247 247 * if look up exists
248 248 * incr statep->ref_cnt holding state mutex
249 249 *
250 250 * acquire state mutex
251 251 * if (state is ESTABLISHED/DREQ SENT/TIMEWAIT)
252 252 * if state is ESTABLISHED/DREQ SENT,
253 253 * change state to DREQ RECVD
254 254 * start timers
255 255 *
256 256 * send DREP reply
257 257 * decr ref_cnt
258 258 * release state mutex
259 259 *
260 260 * 7. Incoming DREP
261 261 *
262 262 * Acquire hca state table READER lock
263 263 * Do lookup in active hca state tree by local com id
264 264 * Release hca state table READER lock
265 265 *
266 266 * If lookup does not exist
267 267 * return
268 268 *
269 269 * if look up exists
270 270 * incr statep->ref_cnt holding state mutex
271 271 *
272 272 * acquire state mutex
273 273 * if state is DREQ_SENT
274 274 * change state to DREP_RCVD
275 275 * cancel timer
276 276 * change state to TIMEWAIT
277 277 * set timewait timer
278 278 * decr ref_cnt
279 279 * release state mutex
280 280 *
281 281 * 8. Timeout handler
282 282 *
283 283 * (for states REQ SENT/REP SENT/REJ SENT/DREQ SENT/DREP SENT/TIMEWAIT)
284 284 *
285 285 * acquire the statep mutex
286 286 *
287 287 * if (set state != stored_state)
288 288 * The thread that changed the state is responsible for any cleanup
289 289 * decrement ref cnt
290 290 * release statep mutex
291 291 * return
292 292 * else if (statep's state == REJ SENT)
293 293 * change state to DELETE
294 294 * decrement ref cnt
295 295 * release statep mutex
296 296 * delete statep
297 297 * return
298 298 * else if (state == TIME WAIT)
299 299 * do the time wait state processing
300 300 * decrement ref cnt
301 301 * change state to DELETE
302 302 * release statep mutex
303 303 * delete statep, and also QP
304 304 * else if (remaining retry cnt > 0)
305 305 * resend the mad
306 306 * decrement ref cnt
307 307 * release statep mutex
308 308 * else if (state == rep sent or req sent or mra rep rcvd or rep wait)
309 309 * (retry counter expired)
310 310 * change state to REJ SENT (No one shall delete in REJ SENT)
311 311 * decrement the ref_cnt
312 312 * release the statep mutex
313 313 * Post REJ MAD
314 314 * cv_signal anyone blocking
315 315 * Invoke client handler
316 316 * else if state == DREQ_SENT
317 317 * change state to TIME WAIT
318 318 * decrement the ref cnt
319 319 * set a timer for time wait time
320 320 * release the statep mutex
321 321 *
322 322 *
323 323 * SIDR processing
324 324 *
325 325 * 9. INCOMING SIDR_REQ MAD
326 326 *
327 327 * Figure out LID/GID
328 328 * Do lookup in SIDR LIST based on LID, GID, grh_exists and req_id
329 329 * increment ud_statep->ud_ref_cnt
330 330 *
331 331 * If (new lookup)
332 332 *
333 333 * validate service id, and the create new statep,
334 334 * initialize key fields
335 335 * do a lookup based on service id
336 336 * if service_id_lookup returns exists
337 337 * set sidr_status to QPN_VALID
338 338 * else
339 339 * set sidr_status to SID_INVALID
340 340 * post SIDR_REP mad
341 341 * decr ud_statep->ud_ref_cnt, release ud_state_mutex
342 342 *
343 343 * else if (existing lookup)
344 344 *
345 345 * if (ud_statep->ud_state is SIDR_REP_SENT)
346 346 * resend the mad
347 347 *
348 348 * decr ud_statep->ud_ref_cnt, release ud_state_mutex
349 349 *
350 350 *
351 351 * 10. INCOMING SIDR_REP MAD
352 352 *
353 353 * Figure out LID/GID
354 354 * Do lookup in SIDR LIST based on LID, GID, grh_exists and req_id
355 355 * increment ud_statep->ud_ref_cnt
356 356 *
357 357 * if look up doesn't exists
358 358 * return
359 359 *
360 360 * if (state == SIDR_REQ_SENT)
361 361 * first, change state to SIDR_REP_RCVD
362 362 * release statep lock
363 363 * cancel timers
364 364 * cv_signal anyone blocking
365 365 * release the statep lock
366 366 * extract return args
367 367 * destroy the statep
368 368 *
369 369 * 11. Timeout handler
370 370 *
371 371 * (for states SIDR_REQ_SENT/SIDR_REP_SENT)
372 372 *
373 373 * acquire the statep mutex
374 374 *
375 375 * if (statep's state == SIDR_REP_SENT SENT)
376 376 * change state to DELETE
377 377 * decrement ref cnt
378 378 * release statep mutex
379 379 * delete statep
380 380 * return
381 381 * else if (remaining retry cnt > 0 and state is SIDR_REQ_SENT)
382 382 * resend the mad
383 383 * decrement ref cnt
384 384 * release statep mutex
385 385 * else if (state == SIDR_REQ_SENT)
386 386 * (retry counter expired)
387 387 * change state to DELETE
388 388 * decrement the ref_cnt
389 389 * the statep mutex
390 390 * cv_signal anyone blocking
391 391 * Invoke client handler
392 392 * delete statep
393 393 */
394 394
395 395 /* Function prototypes */
396 396 static void ibcm_set_primary_adds_vect(ibcm_state_data_t *,
397 397 ibt_adds_vect_t *, ibcm_req_msg_t *);
398 398 static void ibcm_set_alt_adds_vect(ibcm_state_data_t *,
399 399 ibt_adds_vect_t *, ibcm_req_msg_t *);
400 400 static ibt_status_t ibcm_set_primary_cep_path(ibcm_state_data_t *,
401 401 ibt_cep_path_t *, ibcm_req_msg_t *);
402 402 static ibt_status_t ibcm_set_alt_cep_path(ibcm_state_data_t *,
403 403 ibt_cep_path_t *, ibcm_req_msg_t *);
404 404 static ibt_status_t ibcm_invoke_qp_modify(ibcm_state_data_t *,
405 405 ibcm_req_msg_t *, ibcm_rep_msg_t *);
406 406 static ibt_status_t ibcm_invoke_rtu_qp_modify(ibcm_state_data_t *,
407 407 ib_time_t, ibcm_rep_msg_t *);
408 408 static ibcm_status_t ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t *,
409 409 ibcm_sidr_req_msg_t *, ibcm_mad_addr_t *,
410 410 ibt_sidr_status_t *);
411 411 static void ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t *,
412 412 ibcm_sidr_rep_msg_t *);
413 413 static void ibcm_handler_conn_fail(ibcm_state_data_t *,
414 414 uint8_t cf_code, uint8_t cf_msg,
415 415 ibt_cm_reason_t rej_reason, uint8_t *,
416 416 ibt_priv_data_len_t);
417 417 static void ibcm_build_n_post_rej_mad(uint8_t *input_madp,
418 418 ib_com_id_t, ibcm_mad_addr_t *, int, uint16_t);
419 419 static void ibcm_post_drep_mad(ibcm_state_data_t *);
420 420
421 421 static ibcm_status_t ibcm_verify_req_gids_and_svcid(
422 422 ibcm_state_data_t *statep,
423 423 ibcm_req_msg_t *cm_req_msgp);
424 424
425 425 static void ibcm_timeout_client_cb(ibcm_state_data_t *statep);
426 426 static void ibcm_ud_timeout_client_cb(
427 427 ibcm_ud_state_data_t *ud_statep);
428 428
429 429 static void ibcm_process_dreq_timeout(ibcm_state_data_t *statep);
430 430
431 431 static void ibcm_fill_adds_from_lap(ibt_adds_vect_t *adds,
432 432 ibcm_lap_msg_t *lap_msg, ibcm_mode_t mode);
433 433
434 434 static void ibcm_post_stored_apr_mad(ibcm_state_data_t *statep,
435 435 uint8_t *input_madp);
436 436
437 437 static ibcm_status_t ibcm_set_qp_from_apr(ibcm_state_data_t *statep,
438 438 ibcm_lap_msg_t *lap_msg);
439 439
440 440 static boolean_t ibcm_compare_prim_alt_paths(ibt_adds_vect_t *prim,
441 441 ibt_adds_vect_t *alt);
442 442
443 443 static void ibcm_process_get_classport_info(ibcm_hca_info_t *hcap,
444 444 uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr);
445 445
446 446 static void ibcm_decode_classport_info(ibcm_hca_info_t *hcap,
447 447 uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr);
448 448
449 449 static void ibcm_post_rej_ver_mismatch(uint8_t *input_madp,
450 450 ibcm_mad_addr_t *cm_mad_addr);
451 451
452 452 static void ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t *clp,
453 453 ibt_redirect_info_t *rinfo);
454 454
455 455 static void ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t *clp,
456 456 ibt_redirect_info_t *rinfo);
457 457
458 458 static void ibcm_copy_addl_rej(ibcm_state_data_t *statep,
459 459 ibcm_rej_msg_t *rej_msgp,
460 460 ibt_cm_conn_failed_t *failed);
461 461
462 462 static void ibcm_return_open_data(ibcm_state_data_t *statep,
463 463 ibcm_rep_msg_t *rep_msgp,
464 464 ibt_cm_reason_t reject_reason);
465 465
466 466 /* limit the number of taskq threads to handle received MADs. */
467 467 int ibcm_recv_tasks = 0;
468 468 int ibcm_max_recv_tasks = 24;
469 469 int ibcm_recv_timeouts = 0;
470 470
471 471 /*
472 472 * Tunable MAX MRA Service Timeout value in MicroSECONDS.
473 473 * 0 - Tunable parameter not used.
474 474 *
475 475 * Ex: 60000000 - Max MRA Service Delay is 60 Seconds.
476 476 */
↓ open down ↓ |
476 lines elided |
↑ open up ↑ |
477 477 clock_t ibcm_mra_service_timeout_max = 0;
478 478
479 479 #ifdef DEBUG
480 480
481 481 static void print_modify_qp(char *prefix,
482 482 ibt_qp_hdl_t ibt_qp,
483 483 ibt_cep_modify_flags_t flags,
484 484 ibt_qp_info_t *qp_attr);
485 485 #endif
486 486
487 -/* Warlock annotations */
488 -
489 -_NOTE(READ_ONLY_DATA(ibt_arej_info_u))
490 -
491 487 /*
492 488 * ibcm_process_incoming_mad:
493 489 * The CM callback that is invoked by IBMF, when a valid CM MAD arrives
494 490 * on any of the registered ibmf handles by CM.
495 491 *
496 492 * It is assumed that the incoming MAD (except for incoming REQ) belongs
497 493 * to a connection on the HCA, on which the MAD is received.
498 494 * The IBMF callback arg specifies ibcm_hca_info_t
499 495 *
500 496 * NOTE: IBMF always invokes ibcm_recv_cb() in a taskq. CM does some memory
501 497 * allocations and invoke ibcm_sm_funcs_tbl[i]() in the same taskq.
502 498 *
503 499 * INPUTS:
504 500 * ibmf_handle - IBMF Handle
505 501 * args - from IBMF. Is a ptr to ibcm_hca_info_t
506 502 * status - Callback status. Is mostly IBMF_SUCCESS
507 503 * madbuf - IBMF allocated MAD buffer (CM should free it)
508 504 * madaddr - IBMF MAD's address
509 505 * grhvalid - If GRH is valid or not
510 506 *
511 507 * RETURN VALUES: NONE
512 508 */
513 509 void
514 510 ibcm_process_incoming_mad(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
515 511 void *args)
516 512 {
517 513 uint8_t method; /* Method type in MAD hdr */
518 514 ib_mad_hdr_t *in_mad_hdr; /* Incoming MAD's header */
519 515 ibcm_hca_info_t *hcap; /* pointer to HCA entry */
520 516 ibcm_port_info_t *portp;
521 517 ibcm_mad_addr_t *cm_mad_addr; /* MAD address information */
522 518 ibcm_event_type_t attr_id; /* Attribute ID in MAD hdr */
523 519 ibcm_mad_addr_t loc_mad_addr; /* MAD address information */
524 520 ibcm_qp_list_t *cm_qp_entry;
525 521 int ibmf_status;
526 522
527 523
528 524 /* Noticed that IBMF always calls with IBMF_SUCCESS, but still check */
529 525 if (msgp->im_msg_status != IBMF_SUCCESS) {
530 526 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
531 527 "bad status %x", msgp->im_msg_status);
532 528 /* IBMF allocates Input MAD, so free it here */
533 529 if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
534 530 IBMF_SUCCESS)
535 531 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
536 532 "ibmf_free_msg failed %d", ibmf_status);
537 533 return;
538 534 }
539 535
540 536 /* Get the HCA entry pointer */
541 537 cm_qp_entry = (ibcm_qp_list_t *)args;
542 538
543 539 IBTF_DPRINTF_L5(cmlog, "ibcm_process_incoming_mad: ibmf_hdl %p "
544 540 "msg %p args %p", ibmf_handle, msgp, args);
545 541
546 542 #ifdef DEBUG
547 543 if (ibcm_test_mode > 1)
548 544 ibcm_query_qp(ibmf_handle, cm_qp_entry->qp_cm);
549 545 #endif
550 546
551 547 portp = cm_qp_entry->qp_port;
552 548 hcap = portp->port_hcap;
553 549
554 550 IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: CM MAD on "
555 551 "port %d", portp->port_num);
556 552
557 553 /* Increment hca ref cnt, if HCA is in attached state, else fail */
558 554 if (ibcm_inc_hca_acc_cnt(hcap) != IBCM_SUCCESS) {
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
559 555 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
560 556 "hca not in attach state");
561 557 /* IBMF allocates Input MAD, and ibcm free's it */
562 558 if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
563 559 IBMF_SUCCESS)
564 560 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
565 561 "ibmf_free_msg failed %d", ibmf_status);
566 562 return;
567 563 }
568 564
569 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cm_mad_addr))
570 -
571 565 /* allocate memory for internal MAD address buffer */
572 566 cm_mad_addr = &loc_mad_addr;
573 567 bzero(cm_mad_addr, sizeof (ibcm_mad_addr_t));
574 568
575 569 cm_mad_addr->port_num = portp->port_num;
576 570
577 571 /* initialize cm_mad_addr field(s) */
578 572 in_mad_hdr = msgp->im_msgbufs_recv.im_bufs_mad_hdr;
579 573
580 574 if (in_mad_hdr->MgmtClass != MAD_MGMT_CLASS_COMM_MGT) {
581 575 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
582 576 "bad mgmt class %x", in_mad_hdr->MgmtClass);
583 577 if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
584 578 IBMF_SUCCESS)
585 579 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
586 580 "ibmf_free_msg failed %d", ibmf_status);
587 581 ibcm_dec_hca_acc_cnt(hcap);
588 582 return;
589 583 }
590 584
591 585 cm_mad_addr->rcvd_addr = msgp->im_local_addr;
592 586 if (msgp->im_msg_flags & IBMF_MSG_FLAGS_GLOBAL_ADDRESS) {
593 587 cm_mad_addr->grh_hdr = msgp->im_global_addr;
594 588 cm_mad_addr->grh_exists = B_TRUE;
595 589 IBTF_DPRINTF_L3(cmlog, "ibcm_process_incoming_mad: "
596 590 "CM recv GID GUID %llX sender GID GUID %llX",
597 591 msgp->im_global_addr.ig_recver_gid.gid_guid,
598 592 msgp->im_global_addr.ig_sender_gid.gid_guid);
599 593 }
600 594
601 595 /* Save IBMF handle and ibmf qp related information */
602 596 cm_mad_addr->ibmf_hdl = ibmf_handle;
603 597 cm_mad_addr->cm_qp_entry = cm_qp_entry;
604 598
605 599 /* IBMF does not initialize ia_p_key for non-QP1's */
606 600 if (cm_qp_entry->qp_cm != IBMF_QP_HANDLE_DEFAULT)
607 601 cm_mad_addr->rcvd_addr.ia_p_key = cm_qp_entry->qp_pkey;
608 602
609 603 if (cm_mad_addr->rcvd_addr.ia_p_key & 0x8000)
610 604 IBTF_DPRINTF_L5(cmlog, "ibcm_process_incoming_mad: PKEY %x",
611 605 cm_mad_addr->rcvd_addr.ia_p_key);
612 606 else
613 607 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: CM MAD "
614 608 "arrived from limited PKEY %x",
615 609 cm_mad_addr->rcvd_addr.ia_p_key);
616 610
617 611 /* Retrieve the method and Attr-Id from generic mad header */
618 612 method = in_mad_hdr->R_Method;
619 613 attr_id = b2h16(in_mad_hdr->AttributeID);
620 614
621 615 IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: "
622 616 "Method %x Attribute %x", method, attr_id);
623 617
624 618 if (in_mad_hdr->ClassVersion != IBCM_MAD_CLASS_VERSION) {
625 619
626 620 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
627 621 "unsupported ibcm class version %x",
628 622 in_mad_hdr->ClassVersion);
629 623
630 624 if (attr_id == (IBCM_INCOMING_REQ + IBCM_ATTR_BASE_ID))
631 625 ibcm_post_rej_ver_mismatch(
632 626 (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
633 627
634 628 if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) !=
635 629 IBMF_SUCCESS)
636 630 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
637 631 "ibmf_free_msg failed %d", ibmf_status);
638 632 ibcm_dec_hca_acc_cnt(hcap);
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
639 633 return;
640 634 }
641 635
642 636 IBTF_DPRINTF_L4(cmlog, "ibcm_process_incoming_mad: "
643 637 "Transaction Id 0x%llX", b2h64(in_mad_hdr->TransactionID));
644 638
645 639 #ifdef DEBUG
646 640 ibcm_decode_tranid(b2h64(in_mad_hdr->TransactionID), NULL);
647 641 #endif
648 642
649 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*cm_mad_addr))
650 -
651 643 /*
652 644 * The following are valid combination of Method type
653 645 * and attribute id in the received MAD :-
654 646 * o ClassPortInfo with Get method
655 647 * o CM messages with Send method
656 648 */
657 649 if ((attr_id == MAD_ATTR_ID_CLASSPORTINFO) &&
658 650 ((method == MAD_METHOD_GET) ||
659 651 (method == MAD_METHOD_GET_RESPONSE))) {
660 652 if (method == MAD_METHOD_GET)
661 653 ibcm_process_get_classport_info(hcap,
662 654 (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
663 655 else if (method == MAD_METHOD_GET_RESPONSE)
664 656 ibcm_decode_classport_info(hcap,
665 657 (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
666 658 } else if ((attr_id >= IBCM_ATTR_BASE_ID) &&
667 659 (attr_id < (IBCM_ATTR_BASE_ID + IBCM_MAX_EVENTS)) &&
668 660 (method == MAD_METHOD_SEND)) {
669 661
670 662 attr_id -= IBCM_ATTR_BASE_ID; /* figure out CM message id */
671 663
672 664 ASSERT(msgp->im_msgbufs_recv.im_bufs_mad_hdr != NULL);
673 665
674 666 /* Call the CM process connection state function */
675 667 ibcm_sm_funcs_tbl[attr_id](hcap,
676 668 (uint8_t *)IBCM_IN_HDRP(msgp), cm_mad_addr);
677 669 } else {
678 670 /*
679 671 * Any other combination of method and attribute are invalid,
680 672 * hence drop the MAD
681 673 */
682 674 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
683 675 "unknown Method %x or Attribute %x", method, attr_id);
684 676 }
685 677
686 678 /* decrement the hcap access reference count */
687 679 ibcm_dec_hca_acc_cnt(hcap);
688 680
689 681 /* ASSERT(NO_LOCKS_HELD); */
690 682
691 683 /* free up ibmf msgp */
692 684 if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) != IBMF_SUCCESS)
693 685 IBTF_DPRINTF_L2(cmlog, "ibcm_process_incoming_mad: "
694 686 "ibmf_free_msg failed %d", ibmf_status);
695 687 }
696 688
697 689 /*
698 690 * Structure to carry the arguments from ibcm_recv_cb() to
699 691 * ibcm_recv_incoming_mad() via taskq_dispatch
700 692 */
701 693 typedef struct ibcm_taskq_args_s {
702 694 ibmf_handle_t tq_ibmf_handle;
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
703 695 ibmf_msg_t *tq_ibmf_msgp;
704 696 void *tq_args;
705 697 } ibcm_taskq_args_t;
706 698
707 699 #define IBCM_RECV_MAX 128
708 700 ibcm_taskq_args_t ibcm_recv_array[IBCM_RECV_MAX + 1];
709 701 int ibcm_get, ibcm_put;
710 702 int ibcm_recv_total;
711 703 int ibcm_recv_queued;
712 704
713 -_NOTE(READ_ONLY_DATA(ibcm_taskq_args_t))
714 -
715 705 static int
716 706 ibcm_recv_dequeue(ibmf_handle_t *ibmf_handlep, ibmf_msg_t **msgpp, void **argsp)
717 707 {
718 708 ibcm_taskq_args_t *tq;
719 709
720 710 if (ibcm_put == ibcm_get)
721 711 return (0);
722 712
723 713 if (++ibcm_get >= IBCM_RECV_MAX)
724 714 ibcm_get = 0;
725 715 tq = ibcm_recv_array + ibcm_get;
726 716 *ibmf_handlep = tq->tq_ibmf_handle;
727 717 *msgpp = tq->tq_ibmf_msgp;
728 718 *argsp = tq->tq_args;
729 719 return (1);
730 720 }
731 721
732 722 static int
733 723 ibcm_recv_enqueue(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
734 724 {
735 725 int next;
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
736 726 ibcm_taskq_args_t *tq;
737 727
738 728 ASSERT(MUTEX_HELD(&ibcm_recv_mutex));
739 729 next = ibcm_put + 1;
740 730 if (next >= IBCM_RECV_MAX)
741 731 next = 0;
742 732 if (next != ibcm_get) {
743 733 ibcm_recv_queued++;
744 734 ibcm_put = next;
745 735 tq = ibcm_recv_array + next;
746 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tq))
747 736 tq->tq_ibmf_handle = ibmf_handle;
748 737 tq->tq_ibmf_msgp = msgp;
749 738 tq->tq_args = args;
750 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*tq))
751 739 return (1);
752 740 } else {
753 741 return (0);
754 742 }
755 743 }
756 744
757 745 void
758 746 ibcm_drop_msg(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp)
759 747 {
760 748 int ibmf_status;
761 749
762 750 IBTF_DPRINTF_L2(cmlog, "ibcm_drop_msg: discarding MAD");
763 751
764 752 if ((ibmf_status = ibmf_free_msg(ibmf_handle, &msgp)) != IBMF_SUCCESS)
765 753 IBTF_DPRINTF_L2(cmlog, "ibcm_drop_msg: "
766 754 "ibmf_free_msg failed %d", ibmf_status);
767 755 }
768 756
769 757 /*
770 758 * Processing done in taskq thread.
771 759 *
772 760 * Calls ibcm_process_incoming_mad with all function arguments extracted
773 761 * from args. Afterwards, check for queued requests.
774 762 */
775 763 static void
776 764 ibcm_recv_task(void *args)
777 765 {
778 766 ibcm_taskq_args_t *taskq_args;
779 767 ibmf_handle_t ibmf_handle;
780 768 ibmf_msg_t *msgp;
781 769
782 770 taskq_args = (ibcm_taskq_args_t *)args;
783 771
784 772 IBTF_DPRINTF_L4(cmlog, "ibcm_recv_task: Processing incoming MAD"
785 773 " via taskq");
786 774
787 775 ibcm_process_incoming_mad(taskq_args->tq_ibmf_handle,
788 776 taskq_args->tq_ibmf_msgp, taskq_args->tq_args);
789 777
790 778 kmem_free(taskq_args, sizeof (ibcm_taskq_args_t));
791 779
792 780 /* process queued entries before giving up this thread */
793 781 mutex_enter(&ibcm_recv_mutex);
794 782 while (ibcm_recv_dequeue(&ibmf_handle, &msgp, &args)) {
795 783 mutex_exit(&ibcm_recv_mutex);
796 784 ibcm_process_incoming_mad(ibmf_handle, msgp, args);
797 785 mutex_enter(&ibcm_recv_mutex);
798 786 }
799 787 --ibcm_recv_tasks;
800 788 mutex_exit(&ibcm_recv_mutex);
801 789 }
802 790
803 791 static void
804 792 ibcm_recv_timeout_cb(void *args)
805 793 {
806 794 ibcm_taskq_args_t *tq = (ibcm_taskq_args_t *)args;
807 795 int rv = 1;
808 796
809 797 mutex_enter(&ibcm_recv_mutex);
810 798 ibcm_recv_timeouts--;
811 799 if (ibcm_recv_tasks == 0) {
812 800 ibcm_recv_tasks++;
813 801 mutex_exit(&ibcm_recv_mutex);
814 802 if (taskq_dispatch(ibcm_taskq, ibcm_recv_task, tq,
815 803 TQ_NOQUEUE | TQ_NOSLEEP) == 0) {
816 804 mutex_enter(&ibcm_recv_mutex);
817 805 if (--ibcm_recv_tasks == 0) {
818 806 (void) timeout(ibcm_recv_timeout_cb, tq, 1);
819 807 ibcm_recv_timeouts++;
820 808 } else {
821 809 rv = ibcm_recv_enqueue(tq->tq_ibmf_handle,
822 810 tq->tq_ibmf_msgp, tq->tq_args);
823 811 kmem_free(tq, sizeof (*tq));
824 812 }
825 813 mutex_exit(&ibcm_recv_mutex);
826 814 }
827 815 } else {
828 816 /*
829 817 * one or more taskq threads are running now
830 818 * so just try to enqueue this one.
831 819 */
832 820 rv = ibcm_recv_enqueue(tq->tq_ibmf_handle,
833 821 tq->tq_ibmf_msgp, tq->tq_args);
834 822 kmem_free(tq, sizeof (*tq));
835 823 mutex_exit(&ibcm_recv_mutex);
836 824 }
837 825 if (rv == 0)
838 826 ibcm_drop_msg(tq->tq_ibmf_handle, tq->tq_ibmf_msgp);
839 827 }
840 828
841 829 /*
842 830 * Dispatch to taskq if we're not using many, else just queue it
843 831 * and have the taskq thread pick it up. Return 0 if we're dropping it.
844 832 */
845 833 static int
846 834 ibcm_recv_add_one(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
847 835 {
848 836 int rv;
849 837 ibcm_taskq_args_t *tq;
850 838
851 839 mutex_enter(&ibcm_recv_mutex);
852 840 ibcm_recv_total++;
853 841 if (ibcm_recv_tasks >= ibcm_max_recv_tasks) { /* just queue this one */
854 842 rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
855 843 mutex_exit(&ibcm_recv_mutex);
856 844 return (rv);
857 845 } else {
858 846 ibcm_recv_tasks++; /* dispatch this one to a taskq thread */
859 847 mutex_exit(&ibcm_recv_mutex);
↓ open down ↓ |
99 lines elided |
↑ open up ↑ |
860 848 tq = kmem_alloc(sizeof (*tq), KM_NOSLEEP);
861 849 if (tq == NULL) {
862 850 mutex_enter(&ibcm_recv_mutex);
863 851 if (--ibcm_recv_tasks > 0)
864 852 rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
865 853 else /* don't enqueue if no threads are running */
866 854 rv = 0;
867 855 mutex_exit(&ibcm_recv_mutex);
868 856 return (rv);
869 857 }
870 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tq))
871 858 tq->tq_ibmf_handle = ibmf_handle;
872 859 tq->tq_ibmf_msgp = msgp;
873 860 tq->tq_args = args;
874 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*tq))
875 861 if (taskq_dispatch(ibcm_taskq, ibcm_recv_task, tq,
876 862 TQ_NOQUEUE | TQ_NOSLEEP) == 0) { /* dispatch failed */
877 863 mutex_enter(&ibcm_recv_mutex);
878 864 if (--ibcm_recv_tasks == 0) {
879 865 /* try the dispatch again, after a tick */
880 866 (void) timeout(ibcm_recv_timeout_cb, tq, 1);
881 867 ibcm_recv_timeouts++;
882 868 rv = 1; /* indicate success */
883 869 } else {
884 870 rv = ibcm_recv_enqueue(ibmf_handle, msgp, args);
885 871 kmem_free(tq, sizeof (*tq));
886 872 }
887 873 mutex_exit(&ibcm_recv_mutex);
888 874 return (rv);
889 875 } else {
890 876 return (1);
891 877 }
892 878 }
893 879 }
894 880
895 881 /*
896 882 * ibcm_recv_cb:
897 883 * The CM callback that is invoked by IBMF, when a valid CM MAD arrives
898 884 * on any of the registered ibmf handles by CM.
899 885 *
900 886 * INPUTS:
901 887 * ibmf_handle - IBMF Handle
902 888 * msgp - IBMF msg containing the MAD (allocated by IBMF)
903 889 * args - Ptr to ibcm_hca_info_t
904 890 *
905 891 * RETURN VALUES: NONE
906 892 */
907 893 void
908 894 ibcm_recv_cb(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
909 895 {
910 896 if (ibcm_recv_add_one(ibmf_handle, msgp, args) == 0)
911 897 ibcm_drop_msg(ibmf_handle, msgp);
912 898 }
913 899
914 900 /*
915 901 * ibcm_process_req_msg:
916 902 * PASSIVE SIDE CM
917 903 * Called from ibcm_process_incoming_mad on reception of a REQ message
918 904 *
919 905 * Description:
920 906 * If it a new REQ (not duplicate)
921 907 * creates a new state structure in passive connection mode
922 908 * populate state structure fields
923 909 * inserts state structure in hca active and passive trees
924 910 * validates service id
925 911 * validates primary and alternate lid/gid in REQ,
926 912 * calls QP state transition function
927 913 * generates REP/REJ response
928 914 * stores the response MAD in state structure for future re-sends
929 915 * initializes timers as required
930 916 * If a duplicate REQ, action depends upon current state in the state
931 917 * structure
932 918 *
933 919 * INPUTS:
934 920 * hcap - HCA entry ptr
935 921 * input_madp - CM MAD that is input to this function
936 922 * cm_mad_addr - Address information for the MAD
937 923 *
938 924 * RETURN VALUE:
939 925 * NONE
940 926 */
941 927 void
942 928 ibcm_process_req_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
943 929 ibcm_mad_addr_t *cm_mad_addr)
944 930 {
945 931 ibt_priv_data_len_t arej_info_len = 0;
946 932 ib_qpn_t remote_qpn;
947 933 ib_guid_t remote_hca_guid;
948 934 ib_com_id_t remote_comid;
949 935 ib_com_id_t local_comid;
950 936 ibcm_status_t state_lookup_status;
951 937 ibcm_status_t comid_lookup_status;
952 938 ibcm_status_t response;
953 939 ibcm_req_msg_t *req_msgp =
954 940 (ibcm_req_msg_t *)&input_madp[IBCM_MAD_HDR_SIZE];
955 941 ibt_cm_reason_t reject_reason = IBT_CM_SUCCESS;
956 942 ibcm_state_data_t *statep;
957 943 ibcm_state_data_t *stale_statep = NULL;
958 944 ibcm_status_t svc_gid_check;
959 945 uint32_t psn24_timeout5_retry3;
960 946 ibt_tran_srv_t trans;
961 947
962 948 IBTF_DPRINTF_L5(cmlog, "ibcm_process_req_msg(%p, %p, %p)",
963 949 hcap, input_madp, cm_mad_addr);
964 950
965 951 /*
966 952 * Lookup for an existing state structure or create a new state struct
967 953 * If there is no entry, the lookup function also allocates a new
968 954 * state structure and inserts in the table, initializes remote qpn
969 955 * and hca guid from REQ
970 956 */
971 957 remote_hca_guid = b2h64(req_msgp->req_local_ca_guid);
972 958 remote_qpn = b2h32(req_msgp->req_local_qpn_plus) >> 8;
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
973 959 remote_comid = b2h32(req_msgp->req_local_comm_id);
974 960
975 961 IBCM_DUMP_RAW_MSG((uchar_t *)input_madp);
976 962
977 963 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: remote_comid = %x"
978 964 " remote_qpn = %x", remote_comid, remote_qpn);
979 965
980 966 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: remote_hcaguid = %llX",
981 967 remote_hca_guid);
982 968
983 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
984 -
985 969 new_req:
986 970 /* allocate the local_comid before proceeding */
987 971 if (ibcm_alloc_comid(hcap, &local_comid) != IBCM_SUCCESS) {
988 972 ibcm_build_n_post_rej_mad(input_madp,
989 973 b2h32(req_msgp->req_local_comm_id), cm_mad_addr,
990 974 IBT_CM_FAILURE_REQ, IBT_CM_NO_RESC);
991 975 return;
992 976 }
993 977
994 978 /* allocate ibcm_state_data_t before grabbing the WRITER lock */
995 979 statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
996 980
997 981 rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
998 982
999 983 /* NOTE that only a writer lock is held here */
1000 984
1001 985 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REQ,
1002 986 local_comid, remote_qpn, remote_hca_guid, hcap, &statep);
1003 987
1004 988 if (state_lookup_status == IBCM_LOOKUP_NEW) {
1005 989 /* seeing the REQ request for the first time */
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1006 990
1007 991 mutex_enter(&statep->state_mutex);
1008 992 /* Release the state table lock */
1009 993 rw_exit(&hcap->hca_state_rwlock);
1010 994
1011 995 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: New statep 0x%p"
1012 996 " created", statep);
1013 997
1014 998 psn24_timeout5_retry3 = b2h32(req_msgp->req_starting_psn_plus);
1015 999
1016 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
1017 -
1018 1000 /* if ibmf msg allocation fails, delete the statep */
1019 1001 if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
1020 1002 &statep->stored_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
1021 1003
1022 1004 IBCM_REF_CNT_DECR(statep);
1023 1005 statep->state = IBCM_STATE_DELETE;
1024 1006 mutex_exit(&statep->state_mutex);
1025 1007 /* HCA res cnt decremented via ibcm_delete_state_data */
1026 1008 ibcm_inc_hca_res_cnt(hcap);
1027 1009 ibcm_delete_state_data(statep);
1028 1010 return;
1029 1011 }
1030 1012
1031 1013 /* Allocate dreq_msg buf to be used during teardown. */
1032 1014 if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
1033 1015 &statep->dreq_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
1034 1016
1035 1017 IBCM_REF_CNT_DECR(statep);
1036 1018 statep->state = IBCM_STATE_DELETE;
1037 1019 mutex_exit(&statep->state_mutex);
1038 1020 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1039 1021 "statep 0x%p: Failed to allocate dreq_msg", statep);
1040 1022
1041 1023 /* HCA res cnt decremented via ibcm_delete_state_data */
1042 1024 ibcm_inc_hca_res_cnt(hcap);
1043 1025 ibcm_delete_state_data(statep);
1044 1026 return;
1045 1027 }
1046 1028
1047 1029 /* initialize some "statep" fields */
1048 1030 statep->mode = IBCM_PASSIVE_MODE;
1049 1031 statep->hcap = hcap;
1050 1032 statep->remote_comid = remote_comid;
1051 1033 statep->svcid = b2h64(req_msgp->req_svc_id);
1052 1034 statep->local_qp_rnr_cnt =
1053 1035 req_msgp->req_mtu_plus & 0x7;
1054 1036
1055 1037 /*
1056 1038 * get the remote_ack_delay, etc.
1057 1039 */
1058 1040 statep->remote_ack_delay =
1059 1041 ibt_ib2usec(req_msgp->req_primary_localtime_plus >> 3);
1060 1042 statep->cep_retry_cnt = psn24_timeout5_retry3 & 0x7;
1061 1043
1062 1044 /*
1063 1045 * get the req_max_cm_retries
1064 1046 */
1065 1047 statep->max_cm_retries = req_msgp->req_max_cm_retries_plus >> 4;
1066 1048 statep->remaining_retry_cnt = statep->max_cm_retries;
1067 1049
1068 1050 /* Approximate pkt life time for now */
1069 1051 statep->pkt_life_time = statep->remote_ack_delay/2;
1070 1052
1071 1053 /* Passive side timer is set to LocalCMRespTime in REQ */
1072 1054 statep->timer_value =
1073 1055 ibt_ib2usec(psn24_timeout5_retry3 >> 3 & 0x1f);
1074 1056
1075 1057 statep->starting_psn = psn24_timeout5_retry3 >> 8;
1076 1058
1077 1059 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: statep 0x%p "
1078 1060 "active cep timeout(usec) = %u",
1079 1061 statep, statep->remote_ack_delay);
1080 1062 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
1081 1063 "passive timer(usec) = %u", statep->timer_value);
1082 1064 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
1083 1065 "approx pkt lt(usec)= %u ", statep->pkt_life_time);
1084 1066 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
1085 1067 "max cm retries %u", statep->max_cm_retries);
1086 1068
1087 1069 /* The reply ie., REP/REJ transaction id copied from REQ */
1088 1070 IBCM_OUT_HDRP(statep->stored_msg)->TransactionID =
1089 1071 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
1090 1072
1091 1073 /*
1092 1074 * Initialize the stale clock. Any other REQ
1093 1075 * messages on this statep are considered as duplicate
1094 1076 * if they arrive within stale clock
1095 1077 * ibcm_adj_btime is used to offset for retry REQ's
1096 1078 * arriving just after expected retry clock
1097 1079 */
1098 1080 statep->stale_clock = gethrtime() +
1099 1081 (hrtime_t)(ibcm_adj_btime * 1000000000) +
1100 1082 (hrtime_t)statep->remote_ack_delay *
1101 1083 (statep->max_cm_retries * (1000 / 2));
1102 1084
1103 1085 mutex_exit(&statep->state_mutex);
1104 1086
1105 1087 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REQ);
1106 1088
1107 1089 /* Increment the hca's resource count */
1108 1090 ibcm_inc_hca_res_cnt(hcap);
1109 1091
1110 1092 ibcm_build_reply_mad_addr(cm_mad_addr,
1111 1093 &statep->stored_reply_addr);
1112 1094
1113 1095 if (statep->stored_reply_addr.cm_qp_entry == NULL) {
1114 1096
1115 1097 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1116 1098 "statep 0x%p cm_qp_entry alloc failed", statep);
1117 1099
1118 1100 /*
1119 1101 * Not much choice. CM MADs cannot go on QP1, not even
1120 1102 * REJ. Hence delete state data and go away silently.
1121 1103 * The remote will timeout after repeated attempts
1122 1104 */
1123 1105 mutex_enter(&statep->state_mutex);
1124 1106 IBCM_REF_CNT_DECR(statep);
1125 1107 statep->state = IBCM_STATE_DELETE;
1126 1108 mutex_exit(&statep->state_mutex);
1127 1109
1128 1110 ibcm_delete_state_data(statep);
1129 1111 return;
1130 1112 }
1131 1113
1132 1114 stale_statep = statep;
1133 1115 rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
1134 1116 comid_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REQ_STALE,
1135 1117 remote_comid, 0, remote_hca_guid, hcap, &stale_statep);
1136 1118 rw_exit(&hcap->hca_state_rwlock);
1137 1119
1138 1120 if (comid_lookup_status == IBCM_LOOKUP_EXISTS) {
1139 1121
1140 1122 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1141 1123 "dup comid %x stale_statep 0x%p statep 0x%p",
1142 1124 remote_comid, stale_statep, statep);
1143 1125
1144 1126 ibcm_insert_trace(stale_statep,
1145 1127 IBCM_TRACE_STALE_DETECT);
1146 1128
1147 1129 /* Send a REJ with duplicate com id */
1148 1130 ibcm_post_rej_mad(statep, IBT_CM_DUP_COM_ID,
1149 1131 IBT_CM_FAILURE_REQ, NULL, 0);
1150 1132
1151 1133 /*
1152 1134 * Don't free the ibmf msg, if stale_statep is not in
1153 1135 * ESTABLISHED state, because probability is very less.
1154 1136 * ibmf msg shall be deleted along with statep
1155 1137 */
1156 1138
1157 1139 /*
1158 1140 * if stale_statep is in established state, process
1159 1141 * stale connection handling on stale_statep
1160 1142 */
1161 1143 mutex_enter(&stale_statep->state_mutex);
1162 1144 if (stale_statep->state == IBCM_STATE_ESTABLISHED) {
1163 1145
1164 1146 stale_statep->state =
1165 1147 IBCM_STATE_TRANSIENT_DREQ_SENT;
1166 1148 stale_statep->stale = B_TRUE;
1167 1149
1168 1150 /* Cancel pending ibt_set_alt_path */
1169 1151 ibcm_sync_lapr_idle(stale_statep);
1170 1152 /* The above call releases the state mutex */
1171 1153
1172 1154 if (stale_statep->dreq_msg == NULL)
1173 1155 (void) ibcm_alloc_out_msg(stale_statep->
1174 1156 stored_reply_addr.ibmf_hdl,
1175 1157 &stale_statep->dreq_msg,
1176 1158 MAD_METHOD_SEND);
1177 1159
1178 1160 /*
1179 1161 * Spec says, post DREQ MAD on the stale
1180 1162 * channel. This moves channel into timewait
1181 1163 */
1182 1164 if (stale_statep->dreq_msg != NULL) {
1183 1165 ibcm_post_dreq_mad(stale_statep);
1184 1166 mutex_enter(&stale_statep->state_mutex);
1185 1167 } else {
1186 1168 mutex_enter(&stale_statep->state_mutex);
1187 1169 /* Set it back to original state. */
1188 1170 stale_statep->state =
1189 1171 IBCM_STATE_ESTABLISHED;
1190 1172 cv_broadcast(
1191 1173 &stale_statep->block_mad_cv);
1192 1174 }
1193 1175 }
1194 1176
1195 1177 IBCM_REF_CNT_DECR(stale_statep);
1196 1178 mutex_exit(&stale_statep->state_mutex);
1197 1179
1198 1180 mutex_enter(&statep->state_mutex);
1199 1181 IBCM_REF_CNT_DECR(statep);
1200 1182 mutex_exit(&statep->state_mutex);
1201 1183 return;
1202 1184 }
1203 1185
1204 1186 /* If unknown service type, just post a REJ */
1205 1187 trans = ((uint8_t *)&req_msgp->req_remote_eecn_plus)[3] >> 1 &
1206 1188 0x3;
1207 1189 if ((trans != IBT_RC_SRV) && (trans != IBT_UC_SRV) &&
1208 1190 (trans != IBT_RD_SRV)) {
1209 1191
1210 1192 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1211 1193 "statep 0x%p invalid transport type %x", statep,
1212 1194 trans);
1213 1195
1214 1196 /* Send a REJ with invalid transport type */
1215 1197 ibcm_post_rej_mad(statep, IBT_CM_INVALID_SRV_TYPE,
1216 1198 IBT_CM_FAILURE_REQ, NULL, 0);
1217 1199
1218 1200 mutex_enter(&statep->state_mutex);
1219 1201 IBCM_REF_CNT_DECR(statep);
1220 1202 mutex_exit(&statep->state_mutex);
1221 1203 return;
1222 1204 }
1223 1205
1224 1206 /* Validate the gids, lids and service id */
1225 1207 svc_gid_check = ibcm_verify_req_gids_and_svcid(statep,
1226 1208 req_msgp);
1227 1209
1228 1210 if (svc_gid_check == IBCM_FAILURE) {
1229 1211
1230 1212 IBTF_DPRINTF_L3(cmlog, "ibcm_process_req_msg: Either "
1231 1213 "gid or sid invalid for statep 0x%p", statep);
1232 1214 mutex_enter(&statep->state_mutex);
1233 1215 IBCM_REF_CNT_DECR(statep);
1234 1216 mutex_exit(&statep->state_mutex);
1235 1217
1236 1218 /* REJ posted from ibcm_verify_req_gids_and_svcid */
1237 1219 return;
1238 1220 }
1239 1221
1240 1222 /* Call the QP state transition processing function */
1241 1223 response = ibcm_cep_state_req(statep, req_msgp,
1242 1224 &reject_reason, &arej_info_len);
1243 1225
1244 1226 /* If defer, return holding the statep ref cnt */
1245 1227 if (response == IBCM_DEFER) {
↓ open down ↓ |
218 lines elided |
↑ open up ↑ |
1246 1228 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
1247 1229 "statep %0xp client returned DEFER response",
1248 1230 statep);
1249 1231 return;
1250 1232 }
1251 1233
1252 1234 /* statep ref cnt decremented in the func below */
1253 1235 ibcm_handle_cep_req_response(statep, response,
1254 1236 reject_reason, arej_info_len);
1255 1237
1256 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
1257 -
1258 1238 return;
1259 1239
1260 1240 } else {
1261 1241 rw_exit(&hcap->hca_state_rwlock);
1262 1242 ibcm_free_comid(hcap, local_comid);
1263 1243 }
1264 1244
1265 1245 if (state_lookup_status == IBCM_LOOKUP_EXISTS) {
1266 1246 hrtime_t cur_time;
1267 1247
1268 1248 mutex_enter(&statep->state_mutex);
1269 1249
1270 1250 /*
1271 1251 * There is an existing state structure entry
1272 1252 * with the same active comid
1273 1253 * Resending REP MAD is necessary only for REP/REJ/MRA Sent
1274 1254 * states
1275 1255 * Any other state implies the active has already received
1276 1256 * the REP/REJ response, and this REQ is an old MAD popping
1277 1257 * out of the fabric, hence no resend is required
1278 1258 */
1279 1259 cur_time = gethrtime();
1280 1260
1281 1261 if ((remote_comid == statep->remote_comid) &&
1282 1262 (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID ==
1283 1263 ((ib_mad_hdr_t *)(input_madp))->TransactionID) &&
1284 1264 (cur_time <= statep->stale_clock)) {
1285 1265
1286 1266 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REQ);
1287 1267
1288 1268 if (statep->state == IBCM_STATE_REP_SENT)
1289 1269 ibcm_resend_rep_mad(statep);
1290 1270 else if (statep->state == IBCM_STATE_REJ_SENT)
1291 1271 ibcm_resend_rej_mad(statep);
1292 1272 else if (statep->state == IBCM_STATE_MRA_SENT)
1293 1273 ibcm_resend_mra_mad(statep);
1294 1274
1295 1275 /* decrementing ref cnt and returning from below */
1296 1276
1297 1277 } else if ((statep->state == IBCM_STATE_REJ_SENT) &&
1298 1278 remote_comid != statep->remote_comid) {
1299 1279 timeout_id_t timer_val;
1300 1280
1301 1281 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1302 1282 "statep 0x%p being retired, REMOTE_QPN %x",
1303 1283 statep, remote_qpn);
1304 1284 /*
1305 1285 * OK, this is reuse of the QPN on the active side
1306 1286 * that was not connected last time. This REQ is
1307 1287 * considered NEW. We delete the statep here,
1308 1288 * then start over from the top.
1309 1289 */
1310 1290 statep->state = IBCM_STATE_DELETE;
1311 1291 timer_val = statep->timerid;
1312 1292 statep->timerid = 0;
1313 1293 mutex_exit(&statep->state_mutex);
1314 1294 if (timer_val)
1315 1295 (void) untimeout(timer_val);
1316 1296 IBCM_REF_CNT_DECR(statep);
1317 1297 ibcm_delete_state_data(statep);
1318 1298 goto new_req;
1319 1299
1320 1300 /*
1321 1301 * The statep is stale in the following cases :-
1322 1302 * 1) if incoming REQ's comid's doesn't match with what is
1323 1303 * stored in statep
1324 1304 * 2) incoming REQ's local comid matches with statep's
1325 1305 * remote comid, but the REQ is for a new connection.
1326 1306 * This is verified that by comparing the current time
1327 1307 * with stale clock in statep
1328 1308 */
1329 1309 } else {
1330 1310 /* This is a stale connection on passive side */
1331 1311
1332 1312 ibcm_insert_trace(statep, IBCM_TRACE_STALE_DETECT);
1333 1313
1334 1314 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_msg: "
1335 1315 "stale detected statep %p state %x",
1336 1316 statep, statep->state);
1337 1317
1338 1318 IBTF_DPRINTF_L4(cmlog, "ibcm_process_req_msg: "
1339 1319 "cur_time 0x%llX stale_clock 0x%llX", cur_time,
1340 1320 statep->stale_clock);
1341 1321
1342 1322 if (statep->state == IBCM_STATE_ESTABLISHED) {
1343 1323
1344 1324 statep->state = IBCM_STATE_TRANSIENT_DREQ_SENT;
1345 1325 statep->stale = B_TRUE;
1346 1326
1347 1327 /* Cancel pending ibt_set_alt_path */
1348 1328 ibcm_sync_lapr_idle(statep);
1349 1329 /* The above call releases the state mutex */
1350 1330
1351 1331 if (statep->dreq_msg == NULL)
1352 1332 (void) ibcm_alloc_out_msg(
1353 1333 statep->stored_reply_addr.ibmf_hdl,
1354 1334 &statep->dreq_msg, MAD_METHOD_SEND);
1355 1335
1356 1336 /*
1357 1337 * Spec says, post DREQ MAD on the stale
1358 1338 * channel. This moves channel into timewait
1359 1339 */
1360 1340 if (statep->dreq_msg != NULL)
1361 1341 ibcm_post_dreq_mad(statep);
1362 1342 else {
1363 1343 mutex_enter(&statep->state_mutex);
1364 1344 statep->state = IBCM_STATE_ESTABLISHED;
1365 1345 cv_broadcast(&statep->block_mad_cv);
1366 1346 mutex_exit(&statep->state_mutex);
1367 1347 }
1368 1348 } else {
1369 1349 /*
1370 1350 * If not in established state, the CM
1371 1351 * protocol would timeout and delete the
1372 1352 * statep that is stale, eventually
1373 1353 */
1374 1354 mutex_exit(&statep->state_mutex);
1375 1355 }
1376 1356
1377 1357 /* Post a REJ MAD to the incoming REQ's sender */
1378 1358 ibcm_build_n_post_rej_mad(input_madp,
1379 1359 b2h32(req_msgp->req_local_comm_id),
1380 1360 cm_mad_addr, IBT_CM_FAILURE_REQ, IBT_CM_CONN_STALE);
1381 1361
1382 1362 mutex_enter(&statep->state_mutex);
1383 1363 }
1384 1364 IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
1385 1365 mutex_exit(&statep->state_mutex);
1386 1366 }
1387 1367 }
↓ open down ↓ |
120 lines elided |
↑ open up ↑ |
1388 1368
1389 1369 /*
1390 1370 * ibcm_handle_cep_req_response:
1391 1371 * Processes the response from ibcm_cep_state_req. Called holding a
1392 1372 * statep ref cnt. The statep ref cnt is decremented before returning.
1393 1373 */
1394 1374 void
1395 1375 ibcm_handle_cep_req_response(ibcm_state_data_t *statep, ibcm_status_t response,
1396 1376 ibt_cm_reason_t reject_reason, uint8_t arej_info_len)
1397 1377 {
1398 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
1399 -
1400 1378 if (response == IBCM_SEND_REP)
1401 1379 ibcm_post_rep_mad(statep);
1402 1380 else {
1403 1381 ASSERT(response == IBCM_SEND_REJ);
1404 1382 IBTF_DPRINTF_L4(cmlog, "ibcm_handle_cep_req_response: statep %p"
1405 1383 " posting REJ reject_reason = %d", statep, reject_reason);
1406 1384
1407 1385 ibcm_post_rej_mad(statep,
1408 1386 reject_reason, IBT_CM_FAILURE_REQ,
1409 1387 NULL, arej_info_len);
1410 1388 }
1411 1389
1412 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
1413 -
1414 1390 mutex_enter(&statep->state_mutex);
1415 1391 IBCM_REF_CNT_DECR(statep);
1416 1392 mutex_exit(&statep->state_mutex);
1417 1393 }
1418 1394
1419 1395
1420 1396 /*
1421 1397 * ibcm_process_rep_msg:
1422 1398 * ACTIVE SIDE CM
1423 1399 * Called from ibcm_process_incoming_mad on reception of a REP message
1424 1400 *
1425 1401 * INPUTS:
1426 1402 * hcap - HCA entry pointer
1427 1403 * input_madp - CM MAD that is input to this function
1428 1404 * cm_mad_addr - Address information for the MAD
1429 1405 *
1430 1406 * RETURN VALUE: NONE
1431 1407 */
1432 1408 void
1433 1409 ibcm_process_rep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
1434 1410 ibcm_mad_addr_t *cm_mad_addr)
1435 1411 {
1436 1412 ibt_priv_data_len_t arej_info_len = 0;
1437 1413 ib_com_id_t local_comid;
1438 1414 timeout_id_t timer_val;
1439 1415 ibcm_status_t lookup_status; /* state lookup status */
1440 1416 ibcm_status_t stale_lookup_status;
1441 1417 ibcm_status_t stale_comid_lookup_status;
1442 1418 ibcm_status_t response;
1443 1419 ibcm_rep_msg_t *rep_msgp; /* Response REP mesg */
1444 1420 ibt_cm_reason_t reject_reason;
1445 1421 ibcm_state_data_t *statep = NULL;
1446 1422 ibcm_state_data_t *stale_qpn = NULL;
1447 1423 ibcm_state_data_t *stale_comid = NULL;
1448 1424 ib_guid_t remote_ca_guid;
1449 1425
1450 1426 IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg:");
1451 1427
1452 1428 /* Lookup for an existing state structure */
1453 1429 rep_msgp = (ibcm_rep_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
1454 1430
1455 1431 IBCM_DUMP_RAW_MSG((uchar_t *)input_madp);
1456 1432
1457 1433 IBTF_DPRINTF_L5(cmlog, "ibcm_process_rep_msg: active comid: %x",
1458 1434 rep_msgp->rep_remote_comm_id);
1459 1435
1460 1436 local_comid = b2h32(rep_msgp->rep_remote_comm_id);
1461 1437
1462 1438 /* lookup message holding a reader lock */
1463 1439 rw_enter(&hcap->hca_state_rwlock, RW_READER);
1464 1440 lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REP, local_comid, 0, 0,
1465 1441 hcap, &statep);
1466 1442 rw_exit(&hcap->hca_state_rwlock);
1467 1443
1468 1444 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: lkup status %x, "
1469 1445 "statep 0x%p active comid %x", lookup_status, statep, local_comid);
1470 1446
1471 1447 if (lookup_status == IBCM_LOOKUP_FAIL) {
1472 1448 ibcm_build_n_post_rej_mad(input_madp,
1473 1449 b2h32(rep_msgp->rep_local_comm_id), cm_mad_addr,
1474 1450 IBT_CM_FAILURE_REP, IBT_CM_INVALID_CID);
1475 1451
1476 1452 return;
1477 1453 }
1478 1454
1479 1455 /* if transaction id is not as expected, drop the REP mad */
1480 1456 if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
1481 1457 ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
1482 1458
1483 1459 IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg: statep 0x%p, "
1484 1460 "An REP MAD with tid expected 0x%llX tid found 0x%llX ",
1485 1461 statep,
1486 1462 b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
1487 1463 b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
1488 1464
1489 1465 mutex_enter(&statep->state_mutex);
1490 1466 IBCM_REF_CNT_DECR(statep);
1491 1467 mutex_exit(&statep->state_mutex);
1492 1468 return;
1493 1469 }
1494 1470
1495 1471 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REP);
1496 1472
1497 1473 /* grab mutex first */
1498 1474 mutex_enter(&statep->state_mutex);
1499 1475
1500 1476 /*
1501 1477 * There is a state structure entry with active comid
1502 1478 * First, handle the re-send cases
1503 1479 * The resend routines below release the state mutex
1504 1480 */
1505 1481 if (statep->state == IBCM_STATE_ESTABLISHED ||
1506 1482 statep->state == IBCM_STATE_DREQ_SENT)
1507 1483 ibcm_resend_rtu_mad(statep);
1508 1484 else if (statep->state == IBCM_STATE_REJ_SENT)
1509 1485 ibcm_resend_rej_mad(statep);
1510 1486 else if (statep->state == IBCM_STATE_MRA_REP_SENT)
1511 1487 ibcm_resend_mra_mad(statep);
1512 1488 else if ((statep->state == IBCM_STATE_REQ_SENT) ||
1513 1489 (statep->state == IBCM_STATE_REP_WAIT)) {
1514 1490
1515 1491 /* change state */
1516 1492 statep->state = IBCM_STATE_REP_RCVD;
1517 1493 statep->clnt_proceed = IBCM_BLOCK;
1518 1494 statep->local_qp_rnr_cnt =
1519 1495 rep_msgp->rep_rnr_retry_cnt_plus >> 5;
1520 1496
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
1521 1497 /* cancel the REQ timer */
1522 1498 if (statep->timerid != 0) {
1523 1499 timer_val = statep->timerid;
1524 1500 statep->timerid = 0;
1525 1501 mutex_exit(&statep->state_mutex);
1526 1502 (void) untimeout(timer_val);
1527 1503 } else {
1528 1504 mutex_exit(&statep->state_mutex);
1529 1505 }
1530 1506
1531 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
1532 -
1533 1507 /* Initialize the remote destination QPN for further MADs */
1534 1508 statep->stored_reply_addr.rcvd_addr.ia_remote_qno =
1535 1509 cm_mad_addr->rcvd_addr.ia_remote_qno;
1536 1510 statep->remote_qpn = b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
1537 1511 statep->remote_comid = b2h32(rep_msgp->rep_local_comm_id);
1538 1512 bcopy(rep_msgp->rep_local_ca_guid, &remote_ca_guid,
1539 1513 sizeof (ib_guid_t));
1540 1514 statep->remote_hca_guid = b2h64(remote_ca_guid);
1541 1515
1542 1516 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p "
1543 1517 "passive cid = %x passive qpn = %x", statep,
1544 1518 statep->remote_comid, statep->remote_qpn);
1545 1519
1546 1520 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p "
1547 1521 "passive hcaguid = %llX", statep, statep->remote_hca_guid);
1548 1522
1549 1523 stale_qpn = statep;
1550 1524 stale_comid = statep;
1551 1525
1552 1526 /* Handle stale connection detection on active side */
1553 1527 rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
1554 1528
1555 1529 stale_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REP_STALE,
1556 1530 0, statep->remote_qpn, statep->remote_hca_guid, hcap,
1557 1531 &stale_qpn);
1558 1532
1559 1533 stale_comid_lookup_status = ibcm_lookup_msg(
1560 1534 IBCM_INCOMING_REQ_STALE, statep->remote_comid, 0,
1561 1535 statep->remote_hca_guid, hcap, &stale_comid);
1562 1536
1563 1537 rw_exit(&hcap->hca_state_rwlock);
1564 1538
1565 1539 /*
1566 1540 * Check for other side reusing QPN that was attempted
1567 1541 * to be used, but somehow we sent a REJ.
1568 1542 */
1569 1543 mutex_enter(&stale_qpn->state_mutex);
1570 1544 if ((stale_lookup_status == IBCM_LOOKUP_EXISTS) &&
1571 1545 (stale_comid_lookup_status != IBCM_LOOKUP_EXISTS) &&
1572 1546 (stale_qpn->state == IBCM_STATE_REJ_SENT)) {
1573 1547
1574 1548 timeout_id_t timer_val;
1575 1549
1576 1550 IBTF_DPRINTF_L3(cmlog, "ibcm_process_rep_msg: "
1577 1551 "statep 0x%p being retired, REMOTE_QPN %x",
1578 1552 stale_qpn, statep->remote_qpn);
1579 1553 /*
1580 1554 * OK, this is reuse of the QPN on the active side
1581 1555 * that was not connected last time. This REQ is
1582 1556 * considered NEW. We delete the statep here,
1583 1557 * then start over from the top.
1584 1558 */
1585 1559 stale_qpn->state = IBCM_STATE_DELETE;
1586 1560 timer_val = stale_qpn->timerid;
1587 1561 stale_qpn->timerid = 0;
1588 1562 mutex_exit(&stale_qpn->state_mutex);
1589 1563 if (timer_val)
1590 1564 (void) untimeout(timer_val);
1591 1565 IBCM_REF_CNT_DECR(stale_qpn);
1592 1566 ibcm_delete_state_data(stale_qpn);
1593 1567 stale_qpn = statep;
1594 1568 rw_enter(&hcap->hca_state_rwlock, RW_WRITER);
1595 1569 stale_lookup_status = ibcm_lookup_msg(
1596 1570 IBCM_INCOMING_REP_STALE, 0, statep->remote_qpn,
1597 1571 statep->remote_hca_guid, hcap, &stale_qpn);
1598 1572 rw_exit(&hcap->hca_state_rwlock);
1599 1573 /* OK to continue now */
1600 1574 } else
1601 1575 mutex_exit(&stale_qpn->state_mutex);
1602 1576
1603 1577 /*
1604 1578 * lookup exists implies that there is already an entry with
1605 1579 * the remote qpn/comid and remote hca guid
1606 1580 */
1607 1581 if ((stale_lookup_status == IBCM_LOOKUP_EXISTS) ||
1608 1582 (stale_comid_lookup_status == IBCM_LOOKUP_EXISTS)) {
1609 1583
1610 1584 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
1611 1585 "statep 0x%p stale detected "
1612 1586 "qpn_lkup %d comid_lkup %d", statep,
1613 1587 stale_lookup_status, stale_comid_lookup_status);
1614 1588
1615 1589 /* Disassociate statep and QP */
1616 1590 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
1617 1591
1618 1592 if (stale_lookup_status == IBCM_LOOKUP_EXISTS)
1619 1593 reject_reason = IBT_CM_CONN_STALE;
1620 1594 else
1621 1595 reject_reason = IBT_CM_DUP_COM_ID;
1622 1596
1623 1597 ibcm_handler_conn_fail(statep,
1624 1598 IBT_CM_FAILURE_REJ_SENT, IBT_CM_FAILURE_REP,
1625 1599 reject_reason,
1626 1600 IBCM_REJ_PRIV(statep->stored_msg),
1627 1601 IBT_REJ_PRIV_DATA_SZ);
1628 1602
1629 1603 /* Send a REJ with stale reason for statep */
1630 1604 ibcm_post_rej_mad(statep, reject_reason,
1631 1605 IBT_CM_FAILURE_REP, NULL, 0);
1632 1606
1633 1607 /* Now let's handle the logic for stale connections */
1634 1608 /* If in established state, stale_statep is stale */
1635 1609 if (stale_lookup_status == IBCM_LOOKUP_EXISTS) {
1636 1610
1637 1611 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
1638 1612 "state_qpn 0x%p stale QPN detected "
1639 1613 "state %X", stale_qpn, stale_qpn->state);
1640 1614
1641 1615 ibcm_insert_trace(stale_qpn,
1642 1616 IBCM_TRACE_STALE_DETECT);
1643 1617
1644 1618 mutex_enter(&stale_qpn->state_mutex);
1645 1619 if (stale_qpn->state ==
1646 1620 IBCM_STATE_ESTABLISHED) {
1647 1621 /* change state to DREQ sent */
1648 1622 stale_qpn->state =
1649 1623 IBCM_STATE_TRANSIENT_DREQ_SENT;
1650 1624 stale_qpn->stale = B_TRUE;
1651 1625
1652 1626 /* wait for/cancel pending LAP/APR */
1653 1627 ibcm_sync_lapr_idle(stale_qpn);
1654 1628 /* above call releases state mutex */
1655 1629
1656 1630 if (stale_qpn->dreq_msg == NULL)
1657 1631 (void) ibcm_alloc_out_msg(
1658 1632 stale_qpn->
1659 1633 stored_reply_addr.ibmf_hdl,
1660 1634 &stale_qpn->dreq_msg,
1661 1635 MAD_METHOD_SEND);
1662 1636
1663 1637 if (stale_qpn->dreq_msg != NULL) {
1664 1638 ibcm_post_dreq_mad(stale_qpn);
1665 1639 mutex_enter(
1666 1640 &stale_qpn->state_mutex);
1667 1641 } else {
1668 1642 mutex_enter(
1669 1643 &stale_qpn->state_mutex);
1670 1644 stale_qpn->state =
1671 1645 IBCM_STATE_ESTABLISHED;
1672 1646 cv_broadcast(
1673 1647 &stale_qpn->block_mad_cv);
1674 1648 }
1675 1649 }
1676 1650 IBCM_REF_CNT_DECR(stale_qpn);
1677 1651 mutex_exit(&stale_qpn->state_mutex);
1678 1652 }
1679 1653
1680 1654 if (stale_comid_lookup_status == IBCM_LOOKUP_EXISTS) {
1681 1655
1682 1656 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
1683 1657 "state_comid 0x%p stale COMID detected "
1684 1658 "state %X", stale_comid,
1685 1659 stale_comid->state);
1686 1660
1687 1661 mutex_enter(&stale_comid->state_mutex);
1688 1662 if (!((stale_lookup_status ==
1689 1663 IBCM_LOOKUP_EXISTS) &&
1690 1664 (stale_qpn == stale_comid)) &&
1691 1665 (stale_comid->state ==
1692 1666 IBCM_STATE_ESTABLISHED)) {
1693 1667
1694 1668 ibcm_insert_trace(stale_comid,
1695 1669 IBCM_TRACE_STALE_DETECT);
1696 1670
1697 1671 /* change state to DREQ sent */
1698 1672 stale_comid->state =
1699 1673 IBCM_STATE_TRANSIENT_DREQ_SENT;
1700 1674 stale_comid->stale = B_TRUE;
1701 1675
1702 1676 /* wait for/cancel pending LAP/APR */
1703 1677 ibcm_sync_lapr_idle(stale_comid);
1704 1678
1705 1679 /* above call releases state mutex */
1706 1680
1707 1681 if (stale_comid->dreq_msg == NULL)
1708 1682 (void) ibcm_alloc_out_msg(
1709 1683 stale_comid->
1710 1684 stored_reply_addr.ibmf_hdl,
1711 1685 &stale_comid->dreq_msg,
1712 1686 MAD_METHOD_SEND);
1713 1687
1714 1688 if (stale_comid->dreq_msg != NULL) {
1715 1689 ibcm_post_dreq_mad(stale_comid);
1716 1690 mutex_enter(
1717 1691 &stale_comid->state_mutex);
1718 1692 } else {
1719 1693 mutex_enter(
1720 1694 &stale_comid->state_mutex);
1721 1695 stale_comid->state =
1722 1696 IBCM_STATE_ESTABLISHED;
1723 1697 cv_broadcast(
1724 1698 &stale_comid->block_mad_cv);
1725 1699 }
1726 1700 }
1727 1701 IBCM_REF_CNT_DECR(stale_comid);
1728 1702 mutex_exit(&stale_comid->state_mutex);
1729 1703 }
1730 1704 ibcm_return_open_data(statep, rep_msgp, reject_reason);
1731 1705 return;
1732 1706 }
1733 1707
1734 1708 /*
1735 1709 * No need to handle out of memory conditions as we called
1736 1710 * ibcm_lookup_msg() with IBT_CHAN_BLOCKING flags.
1737 1711 */
1738 1712 ASSERT(stale_lookup_status == IBCM_LOOKUP_NEW);
1739 1713
1740 1714 /* Initialize the remote ack delay */
1741 1715 statep->remote_ack_delay =
1742 1716 ibt_ib2usec(rep_msgp->rep_target_delay_plus >> 3);
1743 1717
1744 1718 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: statep 0x%p"
1745 1719 " passive hca_ack_delay= %x ", statep,
1746 1720 statep->remote_ack_delay);
1747 1721
1748 1722 response = ibcm_cep_state_rep(statep, rep_msgp,
1749 1723 &reject_reason, &arej_info_len);
↓ open down ↓ |
207 lines elided |
↑ open up ↑ |
1750 1724
1751 1725 if (response == IBCM_DEFER) {
1752 1726 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rep_msg: "
1753 1727 "statep 0x%p client returned DEFER response",
1754 1728 statep);
1755 1729 return;
1756 1730 }
1757 1731 ibcm_handle_cep_rep_response(statep, response,
1758 1732 reject_reason, arej_info_len, rep_msgp);
1759 1733
1760 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
1761 -
1762 1734 return;
1763 1735
1764 1736 } else if (statep->state == IBCM_STATE_DELETE) {
1765 1737
1766 1738 mutex_exit(&statep->state_mutex);
1767 1739 ibcm_build_n_post_rej_mad(input_madp,
1768 1740 b2h32(rep_msgp->rep_local_comm_id), cm_mad_addr,
1769 1741 IBT_CM_FAILURE_REP, IBT_CM_INVALID_CID);
1770 1742 mutex_enter(&statep->state_mutex);
1771 1743 } else {
1772 1744
1773 1745 #ifdef DEBUG
1774 1746 if (ibcm_test_mode > 0)
1775 1747 if (statep->state == IBCM_STATE_REP_RCVD)
1776 1748 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
1777 1749 "REP re-send from passive for statep 0x%p"
1778 1750 " in state %d", statep, statep->state);
1779 1751 else
1780 1752 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rep_msg: "
1781 1753 "Unexpected REP for statep 0x%p in "
1782 1754 "state %d", statep, statep->state);
1783 1755 #endif
1784 1756 }
1785 1757 /* decrement ref count and return for LOOKUP_EXISTS */
1786 1758 IBCM_REF_CNT_DECR(statep);
1787 1759 mutex_exit(&statep->state_mutex);
1788 1760
1789 1761 }
1790 1762
1791 1763 /*
1792 1764 * ibcm_handle_cep_req_response:
1793 1765 * Processes the response from ibcm_cep_state_rep. Called holding a
1794 1766 * statep ref cnt. The statep ref cnt is decremented before returning.
1795 1767 */
1796 1768 void
1797 1769 ibcm_handle_cep_rep_response(ibcm_state_data_t *statep, ibcm_status_t response,
1798 1770 ibt_cm_reason_t reject_reason, uint8_t arej_info_len,
1799 1771 ibcm_rep_msg_t *rep_msgp)
1800 1772 {
1801 1773 /* wait until the send completion callback is invoked for REQ post */
1802 1774 mutex_enter(&statep->state_mutex);
1803 1775 while (statep->send_mad_flags & IBCM_REQ_POST_BUSY)
1804 1776 cv_wait(&statep->block_mad_cv, &statep->state_mutex);
1805 1777 mutex_exit(&statep->state_mutex);
1806 1778
1807 1779 if (response == IBCM_SEND_RTU) {
1808 1780 /* if connection aborted, return */
1809 1781 if (ibcm_post_rtu_mad(statep) != IBCM_SUCCESS) {
1810 1782 mutex_enter(&statep->state_mutex);
1811 1783 IBCM_REF_CNT_DECR(statep);
1812 1784 mutex_exit(&statep->state_mutex);
1813 1785 return;
1814 1786 }
1815 1787
1816 1788 /*
1817 1789 * Call client handler with cm event IBT_CM_EVENT_CONN_EST to
1818 1790 * indicate RTU posted
1819 1791 */
1820 1792 ibcm_cep_send_rtu(statep);
1821 1793 } else {
1822 1794 IBTF_DPRINTF_L4(cmlog, "ibcm_handle_cep_rep_response: statep %p"
1823 1795 " posting REJ reject_reason = %d", statep, reject_reason);
1824 1796
1825 1797 ASSERT(response == IBCM_SEND_REJ);
1826 1798 ibcm_post_rej_mad(statep, reject_reason, IBT_CM_FAILURE_REP,
1827 1799 NULL, arej_info_len);
1828 1800 }
1829 1801
1830 1802 ibcm_return_open_data(statep, rep_msgp, reject_reason);
1831 1803 }
1832 1804
1833 1805 /*
1834 1806 * ibcm_return_open_data:
1835 1807 * Initializes the ibt_open_rc_channel return data. The statep ref cnt is
1836 1808 * decremented before returning.
1837 1809 */
1838 1810 static void
1839 1811 ibcm_return_open_data(ibcm_state_data_t *statep, ibcm_rep_msg_t *rep_msgp,
1840 1812 ibt_cm_reason_t reject_reason)
1841 1813 {
1842 1814 /* signal waiting CV - blocking in ibt_open_channel() */
1843 1815 if (statep->open_return_data != NULL) {
1844 1816 if (statep->open_return_data->rc_priv_data_len > 0)
1845 1817 bcopy(rep_msgp->rep_private_data,
1846 1818 statep->open_return_data->rc_priv_data,
1847 1819 statep->open_return_data->rc_priv_data_len);
1848 1820 statep->open_return_data->rc_rdma_ra_in =
1849 1821 rep_msgp->rep_initiator_depth;
1850 1822 statep->open_return_data->rc_rdma_ra_out =
1851 1823 rep_msgp->rep_resp_resources;
1852 1824 statep->open_return_data->rc_failover_status =
1853 1825 rep_msgp->rep_target_delay_plus >> 1 & 3;
1854 1826 statep->open_return_data->rc_status = reject_reason;
1855 1827
1856 1828 mutex_enter(&statep->state_mutex);
1857 1829 statep->open_done = B_TRUE;
1858 1830 cv_broadcast(&statep->block_client_cv);
1859 1831 } else mutex_enter(&statep->state_mutex);
1860 1832
1861 1833 /* decrement ref count and return for LOOKUP_EXISTS */
1862 1834 IBCM_REF_CNT_DECR(statep);
1863 1835 mutex_exit(&statep->state_mutex);
1864 1836 }
1865 1837
1866 1838
1867 1839 /*
1868 1840 * ibcm_process_mra_msg:
1869 1841 * Called from ibcm_process_incoming_mad on reception of a MRA message
1870 1842 *
1871 1843 * Cancels existing timer, and sets a new timer based on timeout
1872 1844 * value from MRA message. The remaining retry count of statep is
1873 1845 * not changed, and timer value for the remaining retry timers is
1874 1846 * also not changed
1875 1847 *
1876 1848 * INPUTS:
1877 1849 * hcap - HCA entry pointer
1878 1850 * input_madp - CM MAD that is input to this function
1879 1851 * cm_mad_addr - Address information for the MAD
1880 1852 *
1881 1853 * RETURN VALUE: NONE
1882 1854 */
1883 1855 void
1884 1856 ibcm_process_mra_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
1885 1857 ibcm_mad_addr_t *cm_mad_addr)
1886 1858 {
1887 1859 ibcm_status_t state_lookup_status;
1888 1860 ibcm_mra_msg_t *mra_msgp =
1889 1861 (ibcm_mra_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
1890 1862 ibcm_state_data_t *statep = NULL;
1891 1863 uint8_t mra_msg;
1892 1864
1893 1865 IBTF_DPRINTF_L4(cmlog, "ibcm_process_mra_msg:");
1894 1866
1895 1867 /* Lookup for an existing state structure (as a READER) */
1896 1868 rw_enter(&hcap->hca_state_rwlock, RW_READER);
1897 1869 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_MRA,
1898 1870 b2h32(mra_msgp->mra_remote_comm_id), 0, 0, hcap, &statep);
1899 1871 rw_exit(&hcap->hca_state_rwlock);
1900 1872
1901 1873 /* if state doesn't exist just return */
1902 1874 if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
1903 1875 ibcm_build_n_post_rej_mad(input_madp,
1904 1876 b2h32(mra_msgp->mra_local_comm_id), cm_mad_addr,
1905 1877 IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
1906 1878 return;
1907 1879 }
1908 1880
1909 1881 if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
1910 1882 ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
1911 1883 mutex_enter(&statep->state_mutex);
1912 1884 IBCM_REF_CNT_DECR(statep);
1913 1885 mutex_exit(&statep->state_mutex);
1914 1886 IBTF_DPRINTF_L3(cmlog, "ibcm_process_mra_msg: statep 0x%p "
1915 1887 "MRA MAD with tid expected 0x%llX tid found 0x%llX "
1916 1888 "com id 0x%x arrived", statep,
1917 1889 b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
1918 1890 b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
1919 1891 b2h32(mra_msgp->mra_local_comm_id));
1920 1892 return;
1921 1893 }
1922 1894
1923 1895 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_MRA);
1924 1896
1925 1897 mutex_enter(&statep->state_mutex);
1926 1898
1927 1899 /*
1928 1900 * Only allow for REQ/REP "mra_msg_typ" ONLY
1929 1901 * (to validate MRA message received)?
1930 1902 */
1931 1903 mra_msg = mra_msgp->mra_message_type_plus >> 6;
1932 1904 if ((mra_msg != IBT_CM_MRA_TYPE_REQ) &&
1933 1905 (mra_msg != IBT_CM_MRA_TYPE_REP) &&
1934 1906 (mra_msg != IBT_CM_MRA_TYPE_LAP)) {
1935 1907
1936 1908 IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: statep 0x%p "
1937 1909 "Unexpected MRA MSG Type %x", statep, mra_msg);
1938 1910 IBCM_REF_CNT_DECR(statep);
1939 1911 mutex_exit(&statep->state_mutex);
1940 1912 return;
1941 1913 }
1942 1914
1943 1915 if ((statep->state == IBCM_STATE_REQ_SENT) ||
1944 1916 (statep->state == IBCM_STATE_REP_SENT) ||
1945 1917 ((statep->state == IBCM_STATE_ESTABLISHED) &&
1946 1918 (statep->ap_state == IBCM_AP_STATE_LAP_SENT))) {
1947 1919 timeout_id_t timer_val = statep->timerid;
1948 1920 clock_t service_timeout;
1949 1921
1950 1922 if (statep->state == IBCM_STATE_REQ_SENT) {
1951 1923 mra_msg = IBT_CM_MRA_TYPE_REQ;
1952 1924 statep->state = IBCM_STATE_REP_WAIT;
1953 1925 } else if (statep->state == IBCM_STATE_REP_SENT) {
1954 1926 mra_msg = IBT_CM_MRA_TYPE_REP;
1955 1927 statep->state = IBCM_STATE_MRA_REP_RCVD;
1956 1928 } else { /* statep->state == IBCM_STATE_LAP_SENT */
1957 1929 mra_msg = IBT_CM_MRA_TYPE_LAP;
1958 1930 statep->ap_state = IBCM_AP_STATE_MRA_LAP_RCVD;
1959 1931 }
1960 1932
1961 1933 /* cancel the timer */
1962 1934 statep->timerid = 0;
1963 1935 mutex_exit(&statep->state_mutex);
1964 1936
1965 1937 (void) untimeout(timer_val);
1966 1938
1967 1939 service_timeout =
1968 1940 ibt_ib2usec(mra_msgp->mra_service_timeout_plus >> 3);
1969 1941
1970 1942 /*
1971 1943 * If tunable MAX MRA Service Timeout parameter is set, then
1972 1944 * verify whether the requested timer value exceeds the MAX
1973 1945 * value and reset the timer value to the MAX value.
1974 1946 */
1975 1947 if (ibcm_mra_service_timeout_max &&
1976 1948 ibcm_mra_service_timeout_max < service_timeout) {
1977 1949 IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: "
1978 1950 "Unexpected MRA Service Timeout value (%ld), Max "
1979 1951 "allowed is (%ld)", service_timeout,
1980 1952 ibcm_mra_service_timeout_max);
1981 1953 service_timeout = ibcm_mra_service_timeout_max;
1982 1954 }
1983 1955
1984 1956 /*
1985 1957 * Invoke client handler to pass the MRA private data
1986 1958 */
1987 1959 if (statep->cm_handler != NULL) {
1988 1960 ibt_cm_event_t event;
1989 1961
1990 1962 bzero(&event, sizeof (event));
1991 1963
1992 1964 event.cm_type = IBT_CM_EVENT_MRA_RCV;
1993 1965 event.cm_channel = statep->channel;
1994 1966 event.cm_session_id = NULL;
1995 1967 event.cm_priv_data = mra_msgp->mra_private_data;
1996 1968 event.cm_priv_data_len = IBT_MRA_PRIV_DATA_SZ;
1997 1969
1998 1970 event.cm_event.mra.mra_msg_type = mra_msg;
1999 1971
2000 1972 event.cm_event.mra.mra_service_time = service_timeout;
2001 1973
2002 1974 /* Client cannot return private data */
2003 1975 (void) statep->cm_handler(statep->state_cm_private,
2004 1976 &event, NULL, NULL, 0);
2005 1977 }
2006 1978
2007 1979 /*
2008 1980 * Must re-check state, as an RTU could have come
2009 1981 * after the above mutex_exit and mutex_enter below
2010 1982 */
2011 1983 mutex_enter(&statep->state_mutex);
2012 1984 if ((statep->state == IBCM_STATE_REP_WAIT) ||
2013 1985 (statep->state == IBCM_STATE_MRA_REP_RCVD) ||
2014 1986 (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
2015 1987
2016 1988 statep->remaining_retry_cnt = statep->max_cm_retries;
2017 1989
2018 1990 /*
2019 1991 * The timeout interval is changed only for the first
2020 1992 * retry. The later retries use the timeout from
2021 1993 * statep->timer_value
2022 1994 */
2023 1995 statep->timer_stored_state = statep->state;
2024 1996 statep->timer_value = statep->pkt_life_time +
2025 1997 service_timeout;
2026 1998 statep->timerid = IBCM_TIMEOUT(statep,
2027 1999 statep->timer_value);
2028 2000 }
2029 2001
2030 2002 } else if (statep->state == IBCM_STATE_DELETE) {
2031 2003
2032 2004 mutex_exit(&statep->state_mutex);
2033 2005 ibcm_build_n_post_rej_mad(input_madp,
2034 2006 b2h32(mra_msgp->mra_local_comm_id), cm_mad_addr,
2035 2007 IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
2036 2008 mutex_enter(&statep->state_mutex);
2037 2009 } else {
2038 2010
2039 2011 #ifdef DEBUG
2040 2012 if (ibcm_test_mode > 0)
2041 2013 IBTF_DPRINTF_L2(cmlog, "ibcm_process_mra_msg: "
2042 2014 "Unexpected mra for statep 0x%p in state %d",
2043 2015 statep, statep->state);
2044 2016 #endif
2045 2017 }
2046 2018
2047 2019 IBCM_REF_CNT_DECR(statep);
2048 2020 mutex_exit(&statep->state_mutex);
2049 2021 }
2050 2022
2051 2023
2052 2024 /*
2053 2025 * ibcm_process_rtu_msg:
2054 2026 * Called from ibcm_process_incoming_mad on reception of a RTU message
2055 2027 *
2056 2028 * Changes connection state to established if in REP SENT state
2057 2029 *
2058 2030 * INPUTS:
2059 2031 * hcap - HCA entry pointer
2060 2032 * input_madp - CM MAD that is input to this function
2061 2033 * cm_mad_addr - Address information for the MAD
2062 2034 *
2063 2035 * RETURN VALUE: NONE
2064 2036 */
2065 2037 void
2066 2038 ibcm_process_rtu_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
2067 2039 ibcm_mad_addr_t *cm_mad_addr)
2068 2040 {
2069 2041 timeout_id_t timer_val;
2070 2042 ibcm_status_t status;
2071 2043 ibcm_rtu_msg_t *rtu_msg =
2072 2044 (ibcm_rtu_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
2073 2045 ibcm_state_data_t *statep = NULL;
2074 2046
2075 2047 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rtu_msg:");
2076 2048
2077 2049 /* Lookup for an existing state structure - using a reader lock */
2078 2050 rw_enter(&hcap->hca_state_rwlock, RW_READER);
2079 2051 status = ibcm_lookup_msg(IBCM_INCOMING_RTU,
2080 2052 b2h32(rtu_msg->rtu_remote_comm_id), 0, 0, hcap, &statep);
2081 2053 rw_exit(&hcap->hca_state_rwlock);
2082 2054
2083 2055 /* if state doesn't exist just return */
2084 2056 if (status != IBCM_LOOKUP_EXISTS) {
2085 2057 ibcm_build_n_post_rej_mad(input_madp,
2086 2058 b2h32(rtu_msg->rtu_local_comm_id), cm_mad_addr,
2087 2059 IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
2088 2060 return;
2089 2061 }
2090 2062
2091 2063 if (IBCM_OUT_HDRP(statep->stored_msg)->TransactionID !=
2092 2064 ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
2093 2065 mutex_enter(&statep->state_mutex);
2094 2066 IBCM_REF_CNT_DECR(statep);
2095 2067 mutex_exit(&statep->state_mutex);
2096 2068 IBTF_DPRINTF_L3(cmlog, "ibcm_process_rtu_msg: statep 0x%p "
2097 2069 "An RTU MAD with tid expected 0x%llX tid found 0x%llX "
2098 2070 "com id 0x%x arrived", statep,
2099 2071 b2h64(IBCM_OUT_HDRP(statep->stored_msg)->TransactionID),
2100 2072 b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
2101 2073 b2h32(rtu_msg->rtu_remote_comm_id));
2102 2074 return;
2103 2075 }
2104 2076
2105 2077 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_RTU);
2106 2078
2107 2079 mutex_enter(&statep->state_mutex);
2108 2080
2109 2081 if ((statep->state == IBCM_STATE_REP_SENT) ||
2110 2082 (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
2111 2083
2112 2084 /* transient until ibt_modify_qp succeeds to RTS */
2113 2085 statep->state = IBCM_STATE_TRANSIENT_ESTABLISHED;
2114 2086
2115 2087 timer_val = statep->timerid;
2116 2088 statep->timerid = 0;
2117 2089 mutex_exit(&statep->state_mutex);
2118 2090
2119 2091 (void) untimeout(timer_val);
2120 2092
2121 2093 ibcm_cep_state_rtu(statep, rtu_msg);
2122 2094
2123 2095 mutex_enter(&statep->state_mutex);
2124 2096
2125 2097 } else if (statep->state == IBCM_STATE_REJ_SENT) {
2126 2098 ibcm_resend_rej_mad(statep);
2127 2099 } else if (statep->state == IBCM_STATE_DELETE) {
2128 2100
2129 2101 mutex_exit(&statep->state_mutex);
2130 2102 ibcm_build_n_post_rej_mad(input_madp,
2131 2103 b2h32(rtu_msg->rtu_local_comm_id), cm_mad_addr,
2132 2104 IBT_CM_FAILURE_UNKNOWN, IBT_CM_INVALID_CID);
2133 2105 mutex_enter(&statep->state_mutex);
2134 2106 } else {
2135 2107
2136 2108 #ifdef DEBUG
2137 2109 if ((ibcm_test_mode > 0) &&
2138 2110 (statep->state != IBCM_STATE_ESTABLISHED))
2139 2111 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rtu_msg: "
2140 2112 "Unexpected rtu for statep 0x%p in state %d",
2141 2113 statep, statep->state);
2142 2114 #endif
2143 2115 }
2144 2116
2145 2117 IBCM_REF_CNT_DECR(statep);
2146 2118 mutex_exit(&statep->state_mutex);
2147 2119 }
2148 2120
2149 2121
2150 2122 /*
2151 2123 * ibcm_process_rej_msg:
2152 2124 * Called from ibcm_process_incoming_mad on reception of a REJ message.
2153 2125 *
2154 2126 * INPUTS:
2155 2127 * hcap - HCA entry pointer
2156 2128 * input_madp - CM MAD that is input to this function
2157 2129 * cm_mad_addr - Address information for the MAD
2158 2130 *
2159 2131 * RETURN VALUE: NONE
2160 2132 */
2161 2133 /* ARGSUSED */
2162 2134 void
2163 2135 ibcm_process_rej_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
2164 2136 ibcm_mad_addr_t *cm_mad_addr)
2165 2137 {
2166 2138 ibcm_status_t state_lookup_status;
2167 2139 ibcm_rej_msg_t *rej_msg =
2168 2140 (ibcm_rej_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
2169 2141 ibcm_state_data_t *statep = NULL;
2170 2142 ib_guid_t remote_hca_guid;
2171 2143 ibcm_conn_state_t rej_state;
2172 2144
2173 2145 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg:");
2174 2146
2175 2147 /* Lookup for an existing state structure */
2176 2148 rw_enter(&hcap->hca_state_rwlock, RW_READER); /* grab READER lock */
2177 2149
2178 2150 if ((b2h32(rej_msg->rej_remote_comm_id) == 0) &&
2179 2151 ((rej_msg->rej_reject_info_len_plus >> 1) >= sizeof (ib_guid_t)) &&
2180 2152 (b2h16(rej_msg->rej_rejection_reason) == IBT_CM_TIMEOUT)) {
2181 2153 bcopy(rej_msg->rej_addl_rej_info, &remote_hca_guid,
2182 2154 sizeof (ib_guid_t));
2183 2155 remote_hca_guid = b2h64(remote_hca_guid);
2184 2156
2185 2157 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg: "
2186 2158 "hca guid in REJ's ARI = %llX", remote_hca_guid);
2187 2159
2188 2160 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REJ_RCOMID,
2189 2161 b2h32(rej_msg->rej_local_comm_id), 0, remote_hca_guid,
2190 2162 hcap, &statep);
2191 2163 } else
2192 2164 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_REJ,
2193 2165 b2h32(rej_msg->rej_remote_comm_id), 0, 0, hcap, &statep);
2194 2166
2195 2167 rw_exit(&hcap->hca_state_rwlock);
2196 2168
2197 2169
2198 2170 /* if state doesn't exist just return */
2199 2171 if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
2200 2172
2201 2173 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: no statep with "
2202 2174 "local com id %x remote com id %x reason %d",
2203 2175 b2h32(rej_msg->rej_remote_comm_id),
2204 2176 b2h32(rej_msg->rej_local_comm_id),
2205 2177 b2h16(rej_msg->rej_rejection_reason));
2206 2178
2207 2179 /* Do NOT respond with invalid comid REJ */
2208 2180 return;
2209 2181 }
2210 2182
2211 2183 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: statep 0x%p INCOMING_REJ",
2212 2184 statep);
2213 2185 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_REJ);
2214 2186 if (ibcm_enable_trace & 2)
2215 2187 ibcm_dump_conn_trace(statep);
2216 2188
2217 2189 mutex_enter(&statep->state_mutex);
2218 2190
2219 2191 rej_state = statep->state;
2220 2192
2221 2193 if ((statep->state == IBCM_STATE_REP_SENT) ||
2222 2194 (statep->state == IBCM_STATE_REQ_SENT) ||
2223 2195 (statep->state == IBCM_STATE_REP_WAIT) ||
2224 2196 (statep->state == IBCM_STATE_MRA_REP_RCVD)) {
2225 2197 timeout_id_t timer_val = statep->timerid;
2226 2198
2227 2199 statep->state = IBCM_STATE_DELETE;
2228 2200
2229 2201 /* cancel the REQ/REP timer */
2230 2202 if (timer_val != 0) {
2231 2203 statep->timerid = 0;
2232 2204 mutex_exit(&statep->state_mutex);
2233 2205
2234 2206 (void) untimeout(timer_val);
2235 2207 } else {
2236 2208 mutex_exit(&statep->state_mutex);
2237 2209 }
2238 2210
2239 2211 /*
2240 2212 * Call the QP state transition processing function
2241 2213 * NOTE: Input MAD is the REJ received, there is no output MAD
2242 2214 */
2243 2215 ibcm_cep_state_rej(statep, rej_msg, rej_state);
2244 2216
2245 2217 /* signal waiting CV - blocking in ibt_open_channel() */
2246 2218 if (statep->open_return_data != NULL) {
2247 2219 statep->open_return_data->rc_status =
2248 2220 b2h16(rej_msg->rej_rejection_reason);
2249 2221
2250 2222 if (statep->open_return_data->rc_priv_data_len > 0)
2251 2223 bcopy(rej_msg->rej_private_data,
2252 2224 statep->open_return_data->rc_priv_data,
2253 2225 min(
2254 2226 statep->open_return_data->rc_priv_data_len,
2255 2227 IBT_REJ_PRIV_DATA_SZ));
2256 2228 mutex_enter(&statep->state_mutex);
2257 2229 statep->open_done = B_TRUE;
2258 2230 cv_broadcast(&statep->block_client_cv);
2259 2231 } else {
2260 2232 mutex_enter(&statep->state_mutex);
2261 2233 }
2262 2234
2263 2235 IBCM_REF_CNT_DECR(statep);
2264 2236 mutex_exit(&statep->state_mutex);
2265 2237
2266 2238 /* Now delete the statep */
2267 2239 ibcm_delete_state_data(statep);
2268 2240
2269 2241 } else if ((statep->state == IBCM_STATE_ESTABLISHED) &&
2270 2242 (statep->mode == IBCM_ACTIVE_MODE)) {
2271 2243
2272 2244 IBTF_DPRINTF_L4(cmlog, "ibcm_process_rej_msg: statep 0x%p "
2273 2245 "REJ in established state", statep);
2274 2246
2275 2247 statep->state = IBCM_STATE_TIMEWAIT;
2276 2248
2277 2249 /* wait for/cancel pending LAP/APR, release state mutex */
2278 2250 ibcm_sync_lapr_idle(statep);
2279 2251
2280 2252 /* wait until client is informed CONN EST event */
2281 2253 mutex_enter(&statep->state_mutex);
2282 2254 while (statep->cep_in_rts == IBCM_BLOCK)
2283 2255 cv_wait(&statep->block_mad_cv, &statep->state_mutex);
2284 2256 mutex_exit(&statep->state_mutex);
2285 2257
2286 2258 /*
2287 2259 * Call the QP state transition processing function
2288 2260 * NOTE: Input MAD is the REJ received, there is no output MAD
2289 2261 */
2290 2262 ibcm_cep_state_rej_est(statep);
2291 2263
2292 2264 /*
2293 2265 * Start the timewait state timer, as connection is in
2294 2266 * established state
2295 2267 */
2296 2268
2297 2269 /*
2298 2270 * For passive side CM set it to remote_ack_delay
2299 2271 * For active side CM add the pkt_life_time * 2
2300 2272 */
2301 2273 mutex_enter(&statep->state_mutex);
2302 2274 statep->timer_value = statep->remote_ack_delay;
2303 2275 /* statep->mode == IBCM_ACTIVE_MODE) */
2304 2276 statep->timer_value += (2 * statep->pkt_life_time);
2305 2277
2306 2278 statep->remaining_retry_cnt = 0;
2307 2279 statep->timer_stored_state = statep->state;
2308 2280
2309 2281 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
2310 2282
2311 2283 IBCM_REF_CNT_DECR(statep);
2312 2284 mutex_exit(&statep->state_mutex);
2313 2285
2314 2286 } else if (((statep->state == IBCM_STATE_REQ_RCVD) ||
2315 2287 (statep->state == IBCM_STATE_REP_RCVD) ||
2316 2288 (statep->state == IBCM_STATE_MRA_SENT) ||
2317 2289 (statep->state == IBCM_STATE_MRA_REP_SENT)) &&
2318 2290 (b2h16(rej_msg->rej_rejection_reason) == IBT_CM_TIMEOUT)) {
2319 2291
2320 2292 if (statep->abort_flag == IBCM_ABORT_INIT)
2321 2293 statep->abort_flag = IBCM_ABORT_REJ;
2322 2294
2323 2295 IBCM_REF_CNT_DECR(statep);
2324 2296 mutex_exit(&statep->state_mutex);
2325 2297 } else {
2326 2298
2327 2299 #ifdef DEBUG
2328 2300 if ((ibcm_test_mode > 0) &&
2329 2301 (statep->state != IBCM_STATE_DELETE))
2330 2302 IBTF_DPRINTF_L2(cmlog, "ibcm_process_rej_msg: "
2331 2303 "Unexpected rej for statep 0x%p in state %d",
2332 2304 statep, statep->state);
2333 2305 #endif
2334 2306 IBCM_REF_CNT_DECR(statep);
2335 2307 mutex_exit(&statep->state_mutex);
2336 2308 }
2337 2309 }
2338 2310
2339 2311
2340 2312 /*
2341 2313 * ibcm_process_dreq_msg:
2342 2314 * Processes incoming DREQ message on active/passive side
2343 2315 *
2344 2316 * INPUTS:
2345 2317 * hcap - HCA entry pointer
2346 2318 * input_madp - CM MAD that is input to this function
2347 2319 * cm_mad_addr - Address information for the MAD
2348 2320 *
2349 2321 * RETURN VALUE: NONE
2350 2322 */
2351 2323 /*ARGSUSED*/
2352 2324 void
2353 2325 ibcm_process_dreq_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
2354 2326 ibcm_mad_addr_t *cm_mad_addr)
2355 2327 {
2356 2328 void *priv_data = NULL;
2357 2329 ibcm_status_t state_lookup_status;
2358 2330 ib_qpn_t local_qpn;
2359 2331 ibcm_dreq_msg_t *dreq_msgp =
2360 2332 (ibcm_dreq_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
2361 2333 ibcm_state_data_t *statep = NULL;
2362 2334 uint8_t close_event_type;
2363 2335 ibt_cm_status_t cb_status;
2364 2336
2365 2337 IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg:");
2366 2338
2367 2339 /* Lookup for an existing state structure */
2368 2340 rw_enter(&hcap->hca_state_rwlock, RW_READER);
2369 2341
2370 2342 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_DREQ,
2371 2343 b2h32(dreq_msgp->dreq_remote_comm_id), 0, 0, hcap, &statep);
2372 2344 rw_exit(&hcap->hca_state_rwlock);
2373 2345
2374 2346 local_qpn = b2h32(dreq_msgp->dreq_remote_qpn_eecn_plus) >> 8;
2375 2347
2376 2348 if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
2377 2349 IBTF_DPRINTF_L3(cmlog, "ibcm_process_dreq_msg: no statep with"
2378 2350 "com id %x", b2h32(dreq_msgp->dreq_remote_comm_id));
2379 2351 /* implies a bogus message */
2380 2352 return;
2381 2353 }
2382 2354
2383 2355 IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg: statep 0x%p "
2384 2356 "lookup status %x dreq qpn = %x", statep, state_lookup_status,
2385 2357 local_qpn);
2386 2358
2387 2359 /*
2388 2360 * Local QPN check is necessary. There could be a DREQ from
2389 2361 * a remote stale connection processing with the same com id, but
2390 2362 * not intended for this statep
2391 2363 */
2392 2364 mutex_enter(&statep->state_mutex);
2393 2365 if ((statep->local_qpn != local_qpn) ||
2394 2366 (statep->remote_comid != b2h32(dreq_msgp->dreq_local_comm_id))) {
2395 2367
2396 2368 IBTF_DPRINTF_L3(cmlog, "ibcm_process_dreq_msg:"
2397 2369 "statep->local_qpn = %x qpn in dreq = %x"
2398 2370 "statep->remote_comid = %x local comid in dreq = %x",
2399 2371 statep->local_qpn, local_qpn, statep->remote_comid,
2400 2372 b2h32(dreq_msgp->dreq_local_comm_id));
2401 2373
2402 2374 IBCM_REF_CNT_DECR(statep);
2403 2375 mutex_exit(&statep->state_mutex);
2404 2376 return;
2405 2377 }
2406 2378 /*
2407 2379 * If another thread is processing a copy of this same DREQ,
2408 2380 * bail out here.
2409 2381 */
2410 2382 if (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT ||
2411 2383 statep->drep_in_progress) {
2412 2384 IBCM_REF_CNT_DECR(statep);
2413 2385 mutex_exit(&statep->state_mutex);
2414 2386 return;
2415 2387 }
2416 2388 switch (statep->state) {
2417 2389 case IBCM_STATE_ESTABLISHED:
2418 2390 case IBCM_STATE_DREQ_SENT:
2419 2391 case IBCM_STATE_TIMEWAIT:
2420 2392 break;
2421 2393 default:
2422 2394 /* All other states ignore DREQ */
2423 2395 IBCM_REF_CNT_DECR(statep);
2424 2396 mutex_exit(&statep->state_mutex);
2425 2397 return;
2426 2398 }
2427 2399 statep->drep_in_progress = 1;
2428 2400
2429 2401 /*
2430 2402 * If drep msg wasn't really required, it shall be deleted finally
2431 2403 * when statep goes away
2432 2404 */
2433 2405 if (statep->drep_msg == NULL) {
2434 2406 mutex_exit(&statep->state_mutex);
2435 2407 if (ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
2436 2408 &statep->drep_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
2437 2409 IBTF_DPRINTF_L2(cmlog, "ibcm_process_dreq_msg: "
2438 2410 "statep 0x%p ibcm_alloc_out_msg failed", statep);
2439 2411 mutex_enter(&statep->state_mutex);
2440 2412 statep->drep_in_progress = 0;
2441 2413 IBCM_REF_CNT_DECR(statep);
2442 2414 mutex_exit(&statep->state_mutex);
2443 2415 return;
2444 2416 }
2445 2417 mutex_enter(&statep->state_mutex);
2446 2418 }
2447 2419
2448 2420 if (statep->state == IBCM_STATE_TRANSIENT_DREQ_SENT) {
2449 2421 IBCM_REF_CNT_DECR(statep);
2450 2422 statep->drep_in_progress = 0;
2451 2423 mutex_exit(&statep->state_mutex);
2452 2424 return;
2453 2425 }
2454 2426
2455 2427 /*
2456 2428 * Need to generate drep, as time wait can be reached either by an
2457 2429 * outgoing dreq or an incoming dreq
2458 2430 */
2459 2431 if ((statep->state == IBCM_STATE_ESTABLISHED) ||
2460 2432 (statep->state == IBCM_STATE_DREQ_SENT)) {
2461 2433 timeout_id_t timer_val = statep->timerid;
2462 2434
2463 2435 if (statep->state == IBCM_STATE_DREQ_SENT) {
2464 2436 statep->state = IBCM_STATE_DREQ_RCVD;
2465 2437 statep->timerid = 0;
2466 2438 ibcm_close_done(statep, 0);
2467 2439 mutex_exit(&statep->state_mutex);
2468 2440
2469 2441 close_event_type = IBT_CM_CLOSED_DUP;
2470 2442 if (timer_val != 0) {
2471 2443 /* Cancel the timer set for DREP reception */
2472 2444 (void) untimeout(timer_val);
2473 2445 }
2474 2446 } else { /* In ESTABLISHED State */
2475 2447 boolean_t is_ofuv = statep->is_this_ofuv_chan;
2476 2448
2477 2449 statep->state = IBCM_STATE_DREQ_RCVD;
2478 2450 statep->clnt_proceed = IBCM_BLOCK;
2479 2451
2480 2452 /* Cancel or wait for LAP/APR to complete */
2481 2453 ibcm_sync_lapr_idle(statep);
2482 2454 /* The above function releases the state mutex */
2483 2455
2484 2456 /* wait until client knows CONN EST event */
2485 2457 mutex_enter(&statep->state_mutex);
2486 2458 while (statep->cep_in_rts == IBCM_BLOCK)
2487 2459 cv_wait(&statep->block_mad_cv,
2488 2460 &statep->state_mutex);
2489 2461 mutex_exit(&statep->state_mutex);
2490 2462
2491 2463 close_event_type = IBT_CM_CLOSED_DREQ_RCVD;
2492 2464 /* Move CEP to error state */
2493 2465 if (is_ofuv == B_FALSE) /* Skip for OFUV channel */
2494 2466 (void) ibcm_cep_to_error_state(statep);
2495 2467 }
2496 2468 mutex_enter(&statep->state_mutex);
2497 2469 statep->drep_in_progress = 0;
2498 2470
2499 2471 IBCM_OUT_HDRP(statep->drep_msg)->TransactionID =
2500 2472 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
2501 2473
2502 2474 priv_data = &(((ibcm_drep_msg_t *)
2503 2475 IBCM_OUT_MSGP(statep->drep_msg))->drep_private_data[0]);
2504 2476
2505 2477 if (statep->close_ret_status)
2506 2478 *statep->close_ret_status = close_event_type;
2507 2479
2508 2480 if (statep->close_nocb_state != IBCM_FAIL) {
2509 2481 ibtl_cm_chan_is_closing(statep->channel);
2510 2482 statep->close_nocb_state = IBCM_BLOCK;
2511 2483 }
2512 2484 mutex_exit(&statep->state_mutex);
2513 2485
2514 2486 /*
2515 2487 * if close_nocb_state is IBCM_FAIL, then cm_handler is NULL
2516 2488 * if close_nocb_state is IBCM_BLOCK, client cannot go away
2517 2489 */
2518 2490 if (statep->cm_handler != NULL) {
2519 2491 ibt_cm_event_t event;
2520 2492 ibt_cm_return_args_t ret_args;
2521 2493
2522 2494 bzero(&event, sizeof (event));
2523 2495 bzero(&ret_args, sizeof (ret_args));
2524 2496
2525 2497 event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
2526 2498 event.cm_channel = statep->channel;
2527 2499 event.cm_session_id = statep;
2528 2500 event.cm_priv_data = dreq_msgp->dreq_private_data;
2529 2501 event.cm_priv_data_len = IBT_DREQ_PRIV_DATA_SZ;
2530 2502 event.cm_event.closed = close_event_type;
2531 2503
2532 2504 ibcm_insert_trace(statep,
2533 2505 IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
2534 2506
2535 2507 cb_status = statep->cm_handler(statep->state_cm_private,
2536 2508 &event, &ret_args, priv_data,
2537 2509 IBT_DREP_PRIV_DATA_SZ);
2538 2510
2539 2511 ibcm_insert_trace(statep,
2540 2512 IBCM_TRACE_RET_CONN_CLOSE_EVENT);
2541 2513
2542 2514 if (cb_status == IBT_CM_DEFER) {
2543 2515 mutex_enter(&statep->state_mutex);
2544 2516 statep->clnt_proceed =
2545 2517 IBCM_UNBLOCK;
2546 2518 cv_broadcast(&statep->block_client_cv);
2547 2519 mutex_exit(&statep->state_mutex);
2548 2520
2549 2521 IBTF_DPRINTF_L4(cmlog, "ibcm_process_dreq_msg:"
2550 2522 " statep 0x%p client returned DEFER "
2551 2523 "response", statep);
2552 2524 return;
2553 2525 }
2554 2526 }
2555 2527
2556 2528 /* fail/resume any blocked cm api call */
2557 2529 mutex_enter(&statep->state_mutex);
2558 2530
2559 2531 /* Signal for cm proceed api */
2560 2532 statep->clnt_proceed = IBCM_FAIL;
2561 2533
2562 2534 /* Signal for close with no callbacks */
2563 2535 statep->close_nocb_state = IBCM_FAIL;
2564 2536
2565 2537 /* Signal any waiting close channel thread */
2566 2538 statep->close_done = B_TRUE;
2567 2539
2568 2540 cv_broadcast(&statep->block_client_cv);
2569 2541 mutex_exit(&statep->state_mutex);
2570 2542
2571 2543 ibcm_handle_cep_dreq_response(statep, NULL, 0);
2572 2544
2573 2545 } else if (statep->state == IBCM_STATE_TIMEWAIT) {
2574 2546 statep->drep_in_progress = 0;
2575 2547 if (statep->send_mad_flags & IBCM_DREP_POST_BUSY) {
2576 2548 IBCM_REF_CNT_DECR(statep);
2577 2549 mutex_exit(&statep->state_mutex);
2578 2550 return;
2579 2551 }
2580 2552 statep->send_mad_flags |= IBCM_DREP_POST_BUSY;
2581 2553
2582 2554 /* Release statep mutex before posting the MAD */
2583 2555 mutex_exit(&statep->state_mutex);
2584 2556
2585 2557 IBCM_OUT_HDRP(statep->drep_msg)->TransactionID =
2586 2558 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
2587 2559
2588 2560 ibcm_post_drep_mad(statep);
2589 2561 /* ref cnt decremented in ibcm_post_drep_complete */
2590 2562 } else {
2591 2563 #ifdef DEBUG
2592 2564 if ((ibcm_test_mode > 0) &&
2593 2565 (statep->state != IBCM_STATE_DELETE))
2594 2566 IBTF_DPRINTF_L2(cmlog, "ibcm_process_dreq_msg: "
2595 2567 "Unexpected dreq for statep 0x%p in state %d",
2596 2568 statep, statep->state);
2597 2569 #endif
2598 2570 IBCM_REF_CNT_DECR(statep);
2599 2571 statep->drep_in_progress = 0;
2600 2572 mutex_exit(&statep->state_mutex);
2601 2573 }
2602 2574 }
2603 2575
2604 2576 /*
2605 2577 * ibcm_handle_cep_dreq_response:
2606 2578 * Processes the response from client handler for an incoming DREQ.
2607 2579 * The statep ref cnt is decremented before returning.
2608 2580 */
2609 2581 void
2610 2582 ibcm_handle_cep_dreq_response(ibcm_state_data_t *statep, void *priv_data,
2611 2583 ibt_priv_data_len_t priv_data_len)
2612 2584 {
2613 2585 if ((priv_data != NULL) && (priv_data_len > 0))
2614 2586 bcopy(priv_data,
2615 2587 &(((ibcm_drep_msg_t *)
2616 2588 IBCM_OUT_MSGP(statep->drep_msg))->drep_private_data[0]),
2617 2589 min(priv_data_len, IBT_DREP_PRIV_DATA_SZ));
2618 2590
2619 2591 ibcm_post_drep_mad(statep);
2620 2592 }
2621 2593
2622 2594
2623 2595 /*
2624 2596 * ibcm_post_dreq_mad:
2625 2597 * Posts a DREQ MAD
2626 2598 * Post DREQ now for TIMEWAIT state and DREQ_RCVD
2627 2599 *
2628 2600 * INPUTS:
2629 2601 * statep - state pointer
2630 2602 *
2631 2603 * RETURN VALUE:
↓ open down ↓ |
860 lines elided |
↑ open up ↑ |
2632 2604 * NONE
2633 2605 */
2634 2606 void
2635 2607 ibcm_post_dreq_mad(void *vstatep)
2636 2608 {
2637 2609 ibcm_state_data_t *statep = vstatep;
2638 2610 ibcm_dreq_msg_t *dreq_msgp;
2639 2611
2640 2612 ASSERT(statep->dreq_msg != NULL);
2641 2613
2642 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*dreq_msgp))
2643 -
2644 2614 /* Fill in the DREQ message */
2645 2615 dreq_msgp = (ibcm_dreq_msg_t *)IBCM_OUT_MSGP(statep->dreq_msg);
2646 2616 dreq_msgp->dreq_local_comm_id = h2b32(statep->local_comid);
2647 2617 dreq_msgp->dreq_remote_comm_id = h2b32(statep->remote_comid);
2648 2618 dreq_msgp->dreq_remote_qpn_eecn_plus = h2b32(statep->remote_qpn << 8);
2649 2619
2650 2620 IBCM_OUT_HDRP(statep->dreq_msg)->AttributeID =
2651 2621 h2b16(IBCM_INCOMING_DREQ + IBCM_ATTR_BASE_ID);
2652 2622
2653 2623 /* wait until client knows CONN EST event */
2654 2624 mutex_enter(&statep->state_mutex);
2655 2625 while (statep->cep_in_rts == IBCM_BLOCK)
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
2656 2626 cv_wait(&statep->block_mad_cv, &statep->state_mutex);
2657 2627 mutex_exit(&statep->state_mutex);
2658 2628
2659 2629 /* Transition QP/EEC state to ERROR state */
2660 2630 (void) ibcm_cep_to_error_state(statep);
2661 2631
2662 2632 IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID =
2663 2633 h2b64(ibcm_generate_tranid(IBCM_INCOMING_DREQ, statep->local_comid,
2664 2634 0));
2665 2635
2666 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*dreq_msgp))
2667 -
2668 2636 /* post the first DREQ via timeout callback */
2669 2637 mutex_enter(&statep->state_mutex);
2670 2638
2671 2639 statep->state = IBCM_STATE_DREQ_SENT;
2672 2640 cv_broadcast(&statep->block_mad_cv);
2673 2641
2674 2642 statep->timer_stored_state = statep->state;
2675 2643 /* client cannot specify more than 16 retries */
2676 2644 statep->timer_value = statep->remote_ack_delay;
2677 2645 if (statep->mode == IBCM_ACTIVE_MODE) {
2678 2646 statep->timer_value += (2 * statep->pkt_life_time);
2679 2647 }
2680 2648 statep->remaining_retry_cnt = statep->max_cm_retries + 1;
2681 2649 statep->timerid = IBCM_TIMEOUT(statep, 0);
2682 2650 mutex_exit(&statep->state_mutex);
2683 2651 }
2684 2652
2685 2653 /*
2686 2654 * ibcm_post_drep_mad:
2687 2655 * Posts a DREP MAD
2688 2656 * Post DREP now for TIMEWAIT state and DREQ_RCVD
2689 2657 *
2690 2658 * INPUTS:
2691 2659 * statep - state pointer
2692 2660 *
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
2693 2661 * RETURN VALUE:
2694 2662 * NONE
2695 2663 */
2696 2664 static void
2697 2665 ibcm_post_drep_mad(ibcm_state_data_t *statep)
2698 2666 {
2699 2667 ibcm_drep_msg_t *drep_msgp;
2700 2668
2701 2669 drep_msgp = (ibcm_drep_msg_t *)IBCM_OUT_MSGP(statep->drep_msg);
2702 2670
2703 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*drep_msgp))
2704 -
2705 2671 IBTF_DPRINTF_L4(cmlog, "ibcm_post_drep_mad:");
2706 2672
2707 2673 /* Fill up DREP fields */
2708 2674 drep_msgp->drep_local_comm_id = h2b32(statep->local_comid);
2709 2675 drep_msgp->drep_remote_comm_id = h2b32(statep->remote_comid);
2710 2676 IBCM_OUT_HDRP(statep->drep_msg)->AttributeID =
2711 2677 h2b16(IBCM_INCOMING_DREP + IBCM_ATTR_BASE_ID);
2712 2678
2713 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*drep_msgp))
2714 -
2715 2679 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_DREP);
2716 2680
2717 2681 /* Post the DREP MAD now. */
2718 2682 ibcm_post_rc_mad(statep, statep->drep_msg, ibcm_post_drep_complete,
2719 2683 statep);
2720 2684 }
2721 2685
2722 2686 /*
2723 2687 * ibcm_process_drep_msg:
2724 2688 * Processes incoming DREP message on active/passive side
2725 2689 *
2726 2690 * INPUTS:
2727 2691 * hcap - HCA entry pointer
2728 2692 * input_madp - CM MAD that is input to this function
2729 2693 * cm_mad_addr - Address information for the MAD
2730 2694 *
2731 2695 * RETURN VALUE: NONE
2732 2696 */
2733 2697 /* ARGSUSED */
2734 2698 void
2735 2699 ibcm_process_drep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
2736 2700 ibcm_mad_addr_t *cm_mad_addr)
2737 2701 {
2738 2702 ibcm_status_t state_lookup_status;
2739 2703 ibcm_drep_msg_t *drep_msgp =
2740 2704 (ibcm_drep_msg_t *)(&input_madp[IBCM_MAD_HDR_SIZE]);
2741 2705 ibcm_state_data_t *statep = NULL;
2742 2706
2743 2707 IBTF_DPRINTF_L4(cmlog, "ibcm_process_drep_msg:");
2744 2708
2745 2709 /* Lookup for an existing state structure */
2746 2710 rw_enter(&hcap->hca_state_rwlock, RW_READER);
2747 2711
2748 2712 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_DREP,
2749 2713 b2h32(drep_msgp->drep_remote_comm_id), 0, 0, hcap, &statep);
2750 2714 rw_exit(&hcap->hca_state_rwlock);
2751 2715
2752 2716 if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
2753 2717 IBTF_DPRINTF_L3(cmlog, "ibcm_process_drep_msg: no statep with"
2754 2718 "com id %x", b2h32(drep_msgp->drep_remote_comm_id));
2755 2719 return;
2756 2720 }
2757 2721
2758 2722 /* if transaction id is not as expected, drop the DREP mad */
2759 2723 if (IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID !=
2760 2724 ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
2761 2725 mutex_enter(&statep->state_mutex);
2762 2726 IBCM_REF_CNT_DECR(statep);
2763 2727 mutex_exit(&statep->state_mutex);
2764 2728 IBTF_DPRINTF_L3(cmlog, "ibcm_process_drep_msg: statep 0x%p "
2765 2729 "DREP with tid expected 0x%llX tid found 0x%llX", statep,
2766 2730 b2h64(IBCM_OUT_HDRP(statep->dreq_msg)->TransactionID),
2767 2731 b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
2768 2732 return;
2769 2733 }
2770 2734
2771 2735 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_DREP);
2772 2736
2773 2737 mutex_enter(&statep->state_mutex);
2774 2738
2775 2739 if (statep->state == IBCM_STATE_DREQ_SENT) {
2776 2740 timeout_id_t timer_val = statep->timerid;
2777 2741
2778 2742 statep->state = IBCM_STATE_DREP_RCVD;
2779 2743
2780 2744 statep->timerid = 0;
2781 2745 mutex_exit(&statep->state_mutex);
2782 2746 (void) untimeout(timer_val);
2783 2747
2784 2748 if (statep->stale == B_TRUE)
2785 2749 IBTF_DPRINTF_L2(cmlog, "ibcm_process_drep_msg: "
2786 2750 "statep 0x%p Unexpected DREP received for a stale "
2787 2751 "DREQ sent", statep);
2788 2752
2789 2753 mutex_enter(&statep->state_mutex);
2790 2754 /* allow free qp, if close channel with NOCALLBACKS didn't */
2791 2755 if (statep->close_nocb_state != IBCM_FAIL) {
2792 2756 ibtl_cm_chan_is_closing(statep->channel);
2793 2757 statep->close_nocb_state = IBCM_BLOCK;
2794 2758 }
2795 2759 mutex_exit(&statep->state_mutex);
2796 2760
2797 2761 /* if close_nocb_state is IBCM_FAIL, then cm_handler is NULL */
2798 2762 if (statep->cm_handler != NULL) {
2799 2763 ibt_cm_event_t event;
2800 2764 ibt_cm_return_args_t ret_args;
2801 2765
2802 2766 bzero(&event, sizeof (event));
2803 2767 bzero(&ret_args, sizeof (ret_args));
2804 2768
2805 2769 event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
2806 2770 event.cm_channel = statep->channel;
2807 2771 event.cm_session_id = NULL;
2808 2772
2809 2773 if (statep->stale == B_TRUE) {
2810 2774 event.cm_event.closed = IBT_CM_CLOSED_STALE;
2811 2775 event.cm_priv_data = NULL;
2812 2776 event.cm_priv_data_len = 0;
2813 2777 } else {
2814 2778 event.cm_event.closed = IBT_CM_CLOSED_DREP_RCVD;
2815 2779 event.cm_priv_data =
2816 2780 drep_msgp->drep_private_data;
2817 2781 event.cm_priv_data_len = IBT_DREP_PRIV_DATA_SZ;
2818 2782 }
2819 2783
2820 2784 ibcm_insert_trace(statep,
2821 2785 IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
2822 2786
2823 2787 (void) statep->cm_handler(statep->state_cm_private,
2824 2788 &event, &ret_args, NULL, 0);
2825 2789
2826 2790 ibcm_insert_trace(statep,
2827 2791 IBCM_TRACE_RET_CONN_CLOSE_EVENT);
2828 2792 }
2829 2793
2830 2794 /* copy the private to close channel, if specified */
2831 2795 if ((statep->close_ret_priv_data != NULL) &&
2832 2796 (statep->close_ret_priv_data_len != NULL) &&
2833 2797 (*statep->close_ret_priv_data_len > 0)) {
2834 2798 bcopy(drep_msgp->drep_private_data,
2835 2799 statep->close_ret_priv_data,
2836 2800 min(*statep->close_ret_priv_data_len,
2837 2801 IBT_DREP_PRIV_DATA_SZ));
2838 2802 }
2839 2803
2840 2804 mutex_enter(&statep->state_mutex);
2841 2805 if (statep->close_ret_status)
2842 2806 *statep->close_ret_status = IBT_CM_CLOSED_DREP_RCVD;
2843 2807 /* signal waiting CV - blocking in ibt_close_channel() */
2844 2808 statep->close_done = B_TRUE;
2845 2809
2846 2810 /* signal any blocked close channels with no callbacks */
2847 2811 statep->close_nocb_state = IBCM_FAIL;
2848 2812
2849 2813 cv_broadcast(&statep->block_client_cv);
2850 2814
2851 2815 /* Set the timer wait state timer */
2852 2816 statep->state = statep->timer_stored_state =
2853 2817 IBCM_STATE_TIMEWAIT;
2854 2818 ibcm_close_done(statep, 0);
2855 2819
2856 2820 statep->remaining_retry_cnt = 0;
2857 2821 /*
2858 2822 * For passive side CM set it to remote_ack_delay
2859 2823 * For active side CM add the pkt_life_time * 2
2860 2824 */
2861 2825 statep->timer_value = statep->remote_ack_delay;
2862 2826 if (statep->mode == IBCM_ACTIVE_MODE) {
2863 2827 statep->timer_value += (2 * statep->pkt_life_time);
2864 2828 }
2865 2829
2866 2830 /* start TIMEWAIT processing */
2867 2831 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
2868 2832 }
2869 2833
2870 2834 /* There is no processing required for other states */
2871 2835 IBCM_REF_CNT_DECR(statep);
2872 2836 mutex_exit(&statep->state_mutex);
2873 2837 }
2874 2838
2875 2839 /*
2876 2840 * Following are the routines used to resend various CM MADs as a response to
2877 2841 * incoming MADs
2878 2842 */
2879 2843 void
2880 2844 ibcm_resend_rtu_mad(ibcm_state_data_t *statep)
2881 2845 {
2882 2846 ASSERT(MUTEX_HELD(&statep->state_mutex));
2883 2847
2884 2848 IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rtu_mad statep %p ", statep);
2885 2849
2886 2850 /* don't care, if timer is running or not. Timer may be from LAP */
2887 2851
2888 2852 if (!(statep->send_mad_flags & IBCM_RTU_POST_BUSY)) {
2889 2853 statep->send_mad_flags |= IBCM_RTU_POST_BUSY;
2890 2854 IBCM_REF_CNT_INCR(statep); /* for non-blocking RTU post */
2891 2855 mutex_exit(&statep->state_mutex);
2892 2856
2893 2857 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_RTU);
2894 2858
2895 2859 ibcm_post_rc_mad(statep, statep->stored_msg,
2896 2860 ibcm_post_rtu_complete, statep);
2897 2861 mutex_enter(&statep->state_mutex);
2898 2862 }
2899 2863 /* ref cnt is decremented in ibcm_post_rtu_complete */
2900 2864 }
2901 2865
2902 2866 void
2903 2867 ibcm_resend_rej_mad(ibcm_state_data_t *statep)
2904 2868 {
2905 2869 timeout_id_t timer_val = statep->timerid;
2906 2870
2907 2871 ASSERT(MUTEX_HELD(&statep->state_mutex));
2908 2872
2909 2873 IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rej_mad statep %p ", statep);
2910 2874
2911 2875 /* It's a too fast of a REQ or REP */
2912 2876 if (timer_val == 0)
2913 2877 return;
2914 2878
2915 2879 statep->timerid = 0;
2916 2880 if (!(statep->send_mad_flags & IBCM_REJ_POST_BUSY)) {
2917 2881 statep->send_mad_flags |= IBCM_REJ_POST_BUSY;
2918 2882 IBCM_REF_CNT_INCR(statep); /* for nonblocking REJ post */
2919 2883 mutex_exit(&statep->state_mutex);
2920 2884 (void) untimeout(timer_val);
2921 2885
2922 2886 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REJ);
2923 2887 if (ibcm_enable_trace & 2)
2924 2888 ibcm_dump_conn_trace(statep);
2925 2889 else
2926 2890 IBTF_DPRINTF_L2(cmlog, "ibcm_resend_rej_mad statep %p "
2927 2891 "OUTGOING_REJ", statep);
2928 2892
2929 2893 ibcm_post_rc_mad(statep, statep->stored_msg,
2930 2894 ibcm_post_rej_complete, statep);
2931 2895 mutex_enter(&statep->state_mutex);
2932 2896 }
2933 2897 /* return, holding the state mutex */
2934 2898 }
2935 2899
2936 2900 void
2937 2901 ibcm_resend_rep_mad(ibcm_state_data_t *statep)
2938 2902 {
2939 2903 timeout_id_t timer_val = statep->timerid;
2940 2904
2941 2905 ASSERT(MUTEX_HELD(&statep->state_mutex));
2942 2906
2943 2907 IBTF_DPRINTF_L3(cmlog, "ibcm_resend_rep_mad statep %p ", statep);
2944 2908
2945 2909 /* REP timer that is set by ibcm_post_rep_mad */
2946 2910 if (timer_val != 0) {
2947 2911 /* Re-start REP timeout */
2948 2912 statep->remaining_retry_cnt = statep->max_cm_retries;
2949 2913 if (!(statep->send_mad_flags & IBCM_REP_POST_BUSY)) {
2950 2914 statep->send_mad_flags |= IBCM_REP_POST_BUSY;
2951 2915 /* for nonblocking REP post */
2952 2916 IBCM_REF_CNT_INCR(statep);
2953 2917 mutex_exit(&statep->state_mutex);
2954 2918
2955 2919 ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
2956 2920
2957 2921 ibcm_post_rc_mad(statep, statep->stored_msg,
2958 2922 ibcm_resend_post_rep_complete, statep);
2959 2923 mutex_enter(&statep->state_mutex);
2960 2924 }
2961 2925 }
2962 2926
2963 2927 /*
2964 2928 * else, timer is not yet set by ibcm_post_rep_mad. This is too fast
2965 2929 * of a REQ being re-transmitted.
2966 2930 */
2967 2931 }
2968 2932
2969 2933 void
2970 2934 ibcm_resend_mra_mad(ibcm_state_data_t *statep)
2971 2935 {
2972 2936 ASSERT(MUTEX_HELD(&statep->state_mutex));
2973 2937
2974 2938 IBTF_DPRINTF_L3(cmlog, "ibcm_resend_mra_mad statep %p ", statep);
2975 2939
2976 2940 if (statep->send_mad_flags & IBCM_MRA_POST_BUSY)
2977 2941 return;
2978 2942
2979 2943 statep->send_mad_flags |= IBCM_MRA_POST_BUSY;
2980 2944
2981 2945 statep->mra_time = gethrtime();
2982 2946 IBCM_REF_CNT_INCR(statep); /* for non-blocking MRA post */
2983 2947 /* Exit the statep mutex, before sending the MAD */
2984 2948 mutex_exit(&statep->state_mutex);
2985 2949
2986 2950 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_MRA);
2987 2951
2988 2952 /* Always resend the response MAD to the original reply destination */
2989 2953 ibcm_post_rc_mad(statep, statep->mra_msg, ibcm_post_mra_complete,
2990 2954 statep);
2991 2955
2992 2956 mutex_enter(&statep->state_mutex);
2993 2957
2994 2958 /* return, holding the state mutex */
2995 2959 }
2996 2960
2997 2961
2998 2962 /*
2999 2963 * ibcm_post_rej_mad:
3000 2964 * Posts a REJ MAD and starts timer
3001 2965 *
3002 2966 * INPUTS:
3003 2967 * statep - state pointer
3004 2968 * which_msg - which message is being MRAed
3005 2969 * reject_reason - Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
3006 2970 * addl_rej_info - Additional rej Information
3007 2971 * arej_info_len - Additional rej Info length
3008 2972 *
3009 2973 * RETURN VALUE:
3010 2974 * NONE
3011 2975 * Notes
3012 2976 * There is no need to hold the statep->mutex and call ibcm_post_rej_mad
3013 2977 * REJ can be posted either in IBCM_STATE_REQ_RCVD or IBCM_STATE_REP_RCVD
3014 2978 * In these states, there is no timer active, and an incoming REJ shall
3015 2979 * not modify the state or cancel timers
3016 2980 * An incoming REJ doesn't affect statep in state = IBCM_STATE_REJ_SENT/BUSY
3017 2981 */
3018 2982 void
↓ open down ↓ |
294 lines elided |
↑ open up ↑ |
3019 2983 ibcm_post_rej_mad(ibcm_state_data_t *statep, ibt_cm_reason_t reject_reason,
3020 2984 int which_msg, void *addl_rej_info, ibt_priv_data_len_t arej_info_len)
3021 2985 {
3022 2986 ibcm_rej_msg_t *rej_msg =
3023 2987 (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
3024 2988
3025 2989 /* Message printed if connection gets REJed */
3026 2990 IBTF_DPRINTF_L3(cmlog, "ibcm_post_rej_mad: "
3027 2991 "statep = %p, reject_reason = %d", statep, reject_reason);
3028 2992
3029 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
3030 -
3031 2993 /* Initialize rej_msg fields */
3032 2994 rej_msg->rej_local_comm_id = h2b32(statep->local_comid);
3033 2995 rej_msg->rej_remote_comm_id = h2b32(statep->remote_comid);
3034 2996 rej_msg->rej_msg_type_plus = (which_msg & 0x3) << 6;
3035 2997 rej_msg->rej_reject_info_len_plus = arej_info_len << 1;
3036 2998 rej_msg->rej_rejection_reason = h2b16((uint16_t)reject_reason);
3037 2999
3038 3000 if ((arej_info_len != 0) && (addl_rej_info != NULL))
3039 3001 bcopy(addl_rej_info, rej_msg->rej_addl_rej_info, arej_info_len);
3040 3002
3041 3003 IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
3042 3004 h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
3043 3005
3044 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
3045 -
3046 3006 mutex_enter(&statep->state_mutex);
3047 3007
3048 3008 /* signal any waiting close channels with blocking or no callbacks */
3049 3009 statep->close_done = B_TRUE;
3050 3010 statep->close_nocb_state = IBCM_FAIL;
3051 3011
3052 3012 cv_signal(&statep->block_client_cv);
3053 3013
3054 3014 statep->timer_stored_state = statep->state = IBCM_STATE_REJ_SENT;
3055 3015 statep->send_mad_flags |= IBCM_REJ_POST_BUSY;
3056 3016
3057 3017 IBCM_REF_CNT_INCR(statep); /* for non-blocking post */
3058 3018 mutex_exit(&statep->state_mutex);
3059 3019
3060 3020 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REJ);
3061 3021 if (ibcm_enable_trace & 2)
3062 3022 ibcm_dump_conn_trace(statep);
3063 3023 else
3064 3024 IBTF_DPRINTF_L2(cmlog, "ibcm_post_rej_mad statep %p "
3065 3025 "OUTGOING_REJ", statep);
3066 3026
3067 3027 ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rej_complete,
3068 3028 statep);
3069 3029 }
3070 3030
3071 3031
3072 3032 /*
3073 3033 * ibcm_build_n_post_rej_mad:
3074 3034 * Builds and posts a REJ MAD for "reject_reason"
3075 3035 * Doesn't set a timer, and doesn't need statep
3076 3036 *
3077 3037 * INPUTS:
3078 3038 * input_madp - Incoming MAD
3079 3039 * remote_comid - Local comid in the message being rejected
3080 3040 * cm_mad_addr - Address information for the MAD to be posted
3081 3041 * which_msg - REJ message type ie., REJ for REQ/REP
3082 3042 *
3083 3043 * RETURN VALUE:
3084 3044 * NONE
3085 3045 */
3086 3046 static void
3087 3047 ibcm_build_n_post_rej_mad(uint8_t *input_madp, ib_com_id_t remote_comid,
3088 3048 ibcm_mad_addr_t *cm_mad_addr, int which_msg, uint16_t reject_reason)
3089 3049 {
3090 3050 ibcm_rej_msg_t *rej_msg;
3091 3051 ibmf_msg_t *cm_rej_msg;
3092 3052 ibcm_mad_addr_t rej_reply_addr;
3093 3053
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
3094 3054 IBTF_DPRINTF_L3(cmlog, "ibcm_build_n_post_rej_mad: "
3095 3055 "remote_comid: %x reject_reason %d", remote_comid, reject_reason);
3096 3056
3097 3057 if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg,
3098 3058 MAD_METHOD_SEND) != IBT_SUCCESS) {
3099 3059 IBTF_DPRINTF_L2(cmlog, "ibcm_build_n_post_rej_mad: "
3100 3060 "ibcm_alloc_out_msg failed");
3101 3061 return;
3102 3062 }
3103 3063
3104 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
3105 -
3106 3064 IBCM_OUT_HDRP(cm_rej_msg)->TransactionID =
3107 3065 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
3108 3066
3109 3067 /* Initialize rej_msg fields */
3110 3068 rej_msg = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(cm_rej_msg);
3111 3069 rej_msg->rej_local_comm_id = 0;
3112 3070 rej_msg->rej_remote_comm_id = h2b32(remote_comid);
3113 3071 rej_msg->rej_msg_type_plus = (which_msg & 0x3) << 6;
3114 3072 rej_msg->rej_reject_info_len_plus = 0;
3115 3073 rej_msg->rej_rejection_reason = h2b16(reject_reason);
3116 3074
3117 3075 IBCM_OUT_HDRP(cm_rej_msg)->AttributeID =
3118 3076 h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
3119 3077
3120 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
3121 -
3122 3078 ibcm_build_reply_mad_addr(cm_mad_addr, &rej_reply_addr);
3123 3079
3124 3080 if (rej_reply_addr.cm_qp_entry != NULL) {
3125 3081 (void) ibcm_post_mad(cm_rej_msg, &rej_reply_addr, NULL, NULL);
3126 3082 ibcm_release_qp(rej_reply_addr.cm_qp_entry);
3127 3083 }
3128 3084
3129 3085 (void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg);
3130 3086 }
3131 3087
3132 3088 /* posts a REJ for an incoming REQ with unsupported class version */
3133 3089
3134 3090 static void
3135 3091 ibcm_post_rej_ver_mismatch(uint8_t *input_madp, ibcm_mad_addr_t *cm_mad_addr)
3136 3092 {
3137 3093 ibcm_req_msg_t *req_msgp =
3138 3094 (ibcm_req_msg_t *)&input_madp[IBCM_MAD_HDR_SIZE];
3139 3095 ibcm_rej_msg_t *rej_msg;
3140 3096 ibmf_msg_t *cm_rej_msg;
3141 3097 ibcm_mad_addr_t rej_reply_addr;
3142 3098
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
3143 3099 IBTF_DPRINTF_L3(cmlog, "ibcm_post_rej_ver_mismatch: remote comid %x",
3144 3100 b2h32(req_msgp->req_local_comm_id));
3145 3101
3146 3102 if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg,
3147 3103 MAD_METHOD_SEND) != IBT_SUCCESS) {
3148 3104 IBTF_DPRINTF_L2(cmlog, "ibcm_post_rej_ver_mismatch: "
3149 3105 "ibcm_alloc_out_msg failed");
3150 3106 return;
3151 3107 }
3152 3108
3153 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msg))
3154 -
3155 3109 IBCM_OUT_HDRP(cm_rej_msg)->TransactionID =
3156 3110 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
3157 3111
3158 3112 /* Initialize rej_msg fields */
3159 3113 rej_msg = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(cm_rej_msg);
3160 3114 rej_msg->rej_local_comm_id = 0;
3161 3115 rej_msg->rej_remote_comm_id = req_msgp->req_local_comm_id;
3162 3116 rej_msg->rej_msg_type_plus = IBT_CM_FAILURE_REQ << 6;
3163 3117 rej_msg->rej_rejection_reason = h2b16(IBT_CM_CLASS_NO_SUPPORT);
3164 3118 rej_msg->rej_reject_info_len_plus = 1 << 1;
3165 3119 rej_msg->rej_addl_rej_info[0] = IBCM_MAD_CLASS_VERSION;
3166 3120
3167 3121 IBCM_OUT_HDRP(cm_rej_msg)->AttributeID =
3168 3122 h2b16(IBCM_INCOMING_REJ + IBCM_ATTR_BASE_ID);
3169 3123 IBCM_OUT_HDRP(cm_rej_msg)->Status = h2b16(MAD_STATUS_BAD_VERSION);
3170 3124
3171 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msg))
3172 -
3173 3125 ibcm_build_reply_mad_addr(cm_mad_addr, &rej_reply_addr);
3174 3126 if (rej_reply_addr.cm_qp_entry != NULL) {
3175 3127 (void) ibcm_post_mad(cm_rej_msg, &rej_reply_addr, NULL, NULL);
3176 3128 ibcm_release_qp(rej_reply_addr.cm_qp_entry);
3177 3129 }
3178 3130 (void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &cm_rej_msg);
3179 3131 }
3180 3132
3181 3133
3182 3134 /*
3183 3135 * ibcm_post_rep_mad:
3184 3136 * Posts a REP MAD and starts timer
3185 3137 *
3186 3138 * INPUTS:
3187 3139 * statep - state pointer
3188 3140 *
3189 3141 * RETURN VALUE:
3190 3142 * NONE
3191 3143 */
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
3192 3144 void
3193 3145 ibcm_post_rep_mad(ibcm_state_data_t *statep)
3194 3146 {
3195 3147 ibcm_rep_msg_t *rep_msgp =
3196 3148 (ibcm_rep_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
3197 3149 ibmf_msg_t *mra_msg = NULL;
3198 3150 boolean_t ret = B_FALSE;
3199 3151
3200 3152 IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_mad: statep 0x%p", statep);
3201 3153
3202 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rep_msgp))
3203 -
3204 3154 /*
3205 3155 * All other REP fields, other that the 2 below, are filled in
3206 3156 * the ibcm_cep_state_req() function.
3207 3157 */
3208 3158 rep_msgp->rep_local_comm_id = h2b32(statep->local_comid);
3209 3159 rep_msgp->rep_remote_comm_id = h2b32(statep->remote_comid);
3210 3160 IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
3211 3161 h2b16(IBCM_INCOMING_REP + IBCM_ATTR_BASE_ID);
3212 3162
3213 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rep_msgp))
3214 -
3215 3163 /*
3216 3164 * Changing state and attempt to delete the mra msg must be done
3217 3165 * together holding the state_mutex
3218 3166 */
3219 3167 mutex_enter(&statep->state_mutex);
3220 3168
3221 3169 /* Now, attempt to delete the mra_msg, if there is one allocated */
3222 3170 if (statep->mra_msg != NULL) {
3223 3171 if (!(statep->send_mad_flags & IBCM_MRA_POST_BUSY)) {
3224 3172 mra_msg = statep->mra_msg;
3225 3173 statep->mra_msg = NULL;
3226 3174 } else statep->delete_mra_msg = B_TRUE;
3227 3175 }
3228 3176
3229 3177 if (statep->abort_flag == IBCM_ABORT_CLIENT) {
3230 3178 statep->state = IBCM_STATE_ABORTED;
3231 3179 mutex_exit(&statep->state_mutex);
3232 3180 ibcm_process_abort(statep);
3233 3181
3234 3182 /* Now post a REJ MAD, rej reason consumer abort */
3235 3183 ibcm_post_rej_mad(statep, IBT_CM_CONSUMER, IBT_CM_FAILURE_REQ,
3236 3184 NULL, 0);
3237 3185 ret = B_TRUE;
3238 3186 } else if (statep->abort_flag & IBCM_ABORT_REJ) {
3239 3187
3240 3188 statep->state = IBCM_STATE_DELETE;
3241 3189 mutex_exit(&statep->state_mutex);
3242 3190
3243 3191 ibcm_process_abort(statep);
3244 3192 ibcm_delete_state_data(statep);
3245 3193 ret = B_TRUE;
3246 3194 } else {
3247 3195
3248 3196 statep->state = statep->timer_stored_state =
3249 3197 IBCM_STATE_REP_SENT;
3250 3198 statep->remaining_retry_cnt = statep->max_cm_retries;
3251 3199 statep->send_mad_flags |= IBCM_REP_POST_BUSY;
3252 3200 IBCM_REF_CNT_INCR(statep); /* for nonblocking REP Post */
3253 3201 mutex_exit(&statep->state_mutex);
3254 3202 }
3255 3203
3256 3204 if (mra_msg != NULL)
3257 3205 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
3258 3206 &mra_msg);
3259 3207 if (ret == B_TRUE)
3260 3208 return;
3261 3209
3262 3210 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_REP);
3263 3211
3264 3212 ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rep_complete,
3265 3213 statep);
3266 3214 }
3267 3215
3268 3216
3269 3217 /*
3270 3218 * ibcm_post_rtu_mad:
3271 3219 * From active side post RTU MAD
3272 3220 *
3273 3221 * INPUTS:
3274 3222 * statep - state pointer
3275 3223 *
3276 3224 * RETURN VALUE: NONE
3277 3225 *
3278 3226 * NOTE: No timer set after posting RTU
↓ open down ↓ |
54 lines elided |
↑ open up ↑ |
3279 3227 */
3280 3228 ibcm_status_t
3281 3229 ibcm_post_rtu_mad(ibcm_state_data_t *statep)
3282 3230 {
3283 3231 ibcm_rtu_msg_t *rtu_msg;
3284 3232 ibmf_msg_t *mra_msg = NULL;
3285 3233 boolean_t ret = B_FALSE;
3286 3234
3287 3235 IBTF_DPRINTF_L4(cmlog, "ibcm_post_rtu_mad: statep 0x%p", statep);
3288 3236
3289 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rtu_msg))
3290 -
3291 3237 rtu_msg = (ibcm_rtu_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
3292 3238
3293 3239 rtu_msg->rtu_local_comm_id = h2b32(statep->local_comid);
3294 3240 rtu_msg->rtu_remote_comm_id = h2b32(statep->remote_comid);
3295 3241 IBCM_OUT_HDRP(statep->stored_msg)->AttributeID =
3296 3242 h2b16(IBCM_INCOMING_RTU + IBCM_ATTR_BASE_ID);
3297 3243
3298 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rtu_msg))
3299 -
3300 3244 mutex_enter(&statep->state_mutex);
3301 3245
3302 3246 /* Now, attempt to delete the mra_msg, if there is one allocated */
3303 3247 if (statep->mra_msg != NULL) {
3304 3248 if (!(statep->send_mad_flags & IBCM_MRA_POST_BUSY)) {
3305 3249 mra_msg = statep->mra_msg;
3306 3250 statep->mra_msg = NULL;
3307 3251 } else statep->delete_mra_msg = B_TRUE;
3308 3252 }
3309 3253
3310 3254 if (statep->abort_flag == IBCM_ABORT_CLIENT) {
3311 3255 statep->state = IBCM_STATE_ABORTED;
3312 3256 mutex_exit(&statep->state_mutex);
3313 3257
3314 3258 ibcm_process_abort(statep);
3315 3259
3316 3260 /* Now post a REJ MAD */
3317 3261 ibcm_post_rej_mad(statep, IBT_CM_CONSUMER, IBT_CM_FAILURE_REP,
3318 3262 NULL, 0);
3319 3263 ret = B_TRUE;
3320 3264 } else if (statep->abort_flag & IBCM_ABORT_REJ) {
3321 3265 statep->state = IBCM_STATE_DELETE;
3322 3266 mutex_exit(&statep->state_mutex);
3323 3267
3324 3268 ibcm_process_abort(statep);
3325 3269 ibcm_delete_state_data(statep);
3326 3270 ret = B_TRUE;
3327 3271 } else {
3328 3272 statep->state = IBCM_STATE_ESTABLISHED;
3329 3273 ibtl_cm_chan_is_open(statep->channel);
3330 3274 statep->send_mad_flags |= IBCM_RTU_POST_BUSY;
3331 3275 IBCM_REF_CNT_INCR(statep); /* for nonblocking RTU post */
3332 3276 mutex_exit(&statep->state_mutex);
3333 3277 }
3334 3278
3335 3279 if (mra_msg != NULL)
3336 3280 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
3337 3281 &mra_msg);
3338 3282
3339 3283 if (ret == B_TRUE) /* Abort case, no RTU posted */
3340 3284 return (IBCM_FAILURE);
3341 3285
3342 3286 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_RTU);
3343 3287
3344 3288 ibcm_post_rc_mad(statep, statep->stored_msg, ibcm_post_rtu_complete,
3345 3289 statep);
3346 3290 return (IBCM_SUCCESS);
3347 3291 }
3348 3292
3349 3293
3350 3294 /*
3351 3295 * ibcm_process_abort:
3352 3296 * Processes abort, if client requested abort connection attempt
3353 3297 *
3354 3298 * INPUTS:
3355 3299 * statep - pointer to ibcm_state_data_t is passed
3356 3300 *
3357 3301 * RETURN VALUES: None
3358 3302 */
3359 3303 void
3360 3304 ibcm_process_abort(ibcm_state_data_t *statep)
3361 3305 {
3362 3306 IBTF_DPRINTF_L3(cmlog, "ibcm_process_abort: statep 0x%p", statep);
3363 3307
3364 3308 /* move CEP to error state, before calling client handler */
3365 3309 (void) ibcm_cep_to_error_state(statep);
3366 3310
3367 3311 /* Now disassociate the link between statep and qp */
3368 3312 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
3369 3313
3370 3314 /* invoke cm handler, for non-blocking open/close rc channel calls */
3371 3315 if (statep->cm_handler) { /* cannot be NULL, but still .. */
3372 3316 ibt_cm_event_t event;
3373 3317 ibt_cm_return_args_t ret_args;
3374 3318
3375 3319 bzero(&event, sizeof (event));
3376 3320 bzero(&ret_args, sizeof (ret_args));
3377 3321
3378 3322 if (statep->abort_flag & IBCM_ABORT_REJ)
3379 3323 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_RCV,
3380 3324 IBT_CM_FAILURE_UNKNOWN, IBT_CM_TIMEOUT, NULL, 0);
3381 3325 else {
3382 3326 ibcm_path_cache_purge();
3383 3327
3384 3328 event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
3385 3329 event.cm_channel = statep->channel;
3386 3330 event.cm_event.closed = IBT_CM_CLOSED_ABORT;
3387 3331
3388 3332 ibcm_insert_trace(statep,
3389 3333 IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
3390 3334
3391 3335 if (statep->channel)
3392 3336 ibtl_cm_chan_open_is_aborted(statep->channel);
3393 3337
3394 3338 (void) statep->cm_handler(statep->state_cm_private,
3395 3339 &event, &ret_args, NULL, 0);
3396 3340
3397 3341 ibcm_insert_trace(statep,
3398 3342 IBCM_TRACE_RET_CONN_CLOSE_EVENT);
3399 3343
3400 3344 mutex_enter(&statep->state_mutex);
3401 3345 ibcm_open_done(statep);
3402 3346 mutex_exit(&statep->state_mutex);
3403 3347 }
3404 3348 }
3405 3349
3406 3350 /*
3407 3351 * Unblock an ibt_open_rc_channel called in a blocking mode, though
3408 3352 * it is an unlikely scenario
3409 3353 */
3410 3354 mutex_enter(&statep->state_mutex);
3411 3355
3412 3356 statep->cm_retries++; /* cause connection trace to be printed */
3413 3357 statep->open_done = B_TRUE;
3414 3358 statep->close_done = B_TRUE;
3415 3359 statep->close_nocb_state = IBCM_FAIL; /* sanity sake */
3416 3360
3417 3361 if (statep->open_return_data != NULL) {
3418 3362 /* REJ came first, and then client aborted connection */
3419 3363 if (statep->abort_flag & IBCM_ABORT_REJ)
3420 3364 statep->open_return_data->rc_status = IBT_CM_TIMEOUT;
3421 3365 else statep->open_return_data->rc_status = IBT_CM_ABORT;
3422 3366 }
3423 3367
3424 3368 cv_broadcast(&statep->block_client_cv);
3425 3369 mutex_exit(&statep->state_mutex);
3426 3370 if (ibcm_enable_trace != 0)
3427 3371 ibcm_dump_conn_trace(statep);
3428 3372 }
3429 3373
3430 3374 /*
3431 3375 * ibcm_timeout_cb:
3432 3376 * Called when the timer expires
3433 3377 *
3434 3378 * INPUTS:
3435 3379 * arg - ibcm_state_data_t is passed
3436 3380 *
3437 3381 * RETURN VALUES: NONE
3438 3382 */
3439 3383 void
3440 3384 ibcm_timeout_cb(void *arg)
3441 3385 {
3442 3386 ibcm_state_data_t *statep = (ibcm_state_data_t *)arg;
3443 3387
3444 3388 mutex_enter(&statep->state_mutex);
3445 3389
3446 3390 /*
3447 3391 * The blocking operations are handled in a separate thread.
3448 3392 * All other non-blocking operations, including ibmf non-blocking
3449 3393 * posts are done from timeout context
3450 3394 */
3451 3395
3452 3396 if ((statep->timer_stored_state != statep->state) ||
3453 3397 ((statep->timer_stored_state == IBCM_STATE_ESTABLISHED) &&
3454 3398 (statep->ap_state != statep->timer_stored_ap_state))) {
3455 3399 mutex_exit(&statep->state_mutex);
3456 3400 return;
3457 3401 }
3458 3402
3459 3403 IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: statep 0x%p state %x "
3460 3404 "ap_state %x", statep, statep->state, statep->ap_state);
3461 3405
3462 3406 /* Processing depends upon current state */
3463 3407
3464 3408 if (statep->state == IBCM_STATE_REJ_SENT) {
3465 3409 statep->state = IBCM_STATE_DELETE;
3466 3410 mutex_exit(&statep->state_mutex);
3467 3411
3468 3412 /* Deallocate the CM state structure */
3469 3413 ibcm_delete_state_data(statep);
3470 3414 return;
3471 3415
3472 3416 } else if (statep->state == IBCM_STATE_TIMEWAIT) {
3473 3417 statep->state = IBCM_STATE_DELETE;
3474 3418
3475 3419 /* TIME_WAIT timer expired, so cleanup */
↓ open down ↓ |
166 lines elided |
↑ open up ↑ |
3476 3420 mutex_exit(&statep->state_mutex);
3477 3421
3478 3422 if (statep->channel)
3479 3423 ibtl_cm_chan_is_closed(statep->channel);
3480 3424
3481 3425 if (statep->recycle_arg) {
3482 3426 struct ibcm_taskq_recycle_arg_s *recycle_arg;
3483 3427
3484 3428 recycle_arg = statep->recycle_arg;
3485 3429
3486 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
3487 - statep->recycle_arg))
3488 3430 statep->recycle_arg = NULL;
3489 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
3490 3431
3491 3432 /* if possible, do not slow down calling recycle func */
3492 3433 if (taskq_dispatch(ibcm_taskq, ibcm_process_rc_recycle,
3493 3434 recycle_arg, TQ_NOQUEUE | TQ_NOSLEEP) == 0) {
3494 -
3495 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(
3496 - statep->recycle_arg))
3497 3435 statep->recycle_arg = recycle_arg;
3498 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(
3499 - statep->recycle_arg))
3500 3436 ibcm_add_tlist(statep);
3501 3437 return;
3502 3438 }
3503 3439 }
3504 3440
3505 3441 ibcm_delete_state_data(statep);
3506 3442 return;
3507 3443 } else if (statep->remaining_retry_cnt > 0) {
3508 3444 ibcm_conn_state_t stored_state;
3509 3445 ibcm_ap_state_t stored_ap_state;
3510 3446
3511 3447 statep->remaining_retry_cnt--;
3512 3448 IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: statep 0x%p "
3513 3449 "attr-id= 0x%x, retries remaining = 0x%x", statep,
3514 3450 b2h16(IBCM_OUT_HDRP(statep->stored_msg)->AttributeID),
3515 3451 statep->remaining_retry_cnt);
3516 3452
3517 3453 /*
3518 3454 * REP could be resent, either because of timeout or an
3519 3455 * incoming REQ. Any other MAD below can be resent, because
3520 3456 * of timeout only, hence send_mad_flag manipulation not
3521 3457 * required for those cases.
3522 3458 * If REP is already being retransmitted, then just set the
3523 3459 * timer and return. Else post REP in non-blocking mode
3524 3460 */
3525 3461 if (statep->timer_stored_state == IBCM_STATE_REP_SENT) {
3526 3462 if (statep->send_mad_flags & IBCM_REP_POST_BUSY) {
3527 3463 statep->timerid = IBCM_TIMEOUT(statep,
3528 3464 statep->timer_value);
3529 3465 mutex_exit(&statep->state_mutex);
3530 3466 ibcm_insert_trace(statep,
3531 3467 IBCM_TRACE_TIMEOUT_REP);
3532 3468 return;
3533 3469 }
3534 3470
3535 3471 /*
3536 3472 * Set REP busy flag, so any incoming REQ's will not
3537 3473 * initiate new REP transmissions
3538 3474 */
3539 3475 statep->send_mad_flags |= IBCM_REP_POST_BUSY;
3540 3476
3541 3477 /* Since REQ/RTU/REJ on active side use same MAD, synchronize */
3542 3478 } else if (statep->timer_stored_state == IBCM_STATE_REQ_SENT) {
3543 3479 ASSERT((statep->send_mad_flags & IBCM_REQ_POST_BUSY)
3544 3480 == 0);
3545 3481 statep->send_mad_flags |= IBCM_REQ_POST_BUSY;
3546 3482 }
3547 3483
3548 3484 IBCM_REF_CNT_INCR(statep); /* for non-blocking post */
3549 3485 stored_state = statep->timer_stored_state;
3550 3486 stored_ap_state = statep->timer_stored_ap_state;
3551 3487 mutex_exit(&statep->state_mutex);
3552 3488
3553 3489 /* Post REQ MAD in non-blocking mode */
3554 3490 if (stored_state == IBCM_STATE_REQ_SENT) {
3555 3491 ibcm_insert_trace(statep, IBCM_TRACE_OUT_REQ_RETRY);
3556 3492 ibcm_post_rc_mad(statep, statep->stored_msg,
3557 3493 ibcm_post_req_complete, statep);
3558 3494 /* Post REQ MAD in non-blocking mode */
3559 3495 } else if (stored_state == IBCM_STATE_REP_WAIT) {
3560 3496 ibcm_insert_trace(statep, IBCM_TRACE_OUT_REQ_RETRY);
3561 3497 ibcm_post_rc_mad(statep, statep->stored_msg,
3562 3498 ibcm_post_rep_wait_complete, statep);
3563 3499 /* Post REP MAD in non-blocking mode */
3564 3500 } else if (stored_state == IBCM_STATE_REP_SENT) {
3565 3501 ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
3566 3502 ibcm_post_rc_mad(statep, statep->stored_msg,
3567 3503 ibcm_post_rep_complete, statep);
3568 3504 /* Post REP MAD in non-blocking mode */
3569 3505 } else if (stored_state == IBCM_STATE_MRA_REP_RCVD) {
3570 3506 ibcm_insert_trace(statep, IBCM_TRACE_OUT_REP_RETRY);
3571 3507 mutex_enter(&statep->state_mutex);
3572 3508 statep->mra_time = gethrtime();
3573 3509 mutex_exit(&statep->state_mutex);
3574 3510 ibcm_post_rc_mad(statep, statep->stored_msg,
3575 3511 ibcm_post_mra_rep_complete, statep);
3576 3512 /* Post DREQ MAD in non-blocking mode */
3577 3513 } else if (stored_state == IBCM_STATE_DREQ_SENT) {
3578 3514 mutex_enter(&statep->state_mutex);
3579 3515 if (statep->remaining_retry_cnt ==
3580 3516 statep->max_cm_retries)
3581 3517 ibcm_insert_trace(statep,
3582 3518 IBCM_TRACE_OUTGOING_DREQ);
3583 3519 else {
3584 3520 ibcm_insert_trace(statep,
3585 3521 IBCM_TRACE_OUT_DREQ_RETRY);
3586 3522 statep->cm_retries++;
3587 3523 ibcm_close_done(statep, 0);
3588 3524 }
3589 3525 mutex_exit(&statep->state_mutex);
3590 3526 ibcm_post_rc_mad(statep, statep->dreq_msg,
3591 3527 ibcm_post_dreq_complete, statep);
3592 3528 /* post LAP MAD in non-blocking mode */
3593 3529 } else if (stored_ap_state == IBCM_AP_STATE_LAP_SENT) {
3594 3530 ibcm_insert_trace(statep, IBCM_TRACE_OUT_LAP_RETRY);
3595 3531 ibcm_post_rc_mad(statep, statep->lapr_msg,
3596 3532 ibcm_post_lap_complete, statep);
3597 3533 /* post LAP MAD in non-blocking mode */
3598 3534 } else if (stored_ap_state == IBCM_AP_STATE_MRA_LAP_RCVD) {
3599 3535 ibcm_insert_trace(statep, IBCM_TRACE_OUT_LAP_RETRY);
3600 3536 mutex_enter(&statep->state_mutex);
3601 3537 statep->mra_time = gethrtime();
3602 3538 mutex_exit(&statep->state_mutex);
3603 3539 ibcm_post_rc_mad(statep, statep->lapr_msg,
3604 3540 ibcm_post_mra_lap_complete, statep);
3605 3541 }
3606 3542 return;
3607 3543
3608 3544 } else if ((statep->state == IBCM_STATE_REQ_SENT) ||
3609 3545 (statep->state == IBCM_STATE_REP_SENT) ||
3610 3546 (statep->state == IBCM_STATE_MRA_REP_RCVD) ||
3611 3547 (statep->state == IBCM_STATE_REP_WAIT)) {
3612 3548
3613 3549 /*
3614 3550 * MAX retries reached, send a REJ to the remote,
3615 3551 * and close the connection
3616 3552 */
3617 3553 statep->timedout_state = statep->state;
3618 3554 statep->state = IBCM_STATE_TIMED_OUT;
3619 3555
3620 3556 IBTF_DPRINTF_L3(cmlog, "ibcm_timeout_cb: "
3621 3557 "max retries done for statep 0x%p", statep);
3622 3558 statep->cm_retries++; /* cause conn trace to print */
3623 3559 mutex_exit(&statep->state_mutex);
3624 3560
3625 3561 if ((statep->timedout_state == IBCM_STATE_REP_SENT) ||
3626 3562 (statep->timedout_state == IBCM_STATE_MRA_REP_RCVD))
3627 3563 (void) ibcm_cep_to_error_state(statep);
3628 3564
3629 3565 /* Disassociate statep from QP */
3630 3566 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
3631 3567
3632 3568 /*
3633 3569 * statep is in REJ SENT state, the only way to get deleted is
3634 3570 * the timeout callback that is set after posting REJ
3635 3571 * The thread processing is required where cm handler is
3636 3572 * specified
3637 3573 */
3638 3574
3639 3575 if (statep->cm_handler != NULL) {
3640 3576 /* Attach the statep to timeout list */
3641 3577 ibcm_add_tlist(statep);
3642 3578 } else {
3643 3579 ib_guid_t local_hca_guid;
3644 3580
3645 3581 mutex_enter(&statep->state_mutex);
3646 3582
3647 3583 /*
3648 3584 * statep->open_return_data is set for blocking
3649 3585 * No handler specified, hence signal blocked
3650 3586 * ibt_open_rc_channel from here
3651 3587 */
3652 3588 if (statep->open_return_data != NULL) {
3653 3589 statep->open_return_data->rc_status =
3654 3590 IBT_CM_TIMEOUT;
3655 3591 statep->open_done = B_TRUE;
3656 3592 cv_broadcast(&statep->block_client_cv);
3657 3593 }
3658 3594
3659 3595 mutex_exit(&statep->state_mutex);
3660 3596
3661 3597 local_hca_guid = h2b64(statep->local_hca_guid);
3662 3598 ibcm_post_rej_mad(statep, IBT_CM_TIMEOUT,
3663 3599 (statep->timedout_state == IBCM_STATE_REP_SENT ||
3664 3600 statep->timedout_state == IBCM_STATE_MRA_REP_RCVD) ?
3665 3601 IBT_CM_FAILURE_REP: IBT_CM_FAILURE_REQ,
3666 3602 &local_hca_guid, sizeof (ib_guid_t));
3667 3603 }
3668 3604
3669 3605 } else if ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
3670 3606 (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
3671 3607
3672 3608 IBTF_DPRINTF_L4(cmlog, "ibcm_timeout_cb: statep 0x%p "
3673 3609 "LAP timed out", statep);
3674 3610 statep->timedout_state = statep->state;
3675 3611 /*
3676 3612 * This state setting ensures that the processing of DREQ is
3677 3613 * sequentialized, once this ap_state is set. If statep is
3678 3614 * attached to timeout list, it cannot be re-attached as long
3679 3615 * as in this state
3680 3616 */
3681 3617 statep->ap_state = IBCM_AP_STATE_TIMED_OUT;
3682 3618 ibcm_open_done(statep);
3683 3619
3684 3620 if (statep->cm_handler != NULL) {
3685 3621 /* Attach statep to timeout list - thread handling */
3686 3622 ibcm_add_tlist(statep);
3687 3623 } else if (statep->ap_return_data != NULL) {
3688 3624 /*
3689 3625 * statep->ap_return_data is initialized for blocking in
3690 3626 * ibt_set_alt_path(), signal the waiting CV
3691 3627 */
3692 3628 statep->ap_return_data->ap_status = IBT_CM_AP_TIMEOUT;
3693 3629 statep->ap_done = B_TRUE;
3694 3630 cv_broadcast(&statep->block_client_cv);
3695 3631
3696 3632 statep->ap_state = IBCM_AP_STATE_IDLE;
3697 3633 /* Wake up threads waiting for LAP/APR to complete */
3698 3634 cv_broadcast(&statep->block_mad_cv);
3699 3635 }
3700 3636 mutex_exit(&statep->state_mutex);
3701 3637
3702 3638 } else if (statep->state == IBCM_STATE_DREQ_SENT) {
3703 3639
3704 3640 statep->timedout_state = statep->state;
3705 3641 statep->state = IBCM_STATE_TIMED_OUT;
3706 3642
3707 3643 /*
3708 3644 * The logic below is necessary, for a race situation between
3709 3645 * ibt_close_rc_channel with no callbacks option and CM's
3710 3646 * internal stale connection handling on the same connection
3711 3647 */
3712 3648 if (statep->close_nocb_state != IBCM_FAIL) {
3713 3649 ASSERT(statep->close_nocb_state == IBCM_UNBLOCK);
3714 3650 ibtl_cm_chan_is_closing(statep->channel);
3715 3651 statep->close_nocb_state = IBCM_BLOCK;
3716 3652 }
3717 3653
3718 3654 mutex_exit(&statep->state_mutex);
3719 3655
3720 3656 /*
3721 3657 * If cm handler is specified, then invoke handler for
3722 3658 * the DREQ timeout
3723 3659 */
3724 3660 if (statep->cm_handler != NULL) {
3725 3661 ibcm_add_tlist(statep);
3726 3662 return;
3727 3663 }
3728 3664
3729 3665 ibcm_process_dreq_timeout(statep);
3730 3666 } else {
3731 3667
3732 3668 #ifdef DEBUG
3733 3669 if (ibcm_test_mode > 0)
3734 3670 IBTF_DPRINTF_L2(cmlog, "ibcm_timeout_cb: "
3735 3671 "Unexpected unhandled timeout for statep 0x%p "
3736 3672 "state %d", statep, statep->state);
3737 3673 #endif
3738 3674 mutex_exit(&statep->state_mutex);
3739 3675 }
3740 3676 }
3741 3677
3742 3678 /*
3743 3679 * Following are set of ibmf send callback routines that are used when posting
3744 3680 * various CM MADs in non-blocking post mode
3745 3681 */
3746 3682
3747 3683 /*ARGSUSED*/
3748 3684 void
3749 3685 ibcm_post_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
3750 3686 {
3751 3687 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3752 3688
3753 3689 IBTF_DPRINTF_L4(cmlog, "ibcm_post_req_complete statep %p ", statep);
3754 3690
3755 3691 mutex_enter(&statep->state_mutex);
3756 3692 ibcm_flow_dec(statep->post_time, "REQ");
3757 3693 ibcm_insert_trace(statep, IBCM_TRACE_REQ_POST_COMPLETE);
3758 3694
3759 3695 statep->send_mad_flags &= ~IBCM_REQ_POST_BUSY;
3760 3696
3761 3697 /* signal any waiting threads for REQ MAD to become available */
3762 3698 cv_signal(&statep->block_mad_cv);
3763 3699
3764 3700 if (statep->state == IBCM_STATE_REQ_SENT)
3765 3701 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3766 3702
3767 3703 IBCM_REF_CNT_DECR(statep);
3768 3704 mutex_exit(&statep->state_mutex);
3769 3705 }
3770 3706
3771 3707 /*ARGSUSED*/
3772 3708 void
3773 3709 ibcm_post_rep_wait_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3774 3710 void *args)
3775 3711 {
3776 3712 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3777 3713
3778 3714 IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_wait_complete statep %p", statep);
3779 3715
3780 3716 mutex_enter(&statep->state_mutex);
3781 3717 ibcm_flow_dec(statep->post_time, "REQ_RETRY");
3782 3718 ibcm_insert_trace(statep, IBCM_TRACE_REQ_POST_COMPLETE);
3783 3719 if (statep->state == IBCM_STATE_REP_WAIT)
3784 3720 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3785 3721 IBCM_REF_CNT_DECR(statep);
3786 3722 mutex_exit(&statep->state_mutex);
3787 3723 }
3788 3724
3789 3725 /*ARGSUSED*/
3790 3726 void
3791 3727 ibcm_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
3792 3728 {
3793 3729 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3794 3730
3795 3731 IBTF_DPRINTF_L4(cmlog, "ibcm_post_rep_complete statep %p", statep);
3796 3732
3797 3733 mutex_enter(&statep->state_mutex);
3798 3734 ibcm_flow_dec(statep->post_time, "REP");
3799 3735 ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
3800 3736 statep->send_mad_flags &= ~IBCM_REP_POST_BUSY;
3801 3737 if (statep->state == IBCM_STATE_REP_SENT)
3802 3738 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3803 3739 IBCM_REF_CNT_DECR(statep);
3804 3740 mutex_exit(&statep->state_mutex);
3805 3741 }
3806 3742
3807 3743 /*ARGSUSED*/
3808 3744 void
3809 3745 ibcm_resend_post_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3810 3746 void *args)
3811 3747 {
3812 3748 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3813 3749
3814 3750 IBTF_DPRINTF_L4(cmlog, "ibcm_resend_post_rep_complete(%p)", statep);
3815 3751
3816 3752 mutex_enter(&statep->state_mutex);
3817 3753 ibcm_flow_dec(statep->post_time, "REP_RETRY");
3818 3754 ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
3819 3755 statep->send_mad_flags &= ~IBCM_REP_POST_BUSY;
3820 3756
3821 3757 /* No new timeout is set for resending a REP MAD for an incoming REQ */
3822 3758 IBCM_REF_CNT_DECR(statep);
3823 3759 mutex_exit(&statep->state_mutex);
3824 3760 }
3825 3761
3826 3762 /*ARGSUSED*/
3827 3763 void
3828 3764 ibcm_post_mra_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3829 3765 void *args)
3830 3766 {
3831 3767 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3832 3768
3833 3769 IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_rep_complete statep %p", statep);
3834 3770
3835 3771 mutex_enter(&statep->state_mutex);
3836 3772 ibcm_flow_dec(statep->mra_time, "MRA_REP");
3837 3773 ibcm_insert_trace(statep, IBCM_TRACE_REP_POST_COMPLETE);
3838 3774 if (statep->state == IBCM_STATE_MRA_REP_RCVD)
3839 3775 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3840 3776 IBCM_REF_CNT_DECR(statep);
3841 3777 mutex_exit(&statep->state_mutex);
3842 3778 }
3843 3779
3844 3780
3845 3781 /*ARGSUSED*/
3846 3782 void
3847 3783 ibcm_post_mra_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3848 3784 void *args)
3849 3785 {
3850 3786 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3851 3787
3852 3788 IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_complete statep %p", statep);
3853 3789
3854 3790 mutex_enter(&statep->state_mutex);
3855 3791 ibcm_flow_dec(statep->mra_time, "MRA");
3856 3792 ibcm_insert_trace(statep, IBCM_TRACE_MRA_POST_COMPLETE);
3857 3793
3858 3794 if (statep->delete_mra_msg == B_TRUE) {
3859 3795 ibmf_msg_t *mra_msg;
3860 3796
3861 3797 mra_msg = statep->mra_msg;
3862 3798 statep->mra_msg = NULL;
3863 3799 mutex_exit(&statep->state_mutex);
3864 3800 (void) ibcm_free_out_msg(statep->stored_reply_addr.ibmf_hdl,
3865 3801 &mra_msg);
3866 3802 mutex_enter(&statep->state_mutex);
3867 3803 }
3868 3804 statep->send_mad_flags &= ~IBCM_MRA_POST_BUSY;
3869 3805 IBCM_REF_CNT_DECR(statep);
3870 3806 mutex_exit(&statep->state_mutex);
3871 3807 }
3872 3808
3873 3809 /*ARGSUSED*/
3874 3810 void
3875 3811 ibcm_post_dreq_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
3876 3812 {
3877 3813 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3878 3814
3879 3815 IBTF_DPRINTF_L4(cmlog, "ibcm_post_dreq_complete statep %p", statep);
3880 3816
3881 3817 mutex_enter(&statep->state_mutex);
3882 3818 ibcm_flow_dec(statep->post_time, "DREQ");
3883 3819 ibcm_insert_trace(statep, IBCM_TRACE_DREQ_POST_COMPLETE);
3884 3820 if (statep->state == IBCM_STATE_DREQ_SENT)
3885 3821 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3886 3822 ibcm_close_done(statep, 1);
3887 3823 IBCM_REF_CNT_DECR(statep);
3888 3824 mutex_exit(&statep->state_mutex);
3889 3825 }
3890 3826
3891 3827 /*ARGSUSED*/
3892 3828 void
3893 3829 ibcm_post_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp, void *args)
3894 3830 {
3895 3831 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3896 3832
3897 3833 IBTF_DPRINTF_L4(cmlog, "ibcm_post_lap_complete statep %p", statep);
3898 3834
3899 3835 mutex_enter(&statep->state_mutex);
3900 3836 ibcm_flow_dec(statep->post_time, "LAP");
3901 3837 ibcm_insert_trace(statep, IBCM_TRACE_LAP_POST_COMPLETE);
3902 3838 if (statep->ap_state == IBCM_AP_STATE_LAP_SENT)
3903 3839 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3904 3840 IBCM_REF_CNT_DECR(statep);
3905 3841 mutex_exit(&statep->state_mutex);
3906 3842 }
3907 3843
3908 3844 /*ARGSUSED*/
3909 3845 void
3910 3846 ibcm_post_mra_lap_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3911 3847 void *args)
3912 3848 {
3913 3849 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3914 3850
3915 3851 IBTF_DPRINTF_L4(cmlog, "ibcm_post_mra_lap_complete statep %p", statep);
3916 3852
3917 3853 mutex_enter(&statep->state_mutex);
3918 3854 ibcm_flow_dec(statep->mra_time, "MRA_LAP");
3919 3855 ibcm_insert_trace(statep, IBCM_TRACE_LAP_POST_COMPLETE);
3920 3856 if (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)
3921 3857 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
3922 3858 IBCM_REF_CNT_DECR(statep);
3923 3859 mutex_exit(&statep->state_mutex);
3924 3860 }
3925 3861
3926 3862 /*ARGSUSED*/
3927 3863 void
3928 3864 ibcm_post_rej_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3929 3865 void *args)
3930 3866 {
3931 3867 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3932 3868
3933 3869 IBTF_DPRINTF_L4(cmlog, "ibcm_post_rej_complete statep %p", statep);
3934 3870
3935 3871 mutex_enter(&statep->state_mutex);
3936 3872 ibcm_flow_dec(statep->post_time, "REJ");
3937 3873 ibcm_insert_trace(statep, IBCM_TRACE_REJ_POST_COMPLETE);
3938 3874 statep->send_mad_flags &= ~IBCM_REJ_POST_BUSY;
3939 3875 if (statep->state == IBCM_STATE_REJ_SENT) {
3940 3876 statep->remaining_retry_cnt = 0;
3941 3877
3942 3878 /* wait until all possible retransmits of REQ/REP happened */
3943 3879 statep->timerid = IBCM_TIMEOUT(statep,
3944 3880 statep->timer_value * statep->max_cm_retries);
3945 3881 }
3946 3882
3947 3883 IBCM_REF_CNT_DECR(statep);
3948 3884 mutex_exit(&statep->state_mutex);
3949 3885 }
3950 3886
3951 3887 /*ARGSUSED*/
3952 3888 void
3953 3889 ibcm_post_rtu_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3954 3890 void *args)
3955 3891 {
3956 3892 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3957 3893
3958 3894 IBTF_DPRINTF_L4(cmlog, "ibcm_post_rtu_complete statep %p", statep);
3959 3895
3960 3896 mutex_enter(&statep->state_mutex);
3961 3897 ibcm_flow_dec(statep->post_time, "RTU");
3962 3898 ibcm_insert_trace(statep, IBCM_TRACE_RTU_POST_COMPLETE);
3963 3899 statep->send_mad_flags &= ~IBCM_RTU_POST_BUSY;
3964 3900 IBCM_REF_CNT_DECR(statep);
3965 3901 ibcm_open_done(statep);
3966 3902 mutex_exit(&statep->state_mutex);
3967 3903 }
3968 3904
3969 3905 /*ARGSUSED*/
3970 3906 void
3971 3907 ibcm_post_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3972 3908 void *args)
3973 3909 {
3974 3910 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
3975 3911
3976 3912 IBTF_DPRINTF_L4(cmlog, "ibcm_post_apr_complete statep %p", statep);
3977 3913
3978 3914 mutex_enter(&statep->state_mutex);
3979 3915 ibcm_flow_dec(statep->post_time, "APR");
3980 3916 ibcm_insert_trace(statep, IBCM_TRACE_APR_POST_COMPLETE);
3981 3917 /* As long as one APR mad in transit, no retransmits are allowed */
3982 3918 statep->ap_state = IBCM_AP_STATE_IDLE;
3983 3919
3984 3920 /* unblock any DREQ threads and close channels */
3985 3921 cv_broadcast(&statep->block_mad_cv);
3986 3922 IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
3987 3923 mutex_exit(&statep->state_mutex);
3988 3924
3989 3925 }
3990 3926
3991 3927 /*ARGSUSED*/
3992 3928 void
3993 3929 ibcm_post_stored_apr_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
3994 3930 void *args)
3995 3931 {
3996 3932 ibmf_msg_t *ibmf_apr_msg = (ibmf_msg_t *)args;
3997 3933
3998 3934 IBTF_DPRINTF_L4(cmlog, "ibcm_post_stored_apr_complete args %p", args);
3999 3935
4000 3936 ibcm_flow_dec(0, "APR_RESEND");
4001 3937 (void) ibcm_free_out_msg(ibmf_handle, &ibmf_apr_msg);
4002 3938 }
4003 3939
4004 3940 /*ARGSUSED*/
4005 3941 void
4006 3942 ibcm_post_drep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
4007 3943 void *args)
4008 3944 {
4009 3945 ibcm_state_data_t *statep = (ibcm_state_data_t *)args;
4010 3946
4011 3947 IBTF_DPRINTF_L4(cmlog, "ibcm_post_drep_complete statep %p", statep);
4012 3948
4013 3949 mutex_enter(&statep->state_mutex);
4014 3950 ibcm_flow_dec(statep->post_time, "DREP");
4015 3951 ibcm_insert_trace(statep, IBCM_TRACE_DREP_POST_COMPLETE);
4016 3952 statep->send_mad_flags &= ~IBCM_REJ_POST_BUSY;
4017 3953
4018 3954 if (statep->state == IBCM_STATE_DREQ_RCVD) {
4019 3955
4020 3956 ibcm_close_done(statep, 1);
4021 3957 statep->state = IBCM_STATE_TIMEWAIT;
4022 3958
4023 3959 /*
4024 3960 * For passive side CM set it to remote_ack_delay
4025 3961 * For active side CM add the pkt_life_time * 2
4026 3962 */
4027 3963 statep->timer_value = statep->remote_ack_delay;
4028 3964 if (statep->mode == IBCM_ACTIVE_MODE)
4029 3965 statep->timer_value += (2 * statep->pkt_life_time);
4030 3966 statep->remaining_retry_cnt = 0;
4031 3967 statep->timer_stored_state = statep->state;
4032 3968 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
4033 3969 }
4034 3970
4035 3971 IBCM_REF_CNT_DECR(statep);
4036 3972 mutex_exit(&statep->state_mutex);
4037 3973 }
4038 3974
4039 3975 /*ARGSUSED*/
4040 3976 void
4041 3977 ibcm_post_sidr_rep_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
4042 3978 void *args)
4043 3979 {
4044 3980 ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)args;
4045 3981
4046 3982 IBTF_DPRINTF_L4(cmlog, "ibcm_post_sidr_rep_complete ud_statep %p",
4047 3983 ud_statep);
4048 3984
4049 3985 ibcm_flow_dec(0, "SIDR_REP");
4050 3986 mutex_enter(&ud_statep->ud_state_mutex);
4051 3987 ud_statep->ud_send_mad_flags &= ~IBCM_SREP_POST_BUSY;
4052 3988 ud_statep->ud_remaining_retry_cnt = 0;
4053 3989 if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT)
4054 3990 ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
4055 3991 ud_statep->ud_timer_value);
4056 3992 IBCM_UD_REF_CNT_DECR(ud_statep);
4057 3993 mutex_exit(&ud_statep->ud_state_mutex);
4058 3994
4059 3995 }
4060 3996
4061 3997 /*ARGSUSED*/
4062 3998 void
4063 3999 ibcm_post_sidr_req_complete(ibmf_handle_t ibmf_handle, ibmf_msg_t *msgp,
4064 4000 void *args)
4065 4001 {
4066 4002 ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)args;
4067 4003
4068 4004 IBTF_DPRINTF_L4(cmlog, "ibcm_post_sidr_req_complete ud_statep %p",
4069 4005 ud_statep);
4070 4006
4071 4007 ibcm_flow_dec(0, "SIDR_REQ");
4072 4008 mutex_enter(&ud_statep->ud_state_mutex);
4073 4009 if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT)
4074 4010 ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
4075 4011 ud_statep->ud_timer_value);
4076 4012 IBCM_UD_REF_CNT_DECR(ud_statep);
4077 4013 mutex_exit(&ud_statep->ud_state_mutex);
4078 4014
4079 4015 }
4080 4016
4081 4017 /*
4082 4018 * ibcm_process_dreq_timeout:
4083 4019 * Called when the timer expires on DREP
4084 4020 *
4085 4021 * INPUTS:
4086 4022 * arg - ibcm_state_data_t is passed
4087 4023 *
4088 4024 * RETURN VALUES: NONE
4089 4025 */
4090 4026 void
4091 4027 ibcm_process_dreq_timeout(ibcm_state_data_t *statep)
4092 4028 {
4093 4029 mutex_enter(&statep->state_mutex);
4094 4030
4095 4031 /* Max retries reached, move to the time wait state */
4096 4032 statep->state = statep->timer_stored_state =
4097 4033 IBCM_STATE_TIMEWAIT;
4098 4034 ibcm_close_done(statep, 0);
4099 4035
4100 4036 /* Set the TIME_WAIT state timer value */
4101 4037 statep->timer_value = statep->remote_ack_delay;
4102 4038 if (statep->mode == IBCM_ACTIVE_MODE) {
4103 4039 statep->timer_value += (2 * statep->pkt_life_time);
4104 4040 }
4105 4041
4106 4042 statep->timerid = IBCM_TIMEOUT(statep, statep->timer_value);
4107 4043
4108 4044 if (statep->close_ret_status)
4109 4045 if (statep->stale == B_TRUE)
4110 4046 *statep->close_ret_status = IBT_CM_CLOSED_STALE;
4111 4047 else *statep->close_ret_status = IBT_CM_CLOSED_DREQ_TIMEOUT;
4112 4048
4113 4049 /* signal waiting CVs - blocking in ibt_close_channel() */
4114 4050 statep->close_done = B_TRUE;
4115 4051 if (statep->close_ret_priv_data_len != NULL)
4116 4052 *statep->close_ret_priv_data_len = 0;
4117 4053
4118 4054 /* unblock any close channel with no callbacks option */
4119 4055 statep->close_nocb_state = IBCM_FAIL;
4120 4056
4121 4057 cv_broadcast(&statep->block_client_cv);
4122 4058 mutex_exit(&statep->state_mutex);
4123 4059 }
4124 4060
4125 4061 /*
4126 4062 * ibcm_add_tlist:
4127 4063 * Adds the given RC statep to timeout list
4128 4064 *
4129 4065 * INPUTS:
4130 4066 * arg - ibcm_state_data_t is passed
4131 4067 *
4132 4068 * RETURN VALUES: NONE
4133 4069 */
4134 4070 void
4135 4071 ibcm_add_tlist(ibcm_state_data_t *statep)
4136 4072 {
4137 4073 mutex_enter(&ibcm_timeout_list_lock);
4138 4074
4139 4075 statep->timeout_next = NULL;
4140 4076 if (ibcm_timeout_list_hdr == NULL) {
4141 4077 ibcm_timeout_list_hdr = statep;
4142 4078 } else {
4143 4079 ibcm_timeout_list_tail->timeout_next = statep;
4144 4080 }
4145 4081
4146 4082 ibcm_timeout_list_tail = statep;
4147 4083
4148 4084 cv_signal(&ibcm_timeout_list_cv);
4149 4085
4150 4086 mutex_exit(&ibcm_timeout_list_lock);
4151 4087 IBTF_DPRINTF_L3(cmlog, "ibcm_add_tlist: "
4152 4088 "attached state = %p to timeout list", statep);
4153 4089 }
4154 4090
4155 4091 void
4156 4092 ibcm_run_tlist_thread(void)
4157 4093 {
4158 4094 mutex_enter(&ibcm_timeout_list_lock);
4159 4095 cv_signal(&ibcm_timeout_list_cv);
4160 4096 mutex_exit(&ibcm_timeout_list_lock);
4161 4097 }
4162 4098
4163 4099 /*
4164 4100 * ibcm_add_ud_tlist:
4165 4101 * Adds the given UD statep to timeout list
4166 4102 *
4167 4103 * INPUTS:
4168 4104 * arg - ibcm_ud_state_data_t is passed
4169 4105 *
4170 4106 * RETURN VALUES: NONE
4171 4107 */
4172 4108 void
4173 4109 ibcm_add_ud_tlist(ibcm_ud_state_data_t *ud_statep)
4174 4110 {
4175 4111 mutex_enter(&ibcm_timeout_list_lock);
4176 4112
4177 4113 ud_statep->ud_timeout_next = NULL;
4178 4114 if (ibcm_ud_timeout_list_hdr == NULL) {
4179 4115 ibcm_ud_timeout_list_hdr = ud_statep;
4180 4116 } else {
4181 4117 ibcm_ud_timeout_list_tail->ud_timeout_next = ud_statep;
4182 4118 }
4183 4119
4184 4120 ibcm_ud_timeout_list_tail = ud_statep;
4185 4121
4186 4122 cv_signal(&ibcm_timeout_list_cv);
4187 4123
4188 4124 mutex_exit(&ibcm_timeout_list_lock);
4189 4125 IBTF_DPRINTF_L3(cmlog, "ibcm_add_ud_tlist: "
4190 4126 "attached state = %p to ud timeout list", ud_statep);
4191 4127 }
4192 4128
4193 4129 /*
4194 4130 * ibcm_process_tlist:
4195 4131 * Thread that processes all the RC and UD statep's from
4196 4132 * the appropriate lists
4197 4133 *
4198 4134 * INPUTS:
4199 4135 * NONE
4200 4136 *
4201 4137 * RETURN VALUES: NONE
4202 4138 */
4203 4139 void
4204 4140 ibcm_process_tlist()
4205 4141 {
4206 4142 ibcm_state_data_t *statep;
4207 4143 ibcm_ud_state_data_t *ud_statep;
4208 4144 callb_cpr_t cprinfo;
4209 4145
4210 4146 IBTF_DPRINTF_L5(cmlog, "ibcm_process_tlist: thread started");
4211 4147
4212 4148 mutex_enter(&ibcm_timeout_list_lock);
4213 4149
4214 4150 CALLB_CPR_INIT(&cprinfo, &ibcm_timeout_list_lock, callb_generic_cpr,
4215 4151 "ibcm_process_tlist");
4216 4152
4217 4153 for (;;) {
4218 4154 if (ibcm_timeout_list_flags & IBCM_TIMEOUT_THREAD_EXIT) {
4219 4155 /* The thread needs to exit */
4220 4156 cv_signal(&ibcm_timeout_thread_done_cv);
4221 4157 break;
4222 4158 }
4223 4159 mutex_exit(&ibcm_timeout_list_lock);
4224 4160 ibcm_check_for_opens();
4225 4161 ibcm_check_for_async_close();
4226 4162 mutex_enter(&ibcm_timeout_list_lock);
4227 4163
4228 4164 /* First, handle pending RC statep's, followed by UD's */
4229 4165 if (ibcm_timeout_list_hdr != NULL) {
4230 4166 statep = ibcm_timeout_list_hdr;
4231 4167 ibcm_timeout_list_hdr = statep->timeout_next;
4232 4168
4233 4169 if (ibcm_timeout_list_hdr == NULL)
4234 4170 ibcm_timeout_list_tail = NULL;
4235 4171
4236 4172 statep->timeout_next = NULL;
4237 4173
4238 4174 mutex_exit(&ibcm_timeout_list_lock);
4239 4175 IBTF_DPRINTF_L3(cmlog, "ibcm_process_tlist: "
4240 4176 "scheduling state = %p", statep);
4241 4177 ibcm_timeout_client_cb(statep);
4242 4178 mutex_enter(&ibcm_timeout_list_lock);
4243 4179 } else if (ibcm_ud_timeout_list_hdr != NULL) {
4244 4180 ud_statep = ibcm_ud_timeout_list_hdr;
4245 4181 ibcm_ud_timeout_list_hdr = ud_statep->ud_timeout_next;
4246 4182
4247 4183 if (ibcm_ud_timeout_list_hdr == NULL)
4248 4184 ibcm_ud_timeout_list_tail = NULL;
4249 4185
4250 4186 ud_statep->ud_timeout_next = NULL;
4251 4187
4252 4188 mutex_exit(&ibcm_timeout_list_lock);
4253 4189 IBTF_DPRINTF_L3(cmlog, "ibcm_process_tlist: "
↓ open down ↓ |
744 lines elided |
↑ open up ↑ |
4254 4190 "ud scheduling state = %p", ud_statep);
4255 4191 ibcm_ud_timeout_client_cb(ud_statep);
4256 4192 mutex_enter(&ibcm_timeout_list_lock);
4257 4193 } else {
4258 4194 CALLB_CPR_SAFE_BEGIN(&cprinfo);
4259 4195 cv_wait(&ibcm_timeout_list_cv, &ibcm_timeout_list_lock);
4260 4196 CALLB_CPR_SAFE_END(&cprinfo, &ibcm_timeout_list_lock);
4261 4197 }
4262 4198 }
4263 4199
4264 -#ifndef __lock_lint
4265 4200 CALLB_CPR_EXIT(&cprinfo); /* mutex_exit */
4266 -#endif
4267 4201 }
4268 4202
4269 4203
4270 4204 /*
4271 4205 * ibcm_timeout_client_cb:
4272 4206 * Called from timeout thread processing
4273 4207 * Primary purpose is to call client handler
4274 4208 *
4275 4209 * INPUTS:
4276 4210 * arg - ibcm_state_data_t is passed
4277 4211 *
4278 4212 * RETURN VALUES: NONE
4279 4213 */
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
4280 4214 void
4281 4215 ibcm_timeout_client_cb(ibcm_state_data_t *statep)
4282 4216 {
4283 4217 mutex_enter(&statep->state_mutex);
4284 4218
4285 4219 if ((statep->state == IBCM_STATE_DELETE) &&
4286 4220 (statep->recycle_arg != NULL)) {
4287 4221 struct ibcm_taskq_recycle_arg_s *recycle_arg;
4288 4222
4289 4223 recycle_arg = statep->recycle_arg;
4290 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
4291 4224 statep->recycle_arg = NULL;
4292 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->recycle_arg))
4293 4225 mutex_exit(&statep->state_mutex);
4294 4226 (void) ibcm_process_rc_recycle(recycle_arg);
4295 4227 ibcm_delete_state_data(statep);
4296 4228 return;
4297 4229 }
4298 4230
4299 4231 if ((statep->state == IBCM_STATE_DELETE) &&
4300 4232 (statep->delete_state_data == B_TRUE)) {
4301 4233 mutex_exit(&statep->state_mutex);
4302 4234 ibcm_dealloc_state_data(statep);
4303 4235 return;
4304 4236 }
4305 4237
4306 4238 /* Else, it must be in TIMEOUT state, do the necessary processing */
4307 4239 if (statep->state == IBCM_STATE_TIMED_OUT) {
4308 4240 void *data;
4309 4241 uint8_t cf_msg;
4310 4242 ib_guid_t local_hca_guid;
4311 4243
4312 4244 mutex_exit(&statep->state_mutex);
4313 4245
4314 4246 if (statep->timedout_state == IBCM_STATE_DREQ_SENT) {
4315 4247 ibt_cm_event_t event;
4316 4248 ibt_cm_return_args_t ret_args;
4317 4249
4318 4250 bzero(&event, sizeof (event));
4319 4251 bzero(&ret_args, sizeof (ret_args));
4320 4252
4321 4253 event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
4322 4254 event.cm_channel = statep->channel;
4323 4255 event.cm_session_id = NULL;
4324 4256 event.cm_priv_data = NULL;
4325 4257 event.cm_priv_data_len = 0;
4326 4258
4327 4259 if (statep->stale == B_TRUE)
4328 4260 event.cm_event.closed = IBT_CM_CLOSED_STALE;
4329 4261 else event.cm_event.closed = IBT_CM_CLOSED_DREQ_TIMEOUT;
4330 4262
4331 4263 /*
4332 4264 * cm handler cannot be non-NULL, as that check is
4333 4265 * already made in ibcm_timeout_cb
4334 4266 */
4335 4267 ibcm_insert_trace(statep,
4336 4268 IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
4337 4269
4338 4270 (void) statep->cm_handler(statep->state_cm_private,
4339 4271 &event, &ret_args, NULL, 0);
4340 4272
4341 4273 ibcm_insert_trace(statep,
4342 4274 IBCM_TRACE_RET_CONN_CLOSE_EVENT);
4343 4275
4344 4276 ibcm_process_dreq_timeout(statep);
4345 4277 return;
4346 4278 }
4347 4279
4348 4280 data = ((ibcm_rej_msg_t *)
4349 4281 IBCM_OUT_MSGP(statep->stored_msg))->rej_private_data;
4350 4282
4351 4283 if ((statep->timedout_state == IBCM_STATE_REQ_SENT) ||
4352 4284 (statep->timedout_state == IBCM_STATE_REP_WAIT)) {
4353 4285 cf_msg = IBT_CM_FAILURE_REQ;
4354 4286 } else {
4355 4287 ASSERT(
4356 4288 (statep->timedout_state == IBCM_STATE_REP_SENT) ||
4357 4289 (statep->timedout_state ==
4358 4290 IBCM_STATE_MRA_REP_RCVD));
4359 4291 cf_msg = IBT_CM_FAILURE_REP;
4360 4292 }
4361 4293
4362 4294 /*
4363 4295 * Invoke the CM handler w/ event IBT_CM_EVENT_TIMEOUT
4364 4296 * This callback happens for only active non blocking or
4365 4297 * passive client
4366 4298 */
4367 4299 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_TIMEOUT,
4368 4300 cf_msg, IBT_CM_TIMEOUT, data, IBT_REJ_PRIV_DATA_SZ);
4369 4301
4370 4302 /* signal the blocked ibt_open_rc_channel */
4371 4303 mutex_enter(&statep->state_mutex);
4372 4304
4373 4305 /*
4374 4306 * statep->open_return_data is set for blocking
4375 4307 * signal the blocked ibt_open_rc_channel
4376 4308 */
4377 4309 if (statep->open_return_data != NULL) {
4378 4310 statep->open_return_data->rc_status = IBT_CM_TIMEOUT;
4379 4311 statep->open_done = B_TRUE;
4380 4312 cv_broadcast(&statep->block_client_cv);
4381 4313 }
4382 4314
4383 4315 mutex_exit(&statep->state_mutex);
4384 4316
4385 4317 local_hca_guid = h2b64(statep->local_hca_guid);
4386 4318 ibcm_post_rej_mad(statep, IBT_CM_TIMEOUT,
4387 4319 IBT_CM_FAILURE_UNKNOWN, &local_hca_guid,
4388 4320 sizeof (ib_guid_t));
4389 4321 } else if (statep->ap_state == IBCM_AP_STATE_TIMED_OUT) {
4390 4322
4391 4323 mutex_exit(&statep->state_mutex);
4392 4324
4393 4325 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_TIMEOUT,
4394 4326 IBT_CM_FAILURE_LAP, IBT_CM_TIMEOUT, NULL, 0);
4395 4327
4396 4328 /* Now wake up threads waiting for LAP/APR to complete */
4397 4329 mutex_enter(&statep->state_mutex);
4398 4330 /*
4399 4331 * statep->ap_return_data is initialized for blocking in
4400 4332 * ibt_set_alt_path(), signal the waiting CV
4401 4333 */
4402 4334 if (statep->ap_return_data != NULL) {
4403 4335 statep->ap_return_data->ap_status = IBT_CM_AP_TIMEOUT;
4404 4336 statep->ap_done = B_TRUE;
4405 4337 cv_broadcast(&statep->block_client_cv);
4406 4338 }
4407 4339 statep->ap_state = IBCM_AP_STATE_IDLE;
4408 4340 cv_broadcast(&statep->block_mad_cv);
4409 4341 mutex_exit(&statep->state_mutex);
4410 4342 } else {
4411 4343 IBTF_DPRINTF_L2(cmlog, "ibcm_timeout_client_cb "
4412 4344 "Unexpected else path statep %p state %d ap_state %d",
4413 4345 statep, statep->state, statep->ap_state);
4414 4346 mutex_exit(&statep->state_mutex);
4415 4347
4416 4348 }
4417 4349 }
4418 4350
4419 4351 /*
4420 4352 * ibcm_ud_timeout_client_cb:
4421 4353 * Called from UD timeout thread processing
4422 4354 * Primary purpose is to call client handler
4423 4355 *
4424 4356 * INPUTS:
4425 4357 * arg - ibcm_ud_state_data_t is passed
4426 4358 *
4427 4359 * RETURN VALUES: NONE
4428 4360 */
4429 4361 void
4430 4362 ibcm_ud_timeout_client_cb(ibcm_ud_state_data_t *ud_statep)
4431 4363 {
4432 4364 ibt_cm_ud_event_t ud_event;
4433 4365
4434 4366 mutex_enter(&ud_statep->ud_state_mutex);
4435 4367
4436 4368 if ((ud_statep->ud_state == IBCM_STATE_DELETE) &&
4437 4369 (ud_statep->ud_delete_state_data == B_TRUE)) {
4438 4370
4439 4371 mutex_exit(&ud_statep->ud_state_mutex);
4440 4372 ibcm_dealloc_ud_state_data(ud_statep);
4441 4373 return;
4442 4374 } else
4443 4375 mutex_exit(&ud_statep->ud_state_mutex);
4444 4376
4445 4377 /* Fill in ibt_cm_ud_event_t */
4446 4378 ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REP;
4447 4379 ud_event.cm_session_id = NULL;
4448 4380 ud_event.cm_event.sidr_rep.srep_status = IBT_CM_SREP_TIMEOUT;
4449 4381
4450 4382 (void) ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
4451 4383 &ud_event, NULL, NULL, 0);
4452 4384
4453 4385 /* Delete UD state data now, finally done with it */
4454 4386 ibcm_delete_ud_state_data(ud_statep);
4455 4387 }
4456 4388
4457 4389
4458 4390 /*
4459 4391 * ibcm_process_sidr_req_msg:
4460 4392 * This call processes an incoming SIDR REQ
4461 4393 *
4462 4394 * INPUTS:
4463 4395 * hcap - HCA entry pointer
4464 4396 * input_madp - Incoming CM SIDR REQ MAD
4465 4397 * cm_mad_addr - Address information for the MAD to be posted
4466 4398 *
4467 4399 * RETURN VALUE:
4468 4400 * NONE
4469 4401 */
4470 4402 void
4471 4403 ibcm_process_sidr_req_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
4472 4404 ibcm_mad_addr_t *cm_mad_addr)
4473 4405 {
4474 4406 ib_gid_t gid;
4475 4407 ib_lid_t lid;
4476 4408 uint32_t req_id;
4477 4409 ibcm_status_t state_lookup_status;
4478 4410 ibcm_status_t cm_status;
4479 4411 ibt_sidr_status_t sidr_status;
4480 4412 ibcm_svc_info_t *svc_infop;
4481 4413 ibcm_svc_bind_t *svc_bindp;
4482 4414 ibcm_svc_bind_t *tmp_bindp;
4483 4415 ibcm_sidr_req_msg_t *sidr_reqp = (ibcm_sidr_req_msg_t *)
4484 4416 (&input_madp[IBCM_MAD_HDR_SIZE]);
4485 4417 ibcm_ud_state_data_t *ud_statep = NULL;
4486 4418 ibcm_sidr_srch_t srch_sidr;
4487 4419 ib_pkey_t pkey;
4488 4420 uint8_t port_num;
4489 4421 ib_guid_t hca_guid;
4490 4422
4491 4423 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg:");
4492 4424
4493 4425 hca_guid = hcap->hca_guid;
4494 4426 port_num = cm_mad_addr->port_num;
4495 4427
4496 4428 /* Figure out LID, GID, RequestId for svc_id lookup */
4497 4429 lid = cm_mad_addr->rcvd_addr.ia_remote_lid;
4498 4430 req_id = b2h32(sidr_reqp->sidr_req_request_id);
4499 4431 pkey = b2h16(sidr_reqp->sidr_req_pkey);
4500 4432 if (cm_mad_addr->grh_exists == B_TRUE)
4501 4433 gid = cm_mad_addr->grh_hdr.ig_sender_gid;
↓ open down ↓ |
199 lines elided |
↑ open up ↑ |
4502 4434 else
4503 4435 gid.gid_prefix = gid.gid_guid = 0;
4504 4436
4505 4437 /*
4506 4438 * Lookup for an existing state structure
4507 4439 * - if lookup fails it creates a new ud_state struct
4508 4440 * No need to hold a lock across the call to ibcm_find_sidr_entry() as
4509 4441 * the list lock is held in that function to find the matching entry.
4510 4442 */
4511 4443
4512 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srch_sidr))
4513 -
4514 4444 srch_sidr.srch_lid = lid;
4515 4445 srch_sidr.srch_gid = gid;
4516 4446 srch_sidr.srch_grh_exists = cm_mad_addr->grh_exists;
4517 4447 srch_sidr.srch_req_id = req_id;
4518 4448 srch_sidr.srch_mode = IBCM_PASSIVE_MODE;
4519 4449
4520 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srch_sidr))
4521 -
4522 4450 rw_enter(&hcap->hca_sidr_list_lock, RW_WRITER);
4523 4451 state_lookup_status = ibcm_find_sidr_entry(&srch_sidr, hcap, &ud_statep,
4524 4452 IBCM_FLAG_LOOKUP_AND_ADD);
4525 4453 rw_exit(&hcap->hca_sidr_list_lock);
4526 4454
4527 4455 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: ud_statep 0x%p "
4528 4456 "lookup status %x", ud_statep, state_lookup_status);
4529 4457
4530 4458 if (state_lookup_status == IBCM_LOOKUP_NEW) {
4531 4459
4532 4460 /* Increment hca's resource count */
4533 4461 ibcm_inc_hca_res_cnt(hcap);
4534 4462
4535 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ud_statep))
4536 -
4537 4463 /*
4538 4464 * Allocate CM MAD for a response
4539 4465 * This MAD is deallocated on state structure delete
4540 4466 * and re-used for all outgoing MADs for this connection.
4541 4467 * If MAD allocation fails, delete the ud statep
4542 4468 */
4543 4469 if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl,
4544 4470 &ud_statep->ud_stored_msg, MAD_METHOD_SEND) !=
4545 4471 IBT_SUCCESS) {
4546 4472 mutex_enter(&ud_statep->ud_state_mutex);
4547 4473 IBCM_UD_REF_CNT_DECR(ud_statep);
4548 4474 mutex_exit(&ud_statep->ud_state_mutex);
4549 4475 ibcm_delete_ud_state_data(ud_statep);
4550 4476 return;
4551 4477 }
4552 4478
4553 4479 /* Lookup for service */
4554 4480 ud_statep->ud_svc_id = b2h64(sidr_reqp->sidr_req_service_id);
4555 4481 ud_statep->ud_state = IBCM_STATE_SIDR_REQ_RCVD;
4556 4482 ud_statep->ud_clnt_proceed = IBCM_BLOCK;
4557 4483
4558 4484 mutex_enter(&ibcm_svc_info_lock);
4559 4485
4560 4486 svc_infop = ibcm_find_svc_entry(ud_statep->ud_svc_id);
4561 4487
4562 4488 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: "
4563 4489 " ud_statep 0x%p svc_info %p", ud_statep, svc_infop);
4564 4490
4565 4491 /*
4566 4492 * No need to hold the ud state mutex, as no other thread
4567 4493 * modifies ud statep in IBCM_STATE_SIDR_REQ_RCVD state
4568 4494 */
4569 4495
4570 4496 if (svc_infop != NULL) {
4571 4497 /* find the "bind" entry that enables this port */
4572 4498
4573 4499 svc_bindp = NULL;
4574 4500 tmp_bindp = svc_infop->svc_bind_list;
4575 4501 while (tmp_bindp) {
4576 4502 if (tmp_bindp->sbind_hcaguid == hca_guid &&
4577 4503 tmp_bindp->sbind_port == port_num) {
4578 4504 if (gid.gid_guid ==
4579 4505 tmp_bindp->sbind_gid.gid_guid &&
4580 4506 gid.gid_prefix ==
4581 4507 tmp_bindp->sbind_gid.gid_prefix) {
4582 4508 /* a really good match */
4583 4509 svc_bindp = tmp_bindp;
4584 4510 if (pkey ==
4585 4511 tmp_bindp->sbind_pkey)
4586 4512 /* absolute best */
4587 4513 break;
4588 4514 } else if (svc_bindp == NULL) {
4589 4515 /* port match => a good match */
4590 4516 svc_bindp = tmp_bindp;
4591 4517 }
4592 4518 }
4593 4519 tmp_bindp = tmp_bindp->sbind_link;
4594 4520 }
4595 4521 if (svc_bindp == NULL) {
4596 4522 svc_infop = NULL;
4597 4523 }
4598 4524 }
4599 4525
4600 4526 IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID =
4601 4527 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
4602 4528
4603 4529 ibcm_build_reply_mad_addr(cm_mad_addr,
4604 4530 &ud_statep->ud_stored_reply_addr);
4605 4531
4606 4532 if (ud_statep->ud_stored_reply_addr.cm_qp_entry == NULL) {
4607 4533
4608 4534 mutex_exit(&ibcm_svc_info_lock);
4609 4535
4610 4536 /* Not much choice. CM MADs cannot go on QP1 */
4611 4537 mutex_enter(&ud_statep->ud_state_mutex);
4612 4538 IBCM_UD_REF_CNT_DECR(ud_statep);
4613 4539 ud_statep->ud_state = IBCM_STATE_DELETE;
4614 4540 mutex_exit(&ud_statep->ud_state_mutex);
4615 4541
4616 4542 ibcm_delete_ud_state_data(ud_statep);
4617 4543 return;
4618 4544 }
4619 4545
4620 4546 if (svc_infop == NULL || svc_infop->svc_ud_handler == NULL) {
4621 4547 /*
4622 4548 * Don't have a record of Service ID in CM's
4623 4549 * internal list registered at this gid/lid.
4624 4550 * So, send out Service ID not supported SIDR REP msg
4625 4551 */
4626 4552 sidr_status = IBT_CM_SREP_SID_INVALID;
4627 4553 } else {
4628 4554 ud_statep->ud_cm_handler = svc_infop->svc_ud_handler;
4629 4555 ud_statep->ud_state_cm_private =
4630 4556 svc_bindp->sbind_cm_private;
4631 4557 IBCM_SVC_INCR(svc_infop);
4632 4558 mutex_exit(&ibcm_svc_info_lock);
4633 4559
4634 4560 /* Call Client's UD handler */
4635 4561 cm_status = ibcm_sidr_req_ud_handler(ud_statep,
4636 4562 sidr_reqp, cm_mad_addr, &sidr_status);
4637 4563
4638 4564 mutex_enter(&ibcm_svc_info_lock);
4639 4565 IBCM_SVC_DECR(svc_infop);
4640 4566 }
4641 4567
4642 4568 mutex_exit(&ibcm_svc_info_lock);
↓ open down ↓ |
96 lines elided |
↑ open up ↑ |
4643 4569
4644 4570 if (cm_status == IBCM_DEFER) {
4645 4571 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_req_msg: "
4646 4572 "ud_statep 0x%p client returned DEFER response",
4647 4573 ud_statep);
4648 4574 return;
4649 4575 }
4650 4576
4651 4577 ibcm_post_sidr_rep_mad(ud_statep, sidr_status);
4652 4578
4653 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ud_statep))
4654 -
4655 4579 mutex_enter(&ud_statep->ud_state_mutex);
4656 4580 IBCM_UD_REF_CNT_DECR(ud_statep);
4657 4581 mutex_exit(&ud_statep->ud_state_mutex);
4658 4582 } else {
4659 4583 ASSERT(state_lookup_status == IBCM_LOOKUP_EXISTS);
4660 4584
4661 4585 mutex_enter(&ud_statep->ud_state_mutex);
4662 4586
4663 4587 if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT)
4664 4588 ibcm_resend_srep_mad(ud_statep);
4665 4589
4666 4590 IBCM_UD_REF_CNT_DECR(ud_statep);
4667 4591 mutex_exit(&ud_statep->ud_state_mutex);
4668 4592 }
4669 4593 }
4670 4594
4671 4595
4672 4596 /*
4673 4597 * ibcm_process_sidr_rep_msg:
4674 4598 * This call processes an incoming SIDR REP
4675 4599 *
4676 4600 * INPUTS:
4677 4601 * hcap - HCA entry pointer
4678 4602 * input_madp - incoming CM SIDR REP MAD
4679 4603 * cm_mad_addr - Address information for the MAD to be posted
4680 4604 *
4681 4605 * RETURN VALUE:
4682 4606 * NONE
4683 4607 */
4684 4608 void
4685 4609 ibcm_process_sidr_rep_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
4686 4610 ibcm_mad_addr_t *cm_mad_addr)
4687 4611 {
4688 4612 ib_lid_t lid;
4689 4613 ib_gid_t gid;
4690 4614 ibcm_status_t status;
4691 4615 ib_svc_id_t tmp_svc_id;
4692 4616 ibcm_sidr_rep_msg_t *sidr_repp = (ibcm_sidr_rep_msg_t *)
4693 4617 (&input_madp[IBCM_MAD_HDR_SIZE]);
4694 4618 ibcm_ud_state_data_t *ud_statep = NULL;
4695 4619 ibcm_sidr_srch_t srch_sidr;
4696 4620
4697 4621 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep_msg:");
4698 4622
4699 4623 lid = cm_mad_addr->rcvd_addr.ia_local_lid;
4700 4624 if (cm_mad_addr->grh_exists == B_TRUE)
4701 4625 gid = cm_mad_addr->grh_hdr.ig_recver_gid;
4702 4626 else
4703 4627 gid.gid_prefix = gid.gid_guid = 0;
4704 4628
4705 4629 IBTF_DPRINTF_L3(cmlog, "ibcm_process_sidr_rep_msg: QPN rcvd = %x",
4706 4630 h2b32(sidr_repp->sidr_rep_qpn_plus) >> 8);
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
4707 4631
4708 4632 /*
4709 4633 * Lookup for an existing state structure.
4710 4634 * No need to hold a lock as ibcm_find_sidr_entry() holds the
4711 4635 * list lock to find the matching entry.
4712 4636 */
4713 4637 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep: lid=%x, (%llX, %llX), "
4714 4638 "grh = %x, id = %x", lid, gid.gid_prefix, gid.gid_guid,
4715 4639 cm_mad_addr->grh_exists, sidr_repp->sidr_rep_request_id);
4716 4640
4717 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(srch_sidr))
4718 -
4719 4641 srch_sidr.srch_lid = lid;
4720 4642 srch_sidr.srch_gid = gid;
4721 4643 srch_sidr.srch_grh_exists = cm_mad_addr->grh_exists;
4722 4644 srch_sidr.srch_req_id = b2h32(sidr_repp->sidr_rep_request_id);
4723 4645 srch_sidr.srch_mode = IBCM_ACTIVE_MODE;
4724 4646
4725 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(srch_sidr))
4726 -
4727 4647 rw_enter(&hcap->hca_sidr_list_lock, RW_READER);
4728 4648 status = ibcm_find_sidr_entry(&srch_sidr, hcap, &ud_statep,
4729 4649 IBCM_FLAG_LOOKUP);
4730 4650 rw_exit(&hcap->hca_sidr_list_lock);
4731 4651
4732 4652 IBTF_DPRINTF_L4(cmlog, "ibcm_process_sidr_rep_msg: ud_statep 0x%p "
4733 4653 "find sidr entry status = %x", ud_statep, status);
4734 4654
4735 4655 if (status != IBCM_LOOKUP_EXISTS) {
4736 4656 IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
4737 4657 "No matching ud_statep for SIDR REP");
4738 4658 return;
4739 4659 }
4740 4660
4741 4661 if (IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID !=
4742 4662 ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
4743 4663 mutex_enter(&ud_statep->ud_state_mutex);
4744 4664 IBCM_UD_REF_CNT_DECR(ud_statep);
4745 4665 mutex_exit(&ud_statep->ud_state_mutex);
4746 4666 IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
4747 4667 "ud_statep 0x%p. A SIDR REP MAD with tid expected 0x%llX "
4748 4668 "tid found 0x%llX req_id %x arrived", ud_statep,
4749 4669 b2h64(
4750 4670 IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->TransactionID),
4751 4671 b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID),
4752 4672 b2h32(sidr_repp->sidr_rep_request_id));
4753 4673 return;
4754 4674 }
4755 4675
4756 4676 mutex_enter(&ud_statep->ud_state_mutex);
4757 4677
4758 4678 /*
4759 4679 * We need to check service ID received against the one sent?
4760 4680 * If they don't match just return.
4761 4681 */
4762 4682 bcopy(sidr_repp->sidr_rep_service_id, &tmp_svc_id, sizeof (tmp_svc_id));
4763 4683 bcopy(&tmp_svc_id, sidr_repp->sidr_rep_service_id, sizeof (tmp_svc_id));
4764 4684 if (ud_statep->ud_svc_id != b2h64(tmp_svc_id)) {
4765 4685 IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_rep_msg: "
4766 4686 "ud_statep -0x%p svcids do not match %llx %llx",
4767 4687 ud_statep, ud_statep->ud_svc_id, b2h64(tmp_svc_id));
4768 4688
4769 4689 IBCM_UD_REF_CNT_DECR(ud_statep);
4770 4690 mutex_exit(&ud_statep->ud_state_mutex);
4771 4691 return;
4772 4692 }
4773 4693
4774 4694 if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT) {
4775 4695 timeout_id_t timer_val = ud_statep->ud_timerid;
4776 4696
4777 4697 ud_statep->ud_state = IBCM_STATE_SIDR_REP_RCVD;
4778 4698 ud_statep->ud_timerid = 0;
4779 4699 mutex_exit(&ud_statep->ud_state_mutex);
4780 4700
4781 4701 /* Cancel timer set after sending SIDR REQ */
4782 4702 (void) untimeout(timer_val);
4783 4703
4784 4704 /*
4785 4705 * Call Client's UD handler
4786 4706 */
4787 4707 ibcm_sidr_rep_ud_handler(ud_statep, sidr_repp);
4788 4708
4789 4709 mutex_enter(&ud_statep->ud_state_mutex);
4790 4710
4791 4711 ud_statep->ud_state = IBCM_STATE_DELETE;
4792 4712
4793 4713 /*
4794 4714 * ud_statep->ud_return_data is initialized for blocking in
4795 4715 * ibt_ud_get_dqpn(). Initialize its fields and
4796 4716 * signal the blocking call in ibt_ud_get_dqpn().
4797 4717 */
4798 4718 if (ud_statep->ud_return_data != NULL) {
4799 4719 /* get rep_qpn and rep_status */
4800 4720 ibt_priv_data_len_t len;
4801 4721
4802 4722 /* Copy the SIDR private data */
4803 4723 len = min(ud_statep->ud_return_data->ud_priv_data_len,
4804 4724 IBT_SIDR_REP_PRIV_DATA_SZ);
4805 4725
4806 4726 if ((ud_statep->ud_return_data->ud_priv_data != NULL) &&
4807 4727 (len > 0)) {
4808 4728 bcopy(sidr_repp->sidr_rep_private_data,
4809 4729 ud_statep->ud_return_data->ud_priv_data,
4810 4730 len);
4811 4731 }
4812 4732
4813 4733 /* get status first */
4814 4734 ud_statep->ud_return_data->ud_status =
4815 4735 sidr_repp->sidr_rep_rep_status;
4816 4736
4817 4737 if (ud_statep->ud_return_data->ud_status ==
4818 4738 IBT_CM_SREP_QPN_VALID) {
4819 4739 ud_statep->ud_return_data->ud_dqpn =
4820 4740 h2b32(sidr_repp->sidr_rep_qpn_plus) >> 8;
4821 4741 ud_statep->ud_return_data->ud_qkey =
4822 4742 b2h32(sidr_repp->sidr_rep_qkey);
4823 4743 }
4824 4744
4825 4745 ud_statep->ud_blocking_done = B_TRUE;
4826 4746 cv_broadcast(&ud_statep->ud_block_client_cv);
4827 4747 }
4828 4748
4829 4749 IBCM_UD_REF_CNT_DECR(ud_statep);
4830 4750 mutex_exit(&ud_statep->ud_state_mutex);
4831 4751
4832 4752 /* Delete UD state data now, finally done with it */
4833 4753 ibcm_delete_ud_state_data(ud_statep);
4834 4754 } else {
4835 4755 IBTF_DPRINTF_L3(cmlog, "ibcm_process_sidr_rep_msg: "
4836 4756 "ud state is = 0x%x", ud_statep->ud_state);
4837 4757 IBCM_UD_REF_CNT_DECR(ud_statep);
4838 4758 mutex_exit(&ud_statep->ud_state_mutex);
4839 4759 }
4840 4760 }
4841 4761
4842 4762
4843 4763 /*
4844 4764 * ibcm_post_sidr_rep_mad:
4845 4765 * This call posts a SIDR REP MAD
4846 4766 *
4847 4767 * INPUTS:
4848 4768 * ud_statep - pointer to ibcm_ud_state_data_t
4849 4769 * status - Status information
4850 4770 *
4851 4771 * RETURN VALUE: NONE
4852 4772 */
4853 4773 void
↓ open down ↓ |
117 lines elided |
↑ open up ↑ |
4854 4774 ibcm_post_sidr_rep_mad(ibcm_ud_state_data_t *ud_statep,
4855 4775 ibt_sidr_status_t status)
4856 4776 {
4857 4777 ib_svc_id_t tmp_svc_id;
4858 4778 ibcm_sidr_rep_msg_t *sidr_repp =
4859 4779 (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
4860 4780 clock_t timer_value;
4861 4781
4862 4782 IBTF_DPRINTF_L5(cmlog, "ibcm_post_sidr_rep_mad:");
4863 4783
4864 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
4865 -
4866 4784 IBCM_OUT_HDRP(ud_statep->ud_stored_msg)->AttributeID =
4867 4785 h2b16(IBCM_INCOMING_SIDR_REP + IBCM_ATTR_BASE_ID);
4868 4786
4869 4787 /*
4870 4788 * Initialize SIDR REP message. (Other fields were
4871 4789 * already filled up in ibcm_sidr_req_ud_handler()
4872 4790 */
4873 4791 sidr_repp->sidr_rep_request_id = h2b32(ud_statep->ud_req_id);
4874 4792 tmp_svc_id = h2b64(ud_statep->ud_svc_id);
4875 4793 bcopy(&tmp_svc_id, sidr_repp->sidr_rep_service_id, sizeof (tmp_svc_id));
4876 4794
4877 4795 sidr_repp->sidr_rep_rep_status = (uint8_t)status;
4878 4796
4879 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sidr_repp))
4880 -
4881 4797 /* post the SIDR REP MAD */
4882 4798 ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg, NULL, NULL);
4883 4799
4884 4800 timer_value = ibt_ib2usec(ibcm_max_sidr_rep_store_time);
4885 4801 /*
4886 4802 * Hold the statep lock, as a SIDR REQ may come in after setting state
4887 4803 * but before timeout. This can result in a dangling timeout ie.,
4888 4804 * the incoming SIDR REQ would be unable to cancel this timeout
4889 4805 */
4890 4806 mutex_enter(&ud_statep->ud_state_mutex);
4891 4807
4892 4808 ud_statep->ud_remaining_retry_cnt = 1;
4893 4809 ud_statep->ud_timer_value = timer_value;
4894 4810
4895 4811 ud_statep->ud_timer_stored_state = ud_statep->ud_state =
4896 4812 IBCM_STATE_SIDR_REP_SENT;
4897 4813 ud_statep->ud_timerid = IBCM_UD_TIMEOUT(ud_statep,
4898 4814 ud_statep->ud_timer_value);
4899 4815
4900 4816 mutex_exit(&ud_statep->ud_state_mutex);
4901 4817 }
4902 4818
4903 4819
4904 4820 /*
4905 4821 * ibcm_sidr_timeout_cb:
4906 4822 * Called when the timer expires on SIDR request
4907 4823 *
4908 4824 * INPUTS:
4909 4825 * arg - ibcm_ud_state_data_t with all the info
4910 4826 *
4911 4827 * RETURN VALUE: NONE
4912 4828 */
4913 4829 void
4914 4830 ibcm_sidr_timeout_cb(void *arg)
4915 4831 {
4916 4832 ibcm_ud_state_data_t *ud_statep = (ibcm_ud_state_data_t *)arg;
4917 4833
4918 4834 mutex_enter(&ud_statep->ud_state_mutex);
4919 4835 ud_statep->ud_timerid = 0;
4920 4836
4921 4837 IBTF_DPRINTF_L3(cmlog, "ibcm_sidr_timeout_cb: ud_statep 0x%p "
4922 4838 "state = 0x%x", ud_statep, ud_statep->ud_state);
4923 4839
4924 4840 /* Processing depends upon current state */
4925 4841 if (ud_statep->ud_state == IBCM_STATE_SIDR_REP_SENT) {
4926 4842 ud_statep->ud_state = IBCM_STATE_DELETE;
4927 4843
4928 4844 mutex_exit(&ud_statep->ud_state_mutex);
4929 4845
4930 4846 /* Deallocate the CM state structure */
4931 4847 ibcm_delete_ud_state_data(ud_statep);
4932 4848
4933 4849 } else if ((ud_statep->ud_remaining_retry_cnt > 0) &&
4934 4850 (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT)) {
4935 4851
4936 4852 ud_statep->ud_remaining_retry_cnt--;
4937 4853 IBCM_UD_REF_CNT_INCR(ud_statep); /* for non-blocking post */
4938 4854 IBTF_DPRINTF_L4(cmlog, "ibcm_sidr_timeout_cb: "
4939 4855 "ud_statep = %p, retries remaining = 0x%x",
4940 4856 ud_statep, ud_statep->ud_remaining_retry_cnt);
4941 4857 mutex_exit(&ud_statep->ud_state_mutex);
4942 4858
4943 4859 /* Post mad in non blocking mode */
4944 4860 ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
4945 4861 ibcm_post_sidr_req_complete, ud_statep);
4946 4862
4947 4863 } else if (ud_statep->ud_state == IBCM_STATE_SIDR_REQ_SENT) {
4948 4864
4949 4865 /* This is on SIDR REQ Sender side processing */
4950 4866
4951 4867 /* set state to IBCM_STATE_DELETE */
4952 4868 ud_statep->ud_state = IBCM_STATE_DELETE;
4953 4869
4954 4870 /*
4955 4871 * retry counter expired, clean up
4956 4872 *
4957 4873 * Invoke the client/server handler with a "status" of
4958 4874 * IBT_CM_SREP_TIMEOUT.
4959 4875 */
4960 4876
4961 4877 if (ud_statep->ud_return_data != NULL) {
4962 4878 ud_statep->ud_return_data->ud_status =
4963 4879 IBT_CM_SREP_TIMEOUT;
4964 4880 ud_statep->ud_blocking_done = B_TRUE;
4965 4881 cv_broadcast(&ud_statep->ud_block_client_cv);
4966 4882 }
4967 4883
4968 4884 mutex_exit(&ud_statep->ud_state_mutex);
4969 4885
4970 4886 /* Invoke the client handler in a separate thread */
4971 4887 if (ud_statep->ud_cm_handler != NULL) {
4972 4888 /* UD state data is delete in timeout thread */
4973 4889 ibcm_add_ud_tlist(ud_statep);
4974 4890 return;
4975 4891 }
4976 4892
4977 4893 /* Delete UD state data now, finally done with it */
4978 4894 ibcm_delete_ud_state_data(ud_statep);
4979 4895 } else {
4980 4896
4981 4897 #ifdef DEBUG
4982 4898 if (ibcm_test_mode > 0)
4983 4899 IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_timeout_cb: "
4984 4900 "Nop timeout for ud_statep 0x%p in ud_state %d",
4985 4901 ud_statep, ud_statep->ud_state);
4986 4902 #endif
4987 4903 mutex_exit(&ud_statep->ud_state_mutex);
4988 4904 }
4989 4905 }
4990 4906
4991 4907
4992 4908 /*
4993 4909 * ibcm_resend_srep_mad:
4994 4910 * Called on a duplicate incoming SIDR REQ on server side
4995 4911 * Posts the stored MAD from ud state structure using ud_stored_reply_addr
4996 4912 * Cancels any running timer, and then re-starts the timer
4997 4913 * This routine must be called with state structure table lock held
4998 4914 *
4999 4915 * INPUTS:
5000 4916 * ud_statep - ibcm_ud_state_data_t
5001 4917 *
5002 4918 * RETURN VALUE: NONE
5003 4919 */
5004 4920 void
5005 4921 ibcm_resend_srep_mad(ibcm_ud_state_data_t *ud_statep)
5006 4922 {
5007 4923 timeout_id_t timer_val;
5008 4924
5009 4925 ASSERT(MUTEX_HELD(&ud_statep->ud_state_mutex));
5010 4926
5011 4927 IBTF_DPRINTF_L3(cmlog, "ibcm_resend_srep_mad: ud_statep 0x%p",
5012 4928 ud_statep);
5013 4929
5014 4930 if (ud_statep->ud_send_mad_flags & IBCM_SREP_POST_BUSY)
5015 4931 return;
5016 4932
5017 4933 ud_statep->ud_send_mad_flags |= IBCM_SREP_POST_BUSY;
5018 4934
5019 4935 /* for nonblocking SIDR REP Post */
5020 4936 IBCM_UD_REF_CNT_INCR(ud_statep);
5021 4937
5022 4938 /* Cancel currently running timer */
5023 4939 timer_val = ud_statep->ud_timerid;
5024 4940
5025 4941 if (ud_statep->ud_timerid != 0) {
5026 4942 ud_statep->ud_timerid = 0;
5027 4943 mutex_exit(&ud_statep->ud_state_mutex);
5028 4944 (void) untimeout(timer_val);
5029 4945 } else {
5030 4946 mutex_exit(&ud_statep->ud_state_mutex);
5031 4947 }
5032 4948
5033 4949 /* Always resend the response MAD to the original reply destination */
5034 4950 ibcm_post_ud_mad(ud_statep, ud_statep->ud_stored_msg,
5035 4951 ibcm_post_sidr_rep_complete, ud_statep);
5036 4952
5037 4953 mutex_enter(&ud_statep->ud_state_mutex);
5038 4954 }
5039 4955
5040 4956
5041 4957 /*
5042 4958 * ibcm_build_reply_mad_addr:
5043 4959 * Forms the reply MAD address based on "incoming mad addr" that is
5044 4960 * supplied as an arg.
5045 4961 *
5046 4962 * Swaps the source and destination gids in ib_grh_t
5047 4963 *
5048 4964 * INPUTS:
5049 4965 * inp_mad_addr: Address information in the incoming MAD
5050 4966 * out_mad_addr: Derived address for the reply MAD
↓ open down ↓ |
160 lines elided |
↑ open up ↑ |
5051 4967 * The reply MAD address is derived based
5052 4968 * address information of incoming CM MAD
5053 4969 * RETURN VALUE: NONE
5054 4970 */
5055 4971 void
5056 4972 ibcm_build_reply_mad_addr(ibcm_mad_addr_t *inp_mad_addr,
5057 4973 ibcm_mad_addr_t *out_mad_addr)
5058 4974 {
5059 4975 IBTF_DPRINTF_L5(cmlog, "ibcm_build_reply_mad_addr:");
5060 4976
5061 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*out_mad_addr))
5062 -
5063 4977 bcopy(inp_mad_addr, out_mad_addr, sizeof (ibcm_mad_addr_t));
5064 4978
5065 4979 /* Swap the GIDs in the GRH */
5066 4980 if (inp_mad_addr->grh_exists == B_TRUE) {
5067 4981 ib_gid_t sgid = inp_mad_addr->grh_hdr.ig_sender_gid;
5068 4982
5069 4983 /* swap the SGID and DGID */
5070 4984 out_mad_addr->grh_hdr.ig_sender_gid =
5071 4985 inp_mad_addr->grh_hdr.ig_recver_gid;
5072 4986 out_mad_addr->grh_hdr.ig_recver_gid = sgid;
5073 4987 }
5074 4988
5075 4989 /*
5076 4990 * CM posts response MAD on a new/existing internal QP on the same port
5077 4991 * and pkey
5078 4992 */
5079 4993 out_mad_addr->cm_qp_entry =
5080 4994 ibcm_find_qp(inp_mad_addr->cm_qp_entry->qp_port->port_hcap,
5081 4995 inp_mad_addr->port_num, inp_mad_addr->rcvd_addr.ia_p_key);
5082 -
5083 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*out_mad_addr))
5084 4996 }
5085 4997
5086 4998
5087 4999 /*
5088 5000 * ibcm_post_rc_mad
5089 5001 * Posts a CM MAD associated with a RC statep
5090 5002 *
5091 5003 * INPUTS:
5092 5004 * statep : RC statep associated with the post
5093 5005 * msgp : CM MAD to be posted
5094 5006 * post_cb : non-NULL callback address implies non-blocking post
5095 5007 * args : Args to ibmf send callback
5096 5008 *
5097 5009 * RETURN VALUE: based on ibmf_send_mad
5098 5010 */
5099 5011 void
5100 5012 ibcm_post_rc_mad(ibcm_state_data_t *statep, ibmf_msg_t *msgp,
5101 5013 ibmf_msg_cb_t post_cb, void *args)
5102 5014 {
5103 5015 ibt_status_t status;
5104 5016
5105 5017 mutex_enter(&statep->state_mutex);
5106 5018 statep->post_time = gethrtime();
5107 5019 mutex_exit(&statep->state_mutex);
5108 5020 status = ibcm_post_mad(msgp, &statep->stored_reply_addr, post_cb,
5109 5021 args);
5110 5022 if ((status != IBT_SUCCESS) && (post_cb != NULL))
5111 5023 /* Call ibmf callback directly */
5112 5024 (*post_cb)(NULL, msgp, args);
5113 5025 }
5114 5026
5115 5027
5116 5028 /*
5117 5029 * ibcm_post_ud_mad
5118 5030 * Posts a CM MAD associated with a UD statep
5119 5031 *
5120 5032 * INPUTS:
5121 5033 * ud_statep : UD statep associated with the post
5122 5034 * msgp : CM MAD to be posted
5123 5035 * post_cb : non-NULL callback address implies non-blocking post
5124 5036 * args : Args to ibmf send callback
5125 5037 *
5126 5038 * RETURN VALUE: based on ibmf_send_mad
5127 5039 */
5128 5040 void
5129 5041 ibcm_post_ud_mad(ibcm_ud_state_data_t *ud_statep, ibmf_msg_t *msgp,
5130 5042 ibmf_msg_cb_t ud_post_cb, void *args)
5131 5043 {
5132 5044 ibt_status_t status;
5133 5045 status = ibcm_post_mad(msgp, &ud_statep->ud_stored_reply_addr,
5134 5046 ud_post_cb, args);
5135 5047 if ((status != IBT_SUCCESS) && (ud_post_cb != NULL))
5136 5048 /* Call ibmf callback directly */
5137 5049 (*ud_post_cb)(NULL, msgp, args);
5138 5050 }
5139 5051
5140 5052 /*
5141 5053 * ibcm_post_mad:
5142 5054 * Posts CM MAD using IBMF in blocking mode
5143 5055 *
5144 5056 * INPUTS:
5145 5057 * msgp : CM MAD to be posted
5146 5058 * cm_mad_addr : Address information for the MAD to be posted
5147 5059 * post_cb : non-NULL callback address implies non-blocking post
5148 5060 * args : Args to ibmf send callback
5149 5061 *
5150 5062 * RETURN VALUE: based on ibmf_send_mad
5151 5063 */
5152 5064 ibt_status_t
5153 5065 ibcm_post_mad(ibmf_msg_t *msgp, ibcm_mad_addr_t *cm_mad_addr,
5154 5066 ibmf_msg_cb_t post_cb, void *args)
5155 5067 {
5156 5068 int post_status;
5157 5069
5158 5070 IBTF_DPRINTF_L5(cmlog, "ibcm_post_mad: "
5159 5071 "ibmf_msg_t = %p, cm_madd_adr = %p", msgp, cm_mad_addr);
5160 5072
5161 5073 IBTF_DPRINTF_L4(cmlog, "ibcm_post_mad: dlid = %x, d_qno= %x",
5162 5074 cm_mad_addr->rcvd_addr.ia_remote_lid,
5163 5075 cm_mad_addr->rcvd_addr.ia_remote_qno);
5164 5076 IBTF_DPRINTF_L4(cmlog, "ibcm_post_mad: p_key = %x, q_key = %x, "
5165 5077 "sl = %x, grh_exists = %x",
5166 5078 cm_mad_addr->rcvd_addr.ia_p_key, cm_mad_addr->rcvd_addr.ia_q_key,
5167 5079 cm_mad_addr->rcvd_addr.ia_service_level, cm_mad_addr->grh_exists);
5168 5080
5169 5081 /* Copy local addressing info */
5170 5082 msgp->im_local_addr = cm_mad_addr->rcvd_addr;
5171 5083
5172 5084 /* Copy global/GRH addressing info */
5173 5085 if (cm_mad_addr->grh_exists == B_TRUE)
5174 5086 msgp->im_global_addr = cm_mad_addr->grh_hdr;
5175 5087
5176 5088 if (post_cb)
5177 5089 ibcm_flow_inc();
5178 5090 post_status = ibmf_msg_transport(
5179 5091 cm_mad_addr->ibmf_hdl, cm_mad_addr->cm_qp_entry->qp_cm, msgp,
5180 5092 NULL, post_cb, args, 0);
5181 5093 if (post_status != IBMF_SUCCESS) {
5182 5094 IBTF_DPRINTF_L2(cmlog, "ibcm_post_mad: ibmf_msg_transport "
5183 5095 "failed: status %d, cb = %p", post_status, post_cb);
5184 5096 /* Analyze the reason for failure */
5185 5097 return (ibcm_ibmf_analyze_error(post_status));
5186 5098 }
5187 5099
5188 5100 return (IBT_SUCCESS);
5189 5101 }
5190 5102
5191 5103
5192 5104 /*
5193 5105 * ibcm_process_get_classport_info:
5194 5106 * Get classportinfo
5195 5107 *
5196 5108 * INPUTS:
5197 5109 * hcap - HCA entry pointer
5198 5110 * input_madp - Input MAD pointer
5199 5111 * cm_mad_addr - Address information for the MAD to be posted
5200 5112 *
5201 5113 * RETURN VALUE: NONE
5202 5114 */
5203 5115 static void
5204 5116 ibcm_process_get_classport_info(ibcm_hca_info_t *hcap, uint8_t *input_madp,
5205 5117 ibcm_mad_addr_t *cm_mad_addr)
5206 5118 {
5207 5119 ibmf_msg_t *msgp;
5208 5120
5209 5121 IBTF_DPRINTF_L5(cmlog, "ibcm_process_get_classport_info: (%p, %p, %p)",
5210 5122 hcap, input_madp, cm_mad_addr);
5211 5123
5212 5124 if (ibcm_alloc_out_msg(cm_mad_addr->ibmf_hdl, &msgp,
5213 5125 MAD_METHOD_GET_RESPONSE) != IBT_SUCCESS) {
5214 5126 IBTF_DPRINTF_L2(cmlog, "ibcm_process_get_classport_info: "
5215 5127 "ibcm_alloc_out_msg failed");
5216 5128 return;
5217 5129 }
5218 5130
5219 5131 /* copy the transaction id from input get mad */
5220 5132 IBCM_OUT_HDRP(msgp)->TransactionID =
5221 5133 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
5222 5134 IBCM_OUT_HDRP(msgp)->AttributeID = h2b16(MAD_ATTR_ID_CLASSPORTINFO);
5223 5135
5224 5136 bcopy(&ibcm_clpinfo, IBCM_OUT_MSGP(msgp), sizeof (ibcm_clpinfo));
5225 5137
5226 5138 (void) ibcm_post_mad(msgp, cm_mad_addr, NULL, NULL);
5227 5139 (void) ibcm_free_out_msg(cm_mad_addr->ibmf_hdl, &msgp);
5228 5140
5229 5141 IBTF_DPRINTF_L4(cmlog, "ibcm_process_get_classport_info: done");
5230 5142 }
5231 5143
5232 5144 /*
5233 5145 * ibcm_decode_classport_info:
5234 5146 * Decode classportinfo
5235 5147 *
5236 5148 * INPUTS:
5237 5149 * hcap - HCA entry pointer
5238 5150 * cm_mad_addr - Address information for the MAD to be posted
5239 5151 * input_madp - Input MAD pointer
5240 5152 *
5241 5153 * RETURN VALUE: NONE
5242 5154 */
5243 5155 static void
5244 5156 ibcm_decode_classport_info(ibcm_hca_info_t *hcap, uint8_t *input_madp,
5245 5157 ibcm_mad_addr_t *cm_mad_addr)
5246 5158 {
5247 5159 ibcm_classportinfo_msg_t *portinfop = (ibcm_classportinfo_msg_t *)
5248 5160 (&input_madp[IBCM_MAD_HDR_SIZE]);
5249 5161 IBTF_DPRINTF_L5(cmlog, "ibcm_decode_classport_info: (%p, %p, %p)",
5250 5162 hcap, input_madp, cm_mad_addr);
5251 5163
5252 5164 /* Print various fields of received classportinfo in debuf buf */
5253 5165
5254 5166 IBTF_DPRINTF_L4(cmlog, "ibcm_decode_classport_info: "
5255 5167 "Base version %d Class version %d", portinfop->BaseVersion,
5256 5168 portinfop->ClassVersion);
5257 5169 IBTF_DPRINTF_L4(cmlog, "ibcm_decode_classport_info: "
5258 5170 "Cap Mask %d Resp Time %d", portinfop->CapabilityMask,
5259 5171 portinfop->RespTimeValue_plus);
5260 5172 }
5261 5173
5262 5174
5263 5175 /*
5264 5176 * ibcm_handler_conn_fail:
5265 5177 * Helper function used to call client handler for Conn fail event
5266 5178 *
5267 5179 * INPUTS:
5268 5180 * statep: The connection state pointer
5269 5181 * rej_type: Message being rejected
5270 5182 * rej_reason: Reason why CM is sending the REJ message
5271 5183 * client_data: Private data returned by the client for REJ
5272 5184 * client_data_len: Length of above client's private data.
5273 5185 *
5274 5186 * RETURN VALUE: Client Handler's return status
5275 5187 */
5276 5188 static void
5277 5189 ibcm_handler_conn_fail(ibcm_state_data_t *statep, uint8_t cf_code,
5278 5190 uint8_t cf_msg, ibt_cm_reason_t cf_reason, uint8_t *client_data,
5279 5191 ibt_priv_data_len_t client_data_len)
5280 5192 {
5281 5193 ibt_cm_event_t event;
5282 5194
5283 5195 ibcm_path_cache_purge();
5284 5196
5285 5197 if (statep->channel)
5286 5198 ibtl_cm_chan_open_is_aborted(statep->channel);
5287 5199
5288 5200 /* Invoke CM handler w/ event passed as arg */
5289 5201 if (statep->cm_handler != NULL) {
5290 5202 bzero(&event, sizeof (ibt_cm_event_t));
5291 5203
5292 5204 event.cm_type = IBT_CM_EVENT_FAILURE;
5293 5205 event.cm_channel = statep->channel;
5294 5206 event.cm_session_id = NULL;
5295 5207 event.cm_priv_data = NULL;
5296 5208 event.cm_priv_data_len = 0;
5297 5209
5298 5210 event.cm_event.failed.cf_code = cf_code;
5299 5211 event.cm_event.failed.cf_msg = cf_msg;
5300 5212 event.cm_event.failed.cf_reason = cf_reason;
5301 5213
5302 5214 ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_FAIL_EVENT);
5303 5215
5304 5216 (void) statep->cm_handler(statep->state_cm_private, &event,
5305 5217 NULL, client_data, client_data_len);
5306 5218
5307 5219 ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_FAIL_EVENT);
5308 5220 }
5309 5221 if (ibcm_enable_trace != 0)
5310 5222 ibcm_dump_conn_trace(statep);
5311 5223 mutex_enter(&statep->state_mutex);
5312 5224 ibcm_open_done(statep);
5313 5225 mutex_exit(&statep->state_mutex);
5314 5226 }
5315 5227
5316 5228 /*
5317 5229 * QP State transition functions here
5318 5230 *
5319 5231 * The brief description of these functions :
5320 5232 * Validate QP related attributes in the messages
5321 5233 * Call client/server callback handlers
5322 5234 * Change QP state
5323 5235 * Set QP attributes (modify QP)
5324 5236 * Fill up the response MADs
5325 5237 */
5326 5238
5327 5239 /*
5328 5240 * ibcm_set_primary_adds_vect:
5329 5241 * Helper function used to fill up ibt_adds_vect_t PRIMARY PATH
5330 5242 * (called from ibcm_cep_state_*() functions)
5331 5243 *
5332 5244 * INPUTS:
5333 5245 * statep : The connection state pointer
5334 5246 * adds_vectp : The ibt_adds_vect_t ptr that is being filled up
5335 5247 * msgp : CM REQ message that is the source of information
5336 5248 *
5337 5249 * RETURN VALUE: NONE
5338 5250 */
5339 5251 static void
5340 5252 ibcm_set_primary_adds_vect(ibcm_state_data_t *statep,
5341 5253 ibt_adds_vect_t *adds_vectp, ibcm_req_msg_t *msgp)
5342 5254 {
5343 5255 uint32_t flow_label20_res6_rate6;
5344 5256
5345 5257 flow_label20_res6_rate6 = b2h32(msgp->req_primary_flow_label_plus);
5346 5258
5347 5259 /* first setup the srvl, srate, dlid and dgid */
5348 5260 adds_vectp->av_srvl = msgp->req_primary_sl_plus >> 4;
5349 5261 adds_vectp->av_src_path = statep->prim_src_path_bits;
5350 5262
5351 5263 if (statep->mode == IBCM_PASSIVE_MODE) {
5352 5264 adds_vectp->av_dlid = b2h16(msgp->req_primary_l_port_lid);
5353 5265 adds_vectp->av_dgid.gid_prefix =
5354 5266 b2h64(msgp->req_primary_l_port_gid.gid_prefix);
5355 5267 adds_vectp->av_dgid.gid_guid =
5356 5268 b2h64(msgp->req_primary_l_port_gid.gid_guid);
5357 5269 adds_vectp->av_sgid.gid_prefix =
5358 5270 b2h64(msgp->req_primary_r_port_gid.gid_prefix);
5359 5271 adds_vectp->av_sgid.gid_guid =
5360 5272 b2h64(msgp->req_primary_r_port_gid.gid_guid);
5361 5273 adds_vectp->av_srate = flow_label20_res6_rate6 & 0x3f;
5362 5274 } else {
5363 5275 adds_vectp->av_dlid = b2h16(msgp->req_primary_r_port_lid);
5364 5276 adds_vectp->av_dgid.gid_prefix =
5365 5277 b2h64(msgp->req_primary_r_port_gid.gid_prefix);
5366 5278 adds_vectp->av_dgid.gid_guid =
5367 5279 b2h64(msgp->req_primary_r_port_gid.gid_guid);
5368 5280 adds_vectp->av_sgid.gid_prefix =
5369 5281 b2h64(msgp->req_primary_l_port_gid.gid_prefix);
5370 5282 adds_vectp->av_sgid.gid_guid =
5371 5283 b2h64(msgp->req_primary_l_port_gid.gid_guid);
5372 5284 adds_vectp->av_srate = statep->local_srate;
5373 5285 }
5374 5286
5375 5287 /* next copy off the GRH info if it exists */
5376 5288 if ((msgp->req_primary_sl_plus & 0x8) == 0) {
5377 5289 adds_vectp->av_send_grh = B_TRUE;
5378 5290 adds_vectp->av_flow = flow_label20_res6_rate6 >> 12;
5379 5291 adds_vectp->av_tclass = msgp->req_primary_traffic_class;
5380 5292 adds_vectp->av_hop = msgp->req_primary_hop_limit;
5381 5293 } else {
5382 5294 adds_vectp->av_send_grh = B_FALSE;
5383 5295 }
5384 5296 }
5385 5297
5386 5298
5387 5299 /*
5388 5300 * ibcm_set_alt_adds_vect:
5389 5301 * Helper function used to fill up ibt_adds_vect_t ALTERNATE PATH
5390 5302 * (called from ibcm_cep_state_*() functions)
5391 5303 *
5392 5304 * INPUTS:
5393 5305 * statep : The connection state pointer
5394 5306 * adds_vectp : The ibt_adds_vect_t ptr that is being filled up
5395 5307 * msgp : CM REQ message that is the source of information
5396 5308 *
5397 5309 * RETURN VALUE: NONE
5398 5310 */
5399 5311 static void
5400 5312 ibcm_set_alt_adds_vect(ibcm_state_data_t *statep,
5401 5313 ibt_adds_vect_t *adds_vectp, ibcm_req_msg_t *msgp)
5402 5314 {
5403 5315 ib_gid_t dgid;
5404 5316 ib_gid_t sgid;
5405 5317 uint32_t flow_label20_res6_rate6;
5406 5318
5407 5319 flow_label20_res6_rate6 = b2h32(msgp->req_alt_flow_label_plus);
5408 5320
5409 5321 /* first setup the srvl, srate, dlid and dgid */
5410 5322 adds_vectp->av_srvl = msgp->req_alt_sl_plus >> 4;
5411 5323 adds_vectp->av_src_path = statep->alt_src_path_bits;
5412 5324
5413 5325 if (statep->mode == IBCM_PASSIVE_MODE) {
5414 5326 adds_vectp->av_dlid = b2h16(msgp->req_alt_l_port_lid);
5415 5327 bcopy(&msgp->req_alt_l_port_gid[0], &dgid, sizeof (ib_gid_t));
5416 5328 bcopy(&msgp->req_alt_r_port_gid[0], &sgid, sizeof (ib_gid_t));
5417 5329 adds_vectp->av_srate = flow_label20_res6_rate6 & 0x3f;
5418 5330 } else {
5419 5331 adds_vectp->av_dlid = b2h16(msgp->req_alt_r_port_lid);
5420 5332 bcopy(&msgp->req_alt_r_port_gid[0], &dgid, sizeof (ib_gid_t));
5421 5333 bcopy(&msgp->req_alt_l_port_gid[0], &sgid, sizeof (ib_gid_t));
5422 5334 adds_vectp->av_srate = statep->local_alt_srate;
5423 5335 }
5424 5336 adds_vectp->av_dgid.gid_prefix = b2h64(dgid.gid_prefix);
5425 5337 adds_vectp->av_dgid.gid_guid = b2h64(dgid.gid_guid);
5426 5338 adds_vectp->av_sgid.gid_prefix = b2h64(sgid.gid_prefix);
5427 5339 adds_vectp->av_sgid.gid_guid = b2h64(sgid.gid_guid);
5428 5340
5429 5341 /* next copy off the GRH info if it exists */
5430 5342 if ((msgp->req_alt_sl_plus & 0x8) == 0) {
5431 5343 adds_vectp->av_send_grh = B_TRUE;
5432 5344 adds_vectp->av_flow = flow_label20_res6_rate6 >> 12;
5433 5345 adds_vectp->av_tclass = msgp->req_alt_traffic_class;
5434 5346 adds_vectp->av_hop = msgp->req_alt_hop_limit;
5435 5347 } else {
5436 5348 adds_vectp->av_send_grh = B_FALSE; /* no GRH */
5437 5349 }
5438 5350 }
5439 5351
5440 5352
5441 5353 /*
5442 5354 * ibcm_set_primary_cep_path:
5443 5355 * Helper function used to fill up ibt_cep_path_t PRIMARY PATH
5444 5356 * (called from ibcm_cep_state_*() functions)
5445 5357 *
5446 5358 * INPUTS:
5447 5359 * statep : The connection state pointer
5448 5360 * adds_vectp : The ibt_cep_path_t ptr that is being filled up
5449 5361 * msgp : CM REQ message that is the source of information
5450 5362 *
5451 5363 * RETURN VALUE: NONE
5452 5364 */
5453 5365 static ibt_status_t
5454 5366 ibcm_set_primary_cep_path(ibcm_state_data_t *statep, ibt_cep_path_t *pathp,
5455 5367 ibcm_req_msg_t *msgp)
5456 5368 {
5457 5369 ibt_status_t status;
5458 5370
5459 5371 /* validate the PKEY in REQ for prim port */
5460 5372 status = ibt_pkey2index_byguid(statep->local_hca_guid,
5461 5373 statep->prim_port, b2h16(msgp->req_part_key), &pathp->cep_pkey_ix);
5462 5374
5463 5375 if (status != IBT_SUCCESS) {
5464 5376 IBTF_DPRINTF_L2(cmlog, "ibcm_set_primary_cep_path: "
5465 5377 "statep 0x%p pkey %x prim_port %d ", statep,
5466 5378 b2h16(msgp->req_part_key), statep->prim_port);
5467 5379 IBTF_DPRINTF_L2(cmlog, "ibcm_set_primary_cep_path: "
5468 5380 "statep 0x%p Invalid PKEY on prim_port, status %d ",
5469 5381 statep, status);
5470 5382 return (status);
5471 5383 }
5472 5384 statep->pkey = b2h16(msgp->req_part_key);
5473 5385 ibcm_set_primary_adds_vect(statep, &pathp->cep_adds_vect, msgp);
5474 5386 return (IBT_SUCCESS);
5475 5387 }
5476 5388
5477 5389
5478 5390 /*
5479 5391 * ibcm_set_alt_cep_path:
5480 5392 * Helper function used to fill up ibt_cep_path_t ALTERNATE PATH
5481 5393 * (called from ibcm_cep_state_*() functions)
5482 5394 *
5483 5395 * INPUTS:
5484 5396 * statep : The connection state pointer
5485 5397 * adds_vectp : The ibt_cep_path_t ptr that is being filled up
5486 5398 * msgp : CM REQ message that is the source of information
5487 5399 *
5488 5400 * RETURN VALUE: NONE
5489 5401 */
5490 5402 static ibt_status_t
5491 5403 ibcm_set_alt_cep_path(ibcm_state_data_t *statep, ibt_cep_path_t *pathp,
5492 5404 ibcm_req_msg_t *msgp)
5493 5405 {
5494 5406 ibt_status_t status;
5495 5407
5496 5408 if (b2h16(msgp->req_alt_l_port_lid) == 0) {
5497 5409 /* no alternate path specified */
5498 5410 return (IBT_SUCCESS);
5499 5411 }
5500 5412
5501 5413 /* validate the PKEY in REQ for alt port */
5502 5414 status = ibt_pkey2index_byguid(statep->local_hca_guid,
5503 5415 statep->alt_port, b2h16(msgp->req_part_key), &pathp->cep_pkey_ix);
5504 5416
5505 5417 if (status != IBT_SUCCESS) {
5506 5418 IBTF_DPRINTF_L2(cmlog, "ibcm_set_alt_cep_path: "
5507 5419 "statep 0x%p pkey %x alt_port %d ", statep,
5508 5420 b2h16(msgp->req_part_key), statep->alt_port);
5509 5421 IBTF_DPRINTF_L2(cmlog, "ibcm_set_alt_cep_path: "
5510 5422 "statep 0x%p Invalid PKEY on alt_port, status %d ",
5511 5423 statep, status);
5512 5424 return (status);
5513 5425 }
5514 5426 pathp->cep_hca_port_num = statep->alt_port;
5515 5427 ibcm_set_alt_adds_vect(statep, &pathp->cep_adds_vect, msgp);
5516 5428 return (IBT_SUCCESS);
5517 5429
5518 5430 }
5519 5431
5520 5432 /*
5521 5433 * ibcm_compare_prim_alt_paths:
5522 5434 * Helper function used to find if primary and alternate paths are
5523 5435 * identical
5524 5436 * (called from ibcm_cep_state_req)
5525 5437 *
5526 5438 * INPUTS:
5527 5439 * req: Pointer to ibt_cm_req_rcv_t, filled before invoking
5528 5440 * the function
5529 5441 *
5530 5442 * RETURN VALUE: NONE
5531 5443 */
5532 5444
5533 5445 static boolean_t
5534 5446 ibcm_compare_prim_alt_paths(ibt_adds_vect_t *prim, ibt_adds_vect_t *alt)
5535 5447 {
5536 5448
5537 5449 if ((alt->av_dlid == prim->av_dlid) &&
5538 5450 (alt->av_dgid.gid_prefix == prim->av_dgid.gid_prefix) &&
5539 5451 (alt->av_dgid.gid_guid == prim->av_dgid.gid_guid) &&
5540 5452 (alt->av_sgid.gid_prefix == prim->av_sgid.gid_prefix) &&
5541 5453 (alt->av_sgid.gid_guid == prim->av_sgid.gid_guid) &&
5542 5454 (alt->av_src_path == prim->av_src_path)) {
5543 5455
5544 5456 return (B_TRUE);
5545 5457 }
5546 5458 return (B_FALSE);
5547 5459 }
5548 5460
5549 5461
5550 5462 /*
5551 5463 * ibcm_invoke_qp_modify:
5552 5464 * Helper function used to call ibt_modify_qp()
5553 5465 * called from ibcm_cep_state_req()/ibcm_cep_state_rep()
5554 5466 * It sets up qp_info/eec_info
5555 5467 *
5556 5468 * Sets state to RTR as well.
5557 5469 *
5558 5470 *
5559 5471 * INPUTS:
5560 5472 * statep: The connection state pointer
5561 5473 * req_msgp: The CM REQ message
5562 5474 *
5563 5475 * RETURN VALUE:
5564 5476 * IBT_SUCCESS - call succeeded
5565 5477 */
5566 5478 static ibt_status_t
5567 5479 ibcm_invoke_qp_modify(ibcm_state_data_t *statep, ibcm_req_msg_t *req_msgp,
5568 5480 ibcm_rep_msg_t *rep_msgp)
5569 5481 {
5570 5482 ibt_status_t status;
5571 5483 ibt_qp_info_t qp_info;
5572 5484 ibt_cep_modify_flags_t cep_flags;
5573 5485 ibt_tran_srv_t trans;
5574 5486
5575 5487 cep_flags = IBT_CEP_SET_INIT_RTR | IBT_CEP_SET_PKEY_IX;
5576 5488 trans = ((uint8_t *)&req_msgp->req_remote_eecn_plus)[3] >> 1 & 0x3;
5577 5489
5578 5490 ASSERT(statep->channel != NULL);
5579 5491
5580 5492 /*
5581 5493 * If alternate path is present in REQ message then
5582 5494 * OR in IBT_CEP_SET_ALT_PATH, if APM supported on hca
5583 5495 */
5584 5496 if (b2h16(req_msgp->req_alt_l_port_lid) != 0) {
5585 5497
5586 5498 if (statep->hcap->hca_caps & IBT_HCA_AUTO_PATH_MIG)
5587 5499 cep_flags |= IBT_CEP_SET_ALT_PATH;
5588 5500 /* default value of rep_failover is ACCEPT */
5589 5501 else {
5590 5502 rep_msgp->rep_target_delay_plus |=
5591 5503 IBT_CM_FAILOVER_REJ_NOTSUPP << 1;
5592 5504 IBTF_DPRINTF_L3(cmlog, "ibcm_invoke_qp_modify"
5593 5505 " Alt Path specified in REQ, but not supported");
5594 5506 }
5595 5507 }
5596 5508
5597 5509 /* If transport type is RD OR in IBC_CEP_SET_QKEY */
5598 5510 if (trans == IBT_RD_SRV) {
5599 5511 cep_flags |= IBT_CEP_SET_QKEY;
5600 5512 }
5601 5513
5602 5514 /* Start filling up ibt_qp_info_t. */
5603 5515 bzero(&qp_info, sizeof (qp_info));
5604 5516 qp_info.qp_trans = trans;
5605 5517 qp_info.qp_state = IBT_STATE_RTR;
5606 5518 qp_info.qp_flags = IBT_CEP_NO_FLAGS;
5607 5519
5608 5520 switch (trans) {
5609 5521 case IBT_RC_SRV:
5610 5522
5611 5523 if (statep->mode == IBCM_ACTIVE_MODE) {
5612 5524 /* Setting PSN on RQ */
5613 5525
5614 5526 IBCM_QPINFO_RC(qp_info).rc_rq_psn =
5615 5527 b2h32(req_msgp->req_starting_psn_plus) >> 8;
5616 5528
5617 5529 IBCM_QPINFO_RC(qp_info).rc_dst_qpn =
5618 5530 b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
5619 5531
5620 5532 /* RDMA resources taken from negotiated REP values */
5621 5533 IBCM_QPINFO_RC(qp_info).rc_rdma_ra_in =
5622 5534 rep_msgp->rep_initiator_depth;
5623 5535
5624 5536 } else { /* Passive side CM */
5625 5537 /* Setting PSN on SQ and RQ */
5626 5538 IBCM_QPINFO_RC(qp_info).rc_sq_psn =
5627 5539 IBCM_QPINFO_RC(qp_info).rc_rq_psn =
5628 5540 b2h32(rep_msgp->rep_starting_psn_plus) >> 8;
5629 5541
5630 5542 IBCM_QPINFO_RC(qp_info).rc_dst_qpn =
5631 5543 b2h32(req_msgp->req_local_qpn_plus) >> 8;
5632 5544
5633 5545 /* RDMA resources taken from negotiated REP values */
5634 5546 IBCM_QPINFO_RC(qp_info).rc_rdma_ra_in =
5635 5547 rep_msgp->rep_resp_resources;
5636 5548 }
5637 5549
5638 5550 /* XXX, Oh!, ibtl doesn't have interface for setting this */
5639 5551 IBCM_QPINFO_RC(qp_info).rc_min_rnr_nak =
5640 5552 ibcm_default_rnr_nak_time;
5641 5553 IBCM_QPINFO_RC(qp_info).rc_path_mtu =
5642 5554 req_msgp->req_mtu_plus >> 4;
5643 5555 IBCM_QPINFO_RC(qp_info).rc_retry_cnt =
5644 5556 ((uint8_t *)&req_msgp->req_starting_psn_plus)[3] & 0x7;
5645 5557 IBCM_QPINFO_RC(qp_info).rc_rnr_retry_cnt =
5646 5558 req_msgp->req_mtu_plus & 0x7;
5647 5559
5648 5560 if ((status = ibcm_set_primary_cep_path(statep,
5649 5561 &IBCM_QPINFO_RC(qp_info).rc_path, req_msgp)) !=
5650 5562 IBT_SUCCESS)
5651 5563 return (status);
5652 5564
5653 5565 if ((status = ibcm_set_alt_cep_path(statep,
5654 5566 &IBCM_QPINFO_RC(qp_info).rc_alt_path, req_msgp)) !=
5655 5567 IBT_SUCCESS)
5656 5568 return (status);
5657 5569
5658 5570 break;
5659 5571 case IBT_RD_SRV:
5660 5572 if (statep->mode == IBCM_ACTIVE_MODE) { /* look at REP msg */
5661 5573 IBCM_QPINFO(qp_info).rd.rd_qkey =
5662 5574 b2h32(rep_msgp->rep_local_qkey);
5663 5575 } else {
5664 5576 IBCM_QPINFO(qp_info).rd.rd_qkey =
5665 5577 b2h32(req_msgp->req_local_qkey);
5666 5578 }
5667 5579
5668 5580 break;
5669 5581
5670 5582 case IBT_UC_SRV:
5671 5583 if (statep->mode == IBCM_ACTIVE_MODE) { /* look at REP msg */
5672 5584 IBCM_QPINFO_UC(qp_info).uc_sq_psn =
5673 5585 b2h32(req_msgp->req_starting_psn_plus) >> 8;
5674 5586 IBCM_QPINFO_UC(qp_info).uc_dst_qpn =
5675 5587 b2h32(rep_msgp->rep_local_qpn_plus) >> 8;
5676 5588 } else {
5677 5589 IBCM_QPINFO_UC(qp_info).uc_rq_psn =
5678 5590 IBCM_QPINFO_UC(qp_info).uc_sq_psn =
5679 5591 b2h32(rep_msgp->rep_starting_psn_plus) >> 8;
5680 5592 IBCM_QPINFO_UC(qp_info).uc_dst_qpn =
5681 5593 b2h32(req_msgp->req_local_qpn_plus) >> 8;
5682 5594 }
5683 5595 IBCM_QPINFO_UC(qp_info).uc_path_mtu =
5684 5596 req_msgp->req_mtu_plus >> 4;
5685 5597
5686 5598 if ((status = ibcm_set_primary_cep_path(statep,
5687 5599 &IBCM_QPINFO_UC(qp_info).uc_path, req_msgp)) !=
5688 5600 IBT_SUCCESS)
5689 5601 return (status);
5690 5602
5691 5603 if ((status = ibcm_set_alt_cep_path(statep,
5692 5604 &IBCM_QPINFO_UC(qp_info).uc_alt_path, req_msgp)) !=
5693 5605 IBT_SUCCESS)
5694 5606 return (status);
5695 5607
5696 5608 break;
5697 5609 default:
5698 5610 IBTF_DPRINTF_L2(cmlog, "ibcm_invoke_qp_modify: "
5699 5611 "unknown svc_type = %x", trans);
5700 5612 break;
5701 5613 }
5702 5614
5703 5615 /* Call modify_qp */
5704 5616 status = ibt_modify_qp(statep->channel, cep_flags, &qp_info, NULL);
5705 5617 IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_qp_modify: statep 0x%p"
5706 5618 " ibt_modify_qp() Init to RTR returned = %d", statep, status);
5707 5619
5708 5620 if (status == IBT_SUCCESS)
5709 5621 ibcm_insert_trace(statep, IBCM_TRACE_INIT_RTR);
5710 5622 else
5711 5623 ibcm_insert_trace(statep, IBCM_TRACE_INIT_RTR_FAIL);
5712 5624
5713 5625 #ifdef DEBUG
5714 5626
5715 5627 print_modify_qp("Init to RTR", statep->channel, cep_flags, &qp_info);
5716 5628
5717 5629 if (statep->channel != NULL) {
5718 5630 ibt_qp_query_attr_t qp_attrs;
5719 5631
5720 5632 (void) ibt_query_qp(statep->channel, &qp_attrs);
5721 5633 IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_qp_modify: "
5722 5634 "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
5723 5635 }
5724 5636 #endif
5725 5637
5726 5638 return (status);
5727 5639 }
5728 5640
5729 5641
5730 5642 /*
5731 5643 * ibcm_verify_req_gids_and_svcid
5732 5644 * Validation of LIDs, GIDs and SVC ID
5733 5645 *
5734 5646 * INPUTS:
5735 5647 * statep - state pointer
5736 5648 * cm_req_msgp - REQ message pointer
5737 5649 *
5738 5650 * RETURN VALUE: IBCM_SUCCESS/IBCM_FAILURE
5739 5651 *
5740 5652 */
5741 5653 ibcm_status_t
5742 5654 ibcm_verify_req_gids_and_svcid(ibcm_state_data_t *statep,
5743 5655 ibcm_req_msg_t *cm_req_msgp)
5744 5656 {
5745 5657 ib_gid_t gid;
5746 5658 ib_gid_t agid;
5747 5659 ib_lid_t lid;
5748 5660 ibt_status_t status;
5749 5661 ibtl_cm_hca_port_t port;
5750 5662 ibt_cm_reason_t reject_reason = IBT_CM_SUCCESS;
5751 5663 ibcm_svc_info_t *svc_infop;
5752 5664 ibcm_svc_bind_t *svc_bindp;
5753 5665 ibcm_svc_bind_t *tmp_bindp;
5754 5666 ib_pkey_t pkey;
5755 5667 uint8_t port_num;
5756 5668 ib_guid_t hca_guid;
5757 5669 ibcm_ip_pvtdata_t *ip_data;
5758 5670
5759 5671 /* Verify LID and GID of primary port */
5760 5672
5761 5673 gid.gid_prefix = b2h64(cm_req_msgp->req_primary_r_port_gid.gid_prefix);
5762 5674 gid.gid_guid = b2h64(cm_req_msgp->req_primary_r_port_gid.gid_guid);
5763 5675
5764 5676 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p"
5765 5677 " PRIM _r_gid (%llx, %llx)", statep, gid.gid_prefix,
5766 5678 gid.gid_guid);
5767 5679
5768 5680 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
5769 5681 "PRIM passive lid %x", statep,
5770 5682 b2h16(cm_req_msgp->req_primary_r_port_lid));
5771 5683
5772 5684 /* Verify GID validity, if specified */
5773 5685 if ((status = ibtl_cm_get_hca_port(gid, 0, &port)) == IBT_SUCCESS) {
5774 5686
5775 5687 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
5776 5688 "prim_port_num %d", statep, port.hp_port);
5777 5689
5778 5690 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p "
5779 5691 "passive hca_guid 0x%llX", statep, port.hp_hca_guid);
5780 5692
5781 5693 port_num = port.hp_port;
5782 5694 hca_guid = port.hp_hca_guid;
5783 5695 }
5784 5696
5785 5697 if (status != IBT_SUCCESS) {
5786 5698 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids: statep 0x%p "
5787 5699 "ibtl_cm_get_hca_port() primary port failed = %d", statep,
5788 5700 status);
5789 5701 reject_reason = IBT_CM_PRIM_GID;
5790 5702 /* we will search for an acceptable GID to this port */
5791 5703 port_num = statep->stored_reply_addr.port_num;
5792 5704 hca_guid = statep->hcap->hca_guid;
5793 5705
5794 5706 } else if (port.hp_base_lid !=
5795 5707 (b2h16(cm_req_msgp->req_primary_r_port_lid) &
5796 5708 (~((1 << port.hp_lmc) - 1)))) {
5797 5709 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids: statep 0x%p "
5798 5710 "primary port lid invalid (%x, %x, %x)", statep,
5799 5711 port.hp_base_lid,
5800 5712 b2h16(cm_req_msgp->req_primary_r_port_lid), port.hp_lmc);
5801 5713 reject_reason = IBT_CM_PRIM_LID;
5802 5714 } else {
5803 5715
5804 5716 statep->local_hca_guid = port.hp_hca_guid;
5805 5717 statep->prim_port = port.hp_port;
5806 5718 statep->prim_src_path_bits =
5807 5719 b2h16(cm_req_msgp->req_primary_r_port_lid) -
5808 5720 port.hp_base_lid;
5809 5721
5810 5722 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
5811 5723 "statep 0x%p prim_port_path_bits %d ",
5812 5724 statep, statep->prim_src_path_bits);
5813 5725
5814 5726 /* Verify LID and GID of alternate port. Post REJ if invalid */
5815 5727
5816 5728 /* Need a bcopy, as alt port gid is unaligned in req message */
5817 5729 bcopy(&cm_req_msgp->req_alt_r_port_gid[0], &agid,
5818 5730 sizeof (ib_gid_t));
5819 5731 agid.gid_prefix = b2h64(agid.gid_prefix);
5820 5732 agid.gid_guid = b2h64(agid.gid_guid);
5821 5733
5822 5734 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: statep 0x%p"
5823 5735 " Alt port_gid is (%llX:%llX)", statep, agid.gid_prefix,
5824 5736 agid.gid_guid);
5825 5737
5826 5738 if ((agid.gid_prefix != 0) || (agid.gid_guid != 0)) {
5827 5739
5828 5740 /* Verify GID validity, if specified */
5829 5741 if ((status = ibtl_cm_get_hca_port(agid,
5830 5742 statep->local_hca_guid, &port)) != IBT_SUCCESS) {
5831 5743 IBTF_DPRINTF_L2(cmlog,
5832 5744 "ibcm_verify_req_gids: ibtl_cm_get_hca_port"
5833 5745 " statep 0x%p alternate port failed = %d",
5834 5746 statep, status);
5835 5747 reject_reason = IBT_CM_ALT_GID;
5836 5748
5837 5749 } else if (port.hp_base_lid !=
5838 5750 (b2h16(cm_req_msgp->req_alt_r_port_lid) &
5839 5751 (~((1 << port.hp_lmc) - 1)))) {
5840 5752
5841 5753 IBTF_DPRINTF_L2(cmlog,
5842 5754 "ibcm_verify_req_gids: statep 0x%p "
5843 5755 "alternate port lid invalid (%x, %x, %x)",
5844 5756 statep, port.hp_base_lid,
5845 5757 cm_req_msgp->req_alt_r_port_lid,
5846 5758 port.hp_lmc);
5847 5759 reject_reason = IBT_CM_ALT_LID;
5848 5760 } else { /* Alt LID and GID are valid */
5849 5761 statep->alt_port = port.hp_port;
5850 5762 statep->alt_src_path_bits =
5851 5763 b2h16(cm_req_msgp->req_alt_r_port_lid) -
5852 5764 port.hp_base_lid;
5853 5765
5854 5766 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
5855 5767 "statep 0x%p alt_port_num %d "
5856 5768 "alt_rc_hca_guid 0x%llX", statep,
5857 5769 port.hp_port, port.hp_hca_guid);
5858 5770
5859 5771 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
5860 5772 "statep 0x%p alt_port_path_bits %d ",
5861 5773 statep, statep->alt_src_path_bits);
5862 5774 }
5863 5775 }
5864 5776 }
5865 5777
5866 5778 mutex_enter(&ibcm_svc_info_lock);
5867 5779 svc_infop = ibcm_find_svc_entry(statep->svcid);
5868 5780
5869 5781 /*
5870 5782 * Note: When we return SUCCESS, the reader lock won't get dropped
5871 5783 * until after the cm_handler is called from ibcm_cep_state_req().
5872 5784 */
5873 5785
5874 5786 IBTF_DPRINTF_L4(cmlog, "ibcm_verify_req_gids: "
5875 5787 "ibcm_find_svc_entry found svc_infop %p", svc_infop);
5876 5788
5877 5789 /*
5878 5790 * Send REJ with reject reason "invalid service id" for the
5879 5791 * the following cases :-
5880 5792 * Service id is valid, but not available at gid/lid of REQ
5881 5793 * Service id is invalid
5882 5794 */
5883 5795
5884 5796 if (svc_infop == NULL || svc_infop->svc_bind_list == NULL) {
5885 5797 mutex_exit(&ibcm_svc_info_lock);
5886 5798
5887 5799 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid: "
5888 5800 "statep 0x%p svc_id %llX svc_infop NULL", statep,
5889 5801 statep->svcid);
5890 5802
5891 5803 /* Send a REJ with invalid SID reason */
5892 5804 ibcm_post_rej_mad(statep,
5893 5805 IBT_CM_INVALID_SID, IBT_CM_FAILURE_REQ, NULL, 0);
5894 5806 return (IBCM_FAILURE);
5895 5807 }
5896 5808
5897 5809 if (svc_infop->svc_rc_handler == NULL) {
5898 5810 mutex_exit(&ibcm_svc_info_lock);
5899 5811
5900 5812 /* Send a REJ with invalid SID reason */
5901 5813 ibcm_post_rej_mad(statep,
5902 5814 IBT_CM_INVALID_SRV_TYPE, IBT_CM_FAILURE_REQ, NULL, 0);
5903 5815 return (IBCM_FAILURE);
5904 5816 }
5905 5817
5906 5818 /*
5907 5819 * Check if ServiceID is in RDMA IP CM SID range, if yes, we parse
5908 5820 * the REQ's Private Data and verify for it's goodness.
5909 5821 */
5910 5822 if (((statep->svcid & IB_SID_IPADDR_PREFIX_MASK) == 0) &&
5911 5823 (statep->svcid & IB_SID_IPADDR_PREFIX)) {
5912 5824 ibt_ari_ip_t ari_ip;
5913 5825 boolean_t rdma_rej_mad = B_FALSE;
5914 5826
5915 5827 if (cm_req_msgp->req_private_data == NULL) {
5916 5828 mutex_exit(&ibcm_svc_info_lock);
5917 5829
5918 5830 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5919 5831 " RDMA CM IP REQ Priv Data is NULL");
5920 5832
5921 5833 /* Send a REJ with CONSUMER REJ */
5922 5834 ibcm_post_rej_mad(statep, IBT_CM_CONSUMER,
5923 5835 IBT_CM_FAILURE_REQ, NULL, 0);
5924 5836 return (IBCM_FAILURE);
5925 5837 }
5926 5838 ip_data = (ibcm_ip_pvtdata_t *)cm_req_msgp->req_private_data;
5927 5839
5928 5840 bzero(&ari_ip, sizeof (ibt_ari_ip_t));
5929 5841
5930 5842 /* RDMA IP CM Layer Rejects this */
5931 5843 if (ip_data->ip_MajV != IBT_CM_IP_MAJ_VER) {
5932 5844 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5933 5845 "IP MajorVer mis-match %d", ip_data->ip_MajV);
5934 5846 ari_ip.ip_reason = IBT_ARI_IP_MAJOR_VERSION;
5935 5847 ari_ip.ip_suggested_version = IBT_CM_IP_MAJ_VER;
5936 5848 ari_ip.ip_suggested = B_TRUE;
5937 5849 rdma_rej_mad = B_TRUE;
5938 5850 } else if (ip_data->ip_MinV != IBT_CM_IP_MIN_VER) {
5939 5851 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5940 5852 "IP MinorVer mis-match %d", ip_data->ip_MinV);
5941 5853 ari_ip.ip_reason = IBT_ARI_IP_MINOR_VERSION;
5942 5854 ari_ip.ip_suggested_version = IBT_CM_IP_MIN_VER;
5943 5855 ari_ip.ip_suggested = B_TRUE;
5944 5856 rdma_rej_mad = B_TRUE;
5945 5857 } else if ((ip_data->ip_ipv != IBT_CM_IP_IPV_V4) &&
5946 5858 (ip_data->ip_ipv != IBT_CM_IP_IPV_V6)) {
5947 5859 IBTF_DPRINTF_L2(cmlog, "ibcm_verify_req_gids_and_svcid:"
5948 5860 " Invalid IPV specified %d", ip_data->ip_ipv);
5949 5861 ari_ip.ip_reason = IBT_ARI_IP_IPV;
5950 5862 ari_ip.ip_suggested_version = IBT_CM_IP_IPV_V4;
5951 5863 ari_ip.ip_suggested = B_TRUE;
5952 5864 rdma_rej_mad = B_TRUE;
5953 5865 } else {
5954 5866 /*
5955 5867 * Validate whether ip_addr specified are non-NULL.
5956 5868 *
5957 5869 * NOTE:
5958 5870 * RDMA ULP which is servicing this SID, should validate
5959 5871 * the correctness of srcip/dstip and accordingly post
5960 5872 * REJ related to ibt_ari_ip_reason_t of
5961 5873 * IBT_ARI_IP_SRC_ADDR, IBT_ARI_IP_DST_ADDR and
5962 5874 * IBT_ARI_IP_UNKNOWN_ADDR.
5963 5875 */
5964 5876 if (ip_data->ip_ipv == IBT_CM_IP_IPV_V4) {
5965 5877 if (ip_data->ip_srcv4 == 0) {
5966 5878 IBTF_DPRINTF_L2(cmlog,
5967 5879 "ibcm_verify_req_gids_and_svcid: "
5968 5880 "Invalid NULL V4 SrcIp specified");
5969 5881 rdma_rej_mad = B_TRUE;
5970 5882 ari_ip.ip_reason = IBT_ARI_IP_SRC_ADDR;
5971 5883 ari_ip.ip_suggested = B_TRUE;
5972 5884 ari_ip.ip_suggested_version =
5973 5885 IBT_CM_IP_IPV_V4;
5974 5886 } else if (ip_data->ip_dstv4 == 0) {
5975 5887 IBTF_DPRINTF_L2(cmlog,
5976 5888 "ibcm_verify_req_gids_and_svcid: "
5977 5889 "Invalid NULL V4 DstIp specified");
5978 5890 rdma_rej_mad = B_TRUE;
5979 5891 ari_ip.ip_reason = IBT_ARI_IP_DST_ADDR;
5980 5892 ari_ip.ip_suggested = B_TRUE;
5981 5893 ari_ip.ip_suggested_version =
5982 5894 IBT_CM_IP_IPV_V4;
5983 5895 }
5984 5896 } else if (ip_data->ip_ipv == IBT_CM_IP_IPV_V6) {
5985 5897 if (IN6_IS_ADDR_UNSPECIFIED(
5986 5898 &ip_data->ip_srcv6)) {
5987 5899 IBTF_DPRINTF_L2(cmlog,
5988 5900 "ibcm_verify_req_gids_and_svcid: "
5989 5901 "Invalid NULL V6 SrcIp specified");
5990 5902 rdma_rej_mad = B_TRUE;
5991 5903 ari_ip.ip_reason = IBT_ARI_IP_SRC_ADDR;
5992 5904 ari_ip.ip_suggested = B_TRUE;
5993 5905 ari_ip.ip_suggested_version =
5994 5906 IBT_CM_IP_IPV_V6;
5995 5907 } else if (IN6_IS_ADDR_UNSPECIFIED(
5996 5908 &ip_data->ip_dstv6)) {
5997 5909 IBTF_DPRINTF_L2(cmlog,
5998 5910 "ibcm_verify_req_gids_and_svcid: "
5999 5911 "Invalid NULL V6 DstIp specified");
6000 5912 rdma_rej_mad = B_TRUE;
6001 5913 ari_ip.ip_reason = IBT_ARI_IP_DST_ADDR;
6002 5914 ari_ip.ip_suggested = B_TRUE;
6003 5915 ari_ip.ip_suggested_version =
6004 5916 IBT_CM_IP_IPV_V6;
6005 5917 }
6006 5918 }
6007 5919 /* TBD: IBT_ARI_IP_UNKNOWN_ADDR */
6008 5920 }
6009 5921 if (rdma_rej_mad == B_TRUE) {
6010 5922 ibt_ari_con_t cons_rej;
6011 5923
6012 5924 mutex_exit(&ibcm_svc_info_lock);
6013 5925
6014 5926 cons_rej.rej_ari_len = 1 + sizeof (ibt_ari_ip_t);
6015 5927 cons_rej.rej_ari[0] = 0; /* Rejected by CM Layer */
6016 5928 bcopy(&ari_ip, &cons_rej.rej_ari[1],
6017 5929 sizeof (ibt_ari_ip_t));
6018 5930 /* Send a REJ with CONSUMER REJ */
6019 5931 ibcm_post_rej_mad(statep, IBT_CM_CONSUMER,
6020 5932 IBT_CM_FAILURE_REQ, &cons_rej,
6021 5933 sizeof (ibt_ari_con_t));
6022 5934 return (IBCM_FAILURE);
6023 5935 }
6024 5936 }
6025 5937
6026 5938 /* find the best "bind" entry that enables this port */
6027 5939
6028 5940 pkey = b2h16(cm_req_msgp->req_part_key);
6029 5941 svc_bindp = NULL;
6030 5942 tmp_bindp = svc_infop->svc_bind_list;
6031 5943 while (tmp_bindp) {
6032 5944 if (tmp_bindp->sbind_hcaguid == hca_guid &&
6033 5945 tmp_bindp->sbind_port == port_num) {
6034 5946 if (gid.gid_guid ==
6035 5947 tmp_bindp->sbind_gid.gid_guid &&
6036 5948 gid.gid_prefix ==
6037 5949 tmp_bindp->sbind_gid.gid_prefix) {
6038 5950 /* gid match => really good match */
6039 5951 svc_bindp = tmp_bindp;
6040 5952 if (pkey == tmp_bindp->sbind_pkey)
6041 5953 /* absolute best match */
6042 5954 break;
6043 5955 } else if (svc_bindp == NULL) {
6044 5956 /* port match => a good match */
6045 5957 svc_bindp = tmp_bindp;
6046 5958 }
6047 5959 }
6048 5960 tmp_bindp = tmp_bindp->sbind_link;
6049 5961 }
6050 5962 if (svc_bindp == NULL) { /* port not enabled for this SID */
6051 5963 mutex_exit(&ibcm_svc_info_lock);
6052 5964 IBTF_DPRINTF_L2(cmlog,
6053 5965 "ibcm_verify_req_gids_and_svcid: statep 0x%p "
6054 5966 "no binding found", statep);
6055 5967 ibcm_post_rej_mad(statep,
6056 5968 IBT_CM_INVALID_SID, IBT_CM_FAILURE_REQ, NULL, 0);
6057 5969 return (IBCM_FAILURE);
6058 5970 }
6059 5971 /* copy the GID in case we need it in REJ below */
6060 5972 gid.gid_prefix = b2h64(svc_bindp->sbind_gid.gid_prefix);
6061 5973 gid.gid_guid = b2h64(svc_bindp->sbind_gid.gid_guid);
6062 5974
6063 5975 statep->state_cm_private = svc_bindp->sbind_cm_private;
6064 5976 statep->state_svc_infop = svc_infop;
6065 5977 statep->cm_handler = svc_infop->svc_rc_handler;
6066 5978 if (reject_reason == IBT_CM_SUCCESS)
6067 5979 IBCM_SVC_INCR(svc_infop);
6068 5980 mutex_exit(&ibcm_svc_info_lock);
6069 5981
6070 5982 /*
6071 5983 * If the service id is valid, but gid in REQ is invalid,
6072 5984 * then send a REJ with invalid gid
6073 5985 * For Invalid primary gid, the ARI field is filled with
6074 5986 * with gid from svcinfo
6075 5987 * For invalid prim/alt gid reject, CM uses one of the gids
6076 5988 * registered in ARI.
6077 5989 * For invalid prim/alt lid reject, CM uses the base lid in ARI
6078 5990 */
6079 5991 if (reject_reason != IBT_CM_SUCCESS) {
6080 5992
6081 5993 switch (reject_reason) {
6082 5994
6083 5995 case IBT_CM_PRIM_GID :
6084 5996 case IBT_CM_ALT_GID :
6085 5997 ibcm_post_rej_mad(statep,
6086 5998 reject_reason, IBT_CM_FAILURE_REQ,
6087 5999 &gid, sizeof (ib_gid_t));
6088 6000 break;
6089 6001
6090 6002 case IBT_CM_PRIM_LID :
6091 6003 case IBT_CM_ALT_LID :
6092 6004
6093 6005 lid = h2b16(port.hp_base_lid);
6094 6006 ibcm_post_rej_mad(statep,
6095 6007 reject_reason, IBT_CM_FAILURE_REQ,
6096 6008 &lid, sizeof (ib_lid_t));
6097 6009 break;
6098 6010 }
6099 6011
6100 6012 return (IBCM_FAILURE);
6101 6013 }
6102 6014
6103 6015 /* Service, primary/alt gid and lid are all valid */
6104 6016
6105 6017 return (IBCM_SUCCESS);
6106 6018 }
6107 6019
6108 6020 /*
6109 6021 * ibcm_cep_state_req:
6110 6022 * QP state transition function called for an incoming REQ on passive side
6111 6023 * LIDs and GIDs should be maintained and validated by the client handler
6112 6024 *
6113 6025 * INPUTS:
6114 6026 * statep - state pointer
6115 6027 * cm_req_msgp - REQ message pointer
6116 6028 * reject_reason - Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
6117 6029 * arej_info_len - Additional Rejection reason info length
6118 6030 *
6119 6031 * RETURN VALUE: IBCM_SEND_REP/IBCM_SEND_REJ
6120 6032 */
6121 6033 ibcm_status_t
6122 6034 ibcm_cep_state_req(ibcm_state_data_t *statep, ibcm_req_msg_t *cm_req_msgp,
6123 6035 ibt_cm_reason_t *reject_reason, uint8_t *arej_len)
6124 6036 {
6125 6037 void *priv_data = NULL;
6126 6038 ibt_cm_event_t event;
6127 6039 ibt_cm_status_t cb_status;
6128 6040 ibcm_status_t status;
6129 6041 ibt_cm_return_args_t ret_args;
6130 6042 ibcm_clnt_reply_info_t clnt_info;
6131 6043
6132 6044 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: statep 0x%p", statep);
6133 6045 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: SID 0x%lX",
6134 6046 b2h64(cm_req_msgp->req_svc_id));
6135 6047 /* client handler should be valid */
6136 6048 ASSERT(statep->cm_handler != NULL);
6137 6049
6138 6050 bzero(&event, sizeof (event));
6139 6051
6140 6052 /* Fill in ibt_cm_event_t */
6141 6053 event.cm_type = IBT_CM_EVENT_REQ_RCV;
6142 6054 event.cm_session_id = statep;
6143 6055 IBCM_EVT_REQ(event).req_service_id = b2h64(cm_req_msgp->req_svc_id);
6144 6056 IBCM_EVT_REQ(event).req_transport =
6145 6057 ((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] >> 1 & 0x3;
6146 6058 IBCM_EVT_REQ(event).req_timeout = ibt_ib2usec(
6147 6059 (((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] >> 3) & 0x1F);
6148 6060 IBCM_EVT_REQ(event).req_retry_cnt =
6149 6061 ((uint8_t *)&cm_req_msgp->req_starting_psn_plus)[3] & 0x7;
6150 6062 IBCM_EVT_REQ(event).req_rnr_retry_cnt = cm_req_msgp->req_mtu_plus & 0x7;
6151 6063 IBCM_EVT_REQ(event).req_pkey = b2h16(cm_req_msgp->req_part_key);
6152 6064 IBCM_EVT_REQ(event).req_rdma_ra_in =
6153 6065 ((uint8_t *)&cm_req_msgp->req_local_qpn_plus)[3];
6154 6066 IBCM_EVT_REQ(event).req_rdma_ra_out =
6155 6067 ((uint8_t *)&cm_req_msgp->req_local_eec_no_plus)[3];
6156 6068
6157 6069 /* Check for HCA limits for RDMA Resources */
6158 6070 if (IBCM_EVT_REQ(event).req_rdma_ra_in >
6159 6071 statep->hcap->hca_max_rdma_in_qp) {
6160 6072 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p, REQ "
6161 6073 "req_rdma_ra_in %d is greater than HCA Limit %d, resetting"
6162 6074 "it to HCA limit", statep,
6163 6075 IBCM_EVT_REQ(event).req_rdma_ra_in,
6164 6076 statep->hcap->hca_max_rdma_in_qp);
6165 6077 IBCM_EVT_REQ(event).req_rdma_ra_in =
6166 6078 statep->hcap->hca_max_rdma_in_qp;
6167 6079 }
6168 6080
6169 6081 if (IBCM_EVT_REQ(event).req_rdma_ra_out >
6170 6082 statep->hcap->hca_max_rdma_out_qp) {
6171 6083 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p, REQ "
6172 6084 "req_rdma_ra_out %d is greater than HCA Limit %d, resetting"
6173 6085 "it to HCA limit", statep,
6174 6086 IBCM_EVT_REQ(event).req_rdma_ra_out,
6175 6087 statep->hcap->hca_max_rdma_out_qp);
6176 6088 IBCM_EVT_REQ(event).req_rdma_ra_out =
6177 6089 statep->hcap->hca_max_rdma_out_qp;
6178 6090 }
6179 6091
6180 6092 /* Account for CM and other software delays */
6181 6093 if (IBCM_EVT_REQ(event).req_timeout > ibcm_sw_delay) {
6182 6094 IBCM_EVT_REQ(event).req_timeout -= ibcm_sw_delay;
6183 6095 IBTF_DPRINTF_L5(cmlog, "ibcm_cep_state_req: statep 0x%p"
6184 6096 "Avail resp time %d (usec)", statep,
6185 6097 IBCM_EVT_REQ(event).req_timeout);
6186 6098 } else {
6187 6099 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p "
6188 6100 "REQ rem_resp_time < local sw delay 0x%x", statep,
6189 6101 IBCM_EVT_REQ(event).req_timeout);
6190 6102
6191 6103 IBCM_EVT_REQ(event).req_timeout = 0;
6192 6104 }
6193 6105
6194 6106 IBCM_EVT_REQ(event).req_prim_hca_port = statep->prim_port;
6195 6107 IBCM_EVT_REQ(event).req_alt_hca_port = statep->alt_port;
6196 6108 IBCM_EVT_REQ(event).req_hca_guid = statep->local_hca_guid;
6197 6109 IBCM_EVT_REQ(event).req_remote_qpn = statep->remote_qpn;
6198 6110
6199 6111 if (((uint8_t *)&cm_req_msgp->req_remote_eecn_plus)[3] &
6200 6112 IBT_CM_FLOW_CONTROL)
6201 6113 IBCM_EVT_REQ(event).req_flags |= IBT_CM_FLOW_CONTROL;
6202 6114
6203 6115 if ((cm_req_msgp->req_max_cm_retries_plus >> 3) & 0x1)
6204 6116 IBCM_EVT_REQ(event).req_flags |= IBT_CM_SRQ_EXISTS;
6205 6117
6206 6118 /* Initialize req.req_prim_addr */
6207 6119 ibcm_set_primary_adds_vect(statep, &IBCM_EVT_REQ(event).req_prim_addr,
6208 6120 cm_req_msgp);
6209 6121
6210 6122 /* Initialize req.req_alternate_path if they exist */
6211 6123 if (b2h16(cm_req_msgp->req_alt_l_port_lid) != 0) {
6212 6124 ibcm_set_alt_adds_vect(statep,
6213 6125 &IBCM_EVT_REQ(event).req_alt_addr, cm_req_msgp);
6214 6126
6215 6127 /* Verify, alt path is not same as primary */
6216 6128 if (ibcm_compare_prim_alt_paths(
6217 6129 &event.cm_event.req.req_prim_addr,
6218 6130 &event.cm_event.req.req_alt_addr) == B_TRUE) {
6219 6131 /* XXX New REJ code needed */
6220 6132 *reject_reason = IBT_CM_NO_RESC;
6221 6133 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_req: statep 0x%p"
6222 6134 " Alt and prim paths are same", statep);
6223 6135 mutex_enter(&ibcm_svc_info_lock);
6224 6136 IBCM_SVC_DECR(statep->state_svc_infop);
6225 6137 mutex_exit(&ibcm_svc_info_lock);
6226 6138 return (IBCM_SEND_REJ);
6227 6139 }
6228 6140 }
6229 6141
6230 6142 #ifdef NO_EEC_SUPPORT_YET
6231 6143 IBCM_EVT_REQ(event).req_rdc_exists = cm_req_msgp->req_mtu_plus >> 3 & 1;
6232 6144 IBCM_EVT_REQ(event).req_remote_eecn =
6233 6145 b2h32(cm_req_msgp->req_remote_eecn_plus) >> 8;
6234 6146 IBCM_EVT_REQ(event).req_local_eecn =
6235 6147 b2h32(cm_req_msgp->req_local_eec_no_plus) >> 8;
6236 6148 IBCM_EVT_REQ(event).req_remote_qkey =
6237 6149 b2h32(cm_req_msgp->req_local_qkey);
6238 6150 #endif
6239 6151
6240 6152 /* cm_req_msgp->req_private_data to event.cm_event.cm_priv_data */
6241 6153 event.cm_priv_data = cm_req_msgp->req_private_data;
6242 6154
6243 6155 event.cm_priv_data_len = IBT_REQ_PRIV_DATA_SZ;
6244 6156
6245 6157 /*
6246 6158 * Allocate priv_data of size IBT_MAX_PRIV_DATA_SZ
6247 6159 */
6248 6160 priv_data = kmem_zalloc(IBT_MAX_PRIV_DATA_SZ, KM_SLEEP);
6249 6161
6250 6162 bzero(&ret_args, sizeof (ret_args));
6251 6163
6252 6164 /* Fill in the default values from REQ, that client can modify */
6253 6165 ret_args.cm_ret.rep.cm_rdma_ra_in = IBCM_EVT_REQ(event).req_rdma_ra_out;
6254 6166 ret_args.cm_ret.rep.cm_rdma_ra_out = IBCM_EVT_REQ(event).req_rdma_ra_in;
6255 6167 ret_args.cm_ret.rep.cm_rnr_retry_cnt = cm_req_msgp->req_mtu_plus & 0x7;
6256 6168
6257 6169 ibcm_insert_trace(statep, IBCM_TRACE_CALLED_REQ_RCVD_EVENT);
6258 6170
6259 6171 /* Invoke the client handler */
6260 6172 statep->req_msgp = cm_req_msgp;
6261 6173 cb_status = statep->cm_handler(statep->state_cm_private, &event,
6262 6174 &ret_args, priv_data, IBT_REP_PRIV_DATA_SZ);
6263 6175 statep->req_msgp = NULL;
6264 6176
6265 6177 ibcm_insert_trace(statep, IBCM_TRACE_RET_REQ_RCVD_EVENT);
↓ open down ↓ |
1172 lines elided |
↑ open up ↑ |
6266 6178
6267 6179 mutex_enter(&ibcm_svc_info_lock);
6268 6180 IBCM_SVC_DECR(statep->state_svc_infop);
6269 6181 mutex_exit(&ibcm_svc_info_lock);
6270 6182
6271 6183 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_req: Client handler returned %d"
6272 6184 " statep 0x%p", cb_status, statep);
6273 6185
6274 6186 if (cb_status == IBT_CM_DEFER) {
6275 6187
6276 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
6277 -
6278 6188 if (statep->defer_cm_msg == NULL)
6279 6189 statep->defer_cm_msg =
6280 6190 kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
6281 6191 bcopy(cm_req_msgp, statep->defer_cm_msg, IBCM_MSG_SIZE);
6282 6192
6283 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
6284 -
6285 6193 /*
6286 6194 * unblock any blocked cm proceed api calls. Do not access
6287 6195 * statep after cv_signal
6288 6196 */
6289 6197 mutex_enter(&statep->state_mutex);
6290 6198 statep->clnt_proceed = IBCM_UNBLOCK;
6291 6199 cv_broadcast(&statep->block_client_cv);
6292 6200 mutex_exit(&statep->state_mutex);
6293 6201
6294 6202 kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
6295 6203 return (IBCM_DEFER);
6296 6204 }
6297 6205
6298 6206 /* fail any blocked cm proceed api call - client bug */
6299 6207 mutex_enter(&statep->state_mutex);
6300 6208 statep->clnt_proceed = IBCM_FAIL;
6301 6209 cv_broadcast(&statep->block_client_cv);
6302 6210 mutex_exit(&statep->state_mutex);
6303 6211
6304 6212 clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
6305 6213 clnt_info.priv_data = priv_data;
6306 6214 clnt_info.priv_data_len = ret_args.cm_ret_len;
6307 6215
6308 6216 status =
6309 6217 ibcm_process_cep_req_cm_hdlr(statep, cb_status,
6310 6218 &clnt_info, reject_reason, arej_len, cm_req_msgp);
6311 6219 kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
6312 6220 return (status);
6313 6221 }
6314 6222
6315 6223 /*
6316 6224 * ibcm_process_cep_req_cm_hdlr:
6317 6225 * Processes the response from client handler for an incoming REQ.
6318 6226 */
6319 6227 ibcm_status_t
6320 6228 ibcm_process_cep_req_cm_hdlr(ibcm_state_data_t *statep,
6321 6229 ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
6322 6230 ibt_cm_reason_t *reject_reason, uint8_t *arej_len,
6323 6231 ibcm_req_msg_t *cm_req_msg)
6324 6232 {
6325 6233 ibt_status_t status;
6326 6234 ibt_qp_query_attr_t qp_attrs;
6327 6235 ibcm_state_data_t *old_statep;
6328 6236 ibt_channel_hdl_t channel;
6329 6237 ib_guid_t local_ca_guid;
6330 6238 ibcm_rej_msg_t *rej_msgp;
6331 6239 #ifdef NO_EEC_SUPPORT_YET
6332 6240 ibt_eec_query_attr_t eec_attrs;
6333 6241 #endif
6334 6242
6335 6243 if (cb_status == IBT_CM_DEFAULT)
6336 6244 cb_status = IBT_CM_REJECT;
6337 6245
6338 6246 /* verify status */
6339 6247 if (cb_status == IBT_CM_ACCEPT) {
6340 6248 *reject_reason = IBT_CM_SUCCESS;
6341 6249 } else if (cb_status == IBT_CM_REJECT) {
6342 6250 *reject_reason = IBT_CM_CONSUMER;
6343 6251 } else if (cb_status == IBT_CM_REDIRECT_PORT) {
6344 6252 *reject_reason = IBT_CM_PORT_REDIRECT;
6345 6253 } else if (cb_status == IBT_CM_REDIRECT) {
6346 6254 *reject_reason = IBT_CM_REDIRECT_CM;
6347 6255 } else if (cb_status == IBT_CM_NO_CHANNEL) {
6348 6256 *reject_reason = IBT_CM_NO_CHAN;
6349 6257 } else if (cb_status == IBT_CM_NO_RESOURCE) {
6350 6258 *reject_reason = IBT_CM_NO_RESC;
6351 6259 } else {
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
6352 6260 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: statep %p"
6353 6261 " Client handler unexpected return %x", statep, cb_status);
6354 6262 *reject_reason = IBT_CM_CONSUMER;
6355 6263 }
6356 6264
6357 6265 /* client handler gave CM ok */
6358 6266 if (cb_status == IBT_CM_ACCEPT) {
6359 6267 ibcm_rep_msg_t *rep_msgp = (ibcm_rep_msg_t *)
6360 6268 IBCM_OUT_MSGP(statep->stored_msg);
6361 6269
6362 -
6363 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
6364 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rep_msgp))
6365 -
6366 6270 /*
6367 6271 * Check first if ret_args make sense. If not, bailout
6368 6272 * here rather than going along and panicing later.
6369 6273 */
6370 6274 channel = clnt_info->reply_event->rep.cm_channel;
6371 6275 if (IBCM_INVALID_CHANNEL(channel)) {
6372 6276 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6373 6277 "statep 0x%p server's QP handle is NULL", statep);
6374 6278 *reject_reason = IBT_CM_NO_CHAN;
6375 6279 }
6376 6280
6377 6281 IBCM_GET_CHAN_PRIVATE(channel, old_statep);
6378 6282
6379 6283 if ((*reject_reason == IBT_CM_SUCCESS) &&
6380 6284 (old_statep != NULL)) {
6381 6285 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6382 6286 "statep 0x%p Channel being re-used on passive side",
6383 6287 statep);
6384 6288 *reject_reason = IBT_CM_NO_CHAN;
6385 6289 }
6386 6290 if (old_statep != NULL)
6387 6291 IBCM_RELEASE_CHAN_PRIVATE(channel);
6388 6292
6389 6293 if (*reject_reason != IBT_CM_SUCCESS) {
6390 6294 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6391 6295 IBT_CM_FAILURE_REQ, *reject_reason, NULL, 0);
6392 6296 return (IBCM_SEND_REJ);
6393 6297 }
6394 6298
6395 6299 statep->channel = channel;
6396 6300 status = ibt_query_qp(channel, &qp_attrs);
6397 6301
6398 6302 if (status != IBT_SUCCESS) {
6399 6303 IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6400 6304 "statep %p ibt_query_qp failed %d", statep, status);
6401 6305 *reject_reason = IBT_CM_NO_RESC;
6402 6306 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6403 6307 IBT_CM_FAILURE_REQ, IBT_CM_CI_FAILURE, NULL, 0);
6404 6308 return (IBCM_SEND_REJ);
6405 6309 }
6406 6310
6407 6311 if (qp_attrs.qp_info.qp_trans != IBT_RC_SRV) {
6408 6312 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6409 6313 "statep %p qp is not RC channel on server", statep);
6410 6314 *reject_reason = IBT_CM_INVALID_SRV_TYPE;
6411 6315 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6412 6316 IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
6413 6317 NULL, 0);
6414 6318 return (IBCM_SEND_REJ);
6415 6319 }
6416 6320
6417 6321 if (qp_attrs.qp_info.qp_state != IBT_STATE_INIT &&
6418 6322 statep->is_this_ofuv_chan == B_FALSE) {
6419 6323 IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6420 6324 "qp state != INIT on server");
6421 6325 *reject_reason = IBT_CM_CHAN_INVALID_STATE;
6422 6326 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6423 6327 IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
6424 6328 NULL, 0);
6425 6329 return (IBCM_SEND_REJ);
6426 6330 } else if (statep->is_this_ofuv_chan &&
6427 6331 qp_attrs.qp_info.qp_state != IBT_STATE_RTR &&
6428 6332 qp_attrs.qp_info.qp_state != IBT_STATE_INIT) {
6429 6333 IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6430 6334 "qp state != INIT or RTR on server");
6431 6335 *reject_reason = IBT_CM_CHAN_INVALID_STATE;
6432 6336 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6433 6337 IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
6434 6338 NULL, 0);
6435 6339 return (IBCM_SEND_REJ);
6436 6340 }
6437 6341
6438 6342 if (statep->is_this_ofuv_chan &&
6439 6343 qp_attrs.qp_info.qp_state == IBT_STATE_RTR &&
6440 6344 qp_attrs.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
6441 6345 statep->prim_port) {
6442 6346 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6443 6347 "QP port invalid");
6444 6348 *reject_reason = IBT_CM_CHAN_INVALID_STATE;
6445 6349 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6446 6350 IBT_CM_FAILURE_REQ, IBT_CM_CHAN_INVALID_STATE,
6447 6351 NULL, 0);
6448 6352 return (IBCM_SEND_REJ);
6449 6353 } else if (statep->is_this_ofuv_chan &&
6450 6354 qp_attrs.qp_info.qp_state == IBT_STATE_RTR) {
6451 6355 goto skip_init_trans;
6452 6356 }
6453 6357
6454 6358 /* Init to Init, if required */
6455 6359 if (qp_attrs.qp_info.qp_transport.rc.rc_path.cep_hca_port_num !=
6456 6360 statep->prim_port) {
6457 6361
6458 6362 ibt_qp_info_t qp_info;
6459 6363 ibt_cep_modify_flags_t cep_flags;
6460 6364
6461 6365 IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6462 6366 "chan 0x%p chan port %d", channel,
6463 6367 qp_attrs.qp_info.qp_transport.rc.rc_path.\
6464 6368 cep_hca_port_num);
6465 6369
6466 6370 IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6467 6371 "chan 0x%p d path port %d", channel,
6468 6372 statep->prim_port);
6469 6373
6470 6374 bzero(&qp_info, sizeof (qp_info));
6471 6375 qp_info.qp_trans = IBT_RC_SRV;
6472 6376 qp_info.qp_state = IBT_STATE_INIT;
6473 6377 qp_info.qp_transport.rc.rc_path.cep_hca_port_num =
6474 6378 statep->prim_port;
6475 6379
6476 6380 cep_flags = IBT_CEP_SET_STATE | IBT_CEP_SET_PORT;
6477 6381
6478 6382 status = ibt_modify_qp(statep->channel, cep_flags,
6479 6383 &qp_info, NULL);
6480 6384
6481 6385 if (status != IBT_SUCCESS) {
6482 6386 IBTF_DPRINTF_L2(cmlog,
6483 6387 "ibcm_process_cep_req_cm_hdlr: "
6484 6388 "chan 0x%p ibt_modify_qp() = %d", channel,
6485 6389 status);
6486 6390 *reject_reason = IBT_CM_NO_RESC;
6487 6391
6488 6392 ibcm_insert_trace(statep,
6489 6393 IBCM_TRACE_INIT_INIT_FAIL);
6490 6394
6491 6395 ibcm_handler_conn_fail(statep,
6492 6396 IBT_CM_FAILURE_REJ_SENT, IBT_CM_FAILURE_REQ,
6493 6397 IBT_CM_CI_FAILURE, NULL, 0);
6494 6398 return (IBCM_SEND_REJ);
6495 6399 } else {
6496 6400 ibcm_insert_trace(statep,
6497 6401 IBCM_TRACE_INIT_INIT);
6498 6402
6499 6403 IBTF_DPRINTF_L5(cmlog,
6500 6404 "ibcm_process_cep_req_cm_hdlr: "
6501 6405 "chan 0x%p ibt_modify_qp() = %d", channel,
6502 6406 status);
6503 6407 }
6504 6408 }
6505 6409 skip_init_trans:
6506 6410 /* Do sanity tests even if we are skipping RTR */
6507 6411
6508 6412 /* fill in the REP msg based on ret_args from client */
6509 6413 if (clnt_info->reply_event->rep.cm_rdma_ra_out >
6510 6414 ((uint8_t *)&cm_req_msg->req_local_qpn_plus)[3]) {
6511 6415 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr "
6512 6416 "statep 0x%p ERROR: InitiatorDepth(%d) is Greater "
6513 6417 "than ResponderResource(%d)", statep,
6514 6418 clnt_info->reply_event->rep.cm_rdma_ra_out,
6515 6419 ((uint8_t *)&cm_req_msg->req_local_qpn_plus)[3]);
6516 6420 *reject_reason = IBT_CM_NOT_SUPPORTED;
6517 6421 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6518 6422 IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
6519 6423 return (IBCM_SEND_REJ);
6520 6424 }
6521 6425
6522 6426 /* Check for HCA limits for RDMA Resources */
6523 6427 if (clnt_info->reply_event->rep.cm_rdma_ra_in >
6524 6428 statep->hcap->hca_max_rdma_in_qp) {
6525 6429 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr: "
6526 6430 "statep %p, ERROR: client specified rdma_ra_in %d "
6527 6431 "is greater than HCA Limit %d, rejecting MAD",
6528 6432 statep, clnt_info->reply_event->rep.cm_rdma_ra_in,
6529 6433 statep->hcap->hca_max_rdma_in_qp);
6530 6434 *reject_reason = IBT_CM_NOT_SUPPORTED;
6531 6435 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6532 6436 IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
6533 6437 return (IBCM_SEND_REJ);
6534 6438 }
6535 6439
6536 6440 if (clnt_info->reply_event->rep.cm_rdma_ra_out >
6537 6441 statep->hcap->hca_max_rdma_out_qp) {
6538 6442 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr: "
6539 6443 "statep %p, ERROR: client specified rdma_ra_out %d "
6540 6444 "is greater than HCA Limit %d, rejecting MAD",
6541 6445 statep, clnt_info->reply_event->rep.cm_rdma_ra_out,
6542 6446 statep->hcap->hca_max_rdma_out_qp);
6543 6447 *reject_reason = IBT_CM_NOT_SUPPORTED;
6544 6448 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6545 6449 IBT_CM_FAILURE_REQ, IBT_CM_NOT_SUPPORTED, NULL, 0);
6546 6450 return (IBCM_SEND_REJ);
6547 6451 }
6548 6452
6549 6453 rep_msgp->rep_resp_resources =
6550 6454 clnt_info->reply_event->rep.cm_rdma_ra_in;
6551 6455 rep_msgp->rep_initiator_depth =
6552 6456 clnt_info->reply_event->rep.cm_rdma_ra_out;
6553 6457
6554 6458 /* IBT_CM_FLOW_CONTROL is always set by default. */
6555 6459 rep_msgp->rep_target_delay_plus |= IBT_CM_FLOW_CONTROL;
6556 6460
6557 6461 rep_msgp->rep_rnr_retry_cnt_plus =
6558 6462 (clnt_info->reply_event->rep.cm_rnr_retry_cnt & 0x7) << 5;
6559 6463
6560 6464 /*
6561 6465 * Check out whether SRQ is associated with this channel.
6562 6466 * If yes, then set the appropriate bit.
6563 6467 */
6564 6468 if (qp_attrs.qp_srq != NULL) {
6565 6469 rep_msgp->rep_rnr_retry_cnt_plus |= (1 << 4);
6566 6470 }
6567 6471
6568 6472 local_ca_guid = h2b64(statep->local_hca_guid);
6569 6473 bcopy(&local_ca_guid, rep_msgp->rep_local_ca_guid,
6570 6474 sizeof (ib_guid_t));
6571 6475
6572 6476 if (statep->is_this_ofuv_chan &&
6573 6477 qp_attrs.qp_info.qp_state == IBT_STATE_RTR)
6574 6478 goto skip_rtr_trans;
6575 6479
6576 6480 /* Transition QP from Init to RTR state */
6577 6481 if (ibcm_invoke_qp_modify(statep, cm_req_msg, rep_msgp) !=
6578 6482 IBT_SUCCESS) {
6579 6483
6580 6484 IBTF_DPRINTF_L2(cmlog, "ibcm_process_req_cm_hdlr "
6581 6485 "statep 0x%p ibcm_invoke_qp_modify failed because "
6582 6486 "of invalid data", statep);
6583 6487 *reject_reason = IBT_CM_NO_RESC;
6584 6488 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6585 6489 IBT_CM_FAILURE_REQ, IBT_CM_CI_FAILURE, NULL, 0);
6586 6490 return (IBCM_SEND_REJ);
6587 6491 }
6588 6492 skip_rtr_trans:
6589 6493
6590 6494 /*
6591 6495 * Link statep and channel, once CM determines it is
6592 6496 * post REP definitely.
6593 6497 */
6594 6498 IBCM_SET_CHAN_PRIVATE(statep->channel, statep);
6595 6499
6596 6500 /*
6597 6501 * Fill up the REP fields from ret_args
6598 6502 * failover status, from ret_args
6599 6503 *
6600 6504 * Fill up local QPN and EECN from ret_args->channel
6601 6505 */
6602 6506
6603 6507 /* fill in REP msg bytes Qkey, Starting PSN, 12-15, and 16-19 */
6604 6508 IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr: "
6605 6509 "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
6606 6510
6607 6511 rep_msgp->rep_local_qpn_plus = h2b32(qp_attrs.qp_qpn << 8);
6608 6512
6609 6513 statep->local_qpn = qp_attrs.qp_qpn;
6610 6514
6611 6515 switch (qp_attrs.qp_info.qp_trans) {
6612 6516 case IBT_RD_SRV:
6613 6517 rep_msgp->rep_local_qkey = h2b32(
6614 6518 qp_attrs.qp_info.qp_transport.rd.rd_qkey);
6615 6519 break;
6616 6520 case IBT_RC_SRV:
6617 6521 rep_msgp->rep_starting_psn_plus =
6618 6522 h2b32(IBCM_QP_RC(qp_attrs).rc_rq_psn << 8);
6619 6523 break;
6620 6524 case IBT_UC_SRV:
6621 6525 rep_msgp->rep_starting_psn_plus =
6622 6526 h2b32(IBCM_QP_UC(qp_attrs).uc_sq_psn << 8);
6623 6527 break;
6624 6528 }
6625 6529
6626 6530 #ifdef NO_EEC_SUPPORT_YET
6627 6531 if (ret_args.cm_channel.ch_eec != NULL) {
6628 6532 status = ibt_query_eec(ret_args.cm_channel.ch_eec,
6629 6533 &eec_attrs);
6630 6534 if (status == IBT_SUCCESS) {
6631 6535 rep_msgp->rep_local_eecn_plus =
6632 6536 h2b32(((uint32_t)eec_attrs.eec_eecn << 8));
6633 6537 }
6634 6538 }
6635 6539 #endif
6636 6540
6637 6541 /* figure out Target ACK delay */
6638 6542 rep_msgp->rep_target_delay_plus |= (status == IBT_SUCCESS) ?
6639 6543 statep->hcap->hca_ack_delay << 3 : 0;
↓ open down ↓ |
264 lines elided |
↑ open up ↑ |
6640 6544
6641 6545 IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr:statep %p "
6642 6546 "REP priv len %x", statep, clnt_info->priv_data_len);
6643 6547 /* Copy PrivateData from priv_data */
6644 6548 if (clnt_info->priv_data_len != 0) {
6645 6549 bcopy(clnt_info->priv_data, rep_msgp->rep_private_data,
6646 6550 min(IBT_REP_PRIV_DATA_SZ,
6647 6551 clnt_info->priv_data_len));
6648 6552 }
6649 6553
6650 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*statep))
6651 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rep_msgp))
6652 -
6653 6554 return (IBCM_SEND_REP);
6654 6555 }
6655 6556
6656 6557 /* REJ message */
6657 6558 rej_msgp = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
6658 6559
6659 6560 IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_req_cm_hdlr: statep %p REJ "
6660 6561 "priv len %x", statep, clnt_info->priv_data_len);
6661 6562
6662 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msgp))
6663 -
6664 6563 /* if priv_data_len != 0 use priv_data to copy back to rej_priv_data */
6665 6564 if (clnt_info->priv_data_len != 0) {
6666 6565 bcopy(clnt_info->priv_data, rej_msgp->rej_private_data,
6667 6566 min(IBT_REJ_PRIV_DATA_SZ, clnt_info->priv_data_len));
6668 6567 }
6669 6568
6670 6569 if (cb_status == IBT_CM_REDIRECT_PORT) {
6671 6570 ib_gid_t tgid;
6672 6571
6673 6572 tgid.gid_guid =
6674 6573 h2b64(clnt_info->reply_event->rej.ari_gid.gid_guid);
6675 6574 tgid.gid_prefix =
6676 6575 h2b64(clnt_info->reply_event->rej.ari_gid.gid_prefix);
6677 6576
6678 6577 *arej_len = sizeof (ib_gid_t);
6679 6578 bcopy(&tgid, &rej_msgp->rej_addl_rej_info, sizeof (ib_gid_t));
6680 6579
6681 6580 IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_req_cm_hdlr: ari_gid= "
6682 6581 "%llX:%llX", tgid.gid_prefix, tgid.gid_guid);
6683 6582
6684 6583 } else if (cb_status == IBT_CM_REDIRECT) {
6685 6584 ibcm_classportinfo_msg_t tclp;
6686 6585
6687 6586 ibcm_init_clp_to_mad(&tclp,
6688 6587 &clnt_info->reply_event->rej.ari_redirect);
6689 6588 bcopy(&tclp, rej_msgp->rej_addl_rej_info, sizeof (tclp));
6690 6589
6691 6590 *arej_len = sizeof (ibcm_classportinfo_msg_t);
6692 6591
6693 6592 } else if (cb_status == IBT_CM_REJECT) {
6694 6593
6695 6594 /* Fill up the REJ fields, from ret_args */
6696 6595 *arej_len = min(
6697 6596 clnt_info->reply_event->rej.ari_consumer.rej_ari_len,
6698 6597 IBT_CM_ADDL_REJ_LEN);
6699 6598 bcopy(clnt_info->reply_event->rej.ari_consumer.rej_ari,
6700 6599 &rej_msgp->rej_addl_rej_info, *arej_len);
6701 6600
6702 6601 /*
6703 6602 * RDMA IP REQ was passed up to the ULP, the ULP decided to do
6704 6603 * a "normal" consumer REJ, by the returning IBT_CM_REJECT in
6705 6604 * the cm handler.
6706 6605 * CM has to do some extra stuff too, it has to
6707 6606 * a) return REJ code 28 (consumer) and b) put 0x1 in the first
6708 6607 * byte of the ARI data, to indicate that this is a RDMA aware
6709 6608 * ULP that is doing a consumer reject. The ULP should have
6710 6609 * put its consumer specific data into ibt_arej_info_t(9s) at
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
6711 6610 * byte 1 of the rej_ari[] array.
6712 6611 */
6713 6612 if (((statep->svcid & IB_SID_IPADDR_PREFIX_MASK) == 0) &&
6714 6613 (statep->svcid & IB_SID_IPADDR_PREFIX)) {
6715 6614 rej_msgp->rej_addl_rej_info[0] = 1;
6716 6615 }
6717 6616 }
6718 6617
6719 6618 rej_msgp->rej_msg_type_plus = IBT_CM_FAILURE_REQ << 6;
6720 6619
6721 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msgp))
6722 -
6723 6620 return (IBCM_SEND_REJ);
6724 6621 }
6725 6622
6726 6623 /*
6727 6624 * ibcm_cep_state_rep:
6728 6625 * QP state transition function called for an incoming REP on active side
6729 6626 *
6730 6627 * INPUTS:
6731 6628 * statep - state pointer
6732 6629 * cm_rep_msg - REP message pointer
6733 6630 * reject_reason - Rejection reason See Section 12.6.7.2 rev1.0a IB Spec
6734 6631 *
6735 6632 * RETURN VALUE:
6736 6633 */
6737 6634 ibcm_status_t
6738 6635 ibcm_cep_state_rep(ibcm_state_data_t *statep, ibcm_rep_msg_t *cm_rep_msgp,
6739 6636 ibt_cm_reason_t *reject_reason, uint8_t *arej_len)
6740 6637 {
6741 6638 void *priv_data = NULL;
6742 6639 ibcm_status_t rval = IBCM_SEND_RTU;
6743 6640 ibt_cm_event_t event;
6744 6641 ibt_cm_status_t cb_status = IBT_CM_ACCEPT;
6745 6642 ibt_cm_return_args_t ret_args;
6746 6643 ibcm_clnt_reply_info_t clnt_info;
6747 6644 uint8_t req_init_depth;
6748 6645
6749 6646 IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rep: statep 0x%p", statep);
6750 6647
6751 6648 /* Check first if client handler is valid */
6752 6649 if (statep->cm_handler != NULL) {
6753 6650 /* initialize fields in ibt_cm_event_t */
6754 6651 bzero(&event, sizeof (event));
6755 6652 event.cm_type = IBT_CM_EVENT_REP_RCV;
6756 6653 event.cm_channel = statep->channel;
6757 6654 event.cm_session_id = statep;
6758 6655
6759 6656 IBCM_EVT_REP(event).rep_rdma_ra_in =
6760 6657 cm_rep_msgp->rep_initiator_depth;
6761 6658 req_init_depth =
6762 6659 ((uint8_t *)&(((ibcm_req_msg_t *)IBCM_OUT_MSGP(
6763 6660 statep->stored_msg))->req_local_eec_no_plus))[3];
6764 6661 IBCM_EVT_REP(event).rep_rdma_ra_out =
6765 6662 min(cm_rep_msgp->rep_resp_resources, req_init_depth);
6766 6663
6767 6664 IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rep: statep 0x%p, "
6768 6665 "InitDepth %d, RespResr %d", statep,
6769 6666 cm_rep_msgp->rep_initiator_depth,
6770 6667 IBCM_EVT_REP(event).rep_rdma_ra_out);
6771 6668
6772 6669 IBCM_EVT_REP(event).rep_service_time = ibt_ib2usec(
6773 6670 ((uint8_t *)&(((ibcm_req_msg_t *)IBCM_OUT_MSGP(
6774 6671 statep->stored_msg))->req_starting_psn_plus))[3] >> 3);
6775 6672
6776 6673 IBCM_EVT_REP(event).rep_service_time -=
6777 6674 2 * statep->pkt_life_time - ibcm_sw_delay;
6778 6675
6779 6676 IBCM_EVT_REP(event).rep_failover_status =
6780 6677 cm_rep_msgp->rep_target_delay_plus >> 1 & 3;
6781 6678
6782 6679 if (cm_rep_msgp->rep_target_delay_plus & 0x1)
6783 6680 IBCM_EVT_REP(event).rep_flags |= IBT_CM_FLOW_CONTROL;
6784 6681
6785 6682 if ((cm_rep_msgp->rep_rnr_retry_cnt_plus >> 4) & 0x1)
6786 6683 IBCM_EVT_REP(event).rep_flags |= IBT_CM_SRQ_EXISTS;
6787 6684
6788 6685 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rep: statep 0x%p "
6789 6686 "rep_service_time %d", statep,
6790 6687 IBCM_EVT_REP(event).rep_service_time);
6791 6688
6792 6689 event.cm_priv_data = &(cm_rep_msgp->rep_private_data[0]);
6793 6690 event.cm_priv_data_len = IBT_REP_PRIV_DATA_SZ;
6794 6691
6795 6692 /*
6796 6693 * Allocate priv_data of size IBT_MAX_PRIV_DATA_SZ
6797 6694 */
6798 6695 priv_data = kmem_zalloc(IBT_MAX_PRIV_DATA_SZ, KM_SLEEP);
6799 6696 bzero(&ret_args, sizeof (ret_args));
6800 6697
6801 6698
6802 6699 ibcm_insert_trace(statep, IBCM_TRACE_CALLED_REP_RCVD_EVENT);
6803 6700
6804 6701 /* invoke the CM handler */
6805 6702 cb_status = statep->cm_handler(statep->state_cm_private, &event,
6806 6703 &ret_args, priv_data, IBT_RTU_PRIV_DATA_SZ);
6807 6704
6808 6705 ibcm_insert_trace(statep, IBCM_TRACE_RET_REP_RCVD_EVENT);
6809 6706
6810 6707 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rep: statep 0x%p "
6811 6708 "Client handler returned %x", statep, cb_status);
6812 6709
6813 6710 if (cb_status == IBT_CM_DEFER) {
6814 6711 if (statep->defer_cm_msg == NULL)
6815 6712 statep->defer_cm_msg =
6816 6713 kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
6817 6714 bcopy(cm_rep_msgp, statep->defer_cm_msg, IBCM_MSG_SIZE);
6818 6715
6819 6716 /* unblock any blocked cm proceed api calls */
6820 6717 mutex_enter(&statep->state_mutex);
6821 6718 statep->clnt_proceed = IBCM_UNBLOCK;
6822 6719 cv_broadcast(&statep->block_client_cv);
6823 6720 mutex_exit(&statep->state_mutex);
6824 6721
6825 6722 kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
6826 6723 return (IBCM_DEFER);
6827 6724 }
6828 6725 }
6829 6726
6830 6727 /* fail any blocked cm proceed api calls - client bug */
6831 6728 mutex_enter(&statep->state_mutex);
6832 6729 statep->clnt_proceed = IBCM_FAIL;
6833 6730 cv_broadcast(&statep->block_client_cv);
6834 6731 mutex_exit(&statep->state_mutex);
6835 6732
6836 6733 clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
6837 6734 clnt_info.priv_data = priv_data;
6838 6735 clnt_info.priv_data_len = ret_args.cm_ret_len;
6839 6736
6840 6737 rval =
6841 6738 ibcm_process_cep_rep_cm_hdlr(statep, cb_status, &clnt_info,
6842 6739 reject_reason, arej_len, cm_rep_msgp);
6843 6740
6844 6741 if (priv_data != NULL)
6845 6742 kmem_free(priv_data, IBT_MAX_PRIV_DATA_SZ);
6846 6743 return (rval);
6847 6744 }
6848 6745
6849 6746
6850 6747 /*
6851 6748 * ibcm_process_cep_rep_cm_hdlr:
6852 6749 * Processes the response from client handler for an incoming REP.
6853 6750 */
6854 6751 ibcm_status_t
6855 6752 ibcm_process_cep_rep_cm_hdlr(ibcm_state_data_t *statep,
6856 6753 ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
6857 6754 ibt_cm_reason_t *reject_reason, uint8_t *arej_len,
6858 6755 ibcm_rep_msg_t *cm_rep_msgp)
6859 6756 {
6860 6757 ibcm_status_t rval = IBCM_SEND_RTU;
6861 6758 ibcm_rej_msg_t *rej_msgp;
6862 6759
6863 6760 if (cb_status == IBT_CM_DEFAULT)
6864 6761 cb_status = IBT_CM_ACCEPT;
6865 6762
6866 6763 if (cb_status == IBT_CM_REJECT) {
6867 6764 *reject_reason = IBT_CM_CONSUMER;
6868 6765 } else if (cb_status == IBT_CM_REDIRECT_PORT) {
6869 6766 *reject_reason = IBT_CM_PORT_REDIRECT;
6870 6767 } else if (cb_status == IBT_CM_REDIRECT) {
6871 6768 *reject_reason = IBT_CM_REDIRECT_CM;
6872 6769 } else if (cb_status == IBT_CM_NO_RESOURCE) {
6873 6770 *reject_reason = IBT_CM_NO_RESC;
6874 6771 } else if (cb_status != IBT_CM_ACCEPT) {
6875 6772 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep "
6876 6773 "0x%p, Client handler returned unexpected value %d",
6877 6774 statep, cb_status);
6878 6775 *reject_reason = IBT_CM_CONSUMER;
6879 6776 } else
6880 6777 *reject_reason = IBT_CM_SUCCESS;
6881 6778
6882 6779
6883 6780 /* We come here if status is ACCEPT or CM handler is NULL */
6884 6781 if (cb_status == IBT_CM_ACCEPT) {
6885 6782 ib_time_t time;
6886 6783
6887 6784 time = ibt_usec2ib(statep->pkt_life_time * 2 +
6888 6785 ibt_ib2usec(cm_rep_msgp->rep_target_delay_plus >> 3));
6889 6786
6890 6787 IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
↓ open down ↓ |
158 lines elided |
↑ open up ↑ |
6891 6788 " active cep_timeout(usec) 0x%x ", statep, time);
6892 6789
6893 6790 IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
6894 6791 " passive hca_ack_delay(ib_time) = 0x%x, ", statep,
6895 6792 cm_rep_msgp->rep_target_delay_plus >> 3);
6896 6793
6897 6794 IBTF_DPRINTF_L5(cmlog, "ibcm_process_cep_rep_cm_hdlr: statep %p"
6898 6795 " rnr_retry_cnt = 0x%x", statep,
6899 6796 cm_rep_msgp->rep_rnr_retry_cnt_plus >> 5);
6900 6797
6901 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
6902 6798 statep->starting_psn =
6903 6799 b2h32(cm_rep_msgp->rep_starting_psn_plus) >> 8;
6904 6800
6905 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*statep))
6906 -
6907 6801 /* Call IBTL CM's qp modify function from Init to RTR */
6908 6802 if (ibcm_invoke_qp_modify(statep,
6909 6803 (ibcm_req_msg_t *)IBCM_OUT_MSGP(statep->stored_msg),
6910 6804 cm_rep_msgp) != IBT_SUCCESS) {
6911 6805
6912 6806 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: "
6913 6807 "statep %p, ibcm_invoke_qp_modify to RTR failed",
6914 6808 statep);
6915 6809 *reject_reason = IBT_CM_NO_RESC;
6916 6810 /*
6917 6811 * Call modify qp function from RTR to RTS
6918 6812 * RDMA initiator depth on active is same as negotiated
6919 6813 * passive REP's responder resources
6920 6814 */
6921 6815 } else if (ibcm_invoke_rtu_qp_modify(statep, time, cm_rep_msgp)
6922 6816 != IBT_SUCCESS) {
6923 6817
6924 6818 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_rep_cm_hdlr: "
6925 6819 "statep %p ibcm_invoke_rtu_qp_modify to RTS failed",
6926 6820 statep);
6927 6821 (void) ibcm_cep_to_error_state(statep);
6928 6822 *reject_reason = IBT_CM_NO_RESC;
6929 6823 }
6930 6824
6931 6825 if (*reject_reason == IBT_CM_NO_RESC) {
6932 6826
6933 6827 /* Disassociate statep and QP */
6934 6828 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
6935 6829
6936 6830 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6937 6831 IBT_CM_FAILURE_REP, IBT_CM_CI_FAILURE, NULL, 0);
6938 6832 return (IBCM_SEND_REJ); /* send REJ */
6939 6833 }
6940 6834
6941 6835 if (clnt_info->priv_data_len != 0) {
6942 6836 ibcm_rtu_msg_t *rtu_msgp;
6943 6837 rtu_msgp = (ibcm_rtu_msg_t *)
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
6944 6838 IBCM_OUT_MSGP(statep->stored_msg);
6945 6839 bcopy(clnt_info->priv_data, rtu_msgp->rtu_private_data,
6946 6840 min(IBT_RTU_PRIV_DATA_SZ,
6947 6841 clnt_info->priv_data_len));
6948 6842 }
6949 6843
6950 6844 *reject_reason = IBT_CM_SUCCESS;
6951 6845 return (rval);
6952 6846 }
6953 6847
6954 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rej_msgp))
6955 -
6956 6848 /* Fill up the REJ fields, from ret_args */
6957 6849 rej_msgp = (ibcm_rej_msg_t *)IBCM_OUT_MSGP(statep->stored_msg);
6958 6850 rej_msgp->rej_msg_type_plus = IBT_CM_FAILURE_REP << 6;
6959 6851
6960 6852 /* if priv_len != 0 use priv_data to copy back to rej_priv_data */
6961 6853 if (clnt_info->priv_data_len != 0)
6962 6854 bcopy(clnt_info->priv_data, rej_msgp->rej_private_data,
6963 6855 min(IBT_REJ_PRIV_DATA_SZ, clnt_info->priv_data_len));
6964 6856
6965 6857 if (clnt_info->reply_event != NULL)
6966 6858 *arej_len =
6967 6859 min(clnt_info->reply_event->rej.ari_consumer.rej_ari_len,
6968 6860 IBT_CM_ADDL_REJ_LEN);
6969 6861
6970 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clnt_info->reply_event->rej))
6971 -
6972 6862 if (*arej_len != 0) /* asserts that clnt_info->reply_event != 0 */
6973 6863 bcopy(clnt_info->reply_event->rej.ari_consumer.rej_ari,
6974 6864 &rej_msgp->rej_addl_rej_info, *arej_len);
6975 6865
6976 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clnt_info->reply_event->rej))
6977 -
6978 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rej_msgp))
6979 -
6980 6866 rval = IBCM_SEND_REJ;
6981 6867
6982 6868 /* Disassociate statep and QP */
6983 6869 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
6984 6870
6985 6871 /* callback client, to enable client to do resource cleanup */
6986 6872 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
6987 6873 IBT_CM_FAILURE_REP, *reject_reason, NULL, 0);
6988 6874
6989 6875 return (rval);
6990 6876 }
6991 6877
6992 6878 /*
6993 6879 * ibcm_invoke_rtu_qp_modify:
6994 6880 * Helper function to modify QP for RTU only called from
6995 6881 * ibcm_cep_state_rtu() and ibcm_cep_send_rtu()
6996 6882 *
6997 6883 * INPUTS:
6998 6884 * statep - connection state pointer
6999 6885 *
7000 6886 * RETURN VALUE:
7001 6887 */
7002 6888 static ibt_status_t
7003 6889 ibcm_invoke_rtu_qp_modify(ibcm_state_data_t *statep, ib_time_t timeout,
7004 6890 ibcm_rep_msg_t *rep_msg)
7005 6891 {
7006 6892 ibt_status_t status;
7007 6893 ibt_qp_info_t qp_info;
7008 6894 ibt_cep_modify_flags_t cep_flags = IBT_CEP_SET_RTR_RTS;
7009 6895
7010 6896 /* Start filling up ibt_qp_info_t. */
7011 6897 bzero(&qp_info, sizeof (qp_info));
7012 6898 qp_info.qp_trans = ibtl_cm_get_chan_type(statep->channel);
7013 6899 qp_info.qp_current_state = IBT_STATE_RTR;
7014 6900
7015 6901 switch (qp_info.qp_trans) {
7016 6902 case IBT_RC_SRV:
7017 6903 IBCM_QPINFO_RC_PATH(qp_info).cep_timeout = timeout;
7018 6904 IBCM_QPINFO_RC(qp_info).rc_retry_cnt = statep->cep_retry_cnt;
7019 6905 IBCM_QPINFO_RC(qp_info).rc_rnr_retry_cnt =
7020 6906 statep->local_qp_rnr_cnt;
7021 6907 IBCM_QPINFO_RC(qp_info).rc_sq_psn = statep->starting_psn;
7022 6908
7023 6909 if (statep->mode == IBCM_ACTIVE_MODE) {
7024 6910 IBCM_QPINFO_RC(qp_info).rc_rdma_ra_out =
7025 6911 rep_msg->rep_resp_resources;
7026 6912 } else {
7027 6913 IBCM_QPINFO_RC(qp_info).rc_rdma_ra_out =
7028 6914 rep_msg->rep_initiator_depth;
7029 6915 }
7030 6916 if (statep->alt_port &&
7031 6917 (((rep_msg->rep_target_delay_plus >> 1) & 0x3) ==
7032 6918 IBT_CM_FAILOVER_ACCEPT)) {
7033 6919 /* failover was accepted */
7034 6920 cep_flags |= IBT_CEP_SET_MIG;
7035 6921 IBCM_QPINFO_RC(qp_info).rc_mig_state =
7036 6922 IBT_STATE_REARMED;
7037 6923 }
7038 6924
7039 6925 break;
7040 6926 /* XXX RD? */
7041 6927 case IBT_UC_SRV:
7042 6928 IBCM_QPINFO_UC_PATH(qp_info).cep_timeout = timeout;
7043 6929 break;
7044 6930 default:
7045 6931 IBTF_DPRINTF_L2(cmlog, "ibcm_invoke_rtu_qp_modify: "
7046 6932 "unknow svc_type = %x", qp_info.qp_trans);
7047 6933 break;
7048 6934 }
7049 6935
7050 6936 /* Call modify_qp */
7051 6937 status = ibt_modify_qp(statep->channel, cep_flags, &qp_info, NULL);
7052 6938 IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_rtu_qp_modify: statep 0x%p "
7053 6939 "modify qp status = %d", statep, status);
7054 6940
7055 6941 if (status == IBT_SUCCESS)
7056 6942 ibcm_insert_trace(statep, IBCM_TRACE_RTR_RTS);
7057 6943 else
7058 6944 ibcm_insert_trace(statep, IBCM_TRACE_RTR_RTS_FAIL);
7059 6945
7060 6946 #ifdef DEBUG
7061 6947 print_modify_qp("RTR to RTS", statep->channel, cep_flags, &qp_info);
7062 6948
7063 6949 if (statep->channel != NULL) {
7064 6950 ibt_qp_query_attr_t qp_attrs;
7065 6951
7066 6952 (void) ibt_query_qp(statep->channel, &qp_attrs);
7067 6953 IBTF_DPRINTF_L4(cmlog, "ibcm_invoke_rtu_qp_modify: "
7068 6954 "qp_info.qp_state = %x", qp_attrs.qp_info.qp_state);
7069 6955 }
7070 6956 #endif
7071 6957 return (status);
7072 6958 }
7073 6959
7074 6960
7075 6961 /*
7076 6962 * ibcm_cep_state_rtu:
7077 6963 * QP state transition function called for an incoming RTU
7078 6964 * on passive side.
7079 6965 *
7080 6966 * INPUTS:
7081 6967 * statep - connection state pointer
7082 6968 * cm_rtu_msg - RTU message pointer
7083 6969 *
7084 6970 */
7085 6971 void
7086 6972 ibcm_cep_state_rtu(ibcm_state_data_t *statep, ibcm_rtu_msg_t *cm_rtu_msgp)
7087 6973 {
7088 6974 ibt_status_t status;
7089 6975 ibt_cm_event_t event;
7090 6976 ibcm_rep_msg_t *rep_msgp = (ibcm_rep_msg_t *)
7091 6977 IBCM_OUT_MSGP(statep->stored_msg);
7092 6978
7093 6979 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rtu: statep 0x%p", statep);
7094 6980
7095 6981 ASSERT(statep->channel != NULL);
7096 6982
7097 6983 /* RDMA initiator depth taken from negotiated REP values */
7098 6984 status = ibcm_invoke_rtu_qp_modify(statep,
7099 6985 ibt_usec2ib(statep->remote_ack_delay), rep_msgp);
7100 6986
7101 6987 if (status != IBT_SUCCESS) {
7102 6988
7103 6989 (void) ibcm_cep_to_error_state(statep);
7104 6990 /*
7105 6991 * Disassociate statep and QP, as there is a
7106 6992 * QP associated with this statep.
7107 6993 */
7108 6994 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
7109 6995
7110 6996 ibcm_post_rej_mad(statep, IBT_CM_NO_RESC,
7111 6997 IBT_CM_FAILURE_UNKNOWN, NULL, 0);
7112 6998 /*
7113 6999 * Invoke CM handler, so client/server can do
7114 7000 * resource cleanup. No private data can be returned here
7115 7001 */
7116 7002 ibcm_handler_conn_fail(statep, IBT_CM_FAILURE_REJ_SENT,
7117 7003 IBT_CM_FAILURE_UNKNOWN, IBT_CM_NO_RESC, NULL, 0);
7118 7004
7119 7005 /* unblock any pending DREQ threads */
7120 7006 mutex_enter(&statep->state_mutex);
7121 7007 statep->cep_in_rts = IBCM_FAIL;
7122 7008 cv_broadcast(&statep->block_mad_cv);
7123 7009 mutex_exit(&statep->state_mutex);
7124 7010 return;
7125 7011 }
7126 7012
7127 7013 mutex_enter(&statep->state_mutex);
7128 7014 statep->state = IBCM_STATE_ESTABLISHED;
7129 7015 ibtl_cm_chan_is_open(statep->channel);
7130 7016 mutex_exit(&statep->state_mutex);
7131 7017
7132 7018 /* invoke the CM handler */
7133 7019 ASSERT(statep->cm_handler != NULL);
7134 7020
7135 7021 bzero(&event, sizeof (event));
7136 7022 event.cm_channel = statep->channel;
7137 7023 event.cm_session_id = NULL;
7138 7024
7139 7025 event.cm_type = IBT_CM_EVENT_CONN_EST;
7140 7026 if (cm_rtu_msgp != NULL) {
7141 7027 event.cm_priv_data = &(cm_rtu_msgp->rtu_private_data[0]);
7142 7028 event.cm_priv_data_len = IBT_RTU_PRIV_DATA_SZ;
7143 7029 }
7144 7030
7145 7031 ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_EST_EVENT);
7146 7032
7147 7033 (void) statep->cm_handler(statep->state_cm_private, &event, NULL,
7148 7034 NULL, 0);
7149 7035
7150 7036 ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_EST_EVENT);
7151 7037 if (ibcm_enable_trace & 4)
7152 7038 ibcm_dump_conn_trace(statep);
7153 7039 else
7154 7040 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_state_rtu CONN_EST Channel %p",
7155 7041 statep->channel);
7156 7042
7157 7043 /* unblock any pending DREQ threads */
7158 7044 mutex_enter(&statep->state_mutex);
7159 7045 statep->cep_in_rts = IBCM_UNBLOCK;
7160 7046 cv_broadcast(&statep->block_mad_cv);
7161 7047 mutex_exit(&statep->state_mutex);
7162 7048 }
7163 7049
7164 7050
7165 7051 /*
7166 7052 * ibcm_cep_send_rtu:
7167 7053 * QP state transition function called for an outgoing RTU
7168 7054 * on active side.
7169 7055 *
7170 7056 * INPUTS:
7171 7057 * statep - connection state pointer
7172 7058 *
7173 7059 * RETURN VALUE:
7174 7060 */
7175 7061 void
7176 7062 ibcm_cep_send_rtu(ibcm_state_data_t *statep)
7177 7063 {
7178 7064 /* invoke the CM handler */
7179 7065 if (statep->cm_handler) {
7180 7066 ibt_cm_event_t event;
7181 7067
7182 7068 bzero(&event, sizeof (event));
7183 7069 event.cm_type = IBT_CM_EVENT_CONN_EST;
7184 7070 event.cm_channel = statep->channel;
7185 7071 event.cm_session_id = NULL;
7186 7072 event.cm_priv_data = NULL;
7187 7073 event.cm_priv_data_len = 0;
7188 7074
7189 7075 ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_EST_EVENT);
7190 7076
7191 7077 (void) statep->cm_handler(statep->state_cm_private, &event,
7192 7078 NULL, NULL, 0);
7193 7079
7194 7080 ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_EST_EVENT);
7195 7081
7196 7082 } else {
7197 7083 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_send_rtu: cm_handler NULL");
7198 7084 }
7199 7085 if (ibcm_enable_trace & 4)
7200 7086 ibcm_dump_conn_trace(statep);
7201 7087 else
7202 7088 IBTF_DPRINTF_L2(cmlog, "ibcm_cep_send_rtu CONN_EST Channel %p",
7203 7089 statep->channel);
7204 7090
7205 7091 /* unblock any pending DREQ threads */
7206 7092 mutex_enter(&statep->state_mutex);
7207 7093 statep->cep_in_rts = IBCM_UNBLOCK;
7208 7094 cv_broadcast(&statep->block_mad_cv);
7209 7095 mutex_exit(&statep->state_mutex);
7210 7096 }
7211 7097
7212 7098
7213 7099 /*
7214 7100 * ibcm_cep_to_error_state:
7215 7101 * CEP state transition function. Changes state to IBT_STATE_ERROR
7216 7102 *
7217 7103 * INPUTS:
7218 7104 * statep - connection state pointer
7219 7105 *
7220 7106 * RETURN VALUE:
7221 7107 * IBT_SUCCESS - if able to change state otherwise failure
7222 7108 */
7223 7109 ibt_status_t
7224 7110 ibcm_cep_to_error_state(ibcm_state_data_t *statep)
7225 7111 {
7226 7112 ibt_status_t status = IBT_SUCCESS;
7227 7113
7228 7114 if (statep->channel != NULL) {
7229 7115 ibt_qp_info_t qp_info;
7230 7116
7231 7117 bzero(&qp_info, sizeof (qp_info));
7232 7118 /* For now, set it to RC type */
7233 7119 qp_info.qp_trans = IBT_RC_SRV;
7234 7120 qp_info.qp_state = IBT_STATE_ERROR;
7235 7121
7236 7122 /* Call modify_qp to move to ERROR state */
7237 7123 status = ibt_modify_qp(statep->channel, IBT_CEP_SET_STATE,
7238 7124 &qp_info, NULL);
7239 7125
7240 7126 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_to_error_state: "
7241 7127 "statep %p ibt_modify_qp() = %d", statep, status);
7242 7128
7243 7129 if (status == IBT_SUCCESS)
7244 7130 ibcm_insert_trace(statep, IBCM_TRACE_ERROR);
7245 7131 else
7246 7132 ibcm_insert_trace(statep, IBCM_TRACE_ERROR_FAIL);
7247 7133
7248 7134 }
7249 7135
7250 7136 #ifdef NO_EEC_SUPPORT_YET
7251 7137 if (statep->channel.ch_eec != NULL) {
7252 7138 ibt_eec_info_t eec_info;
7253 7139
7254 7140 bzero(&eec_info, sizeof (ibt_eec_info_t));
7255 7141 eec_info.eec_state = what;
7256 7142
7257 7143 /* Call modify_eec */
7258 7144 status = ibtl_cm_modify_eec(statep->channel.ch_eec, &eec_info,
7259 7145 IBT_CEP_SET_NOTHING);
7260 7146 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_to_error_state: "
7261 7147 "ibtl_cm_modify_eec() returned = %x", status);
7262 7148 }
7263 7149 #endif
7264 7150
7265 7151 return (status);
7266 7152 }
7267 7153
7268 7154
7269 7155 /*
7270 7156 * ibcm_cep_state_rej:
7271 7157 * QP state transition function called for an incoming REJ
7272 7158 * on active/passive side
7273 7159 *
7274 7160 * INPUTS:
7275 7161 * statep - connection state pointer
7276 7162 * rej_msgp - REJ message pointer
7277 7163 * rej_state - State where REJ processing began
7278 7164 *
7279 7165 * RETURN VALUE:
7280 7166 */
7281 7167 void
7282 7168 ibcm_cep_state_rej(ibcm_state_data_t *statep, ibcm_rej_msg_t *rej_msgp,
7283 7169 ibcm_conn_state_t rej_state)
7284 7170 {
7285 7171 ibt_cm_event_t event;
7286 7172 ibt_status_t status;
7287 7173
7288 7174 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej: statep 0x%p", statep);
7289 7175
7290 7176 ibcm_path_cache_purge();
7291 7177
7292 7178 if ((rej_state == IBCM_STATE_REP_SENT) ||
7293 7179 (rej_state == IBCM_STATE_MRA_REP_RCVD)) {
7294 7180 status = ibcm_cep_to_error_state(statep);
7295 7181 IBTF_DPRINTF_L5(cmlog, "ibcm_cep_state_rej: statep 0x%p "
7296 7182 "ibcm_cep_to_error_state returned %d", statep,
7297 7183 status);
7298 7184 }
7299 7185
7300 7186 if (statep->channel)
7301 7187 ibtl_cm_chan_open_is_aborted(statep->channel);
7302 7188
7303 7189 /* Disassociate state structure and CM */
7304 7190 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
7305 7191
7306 7192 /* invoke the CM handler */
7307 7193 bzero(&event, sizeof (event));
7308 7194 if (statep->cm_handler) {
7309 7195 event.cm_type = IBT_CM_EVENT_FAILURE;
7310 7196 event.cm_channel = statep->channel;
7311 7197 event.cm_session_id = NULL;
7312 7198
7313 7199 /*
7314 7200 * copy rej_msgp->rej_private_data to
7315 7201 * event.cm_event.cm_priv_data
7316 7202 */
7317 7203 event.cm_priv_data = &(rej_msgp->rej_private_data[0]);
7318 7204 event.cm_priv_data_len = IBT_REJ_PRIV_DATA_SZ;
7319 7205
7320 7206 event.cm_event.failed.cf_code = IBT_CM_FAILURE_REJ_RCV;
7321 7207 event.cm_event.failed.cf_msg = rej_msgp->rej_msg_type_plus >> 6;
7322 7208 event.cm_event.failed.cf_reason =
7323 7209 b2h16(rej_msgp->rej_rejection_reason);
7324 7210
7325 7211 IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rej: rej_reason = %d",
7326 7212 event.cm_event.failed.cf_reason);
7327 7213
7328 7214 ibcm_copy_addl_rej(statep, rej_msgp, &event.cm_event.failed);
7329 7215
7330 7216 (void) statep->cm_handler(statep->state_cm_private, &event,
7331 7217 NULL, NULL, 0);
7332 7218 }
7333 7219
7334 7220 if (statep->open_return_data != NULL)
7335 7221 bcopy(&event.cm_event.failed.cf_additional,
7336 7222 &statep->open_return_data->rc_arej_info,
7337 7223 sizeof (ibt_arej_info_t));
7338 7224 if (ibcm_enable_trace != 0)
7339 7225 ibcm_dump_conn_trace(statep);
7340 7226 mutex_enter(&statep->state_mutex);
7341 7227 ibcm_open_done(statep);
7342 7228 mutex_exit(&statep->state_mutex);
7343 7229 }
7344 7230
↓ open down ↓ |
355 lines elided |
↑ open up ↑ |
7345 7231 /* Used to initialize client args with addl rej information from REJ MAD */
7346 7232 static void
7347 7233 ibcm_copy_addl_rej(ibcm_state_data_t *statep, ibcm_rej_msg_t *rej_msgp,
7348 7234 ibt_cm_conn_failed_t *failed)
7349 7235 {
7350 7236 uint16_t rej_reason = b2h16(rej_msgp->rej_rejection_reason);
7351 7237 uint8_t ari_len = rej_msgp->rej_reject_info_len_plus >> 1;
7352 7238 ibcm_classportinfo_msg_t tclp;
7353 7239 ibt_arej_info_t *cf_addl = &failed->cf_additional;
7354 7240
7355 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*cf_addl))
7356 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(failed->cf_arej_info_valid))
7357 -
7358 7241 failed->cf_arej_info_valid = B_FALSE;
7359 7242
7360 7243 IBTF_DPRINTF_L3(cmlog, "ibcm_copy_addl_rej: rej_reason = %d "
7361 7244 "ari_len = %d", rej_reason, ari_len);
7362 7245
7363 7246 if ((statep->mode == IBCM_PASSIVE_MODE) &&
7364 7247 (rej_reason != IBT_CM_CONSUMER))
7365 7248 return;
7366 7249
7367 7250 switch (rej_reason) {
7368 7251 case IBT_CM_PRIM_GID:
7369 7252 case IBT_CM_ALT_GID:
7370 7253 case IBT_CM_PORT_REDIRECT:
7371 7254 if (ari_len < sizeof (ib_gid_t))
7372 7255 break;
7373 7256 failed->cf_arej_info_valid = B_TRUE;
7374 7257 bcopy(rej_msgp->rej_addl_rej_info, &cf_addl->ari_gid,
7375 7258 sizeof (ib_gid_t));
7376 7259 cf_addl->ari_gid.gid_guid = b2h64(cf_addl->ari_gid.gid_guid);
7377 7260 cf_addl->ari_gid.gid_prefix =
7378 7261 b2h64(cf_addl->ari_gid.gid_prefix);
7379 7262
7380 7263 IBTF_DPRINTF_L4(cmlog, "ibcm_copy_addl_rej: ari_gid= %llX:%llX",
7381 7264 cf_addl->ari_gid.gid_prefix, cf_addl->ari_gid.gid_guid);
7382 7265
7383 7266 break;
7384 7267 case IBT_CM_PRIM_LID:
7385 7268 case IBT_CM_ALT_LID:
7386 7269 if (ari_len < sizeof (ib_lid_t))
7387 7270 break;
7388 7271 failed->cf_arej_info_valid = B_TRUE;
7389 7272 bcopy(rej_msgp->rej_addl_rej_info, &cf_addl->ari_lid,
7390 7273 sizeof (ib_lid_t));
7391 7274 cf_addl->ari_lid = b2h16(cf_addl->ari_lid);
7392 7275 IBTF_DPRINTF_L4(cmlog, "ibcm_copy_addl_rej: ari_lid= 0x%lX",
7393 7276 cf_addl->ari_lid);
7394 7277
7395 7278 break;
7396 7279 case IBT_CM_INVALID_PRIM_SL:
7397 7280 case IBT_CM_INVALID_ALT_SL:
7398 7281 if (ari_len < 1)
7399 7282 break;
7400 7283 failed->cf_arej_info_valid = B_TRUE;
7401 7284 /* take the first 4 bits */
7402 7285 cf_addl->ari_sl = rej_msgp->rej_addl_rej_info[0] >> 4;
7403 7286 break;
7404 7287 case IBT_CM_INVALID_PRIM_TC:
7405 7288 case IBT_CM_INVALID_ALT_TC:
7406 7289 if (ari_len < 1)
7407 7290 break;
7408 7291 failed->cf_arej_info_valid = B_TRUE;
7409 7292 /* take the first byte */
7410 7293 cf_addl->ari_tclass = rej_msgp->rej_addl_rej_info[0];
7411 7294 break;
7412 7295 case IBT_CM_INVALID_PRIM_HOP:
7413 7296 case IBT_CM_INVALID_ALT_HOP:
7414 7297 if (ari_len < 1)
7415 7298 break;
7416 7299 failed->cf_arej_info_valid = B_TRUE;
7417 7300 /* take the first byte */
7418 7301 cf_addl->ari_hop = rej_msgp->rej_addl_rej_info[0];
7419 7302 break;
7420 7303 case IBT_CM_INVALID_PRIM_RATE:
7421 7304 case IBT_CM_INVALID_ALT_RATE:
7422 7305 if (ari_len < 1)
7423 7306 break;
7424 7307 failed->cf_arej_info_valid = B_TRUE;
7425 7308 /* take the first 6 bits */
7426 7309 cf_addl->ari_rate = rej_msgp->rej_addl_rej_info[0] >> 2;
7427 7310 break;
7428 7311 case IBT_CM_REDIRECT_CM:
7429 7312 if (ari_len < sizeof (ibcm_classportinfo_msg_t))
7430 7313 break;
7431 7314 failed->cf_arej_info_valid = B_TRUE;
7432 7315 bcopy(rej_msgp->rej_addl_rej_info, &tclp, sizeof (tclp));
7433 7316 ibcm_init_clp_from_mad(&tclp, &cf_addl->ari_redirect);
7434 7317 break;
7435 7318 case IBT_CM_INVALID_MTU:
7436 7319 if (ari_len < 1)
7437 7320 break;
7438 7321 failed->cf_arej_info_valid = B_TRUE;
7439 7322 /* take the first 4 bits */
7440 7323 cf_addl->ari_mtu = rej_msgp->rej_addl_rej_info[0] >> 4;
7441 7324 break;
7442 7325 case IBT_CM_CONSUMER:
7443 7326 if (ari_len == 0)
7444 7327 break;
7445 7328 failed->cf_arej_info_valid = B_TRUE;
7446 7329 if (ari_len > IBT_CM_ADDL_REJ_LEN)
7447 7330 ari_len = IBT_CM_ADDL_REJ_LEN;
7448 7331 bcopy(&rej_msgp->rej_addl_rej_info,
7449 7332 cf_addl->ari_consumer.rej_ari, ari_len);
7450 7333 cf_addl->ari_consumer.rej_ari_len = ari_len;
7451 7334 break;
7452 7335 case IBT_CM_INVALID_PRIM_FLOW:
7453 7336 case IBT_CM_INVALID_ALT_FLOW:
↓ open down ↓ |
86 lines elided |
↑ open up ↑ |
7454 7337 if (ari_len < 3) /* 3 bytes needed for 20 bits */
7455 7338 break;
7456 7339 failed->cf_arej_info_valid = B_TRUE;
7457 7340 /* take the first 20 bits */
7458 7341 cf_addl->ari_flow =
7459 7342 b2h32(*(uint32_t *)&rej_msgp->rej_addl_rej_info) >> 12;
7460 7343 break;
7461 7344 default:
7462 7345 break;
7463 7346 }
7464 -
7465 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(failed->cf_arej_info_valid))
7466 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*cf_addl))
7467 7347 }
7468 7348
7469 7349
7470 7350 /* Used to copy classportinfo to MAD from client initialized args */
7471 7351 static void
7472 7352 ibcm_init_clp_to_mad(ibcm_classportinfo_msg_t *clp, ibt_redirect_info_t *rinfo)
7473 7353 {
7474 7354
7475 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*clp))
7476 -
7477 7355 bcopy(&ibcm_clpinfo, clp, sizeof (ibcm_clpinfo));
7478 7356
7479 7357 clp->RedirectGID_hi = h2b64(rinfo->rdi_gid.gid_prefix);
7480 7358 clp->RedirectGID_lo = h2b64(rinfo->rdi_gid.gid_guid);
7481 7359 clp->RedirectTC_plus =
7482 7360 h2b32((rinfo->rdi_tclass << 24) | (rinfo->rdi_sl << 20) |
7483 7361 (rinfo->rdi_flow & 0xfffff));
7484 7362 clp->RedirectLID = h2b16(rinfo->rdi_dlid);
7485 7363 clp->RedirectQP_plus = h2b32(rinfo->rdi_qpn & 0xffffff);
7486 7364 clp->RedirectQ_Key = h2b32(rinfo->rdi_qkey);
7487 7365 clp->RedirectP_Key = h2b16(rinfo->rdi_pkey);
7488 7366
7489 7367 IBTF_DPRINTF_L4(cmlog, "ibcm_init_clp_to_mad: RedirectGID= %llX:%llX,"
7490 7368 " RedirectLID= 0x%lX", clp->RedirectGID_hi, clp->RedirectGID_lo,
7491 7369 clp->RedirectLID);
7492 -
7493 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*clp))
7494 7370 }
7495 7371
7496 7372
7497 7373 /* Used to initialize classportinfo to be returned to clients, from MAD */
7498 7374 static void
7499 7375 ibcm_init_clp_from_mad(ibcm_classportinfo_msg_t *clp,
7500 7376 ibt_redirect_info_t *rinfo)
7501 7377 {
7502 7378 uint32_t temp32;
7503 7379
7504 7380 rinfo->rdi_gid.gid_prefix = b2h64(clp->RedirectGID_hi);
7505 7381 rinfo->rdi_gid.gid_guid = b2h64(clp->RedirectGID_lo);
7506 7382 temp32 = b2h32(clp->RedirectTC_plus);
7507 7383 rinfo->rdi_tclass = temp32 >> 24;
7508 7384 rinfo->rdi_sl = (temp32 >> 20) & 0xf;
7509 7385 rinfo->rdi_flow = temp32 & 0xffff;
7510 7386 rinfo->rdi_dlid = b2h16(clp->RedirectLID);
7511 7387 rinfo->rdi_qpn = b2h32(clp->RedirectQP_plus & 0xffffff);
7512 7388 rinfo->rdi_qkey = b2h32(clp->RedirectQ_Key);
7513 7389 rinfo->rdi_pkey = b2h16(clp->RedirectP_Key);
7514 7390
7515 7391 IBTF_DPRINTF_L4(cmlog, "ibcm_init_clp_from_mad: RedirectGID= %llX:%llX,"
7516 7392 " RedirectLID= 0x%lX", rinfo->rdi_gid.gid_prefix,
7517 7393 rinfo->rdi_gid.gid_guid, rinfo->rdi_dlid);
7518 7394 }
7519 7395
7520 7396
7521 7397 /*
7522 7398 * ibcm_cep_state_rej_est:
7523 7399 * QP state transition function called for an incoming REJ
7524 7400 * on active side in established state
7525 7401 *
7526 7402 * INPUTS:
7527 7403 * statep - connection state pointer
7528 7404 *
7529 7405 * RETURN VALUE:
7530 7406 */
7531 7407 void
7532 7408 ibcm_cep_state_rej_est(ibcm_state_data_t *statep)
7533 7409 {
7534 7410 ibt_cm_event_t event;
7535 7411 ibt_status_t status;
7536 7412
7537 7413 IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_rej_est:");
7538 7414
7539 7415 status = ibcm_cep_to_error_state(statep);
7540 7416 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej_est: statep 0x%p "
7541 7417 "ibcm_cep_to_error_state returned %d", statep, status);
7542 7418
7543 7419 /* Disassociate state structure and CM */
7544 7420 IBCM_SET_CHAN_PRIVATE(statep->channel, NULL);
7545 7421
7546 7422 ibtl_cm_chan_is_closing(statep->channel);
7547 7423
7548 7424 /* invoke the CM handler */
7549 7425 if (statep->cm_handler) {
7550 7426 bzero(&event, sizeof (event));
7551 7427 event.cm_type = IBT_CM_EVENT_CONN_CLOSED;
7552 7428 event.cm_channel = statep->channel;
7553 7429 event.cm_session_id = NULL;
7554 7430
7555 7431 event.cm_priv_data = NULL;
7556 7432 event.cm_priv_data_len = 0;
7557 7433
7558 7434 event.cm_event.closed = IBT_CM_CLOSED_REJ_RCVD;
7559 7435
7560 7436 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_rej_est: "
7561 7437 "rej_reason = %d", event.cm_event.failed.cf_reason);
7562 7438
7563 7439 ibcm_insert_trace(statep, IBCM_TRACE_CALLED_CONN_CLOSE_EVENT);
7564 7440
7565 7441 (void) statep->cm_handler(statep->state_cm_private, &event,
7566 7442 NULL, NULL, 0);
7567 7443
7568 7444 ibcm_insert_trace(statep, IBCM_TRACE_RET_CONN_CLOSE_EVENT);
7569 7445
7570 7446 }
7571 7447 }
7572 7448
7573 7449
7574 7450 /*
7575 7451 * ibcm_sidr_req_ud_handler:
7576 7452 * Invoke Client's UD handler For SIDR_REQ msg
7577 7453 *
7578 7454 * INPUTS:
7579 7455 * ud_statep - ud_state pointer
7580 7456 * sidr_reqp - SIDR_REQ message pointer
7581 7457 *
7582 7458 * RETURN VALUE: IBCM_SEND_REP/IBCM_SEND_REJ
7583 7459 */
7584 7460 static ibcm_status_t
7585 7461 ibcm_sidr_req_ud_handler(ibcm_ud_state_data_t *ud_statep,
7586 7462 ibcm_sidr_req_msg_t *sidr_reqp, ibcm_mad_addr_t *cm_mad_addr,
7587 7463 ibt_sidr_status_t *sidr_status)
7588 7464 {
7589 7465 void *priv_data = NULL;
7590 7466 ibt_cm_ud_event_t ud_event;
7591 7467 ibcm_sidr_rep_msg_t *sidr_repp;
7592 7468 ibt_cm_ud_return_args_t ud_ret_args;
7593 7469 ibt_cm_status_t cb_status;
7594 7470 ibt_qp_query_attr_t qp_attr;
7595 7471 ibt_status_t retval;
7596 7472 ibcm_ud_clnt_reply_info_t ud_clnt_info;
7597 7473
7598 7474 /* Check first if UD client handler is valid */
7599 7475 ASSERT(ud_statep->ud_cm_handler != NULL);
7600 7476
7601 7477 /* Fill in ibt_cm_ud_event_t */
7602 7478 ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REQ;
7603 7479 ud_event.cm_session_id = ud_statep;
7604 7480 ud_event.cm_event.sidr_req.sreq_service_id = ud_statep->ud_svc_id;
7605 7481 ud_event.cm_event.sidr_req.sreq_hca_guid = ud_statep->ud_hcap->hca_guid;
7606 7482 ud_event.cm_event.sidr_req.sreq_pkey = b2h16(sidr_reqp->sidr_req_pkey);
7607 7483 ud_event.cm_event.sidr_req.sreq_hca_port = cm_mad_addr->port_num;
7608 7484
7609 7485 ud_event.cm_priv_data =
7610 7486 &(sidr_reqp->sidr_req_private_data[0]);
7611 7487 ud_event.cm_priv_data_len = IBT_SIDR_REQ_PRIV_DATA_SZ;
7612 7488
7613 7489 sidr_repp =
7614 7490 (ibcm_sidr_rep_msg_t *)IBCM_OUT_MSGP(ud_statep->ud_stored_msg);
7615 7491
7616 7492 priv_data = &(sidr_repp->sidr_rep_private_data[0]);
7617 7493
7618 7494 bzero(&ud_ret_args, sizeof (ud_ret_args));
7619 7495
7620 7496 /* Invoke the client handler */
7621 7497 cb_status = ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
7622 7498 &ud_event, &ud_ret_args, priv_data, IBT_SIDR_REP_PRIV_DATA_SZ);
7623 7499
7624 7500 if (cb_status == IBT_CM_DEFER) {
7625 7501
7626 7502 /* unblock any blocked cm ud proceed api calls */
7627 7503 mutex_enter(&ud_statep->ud_state_mutex);
7628 7504 ud_statep->ud_clnt_proceed = IBCM_UNBLOCK;
7629 7505 cv_broadcast(&ud_statep->ud_block_client_cv);
7630 7506 mutex_exit(&ud_statep->ud_state_mutex);
7631 7507
7632 7508 return (IBCM_DEFER);
7633 7509 }
7634 7510
7635 7511 /* fail any blocked ud cm proceed api calls - client bug */
7636 7512 mutex_enter(&ud_statep->ud_state_mutex);
7637 7513 ud_statep->ud_clnt_proceed = IBCM_FAIL;
7638 7514 cv_broadcast(&ud_statep->ud_block_client_cv);
7639 7515 mutex_exit(&ud_statep->ud_state_mutex);
7640 7516
7641 7517 /* do the query qp as soon as possible, after return from cm handler */
7642 7518 if (cb_status == IBT_CM_ACCEPT) {
7643 7519 retval = ibt_query_qp(ud_ret_args.ud_channel, &qp_attr);
7644 7520 if (retval != IBT_SUCCESS) {
7645 7521 IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_req_ud_handler: "
7646 7522 "Failed to retrieve QPN from the channel: %d",
7647 7523 retval);
7648 7524 *sidr_status = IBT_CM_SREP_NO_CHAN;
7649 7525 return (IBCM_SEND_SIDR_REP);
7650 7526 } else if (qp_attr.qp_info.qp_trans != IBT_UD_SRV) {
7651 7527 IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_req_ud_handler: "
7652 7528 "Server/Passive returned non-UD %d transport type "
7653 7529 "QP", qp_attr.qp_info.qp_trans);
7654 7530 *sidr_status = IBT_CM_SREP_NO_CHAN;
7655 7531 return (IBCM_SEND_SIDR_REP);
7656 7532 }
7657 7533
7658 7534 ud_clnt_info.ud_qkey = qp_attr.qp_info.qp_transport.ud.ud_qkey;
7659 7535 ud_clnt_info.ud_qpn = qp_attr.qp_qpn;
7660 7536 }
7661 7537
7662 7538 ud_clnt_info.priv_data = priv_data;
7663 7539 ud_clnt_info.priv_data_len = ud_ret_args.ud_ret_len;
7664 7540
7665 7541 ud_clnt_info.redirect_infop = &ud_ret_args.ud_redirect;
7666 7542
7667 7543 ibcm_process_sidr_req_cm_hdlr(ud_statep, cb_status, &ud_clnt_info,
7668 7544 sidr_status, sidr_repp);
7669 7545
7670 7546 return (IBCM_SEND_SIDR_REP);
7671 7547 }
7672 7548
7673 7549 /*ARGSUSED*/
7674 7550 void
7675 7551 ibcm_process_sidr_req_cm_hdlr(ibcm_ud_state_data_t *ud_statep,
7676 7552 ibt_cm_status_t cb_status, ibcm_ud_clnt_reply_info_t *ud_clnt_info,
7677 7553 ibt_sidr_status_t *sidr_status, ibcm_sidr_rep_msg_t *sidr_repp)
7678 7554 {
7679 7555 void *sidr_rep_privp;
7680 7556
7681 7557 IBTF_DPRINTF_L5(cmlog, "ibcm_process_sidr_req_cm_hdlr(%p, %x, "
7682 7558 "%p, %p, %p)", ud_statep, cb_status, ud_clnt_info,
7683 7559 sidr_status, sidr_repp);
7684 7560
7685 7561 if (cb_status == IBT_CM_DEFAULT)
7686 7562 cb_status = IBT_CM_REJECT;
7687 7563
7688 7564 if (cb_status == IBT_CM_ACCEPT)
7689 7565 *sidr_status = IBT_CM_SREP_CHAN_VALID;
7690 7566 else if ((cb_status == IBT_CM_REJECT) ||
7691 7567 (cb_status == IBT_CM_NO_RESOURCE))
7692 7568 *sidr_status = IBT_CM_SREP_REJ;
7693 7569 else if (cb_status == IBT_CM_NO_CHANNEL)
7694 7570 *sidr_status = IBT_CM_SREP_NO_CHAN;
7695 7571 else if (cb_status == IBT_CM_REDIRECT)
7696 7572 *sidr_status = IBT_CM_SREP_REDIRECT;
7697 7573 else *sidr_status = IBT_CM_SREP_REJ;
7698 7574
7699 7575 /*
7700 7576 * For Accept and reject copy the private data, if ud_clnt_info
7701 7577 * priv_data does not point to SIDR Response private data. This
7702 7578 * copy is needed for ibt_cm_ud_proceed().
7703 7579 */
7704 7580 sidr_rep_privp = (void *)(&(sidr_repp->sidr_rep_private_data[0]));
7705 7581 if ((cb_status == IBT_CM_ACCEPT || cb_status == IBT_CM_REJECT) &&
7706 7582 (ud_clnt_info->priv_data != sidr_rep_privp) &&
7707 7583 ud_clnt_info->priv_data_len) {
7708 7584 bcopy(ud_clnt_info->priv_data, sidr_rep_privp,
7709 7585 min(ud_clnt_info->priv_data_len,
7710 7586 IBT_SIDR_REP_PRIV_DATA_SZ));
7711 7587 }
7712 7588
7713 7589 if (*sidr_status != IBT_CM_SREP_CHAN_VALID) {
7714 7590 IBTF_DPRINTF_L2(cmlog, "ibcm_process_sidr_req_cm_hdlr: "
7715 7591 "ud_handler return a failure: %d", cb_status);
7716 7592 if (*sidr_status == IBT_CM_SREP_REDIRECT) {
7717 7593 /*
7718 7594 * typecasting to ibcm_classportinfo_msg_t is ok, as addl info
↓ open down ↓ |
215 lines elided |
↑ open up ↑ |
7719 7595 * begins at offset 24 in sidr rep
7720 7596 */
7721 7597 ibcm_init_clp_to_mad(
7722 7598 (ibcm_classportinfo_msg_t *)
7723 7599 &sidr_repp->sidr_rep_class_port_info,
7724 7600 ud_clnt_info->redirect_infop);
7725 7601 }
7726 7602 return;
7727 7603 }
7728 7604
7729 -
7730 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
7731 -
7732 7605 sidr_repp->sidr_rep_qkey =
7733 7606 h2b32(ud_clnt_info->ud_qkey);
7734 7607 sidr_repp->sidr_rep_qpn_plus = h2b32(ud_clnt_info->ud_qpn << 8);
7735 -
7736 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sidr_repp))
7737 7608 }
7738 7609
7739 7610 /*
7740 7611 * ibcm_sidr_rep_ud_handler:
7741 7612 * Invoke Client's UD handler For SIDR_REP msg
7742 7613 *
7743 7614 * INPUTS:
7744 7615 * ud_statep - ud_state pointer
7745 7616 * sidr_rep_msgp - SIDR_REQ message pointer
7746 7617 *
7747 7618 */
7748 7619 static void
7749 7620 ibcm_sidr_rep_ud_handler(ibcm_ud_state_data_t *ud_statep,
7750 7621 ibcm_sidr_rep_msg_t *sidr_rep_msgp)
7751 7622 {
7752 7623 ibt_cm_ud_event_t ud_event;
7753 7624
7754 7625 IBTF_DPRINTF_L5(cmlog, "ibcm_sidr_rep_ud_handler: ud_statep 0x%p",
7755 7626 ud_statep);
7756 7627
7757 7628 /* Check first if UD client handler is valid */
7758 7629 if (ud_statep->ud_cm_handler == NULL) {
7759 7630 IBTF_DPRINTF_L2(cmlog, "ibcm_sidr_rep_ud_handler: "
7760 7631 "cm_handler NULL");
7761 7632 return;
7762 7633 }
7763 7634
7764 7635 /* Fill in ibt_cm_ud_event_t */
7765 7636 ud_event.cm_type = IBT_CM_UD_EVENT_SIDR_REP;
7766 7637 ud_event.cm_session_id = NULL;
7767 7638 ud_event.cm_event.sidr_rep.srep_status =
7768 7639 sidr_rep_msgp->sidr_rep_rep_status;
7769 7640 ud_event.cm_event.sidr_rep.srep_remote_qpn =
7770 7641 b2h32(sidr_rep_msgp->sidr_rep_qpn_plus) >> 8;
7771 7642 ud_event.cm_event.sidr_rep.srep_remote_qkey =
7772 7643 h2b32(sidr_rep_msgp->sidr_rep_qkey);
7773 7644
7774 7645 if (ud_event.cm_event.sidr_rep.srep_status == IBT_CM_SREP_REDIRECT) {
7775 7646 /*
7776 7647 * typecasting to ibcm_classportinfo_msg_t is ok, as addl info
7777 7648 * begins at offset 24 in sidr rep
7778 7649 */
7779 7650 ibcm_init_clp_from_mad(
7780 7651 (ibcm_classportinfo_msg_t *)
7781 7652 sidr_rep_msgp->sidr_rep_class_port_info,
7782 7653 &ud_event.cm_event.sidr_rep.srep_redirect);
7783 7654
7784 7655 if (ud_statep->ud_return_data != NULL)
7785 7656 bcopy(&ud_event.cm_event.sidr_rep.srep_redirect,
7786 7657 &ud_statep->ud_return_data->ud_redirect,
7787 7658 sizeof (ibt_redirect_info_t));
7788 7659 }
7789 7660
7790 7661 ud_event.cm_priv_data = &(sidr_rep_msgp->sidr_rep_private_data[0]);
7791 7662 ud_event.cm_priv_data_len = IBT_SIDR_REP_PRIV_DATA_SZ;
7792 7663
7793 7664 /* Invoke the client handler - inform only, so ignore retval */
7794 7665 (void) ud_statep->ud_cm_handler(ud_statep->ud_state_cm_private,
7795 7666 &ud_event, NULL, NULL, 0);
7796 7667
7797 7668
7798 7669 }
7799 7670
7800 7671 /*
7801 7672 * ibcm_process_lap_msg:
7802 7673 * This call processes an incoming LAP message
7803 7674 *
7804 7675 * INPUTS:
7805 7676 * hcap - HCA entry pointer
7806 7677 * input_madp - incoming CM LAP MAD
7807 7678 * cm_mad_addr - Address information for the MAD
7808 7679 *
7809 7680 * RETURN VALUE: NONE
7810 7681 */
7811 7682 /* ARGSUSED */
7812 7683 void
7813 7684 ibcm_process_lap_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
7814 7685 ibcm_mad_addr_t *cm_mad_addr)
7815 7686 {
7816 7687 ibcm_status_t state_lookup_status;
7817 7688 ibcm_lap_msg_t *lap_msg = (ibcm_lap_msg_t *)
7818 7689 (&input_madp[IBCM_MAD_HDR_SIZE]);
7819 7690 ibcm_apr_msg_t *apr_msg;
7820 7691 ibcm_state_data_t *statep = NULL;
7821 7692
7822 7693 IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg:");
7823 7694
7824 7695 rw_enter(&hcap->hca_state_rwlock, RW_READER);
7825 7696
7826 7697 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_LAP,
7827 7698 b2h32(lap_msg->lap_remote_comm_id), 0, 0, hcap, &statep);
7828 7699
7829 7700 rw_exit(&hcap->hca_state_rwlock);
7830 7701
7831 7702 IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg: lookup status %x"
7832 7703 " com id %x", state_lookup_status,
7833 7704 b2h32(lap_msg->lap_remote_comm_id));
7834 7705
7835 7706 if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
7836 7707 /* Post a REJ message ? - but spec doesn't state so */
7837 7708 return;
7838 7709 }
7839 7710
7840 7711 /* There is an existing state structure entry with active comid */
7841 7712
7842 7713 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_LAP);
7843 7714
7844 7715 mutex_enter(&statep->state_mutex);
7845 7716
7846 7717 if ((statep->state == IBCM_STATE_ESTABLISHED) &&
7847 7718 (statep->ap_state == IBCM_AP_STATE_IDLE) &&
7848 7719 (statep->mode == IBCM_PASSIVE_MODE)) {
7849 7720 if ((statep->lapr_msg) &&
7850 7721 (IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID ==
7851 7722 ((ib_mad_hdr_t *)(input_madp))->TransactionID))
7852 7723 ibcm_post_stored_apr_mad(statep, input_madp);
7853 7724 else {
7854 7725 ibcm_status_t clnt_response;
7855 7726
7856 7727 statep->ap_state = IBCM_AP_STATE_LAP_RCVD;
7857 7728 statep->clnt_proceed = IBCM_BLOCK;
7858 7729 mutex_exit(&statep->state_mutex);
7859 7730
7860 7731 if (statep->lapr_msg == NULL) {
7861 7732 if (ibcm_alloc_out_msg(
7862 7733 statep->stored_reply_addr.ibmf_hdl,
7863 7734 &statep->lapr_msg, MAD_METHOD_SEND) !=
7864 7735 IBT_SUCCESS) {
7865 7736
7866 7737 mutex_enter(&statep->state_mutex);
7867 7738 statep->clnt_proceed = IBCM_FAIL;
7868 7739 cv_broadcast(&statep->block_client_cv);
7869 7740 IBCM_REF_CNT_DECR(statep);
7870 7741 mutex_exit(&statep->state_mutex);
7871 7742 return;
7872 7743 }
7873 7744 }
7874 7745 apr_msg = (ibcm_apr_msg_t *)
7875 7746 IBCM_OUT_MSGP(statep->lapr_msg);
7876 7747 IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID =
7877 7748 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
7878 7749 clnt_response =
7879 7750 ibcm_cep_state_lap(statep, lap_msg, apr_msg);
7880 7751 IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg:"
7881 7752 " statep 0x%p apr status %d", statep,
7882 7753 apr_msg->apr_ap_status);
7883 7754
7884 7755 if (clnt_response == IBCM_DEFER) {
7885 7756 IBTF_DPRINTF_L4(cmlog, "ibcm_process_lap_msg: "
7886 7757 "client returned DEFER response");
7887 7758 return;
7888 7759 }
7889 7760
7890 7761 /* fail any blocked cm proceed api calls - client bug */
7891 7762 mutex_enter(&statep->state_mutex);
7892 7763 statep->clnt_proceed = IBCM_FAIL;
7893 7764 cv_broadcast(&statep->block_client_cv);
7894 7765 mutex_exit(&statep->state_mutex);
7895 7766
7896 7767 ibcm_post_apr_mad(statep);
7897 7768 return;
7898 7769 }
7899 7770 } /* drop the LAP MAD in any other state */
7900 7771
7901 7772 IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
7902 7773 mutex_exit(&statep->state_mutex);
7903 7774 }
7904 7775
7905 7776 /*
7906 7777 * ibcm_post_stored_apr_mad:
7907 7778 * Builds and posts an APR MAD from the stored APR MAD
7908 7779 *
7909 7780 * INPUTS:
7910 7781 * statep - pointer to ibcm_state_data_t
7911 7782 * input_madp - pointer to incoming lap mad
7912 7783 *
7913 7784 * RETURN VALUE:
7914 7785 * NONE
7915 7786 *
7916 7787 * This function is called holding the state mutex, and returns
7917 7788 * holding the state mutex
7918 7789 */
7919 7790 static void
7920 7791 ibcm_post_stored_apr_mad(ibcm_state_data_t *statep, uint8_t *input_madp)
7921 7792 {
7922 7793 ibmf_msg_t *ibmf_apr_msg;
7923 7794 uint8_t apr_msg[IBCM_MSG_SIZE];
7924 7795
7925 7796 /* Need to make a copy, else an incoming new LAP may modify lapr_msg */
7926 7797 bcopy(IBCM_OUT_MSGP(statep->lapr_msg), apr_msg, IBCM_MSG_SIZE);
7927 7798
7928 7799 mutex_exit(&statep->state_mutex);
7929 7800
7930 7801 if (ibcm_alloc_out_msg(statep->stored_reply_addr.ibmf_hdl,
7931 7802 &ibmf_apr_msg, MAD_METHOD_SEND) != IBT_SUCCESS) {
7932 7803 IBTF_DPRINTF_L2(cmlog, "ibcm_post_stored_apr_mad: "
7933 7804 "ibcm_alloc_out_msg failed");
7934 7805 mutex_enter(&statep->state_mutex);
7935 7806 return;
7936 7807 }
7937 7808
7938 7809 bcopy(apr_msg, IBCM_OUT_MSGP(ibmf_apr_msg), IBCM_MSG_SIZE);
7939 7810
7940 7811 IBCM_OUT_HDRP(ibmf_apr_msg)->AttributeID =
7941 7812 h2b16(IBCM_INCOMING_APR + IBCM_ATTR_BASE_ID);
7942 7813
7943 7814 IBCM_OUT_HDRP(ibmf_apr_msg)->TransactionID =
7944 7815 ((ib_mad_hdr_t *)(input_madp))->TransactionID;
7945 7816
7946 7817 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_APR);
7947 7818
7948 7819 ibcm_post_rc_mad(statep, ibmf_apr_msg, ibcm_post_stored_apr_complete,
7949 7820 ibmf_apr_msg);
7950 7821
7951 7822 /* ibcm_free_out_msg done in ibcm_post_stored_apr_complete */
7952 7823
7953 7824 mutex_enter(&statep->state_mutex);
7954 7825 }
7955 7826
7956 7827 /*
7957 7828 * ibcm_cep_state_lap:
7958 7829 * This call processes an incoming LAP message for cep state
7959 7830 * transition and invoking cm handler
7960 7831 *
7961 7832 * INPUTS:
7962 7833 * statep - pointer to ibcm_state_data_t
7963 7834 * lap_msg - lap msg received
7964 7835 * apr_msg - apr msg to be sent
7965 7836 *
7966 7837 * RETURN VALUE: NONE
7967 7838 */
7968 7839 ibcm_status_t
7969 7840 ibcm_cep_state_lap(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg,
↓ open down ↓ |
223 lines elided |
↑ open up ↑ |
7970 7841 ibcm_apr_msg_t *apr_msg)
7971 7842 {
7972 7843 ibt_cm_event_t event;
7973 7844 ibt_cm_return_args_t ret_args;
7974 7845 ibt_cm_status_t cb_status;
7975 7846 ibcm_clnt_reply_info_t clnt_info;
7976 7847
7977 7848
7978 7849 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_lap: statep 0x%p", statep);
7979 7850
7980 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msg))
7981 -
7982 7851 /* If APM is not supported, return error */
7983 7852 if (!(statep->hcap->hca_caps & IBT_HCA_AUTO_PATH_MIG)) {
7984 7853 apr_msg->apr_ap_status = IBT_CM_AP_NOT_SUPPORTED;
7985 7854 return (IBCM_SEND_APR);
7986 7855 }
7987 7856
7988 7857 if (statep->local_qpn !=
7989 7858 b2h32(lap_msg->lap_remote_qpn_eecn_plus) >> 8) {
7990 7859 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
7991 7860 IBTF_DPRINTF_L4(cmlog, "ibcm_cep_state_lap: local_qpn %x does "
7992 7861 "not match remote's remote_qpn %x", statep->local_qpn,
7993 7862 b2h32(lap_msg->lap_remote_qpn_eecn_plus) >> 8);
7994 7863 return (IBCM_SEND_APR);
7995 7864 }
7996 7865
7997 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msg))
7998 -
7999 7866 /* Fill up the event */
8000 7867 bzero(&event, sizeof (event));
8001 7868 event.cm_type = IBT_CM_EVENT_LAP_RCV;
8002 7869 event.cm_channel = statep->channel;
8003 7870 event.cm_session_id = statep;
8004 7871 event.cm_priv_data = lap_msg->lap_private_data;
8005 7872 event.cm_priv_data_len = IBT_LAP_PRIV_DATA_SZ;
8006 7873 event.cm_event.lap.lap_timeout = ibt_ib2usec(
8007 7874 ((uint8_t *)&lap_msg->lap_remote_qpn_eecn_plus)[3] >> 3);
8008 7875
8009 7876 ibcm_fill_adds_from_lap(&event.cm_event.lap.lap_alternate_path,
8010 7877 lap_msg, IBCM_PASSIVE_MODE);
8011 7878
8012 7879 cb_status = statep->cm_handler(statep->state_cm_private, &event,
8013 7880 &ret_args, apr_msg->apr_private_data, IBT_APR_PRIV_DATA_SZ);
8014 7881
8015 7882 IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_lap: cb_status = %d", cb_status);
8016 7883 if (cb_status == IBT_CM_DEFER) {
8017 -
8018 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
8019 -
8020 7884 if (statep->defer_cm_msg == NULL)
8021 7885 statep->defer_cm_msg =
8022 7886 kmem_zalloc(IBCM_MSG_SIZE, KM_SLEEP);
8023 7887 bcopy(lap_msg, statep->defer_cm_msg, IBCM_MSG_SIZE);
8024 -
8025 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(statep->defer_cm_msg))
8026 -
8027 7888 /* unblock any blocked cm proceed api calls */
8028 7889 mutex_enter(&statep->state_mutex);
8029 7890 statep->clnt_proceed = IBCM_UNBLOCK;
8030 7891 cv_broadcast(&statep->block_client_cv);
8031 7892 mutex_exit(&statep->state_mutex);
8032 7893
8033 7894 return (IBCM_DEFER);
8034 7895 }
8035 7896
8036 7897 clnt_info.reply_event = (ibt_cm_proceed_reply_t *)&ret_args.cm_ret;
8037 7898 clnt_info.priv_data = NULL;
8038 7899 clnt_info.priv_data_len = 0;
8039 7900
8040 7901 ibcm_process_cep_lap_cm_hdlr(statep, cb_status, &clnt_info, lap_msg,
8041 7902 apr_msg);
8042 7903 return (IBCM_SEND_APR);
8043 7904 }
8044 7905
8045 7906 /*
8046 7907 * ibcm_fill_adds_from_lap:
8047 7908 * Fills the address vector (part of event structure passed to
8048 7909 * client) from the LAP message
8049 7910 *
8050 7911 * INPUTS:
8051 7912 * adds - Address vector to be filled-in
8052 7913 * lap_msg - LAP message used to fill the address vector
8053 7914 *
8054 7915 * RETURN VALUE: NONE
8055 7916 */
8056 7917 static void
8057 7918 ibcm_fill_adds_from_lap(ibt_adds_vect_t *adds, ibcm_lap_msg_t *lap_msg,
8058 7919 ibcm_mode_t mode)
8059 7920 {
8060 7921 adds->av_srvl = lap_msg->lap_alt_sl_plus >> 4;
8061 7922 if (mode == IBCM_PASSIVE_MODE) {
8062 7923 adds->av_dgid.gid_prefix =
8063 7924 b2h64(lap_msg->lap_alt_l_port_gid.gid_prefix);
8064 7925 adds->av_dgid.gid_guid =
8065 7926 b2h64(lap_msg->lap_alt_l_port_gid.gid_guid);
8066 7927 adds->av_sgid.gid_prefix =
8067 7928 b2h64(lap_msg->lap_alt_r_port_gid.gid_prefix);
8068 7929 adds->av_sgid.gid_guid =
8069 7930 b2h64(lap_msg->lap_alt_r_port_gid.gid_guid);
8070 7931 adds->av_dlid = b2h16(lap_msg->lap_alt_l_port_lid);
8071 7932 } else {
8072 7933 adds->av_sgid.gid_prefix =
8073 7934 b2h64(lap_msg->lap_alt_l_port_gid.gid_prefix);
8074 7935 adds->av_sgid.gid_guid =
8075 7936 b2h64(lap_msg->lap_alt_l_port_gid.gid_guid);
8076 7937 adds->av_dgid.gid_prefix =
8077 7938 b2h64(lap_msg->lap_alt_r_port_gid.gid_prefix);
8078 7939 adds->av_dgid.gid_guid =
8079 7940 b2h64(lap_msg->lap_alt_r_port_gid.gid_guid);
8080 7941 adds->av_dlid = b2h16(lap_msg->lap_alt_r_port_lid);
8081 7942 }
8082 7943
8083 7944 IBTF_DPRINTF_L4(cmlog, "ibcm_fill_adds_from_lap: SGID=(%llX:%llX)",
8084 7945 adds->av_sgid.gid_prefix, adds->av_sgid.gid_guid);
8085 7946
8086 7947 IBTF_DPRINTF_L4(cmlog, "ibcm_fill_adds_from_lap: DGID=(%llX:%llX)",
8087 7948 adds->av_dgid.gid_prefix, adds->av_dgid.gid_guid);
8088 7949
8089 7950 adds->av_srate = lap_msg->lap_alt_srate_plus & 0x3f;
8090 7951
8091 7952 /* next copy off the GRH info if it exists */
8092 7953 if ((lap_msg->lap_alt_sl_plus & 0x8) == 0) {
8093 7954 uint32_t flow_tclass = b2h32(lap_msg->lap_alt_flow_label_plus);
8094 7955
8095 7956 adds->av_send_grh = B_TRUE;
8096 7957 adds->av_flow = flow_tclass >> 12;
8097 7958 adds->av_tclass = flow_tclass & 0xff;
8098 7959 adds->av_hop = lap_msg->lap_alt_hop_limit;
8099 7960 } else {
8100 7961 adds->av_send_grh = B_FALSE;
8101 7962 }
8102 7963 }
8103 7964
8104 7965 /*
8105 7966 * ibcm_process_cep_lap_cm_hdlr:
8106 7967 * Processes the cm handler response for an incoming LAP.
8107 7968 */
8108 7969
8109 7970 void
8110 7971 ibcm_process_cep_lap_cm_hdlr(ibcm_state_data_t *statep,
8111 7972 ibt_cm_status_t cb_status, ibcm_clnt_reply_info_t *clnt_info,
8112 7973 ibcm_lap_msg_t *lap_msg, ibcm_apr_msg_t *apr_msg)
↓ open down ↓ |
76 lines elided |
↑ open up ↑ |
8113 7974 {
8114 7975 ibtl_cm_hca_port_t port;
8115 7976 ibt_qp_query_attr_t qp_attrs;
8116 7977 ibt_cep_modify_flags_t cep_flags;
8117 7978 ibt_status_t status;
8118 7979 ibt_adds_vect_t *adds;
8119 7980
8120 7981 if (cb_status == IBT_CM_DEFAULT)
8121 7982 cb_status = IBT_CM_REJECT;
8122 7983
8123 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msg))
8124 -
8125 7984 /* verify status */
8126 7985 apr_msg->apr_addl_info_len = 0;
8127 7986 if (cb_status == IBT_CM_ACCEPT) {
8128 7987 apr_msg->apr_ap_status = IBT_CM_AP_LOADED;
8129 7988 } else if (cb_status == IBT_CM_REJECT) {
8130 7989 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8131 7990 } else if (cb_status == IBT_CM_REDIRECT) {
8132 7991 apr_msg->apr_ap_status = IBT_CM_AP_REDIRECT;
8133 7992 /* copy redirect info to APR */
8134 7993 apr_msg->apr_addl_info_len = sizeof (ibcm_classportinfo_msg_t);
8135 7994 ibcm_init_clp_to_mad(
8136 7995 (ibcm_classportinfo_msg_t *)apr_msg->apr_addl_info,
8137 7996 &clnt_info->reply_event->apr);
8138 7997 } else if (cb_status == IBT_CM_NO_RESOURCE) {
8139 7998 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8140 7999 } else {
8141 8000 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
8142 8001 " Client handler unexpected return %x", statep, cb_status);
8143 8002 cb_status = IBT_CM_REJECT;
8144 8003 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8145 8004 }
8146 8005
8147 8006 IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep 0x%p "
8148 8007 " client handler returned %d, apr status %d", statep, cb_status,
8149 8008 apr_msg->apr_ap_status);
8150 8009
8151 8010 /* copy private data to outgoing apr, specified via priv_data */
8152 8011 if ((clnt_info->priv_data != NULL) && (clnt_info->priv_data_len > 0))
8153 8012 bcopy(clnt_info->priv_data, apr_msg->apr_private_data,
8154 8013 min(clnt_info->priv_data_len, IBT_APR_PRIV_DATA_SZ));
8155 8014
8156 8015 if (cb_status != IBT_CM_ACCEPT)
8157 8016 return;
8158 8017
8159 8018 if (ibt_query_qp(statep->channel, &qp_attrs) != IBT_SUCCESS ||
8160 8019 (qp_attrs.qp_info.qp_state != IBT_STATE_RTS &&
8161 8020 qp_attrs.qp_info.qp_state != IBT_STATE_SQD)) {
8162 8021 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8163 8022 return;
8164 8023 }
8165 8024
8166 8025 /* Fill up input args for ibt_modify_qp */
8167 8026 cep_flags = IBT_CEP_SET_ALT_PATH | IBT_CEP_SET_STATE;
8168 8027
8169 8028 /* do RTS=>RTS or SQD=>SQD. The next line is needed for RTS=>RTS. */
8170 8029 qp_attrs.qp_info.qp_current_state = qp_attrs.qp_info.qp_state;
8171 8030
8172 8031 adds = &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect;
8173 8032 ibcm_fill_adds_from_lap(adds, lap_msg, IBCM_PASSIVE_MODE);
8174 8033
8175 8034 if ((status = ibtl_cm_get_hca_port(adds->av_sgid,
8176 8035 statep->local_hca_guid, &port)) != IBT_SUCCESS) {
8177 8036
8178 8037 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr:"
8179 8038 " ibtl_cm_get_hca_port failed status %d", status);
8180 8039 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8181 8040 return;
8182 8041 }
8183 8042
8184 8043 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_hca_port_num = port.hp_port;
8185 8044
8186 8045 IBTF_DPRINTF_L4(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep 0x%p "
8187 8046 "gid = (%llx, %llx), port_num = %d", statep,
8188 8047 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_dgid.
8189 8048 gid_prefix,
8190 8049 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_dgid.gid_guid,
8191 8050 port.hp_port);
8192 8051
8193 8052 /* The pkey is same as the primary path */
8194 8053 status = ibt_pkey2index_byguid(statep->local_hca_guid,
8195 8054 port.hp_port, statep->pkey,
8196 8055 &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_pkey_ix);
8197 8056
8198 8057 if (status != IBT_SUCCESS) {
8199 8058 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
8200 8059 " ibt_pkey2index_byguid failed %d", statep, status);
8201 8060 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8202 8061 return;
8203 8062 }
8204 8063
8205 8064 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_timeout =
8206 8065 lap_msg->lap_alt_local_acktime_plus >> 3;
8207 8066
8208 8067 qp_attrs.qp_info.qp_trans = IBT_RC_SRV;
8209 8068 if (IBCM_QP_RC(qp_attrs).rc_mig_state == IBT_STATE_MIGRATED) {
8210 8069 IBTF_DPRINTF_L3(cmlog, "ibcm_process_cep_lap_cm_hdlr: statep %p"
8211 8070 ": rearming APM", statep);
8212 8071 cep_flags |= IBT_CEP_SET_MIG;
8213 8072 IBCM_QP_RC(qp_attrs).rc_mig_state = IBT_STATE_REARMED;
8214 8073 }
8215 8074 status = ibt_modify_qp(statep->channel, cep_flags, &qp_attrs.qp_info,
8216 8075 NULL);
8217 8076
8218 8077 if (status != IBT_SUCCESS) {
8219 8078 ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT_FAIL);
8220 8079 } else
8221 8080 ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT);
8222 8081
8223 8082 #ifdef DEBUG
8224 8083 (void) ibt_query_qp(statep->channel, &qp_attrs);
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
8225 8084 print_modify_qp("PASSIVE LAP QUERY", statep->channel,
8226 8085 cep_flags, &qp_attrs.qp_info);
8227 8086 #endif
8228 8087
8229 8088 if (status != IBT_SUCCESS) {
8230 8089 apr_msg->apr_ap_status = IBT_CM_AP_REJECT;
8231 8090 IBTF_DPRINTF_L2(cmlog, "ibcm_process_cep_lap_cm_hdlr:"
8232 8091 " ibt_modify_qp() returned = %d", status);
8233 8092 return;
8234 8093 }
8235 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msg))
8236 8094 }
8237 8095
8238 8096
8239 8097 /*
8240 8098 * ibcm_post_apr_mad:
8241 8099 * Posts a APR MAD and starts timer
8242 8100 *
8243 8101 * INPUTS:
8244 8102 * statep - state pointer
8245 8103 *
8246 8104 * RETURN VALUE: NONE
8247 8105 */
8248 8106 void
8249 8107 ibcm_post_apr_mad(ibcm_state_data_t *statep)
8250 8108 {
8251 8109 ibcm_apr_msg_t *apr_msgp;
8252 8110
8253 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*apr_msgp))
8254 -
8255 8111 apr_msgp = (ibcm_apr_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg);
8256 8112
8257 8113 apr_msgp->apr_local_comm_id = h2b32(statep->local_comid);
8258 8114 apr_msgp->apr_remote_comm_id = h2b32(statep->remote_comid);
8259 8115 IBCM_OUT_HDRP(statep->lapr_msg)->AttributeID =
8260 8116 h2b16(IBCM_INCOMING_APR + IBCM_ATTR_BASE_ID);
8261 8117
8262 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*apr_msgp))
8263 -
8264 8118 ibcm_insert_trace(statep, IBCM_TRACE_OUTGOING_APR);
8265 8119
8266 8120 ibcm_post_rc_mad(statep, statep->lapr_msg, ibcm_post_apr_complete,
8267 8121 statep);
8268 8122 }
8269 8123
8270 8124 /*
8271 8125 * ibcm_process_apr_msg:
8272 8126 * This call processes an incoming APR message
8273 8127 *
8274 8128 * INPUTS:
8275 8129 * hcap - HCA entry pointer
8276 8130 * input_madp - incoming CM SIDR REP MAD
8277 8131 * cm_mad_addr - Address information for the MAD to be posted
8278 8132 *
8279 8133 * RETURN VALUE: NONE
8280 8134 */
8281 8135 /*ARGSUSED*/
8282 8136 void
8283 8137 ibcm_process_apr_msg(ibcm_hca_info_t *hcap, uint8_t *input_madp,
8284 8138 ibcm_mad_addr_t *cm_mad_addr)
8285 8139 {
8286 8140 ibcm_status_t state_lookup_status;
8287 8141 ibcm_apr_msg_t *apr_msg = (ibcm_apr_msg_t *)
8288 8142 (&input_madp[IBCM_MAD_HDR_SIZE]);
8289 8143 ibcm_state_data_t *statep = NULL;
8290 8144
8291 8145 IBTF_DPRINTF_L4(cmlog, "ibcm_process_apr_msg:");
8292 8146
8293 8147 rw_enter(&hcap->hca_state_rwlock, RW_READER);
8294 8148 state_lookup_status = ibcm_lookup_msg(IBCM_INCOMING_APR,
8295 8149 b2h32(apr_msg->apr_remote_comm_id), 0, 0, hcap, &statep);
8296 8150 rw_exit(&hcap->hca_state_rwlock);
8297 8151
8298 8152 if (state_lookup_status != IBCM_LOOKUP_EXISTS) {
8299 8153 return;
8300 8154 }
8301 8155
8302 8156 /* if transaction id is not as expected, drop the APR mad */
8303 8157 if (IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID !=
8304 8158 ((ib_mad_hdr_t *)(input_madp))->TransactionID) {
8305 8159 mutex_enter(&statep->state_mutex);
8306 8160 IBCM_REF_CNT_DECR(statep);
8307 8161 mutex_exit(&statep->state_mutex);
8308 8162 IBTF_DPRINTF_L3(cmlog, "ibcm_process_apr_msg: statep 0x%p"
8309 8163 ": rcv'd APR MAD with comid 0x%x",
8310 8164 statep, b2h32(apr_msg->apr_remote_comm_id));
8311 8165 IBTF_DPRINTF_L3(cmlog, "ibcm_process_apr_msg: "
8312 8166 "tid expected 0x%llX tid found 0x%llX",
8313 8167 b2h64(IBCM_OUT_HDRP(statep->lapr_msg)->TransactionID),
8314 8168 b2h64(((ib_mad_hdr_t *)(input_madp))->TransactionID));
8315 8169 return;
8316 8170 }
8317 8171
8318 8172 IBTF_DPRINTF_L4(cmlog, "ibcm_process_apr_msg: statep 0x%p "
8319 8173 "lookup status %x", statep, state_lookup_status);
8320 8174
8321 8175 mutex_enter(&statep->state_mutex);
8322 8176
8323 8177 if (!((statep->state == IBCM_STATE_ESTABLISHED) &&
8324 8178 ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
8325 8179 (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)))) {
8326 8180 IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
8327 8181 mutex_exit(&statep->state_mutex);
8328 8182 return;
8329 8183 }
8330 8184
8331 8185 statep->ap_state = IBCM_AP_STATE_APR_RCVD;
8332 8186
8333 8187 /* cancel the LAP timer */
8334 8188 if (statep->timerid != 0) {
8335 8189 timeout_id_t timer_val;
8336 8190 timer_val = statep->timerid;
8337 8191 statep->timerid = 0;
8338 8192 mutex_exit(&statep->state_mutex);
8339 8193 (void) untimeout(timer_val);
8340 8194 } else {
8341 8195 mutex_exit(&statep->state_mutex);
8342 8196 }
8343 8197
8344 8198 ibcm_insert_trace(statep, IBCM_TRACE_INCOMING_APR);
8345 8199
8346 8200 ibcm_cep_state_apr(statep,
8347 8201 (ibcm_lap_msg_t *)IBCM_OUT_MSGP(statep->lapr_msg), apr_msg);
8348 8202
8349 8203 mutex_enter(&statep->state_mutex);
8350 8204 statep->ap_state = IBCM_AP_STATE_IDLE;
8351 8205
8352 8206 /* unblock any DREQ threads and close channels */
8353 8207 cv_broadcast(&statep->block_mad_cv);
8354 8208
8355 8209 statep->ap_done = B_TRUE;
8356 8210
8357 8211 /* wake up blocking ibt_set_alt_path */
8358 8212 cv_broadcast(&statep->block_client_cv);
8359 8213
8360 8214 IBCM_REF_CNT_DECR(statep); /* decrement the ref count */
8361 8215 mutex_exit(&statep->state_mutex);
8362 8216 }
8363 8217
8364 8218 static void
8365 8219 ibcm_set_apr_arej(int ap_status, ibcm_apr_msg_t *apr_msgp,
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
8366 8220 ibt_arej_info_t *ari, boolean_t *ari_valid)
8367 8221 {
8368 8222 uint8_t ari_len = apr_msgp->apr_addl_info_len;
8369 8223 ibcm_classportinfo_msg_t tclp;
8370 8224
8371 8225 *ari_valid = B_FALSE;
8372 8226
8373 8227 IBTF_DPRINTF_L3(cmlog, "ibcm_set_apr_arej: apr_status = %d "
8374 8228 "ari_len = %d", ap_status, ari_len);
8375 8229
8376 - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ari))
8377 -
8378 8230 switch (ap_status) {
8379 8231 case IBT_CM_AP_REDIRECT:
8380 8232 if (ari_len < sizeof (ibcm_classportinfo_msg_t))
8381 8233 break;
8382 8234 *ari_valid = B_TRUE;
8383 8235 bcopy(apr_msgp->apr_addl_info, &tclp, sizeof (tclp));
8384 8236 ibcm_init_clp_from_mad(&tclp, &ari->ari_redirect);
8385 8237 break;
8386 8238 case IBT_CM_AP_RLID_REJECTED:
8387 8239 if (ari_len < sizeof (ib_lid_t))
8388 8240 break;
8389 8241 *ari_valid = B_TRUE;
8390 8242 bcopy(apr_msgp->apr_addl_info, &ari->ari_lid,
8391 8243 sizeof (ib_lid_t));
8392 8244 ari->ari_lid = b2h16(ari->ari_lid);
8393 8245 break;
8394 8246 case IBT_CM_AP_RGID_REJECTED:
8395 8247 if (ari_len < sizeof (ib_gid_t))
8396 8248 break;
8397 8249 *ari_valid = B_TRUE;
8398 8250 bcopy(apr_msgp->apr_addl_info, &ari->ari_gid,
8399 8251 sizeof (ib_gid_t));
8400 8252 ari->ari_gid.gid_guid = b2h64(ari->ari_gid.gid_guid);
8401 8253 ari->ari_gid.gid_prefix = b2h64(ari->ari_gid.gid_prefix);
8402 8254
8403 8255 IBTF_DPRINTF_L4(cmlog, "ibcm_set_apr_arej: ari_gid= %llX:%llX",
8404 8256 ari->ari_gid.gid_prefix, ari->ari_gid.gid_guid);
8405 8257 break;
8406 8258 case IBT_CM_AP_FLOW_REJECTED:
8407 8259 if (ari_len < 3) /* 3 bytes needed for 20 bits */
8408 8260 break;
8409 8261 *ari_valid = B_TRUE;
8410 8262 /* take the first 20 bits */
8411 8263 ari->ari_flow =
8412 8264 b2h32(*(uint32_t *)&apr_msgp->apr_addl_info) >> 12;
8413 8265 break;
8414 8266 case IBT_CM_AP_TCLASS_REJECTED:
8415 8267 if (ari_len < 1)
8416 8268 break;
8417 8269 *ari_valid = B_TRUE;
8418 8270 /* take the first byte */
8419 8271 ari->ari_tclass = apr_msgp->apr_addl_info[0];
8420 8272 break;
8421 8273 case IBT_CM_AP_HOP_REJECTED:
8422 8274 if (ari_len < 1)
8423 8275 break;
8424 8276 *ari_valid = B_TRUE;
8425 8277 /* take the first byte */
8426 8278 ari->ari_hop = apr_msgp->apr_addl_info[0];
8427 8279 break;
8428 8280 case IBT_CM_AP_RATE_REJECTED:
8429 8281 if (ari_len < 1)
8430 8282 break;
8431 8283 *ari_valid = B_TRUE;
8432 8284 /* take the first 6 bits */
8433 8285 ari->ari_rate = apr_msgp->apr_addl_info[0] >> 2;
8434 8286 break;
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
8435 8287 case IBT_CM_AP_SL_REJECTED:
8436 8288 if (ari_len < 1)
8437 8289 break;
8438 8290 *ari_valid = B_TRUE;
8439 8291 /* take the first 4 bits */
8440 8292 ari->ari_sl = apr_msgp->apr_addl_info[0] >> 4;
8441 8293 break;
8442 8294 default:
8443 8295 break;
8444 8296 }
8445 - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ari))
8446 8297 }
8447 8298
8448 8299 /*
8449 8300 * ibcm_cep_state_apr:
8450 8301 * This call processes an incoming APR message
8451 8302 *
8452 8303 * INPUTS:
8453 8304 * statep - pointer to ibcm_state_data_t
8454 8305 * lap_msg - lap msg sent earlier
8455 8306 * apr_msg - apr msg received
8456 8307 *
8457 8308 * RETURN VALUE: NONE
8458 8309 */
8459 8310 void
8460 8311 ibcm_cep_state_apr(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg,
8461 8312 ibcm_apr_msg_t *apr_msg)
8462 8313 {
8463 8314 ibt_cm_event_t event;
8464 8315 ibcm_status_t status = IBCM_SUCCESS;
8465 8316 uint8_t ap_status = apr_msg->apr_ap_status;
8466 8317
8467 8318 IBTF_DPRINTF_L3(cmlog, "ibcm_cep_state_apr: statep 0x%p, ap_status %d",
8468 8319 statep, ap_status);
8469 8320
8470 8321 if (ap_status == IBT_CM_AP_LOADED)
8471 8322 status = ibcm_set_qp_from_apr(statep, lap_msg);
8472 8323
8473 8324 if (statep->ap_return_data != NULL) { /* blocking call */
8474 8325
8475 8326 /* copy the private data */
8476 8327 if ((statep->ap_return_data->ap_priv_data != NULL) &&
8477 8328 (statep->ap_return_data->ap_priv_data_len > 0))
8478 8329 bcopy(apr_msg->apr_private_data,
8479 8330 statep->ap_return_data->ap_priv_data,
8480 8331 statep->ap_return_data->ap_priv_data_len);
8481 8332
8482 8333 /* initialize the ap status */
8483 8334 if (status == IBCM_FAILURE) {
8484 8335 statep->ap_return_data->ap_status = IBT_CM_AP_REJECT;
8485 8336 statep->ap_return_data->ap_arej_info_valid = B_FALSE;
8486 8337 } else {
8487 8338 statep->ap_return_data->ap_status = ap_status;
8488 8339 ibcm_set_apr_arej(ap_status, apr_msg,
8489 8340 &statep->ap_return_data->ap_arej_info,
8490 8341 &statep->ap_return_data->ap_arej_info_valid);
8491 8342 }
8492 8343
8493 8344 /* do a cv signal for a blocking ibt_set_alt_path */
8494 8345 mutex_enter(&statep->state_mutex);
8495 8346 statep->ap_done = B_TRUE;
8496 8347 cv_broadcast(&statep->block_client_cv);
8497 8348 mutex_exit(&statep->state_mutex);
8498 8349
8499 8350 } else { /* Non blocking call */
8500 8351 /* Fill up the event */
8501 8352
8502 8353 bzero(&event, sizeof (event));
8503 8354 event.cm_type = IBT_CM_EVENT_APR_RCV;
8504 8355 event.cm_channel = statep->channel;
8505 8356 event.cm_session_id = NULL;
8506 8357 event.cm_priv_data = apr_msg->apr_private_data;
8507 8358 event.cm_priv_data_len = IBT_APR_PRIV_DATA_SZ;
8508 8359 if (status == IBCM_FAILURE) {
8509 8360 event.cm_event.apr.apr_status = IBT_CM_AP_REJECT;
8510 8361 event.cm_event.apr.apr_arej_info_valid = B_FALSE;
8511 8362 } else {
8512 8363 event.cm_event.apr.apr_status = ap_status;
8513 8364 ibcm_set_apr_arej(ap_status, apr_msg,
8514 8365 &event.cm_event.apr.apr_arej_info,
8515 8366 &event.cm_event.apr.apr_arej_info_valid);
8516 8367 }
8517 8368
8518 8369 /* initialize the ap status */
8519 8370 statep->cm_handler(statep->state_cm_private, &event,
8520 8371 NULL, apr_msg->apr_private_data, IBT_APR_PRIV_DATA_SZ);
8521 8372 }
8522 8373 mutex_enter(&statep->state_mutex);
8523 8374 ibcm_open_done(statep);
8524 8375 mutex_exit(&statep->state_mutex);
8525 8376 }
8526 8377
8527 8378 /*
8528 8379 * ibcm_set_qp_from_apr:
8529 8380 * This call sets QP's alt path info based on APR message contents
8530 8381 *
8531 8382 * INPUTS:
8532 8383 * statep - pointer to ibcm_state_data_t
8533 8384 * lap_msg - lap msg sent earlier
8534 8385 *
8535 8386 * RETURN VALUE: ibcm_status_t
8536 8387 */
8537 8388 static ibcm_status_t
8538 8389 ibcm_set_qp_from_apr(ibcm_state_data_t *statep, ibcm_lap_msg_t *lap_msg)
8539 8390 {
8540 8391 ibtl_cm_hca_port_t port;
8541 8392 ibt_adds_vect_t *adds;
8542 8393
8543 8394 ibt_qp_query_attr_t qp_attrs;
8544 8395 ibt_cep_modify_flags_t cep_flags;
8545 8396 ibt_status_t status;
8546 8397
8547 8398 IBTF_DPRINTF_L3(cmlog, "ibcm_set_qp_from_apr: statep 0x%p", statep);
8548 8399
8549 8400 status = ibt_query_qp(statep->channel, &qp_attrs);
8550 8401 if (status != IBT_SUCCESS ||
8551 8402 (qp_attrs.qp_info.qp_state != IBT_STATE_RTS &&
8552 8403 qp_attrs.qp_info.qp_state != IBT_STATE_SQD)) {
8553 8404 IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: ibt_query_qp "
8554 8405 "failed, status = %d, qp_state = %d", statep, status,
8555 8406 qp_attrs.qp_info.qp_state);
8556 8407 return (IBCM_FAILURE);
8557 8408 }
8558 8409
8559 8410 /* Fill up input args for ibt_modify_qp */
8560 8411 cep_flags = IBT_CEP_SET_ALT_PATH | IBT_CEP_SET_STATE;
8561 8412
8562 8413 /* do RTS=>RTS or SQD=>SQD. The next line is needed for RTS=>RTS. */
8563 8414 qp_attrs.qp_info.qp_current_state = qp_attrs.qp_info.qp_state;
8564 8415
8565 8416 /* Fill up input args for ibt_modify_qp */
8566 8417 adds = &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect;
8567 8418
8568 8419 ibcm_fill_adds_from_lap(adds, lap_msg, IBCM_ACTIVE_MODE);
8569 8420
8570 8421 if ((status = ibtl_cm_get_hca_port(adds->av_sgid,
8571 8422 statep->local_hca_guid, &port)) != IBT_SUCCESS) {
8572 8423 IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: "
8573 8424 "ibtl_cm_get_hca_port failed status = %d", status);
8574 8425 IBTF_DPRINTF_L5(cmlog, "ibcm_set_qp_from_apr:"
8575 8426 " ibtl_cm_get_hca_port sgid guid %llX",
8576 8427 adds->av_sgid.gid_guid);
8577 8428 IBTF_DPRINTF_L5(cmlog, "ibcm_set_qp_from_apr:"
8578 8429 " ibtl_cm_get_hca_port sgid prefix %llX ",
8579 8430 adds->av_sgid.gid_prefix);
8580 8431 return (IBCM_FAILURE);
8581 8432 }
8582 8433
8583 8434 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_hca_port_num =
8584 8435 port.hp_port;
8585 8436
8586 8437 IBTF_DPRINTF_L4(cmlog, "ibcm_set_qp_from_apr: "
8587 8438 "gid = %llx:%llx, port_num = %d",
8588 8439 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_sgid.
8589 8440 gid_prefix,
8590 8441 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_adds_vect.av_sgid.gid_guid,
8591 8442 port.hp_port);
8592 8443
8593 8444 /* The pkey is same as the primary path */
8594 8445 status = ibt_pkey2index_byguid(statep->local_hca_guid,
8595 8446 port.hp_port, statep->pkey,
8596 8447 &IBCM_QP_RC(qp_attrs).rc_alt_path.cep_pkey_ix);
8597 8448
8598 8449 if (status != IBT_SUCCESS) {
8599 8450 IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr: "
8600 8451 "ibt_pkey2index_byguid failed %d", status);
8601 8452 return (IBCM_FAILURE);
8602 8453 }
8603 8454 qp_attrs.qp_info.qp_trans = IBT_RC_SRV;
8604 8455 IBCM_QP_RC(qp_attrs).rc_alt_path.cep_timeout =
8605 8456 ibt_usec2ib(statep->remote_ack_delay +
8606 8457 2 * statep->rc_alt_pkt_lt);
8607 8458 if (IBCM_QP_RC(qp_attrs).rc_mig_state == IBT_STATE_MIGRATED) {
8608 8459 /* Need to rearm */
8609 8460 IBTF_DPRINTF_L3(cmlog, "ibcm_set_qp_from_apr: statep 0x%p: "
8610 8461 "rearming APM", statep);
8611 8462 cep_flags |= IBT_CEP_SET_MIG;
8612 8463 IBCM_QP_RC(qp_attrs).rc_mig_state = IBT_STATE_REARMED;
8613 8464 }
8614 8465
8615 8466 status = ibt_modify_qp(statep->channel, cep_flags, &qp_attrs.qp_info,
8616 8467 NULL);
8617 8468
8618 8469 if (status != IBT_SUCCESS)
8619 8470 ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT_FAIL);
8620 8471 else
8621 8472 ibcm_insert_trace(statep, IBCM_TRACE_SET_ALT);
8622 8473
8623 8474 #ifdef DEBUG
8624 8475 (void) ibt_query_qp(statep->channel, &qp_attrs);
8625 8476 print_modify_qp("ACTIVE LAP QUERY", statep->channel,
8626 8477 cep_flags, &qp_attrs.qp_info);
8627 8478 #endif
8628 8479
8629 8480 if (status != IBT_SUCCESS) {
8630 8481 IBTF_DPRINTF_L2(cmlog, "ibcm_set_qp_from_apr:"
8631 8482 " ibt_modify_qp() failed, status = %d", status);
8632 8483 return (IBCM_FAILURE);
8633 8484 }
8634 8485
8635 8486 return (IBCM_SUCCESS);
8636 8487 }
8637 8488
8638 8489 /*
8639 8490 * ibcm_sync_lapr_idle:
8640 8491 *
8641 8492 * This call either cancels a LAP/APR operation or waits
8642 8493 * until the operation is complete
8643 8494 *
8644 8495 * INPUTS:
8645 8496 * statep Pointer to ibcm_state_data_t
8646 8497 *
8647 8498 * RETURN VALUE: NONE
8648 8499 *
8649 8500 * This function is called holding state mutex
8650 8501 * This function returns, releasing the state mutex
8651 8502 */
8652 8503 void
↓ open down ↓ |
197 lines elided |
↑ open up ↑ |
8653 8504 ibcm_sync_lapr_idle(ibcm_state_data_t *statep)
8654 8505 {
8655 8506 timeout_id_t timer_val = statep->timerid;
8656 8507 ibt_cm_event_t event;
8657 8508
8658 8509 IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
8659 8510 "statep %p state %d ap_state %d", statep, statep->state,
8660 8511 statep->ap_state);
8661 8512
8662 8513 ASSERT(MUTEX_HELD(&statep->state_mutex));
8663 - _NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(&statep->state_mutex))
8664 8514
8665 8515 /* Busy AP states on active/passive sides */
8666 8516 if ((statep->ap_state == IBCM_AP_STATE_LAP_RCVD) ||
8667 8517 (statep->ap_state == IBCM_AP_STATE_APR_RCVD) ||
8668 8518 (statep->ap_state == IBCM_AP_STATE_MRA_LAP_SENT) ||
8669 8519 (statep->ap_state == IBCM_AP_STATE_TIMED_OUT)) {
8670 8520
8671 8521 /* wait till ap_state becomes IBCM_AP_STATE_IDLE */
8672 8522 while (statep->ap_state != IBCM_AP_STATE_IDLE)
8673 8523 cv_wait(&statep->block_mad_cv, &statep->state_mutex);
8674 8524
8675 8525 mutex_exit(&statep->state_mutex);
8676 8526
8677 8527 } else if ((statep->ap_state == IBCM_AP_STATE_LAP_SENT) ||
8678 8528 (statep->ap_state == IBCM_AP_STATE_MRA_LAP_RCVD)) {
8679 8529
8680 8530 /* fail the client's ibt_set_alt_path */
8681 8531
8682 8532 /* blocking ibt_set_alt_path */
8683 8533 if (statep->ap_return_data != NULL) {
8684 8534 statep->ap_return_data->ap_status =
8685 8535 IBT_CM_AP_ABORT;
8686 8536 statep->ap_state = IBCM_AP_STATE_IDLE;
8687 8537 cv_broadcast(&statep->block_client_cv);
8688 8538 IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
8689 8539 "blocked wait");
8690 8540 }
8691 8541
8692 8542 statep->timerid = 0;
8693 8543 /* Cancel the timeout */
8694 8544 mutex_exit(&statep->state_mutex);
8695 8545 if (timer_val != 0)
8696 8546 (void) untimeout(timer_val);
8697 8547
8698 8548 /* Non blocking ibt_set_alt_path */
8699 8549 if (statep->ap_return_data == NULL) {
8700 8550
8701 8551 /* Fill up the event */
8702 8552
8703 8553 bzero(&event, sizeof (event));
8704 8554 event.cm_type = IBT_CM_EVENT_APR_RCV;
8705 8555 event.cm_channel = statep->channel;
8706 8556 event.cm_session_id = NULL;
8707 8557 event.cm_priv_data = NULL;
8708 8558 event.cm_priv_data_len = 0;
8709 8559 event.cm_event.apr.apr_status = IBT_CM_AP_ABORT;
8710 8560
8711 8561 /* Call the cm handler */
8712 8562 statep->cm_handler(statep->state_cm_private, &event,
8713 8563 NULL, NULL, 0);
8714 8564 IBTF_DPRINTF_L3(cmlog, "ibcm_sync_lapr_idle:"
8715 8565 "non-blocked wait");
8716 8566 }
8717 8567 } else mutex_exit(&statep->state_mutex);
8718 8568
8719 8569 ASSERT(!MUTEX_HELD(&statep->state_mutex));
8720 8570 }
8721 8571
8722 8572 #ifdef DEBUG
8723 8573
8724 8574 /*
8725 8575 * Debug function used to print all the modify qp attributes.
8726 8576 * Useful to manually verify the modify qp parameters are as
8727 8577 * expected
8728 8578 */
8729 8579 static void
8730 8580 print_modify_qp(char *prefix, ibt_qp_hdl_t ibt_qp,
8731 8581 ibt_cep_modify_flags_t flags, ibt_qp_info_t *qp_attr)
8732 8582 {
8733 8583 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP %s %p", prefix, ibt_qp);
8734 8584 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP flags 0x%x", flags);
8735 8585
8736 8586 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP "
8737 8587 "rc_rdma_ra_in %d rc_rdma_ra_out %d",
8738 8588 qp_attr->qp_transport.rc.rc_rdma_ra_in,
8739 8589 qp_attr->qp_transport.rc.rc_rdma_ra_out);
8740 8590
8741 8591 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
8742 8592 "port %d path bits %d dlid %X",
8743 8593 qp_attr->qp_transport.rc.rc_path.cep_hca_port_num,
8744 8594 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_src_path,
8745 8595 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dlid);
8746 8596 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
8747 8597 "pkey index %d cep_timeout %d",
8748 8598 qp_attr->qp_transport.rc.rc_path.cep_pkey_ix,
8749 8599 qp_attr->qp_transport.rc.rc_path.cep_timeout);
8750 8600 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
8751 8601 "srvl %d flow label %d tclass %d",
8752 8602 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_srvl,
8753 8603 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_flow,
8754 8604 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_tclass);
8755 8605 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
8756 8606 "hop %d srate %d sgid_ix %d send_grh %d",
8757 8607 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_hop,
8758 8608 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_srate,
8759 8609 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid_ix,
8760 8610 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_send_grh);
8761 8611 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
8762 8612 "dgid prefix %llX dgid guid %llX",
8763 8613 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dgid.gid_prefix,
8764 8614 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_dgid.gid_guid);
8765 8615 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP primary: "
8766 8616 "sgid prefix %llX sgid guid %llX",
8767 8617 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid.gid_prefix,
8768 8618 qp_attr->qp_transport.rc.rc_path.cep_adds_vect.av_sgid.gid_guid);
8769 8619
8770 8620 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
8771 8621 "port %d path bits %d dlid %X",
8772 8622 qp_attr->qp_transport.rc.rc_alt_path.cep_hca_port_num,
8773 8623 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_src_path,
8774 8624 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dlid);
8775 8625 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
8776 8626 "pkey index %d cep_timeout %d",
8777 8627 qp_attr->qp_transport.rc.rc_alt_path.cep_pkey_ix,
8778 8628 qp_attr->qp_transport.rc.rc_alt_path.cep_timeout);
8779 8629 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
8780 8630 "srvl %d flow label %d tclass %d",
8781 8631 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_srvl,
8782 8632 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_flow,
8783 8633 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_tclass);
8784 8634 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
8785 8635 "hop %d srate %d sgid_ix %d send_grh %d",
8786 8636 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_hop,
8787 8637 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_srate,
8788 8638 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid_ix,
8789 8639 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_send_grh);
8790 8640 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
8791 8641 "dgid prefix %llX dgid guid %llX",
8792 8642 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dgid.
8793 8643 gid_prefix,
8794 8644 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_dgid.
8795 8645 gid_guid);
8796 8646 IBTF_DPRINTF_L4(cmlog, "PRINT_MODIFY_QP alternate: "
8797 8647 "sgid prefix %llX sgid guid %llX",
8798 8648 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid.
8799 8649 gid_prefix,
8800 8650 qp_attr->qp_transport.rc.rc_alt_path.cep_adds_vect.av_sgid.
8801 8651 gid_guid);
8802 8652 }
8803 8653 #endif
↓ open down ↓ |
130 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX