Index: iscsi_ioctl.c =================================================================== RCS file: /cvsroot/src/sys/dev/iscsi/iscsi_ioctl.c,v retrieving revision 1.33.4.2 diff -p -u -r1.33.4.2 iscsi_ioctl.c --- iscsi_ioctl.c 1 Nov 2024 15:06:22 -0000 1.33.4.2 +++ iscsi_ioctl.c 13 Nov 2024 07:16:51 -0000 @@ -490,6 +490,7 @@ kill_connection(connection_t *conn, uint "state=%d\n", conn->c_terminating, status, logout, conn->c_state)); + mutex_enter(&conn->c_lock); mutex_enter(&iscsi_cleanup_mtx); if (recover && !conn->c_destroy && @@ -545,14 +546,22 @@ kill_connection(connection_t *conn, uint logout == LOGOUT_CONNECTION) { logout = LOGOUT_SESSION; } + + /* connection is terminating, prevent cleanup */ + conn->c_usecount++; + mutex_exit(&iscsi_cleanup_mtx); + mutex_exit(&conn->c_lock); DEBC(conn, 1, ("Send_logout for reason %d\n", logout)); connection_timeout_start(conn, CONNECTION_TIMEOUT); if (!send_logout(conn, conn, logout, FALSE)) { + mutex_enter(&conn->c_lock); + conn->c_usecount--; conn->c_terminating = ISCSI_STATUS_SUCCESS; + mutex_exit(&conn->c_lock); return; } /* @@ -563,7 +572,11 @@ kill_connection(connection_t *conn, uint * once the timeout hits. */ + mutex_enter(&conn->c_lock); mutex_enter(&iscsi_cleanup_mtx); + + /* release connection */ + conn->c_usecount--; } } @@ -573,7 +586,6 @@ kill_connection(connection_t *conn, uint done: /* let send thread take over next step of cleanup */ - mutex_enter(&conn->c_lock); cv_broadcast(&conn->c_conn_cv); mutex_exit(&conn->c_lock); @@ -630,19 +642,20 @@ kill_session(uint32_t sid, uint32_t stat } if (recover) { - mutex_exit(&iscsi_cleanup_mtx); - /* * Only recover when there's just one active connection left. * Otherwise we get in all sorts of timing problems, and it doesn't * make much sense anyway to recover when the other side has * requested that we kill a multipathed session. */ - if (sess->s_active_connections == 1) { + conn = NULL; + if (sess->s_active_connections == 1) conn = assign_connection(sess, FALSE); - if (conn != NULL) - kill_connection(conn, status, logout, TRUE); - } + + mutex_exit(&iscsi_cleanup_mtx); + + if (conn != NULL) + kill_connection(conn, status, logout, TRUE); return; } Index: iscsi_rcv.c =================================================================== RCS file: /cvsroot/src/sys/dev/iscsi/iscsi_rcv.c,v retrieving revision 1.26 diff -p -u -r1.26 iscsi_rcv.c --- iscsi_rcv.c 13 Sep 2022 13:09:16 -0000 1.26 +++ iscsi_rcv.c 13 Nov 2024 07:16:51 -0000 @@ -582,18 +582,20 @@ receive_logout_pdu(connection_t *conn, p wake_ccb(req_ccb, status); + mutex_enter(&conn->c_lock); if (!otherconn && conn->c_state == ST_LOGOUT_SENT) { conn->c_terminating = ISCSI_STATUS_LOGOUT; conn->c_state = ST_SETTLING; conn->c_loggedout = (response) ? LOGOUT_FAILED : LOGOUT_SUCCESS; + mutex_exit(&conn->c_lock); connection_timeout_stop(conn); /* let send thread take over next step of cleanup */ mutex_enter(&conn->c_lock); cv_broadcast(&conn->c_conn_cv); - mutex_exit(&conn->c_lock); } + mutex_exit(&conn->c_lock); return !otherconn; } Index: iscsi_send.c =================================================================== RCS file: /cvsroot/src/sys/dev/iscsi/iscsi_send.c,v retrieving revision 1.39.4.2 diff -p -u -r1.39.4.2 iscsi_send.c --- iscsi_send.c 1 Nov 2024 15:06:22 -0000 1.39.4.2 +++ iscsi_send.c 13 Nov 2024 07:16:52 -0000 @@ -343,6 +343,9 @@ iscsi_send_thread(void *par) (pdu = TAILQ_FIRST(&conn->c_pdus_to_send)) != NULL) { TAILQ_REMOVE(&conn->c_pdus_to_send, pdu, pdu_send_chain); pdu->pdu_flags &= ~PDUF_INQUEUE; + pdisp = pdu->pdu_disp; + if (pdisp > PDUDISP_FREE) + pdu->pdu_flags &= ~PDUF_BUSY; mutex_exit(&conn->c_lock); /* update ExpStatSN here to avoid discontinuities */ @@ -357,11 +360,6 @@ iscsi_send_thread(void *par) ntohl(pdu->pdu_hdr.pduh_p.command.ExpStatSN))); my_soo_write(conn, &pdu->pdu_uio); - mutex_enter(&conn->c_lock); - pdisp = pdu->pdu_disp; - if (pdisp > PDUDISP_FREE) - pdu->pdu_flags &= ~PDUF_BUSY; - mutex_exit(&conn->c_lock); if (pdisp <= PDUDISP_FREE) free_pdu(pdu); @@ -527,9 +525,7 @@ send_pdu(ccb_t *ccb, pdu_t *pdu, ccb_dis if (prev_cdisp <= CCBDISP_NOWAIT) suspend_ccb(ccb, TRUE); - mutex_exit(&conn->c_lock); ccb_timeout_start(ccb, COMMAND_TIMEOUT); - mutex_enter(&conn->c_lock); while (ccb->ccb_disp == CCBDISP_WAIT) { DEBC(conn, 15, ("Send_pdu: ccb=%p cdisp=%d waiting\n", Index: iscsi_text.c =================================================================== RCS file: /cvsroot/src/sys/dev/iscsi/iscsi_text.c,v retrieving revision 1.13.28.1 diff -p -u -r1.13.28.1 iscsi_text.c --- iscsi_text.c 18 Dec 2023 14:15:58 -0000 1.13.28.1 +++ iscsi_text.c 13 Nov 2024 07:16:52 -0000 @@ -744,7 +744,7 @@ put_parameter(uint8_t *buf, unsigned len default: cl = 0; - /* We should't be here... */ + /* We shouldn't be here... */ DEBOUT(("Invalid type %d in put_parameter!\n", entries[par->key].val)); break; @@ -866,7 +866,7 @@ parameter_size(negotiation_parameter_t * break; default: - /* We should't be here... */ + /* We shouldn't be here... */ DEBOUT(("Invalid type %d in parameter_size!\n", entries[par->key].val)); break; Index: iscsi_utils.c =================================================================== RCS file: /cvsroot/src/sys/dev/iscsi/iscsi_utils.c,v retrieving revision 1.28.4.1 diff -p -u -r1.28.4.1 iscsi_utils.c --- iscsi_utils.c 18 Dec 2023 14:15:58 -0000 1.28.4.1 +++ iscsi_utils.c 13 Nov 2024 07:16:52 -0000 @@ -259,6 +259,7 @@ free_ccb(ccb_t *ccb) session_t *sess = ccb->ccb_session; connection_t *conn = ccb->ccb_connection; pdu_t *pdu; + pdu_disp_t pdisp; DEBC(conn, 15, ( "free_ccb: ccb = %p, usecount = %d\n", @@ -288,12 +289,14 @@ free_ccb(ccb_t *ccb) if ((pdu = ccb->ccb_pdu_waiting) != NULL) { ccb->ccb_pdu_waiting = NULL; mutex_enter(&conn->c_lock); + pdisp = pdu->pdu_disp; if ((pdu->pdu_flags & PDUF_INQUEUE) != 0) { TAILQ_REMOVE(&conn->c_pdus_to_send, pdu, pdu_send_chain); pdu->pdu_flags &= ~PDUF_INQUEUE; } mutex_exit(&conn->c_lock); - free_pdu(pdu); + if (pdisp > PDUDISP_FREE) + free_pdu(pdu); } mutex_enter(&sess->s_lock);