303 mutex_enter(&conn->c_send_lock);
304 while (atomic_get(&conn->c_senders)) {
305 mutex_exit(&conn->c_send_lock);
306 delay(1);
307 mutex_enter(&conn->c_send_lock);
308 }
309
310 conn->c_trans->conn_shutdown(conn);
311 rdsv3_conn_reset(conn);
312 mutex_exit(&conn->c_send_lock);
313
314 if (!rdsv3_conn_transition(conn, RDSV3_CONN_DISCONNECTING,
315 RDSV3_CONN_DOWN)) {
316 /*
317 * This can happen - eg when we're in the middle of
318 * tearing down the connection, and someone unloads
319 * the rds module.
320 * Quite reproduceable with loopback connections.
321 * Mostly harmless.
322 */
323 #ifndef __lock_lint
324 RDSV3_DPRINTF2("rdsv3_conn_shutdown",
325 "failed to transition to state DOWN, "
326 "current statis is: %d",
327 atomic_get(&conn->c_state));
328 rdsv3_conn_drop(conn);
329 #endif
330 return;
331 }
332 }
333
334 /*
335 * Then reconnect if it's still live.
336 * The passive side of an IB loopback connection is never added
337 * to the conn hash, so we never trigger a reconnect on this
338 * conn - the reconnect is always triggered by the active peer.
339 */
340 rdsv3_cancel_delayed_work(&conn->c_conn_w);
341
342 {
343 struct rdsv3_conn_info_s conn_info;
344
345 conn_info.c_laddr = conn->c_laddr;
346 conn_info.c_faddr = conn->c_faddr;
347 if (avl_find(&rdsv3_conn_hash, &conn_info, NULL) == conn)
348 rdsv3_queue_reconnect(conn);
349 }
|
303 mutex_enter(&conn->c_send_lock);
304 while (atomic_get(&conn->c_senders)) {
305 mutex_exit(&conn->c_send_lock);
306 delay(1);
307 mutex_enter(&conn->c_send_lock);
308 }
309
310 conn->c_trans->conn_shutdown(conn);
311 rdsv3_conn_reset(conn);
312 mutex_exit(&conn->c_send_lock);
313
314 if (!rdsv3_conn_transition(conn, RDSV3_CONN_DISCONNECTING,
315 RDSV3_CONN_DOWN)) {
316 /*
317 * This can happen - eg when we're in the middle of
318 * tearing down the connection, and someone unloads
319 * the rds module.
320 * Quite reproduceable with loopback connections.
321 * Mostly harmless.
322 */
323 RDSV3_DPRINTF2("rdsv3_conn_shutdown",
324 "failed to transition to state DOWN, "
325 "current statis is: %d",
326 atomic_get(&conn->c_state));
327 rdsv3_conn_drop(conn);
328 return;
329 }
330 }
331
332 /*
333 * Then reconnect if it's still live.
334 * The passive side of an IB loopback connection is never added
335 * to the conn hash, so we never trigger a reconnect on this
336 * conn - the reconnect is always triggered by the active peer.
337 */
338 rdsv3_cancel_delayed_work(&conn->c_conn_w);
339
340 {
341 struct rdsv3_conn_info_s conn_info;
342
343 conn_info.c_laddr = conn->c_laddr;
344 conn_info.c_faddr = conn->c_faddr;
345 if (avl_find(&rdsv3_conn_hash, &conn_info, NULL) == conn)
346 rdsv3_queue_reconnect(conn);
347 }
|