Module Name: src
Committed By: snj
Date: Thu Dec 21 19:17:43 UTC 2017
Modified Files:
src/sys/dev/iscsi [netbsd-8]: iscsi_ioctl.c iscsi_main.c iscsi_send.c
Log Message:
Pull up following revision(s) (requested by mlelstv in ticket #437):
sys/dev/iscsi/iscsi_ioctl.c: 1.26-1.27
sys/dev/iscsi/iscsi_main.c: 1.26
sys/dev/iscsi/iscsi_send.c: 1.35
Fix session cleanup.
--
add debug messages
-
use same lock for ref/deref.
--
unreference session only for responses to SCSI commands.
To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.25.6.1 src/sys/dev/iscsi/iscsi_ioctl.c
cvs rdiff -u -r1.24 -r1.24.8.1 src/sys/dev/iscsi/iscsi_main.c
cvs rdiff -u -r1.34 -r1.34.6.1 src/sys/dev/iscsi/iscsi_send.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/iscsi/iscsi_ioctl.c
diff -u src/sys/dev/iscsi/iscsi_ioctl.c:1.25 src/sys/dev/iscsi/iscsi_ioctl.c:1.25.6.1
--- src/sys/dev/iscsi/iscsi_ioctl.c:1.25 Sat Feb 25 12:03:57 2017
+++ src/sys/dev/iscsi/iscsi_ioctl.c Thu Dec 21 19:17:43 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_ioctl.c,v 1.25 2017/02/25 12:03:57 mlelstv Exp $ */
+/* $NetBSD: iscsi_ioctl.c,v 1.25.6.1 2017/12/21 19:17:43 snj Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -464,12 +464,12 @@ void
unref_session(session_t *session)
{
- mutex_enter(&session->lock);
+ mutex_enter(&iscsi_cleanup_mtx);
KASSERT(session != NULL);
KASSERT(session->refcount > 0);
if (--session->refcount == 0)
cv_broadcast(&session->sess_cv);
- mutex_exit(&session->lock);
+ mutex_exit(&iscsi_cleanup_mtx);
}
@@ -520,16 +520,19 @@ kill_connection(connection_t *conn, uint
terminating = conn->terminating;
if (!terminating)
conn->terminating = status;
- mutex_exit(&iscsi_cleanup_mtx);
/* Don't recurse */
if (terminating) {
+ mutex_exit(&iscsi_cleanup_mtx);
+
+ KASSERT(conn->state != ST_FULL_FEATURE);
DEBC(conn, 1, ("Kill_connection exiting (already terminating)\n"));
goto done;
}
if (conn->state == ST_FULL_FEATURE) {
sess->active_connections--;
+ conn->state = ST_WINDING_DOWN;
/* If this is the last connection and ERL < 2, reset TSIH */
if (!sess->active_connections && sess->ErrorRecoveryLevel < 2)
@@ -538,9 +541,6 @@ kill_connection(connection_t *conn, uint
/* Don't try to log out if the socket is broken or we're in the middle */
/* of logging in */
if (logout >= 0) {
- conn->state = ST_WINDING_DOWN;
- connection_timeout_start(conn, CONNECTION_TIMEOUT);
-
if (sess->ErrorRecoveryLevel < 2 &&
logout == RECOVER_CONNECTION) {
logout = LOGOUT_CONNECTION;
@@ -549,20 +549,29 @@ kill_connection(connection_t *conn, uint
logout == LOGOUT_CONNECTION) {
logout = LOGOUT_SESSION;
}
+ mutex_exit(&iscsi_cleanup_mtx);
+
+ connection_timeout_start(conn, CONNECTION_TIMEOUT);
+
if (!send_logout(conn, conn, logout, FALSE)) {
conn->terminating = ISCSI_STATUS_SUCCESS;
return;
}
/*
- * if the logout request was successfully sent, the logout response
- * handler will do the rest of the termination processing. If the
- * logout doesn't get a response, we'll get back in here once
- * the timeout hits.
+ * if the logout request was successfully sent,
+ * the logout response handler will do the rest
+ * of the termination processing. If the logout
+ * doesn't get a response, we'll get back in here
+ * once the timeout hits.
*/
+
+ mutex_enter(&iscsi_cleanup_mtx);
}
+
}
conn->state = ST_SETTLING;
+ mutex_exit(&iscsi_cleanup_mtx);
done:
/* let send thread take over next step of cleanup */
@@ -1641,6 +1650,7 @@ add_connection_cleanup(connection_t *con
if (conn->in_session) {
sess = conn->session;
conn->in_session = FALSE;
+ conn->session = NULL;
TAILQ_REMOVE(&sess->conn_list, conn, connections);
sess->mru_connection = TAILQ_FIRST(&sess->conn_list);
}
Index: src/sys/dev/iscsi/iscsi_main.c
diff -u src/sys/dev/iscsi/iscsi_main.c:1.24 src/sys/dev/iscsi/iscsi_main.c:1.24.8.1
--- src/sys/dev/iscsi/iscsi_main.c:1.24 Sun Dec 25 06:55:28 2016
+++ src/sys/dev/iscsi/iscsi_main.c Thu Dec 21 19:17:43 2017
@@ -558,6 +558,7 @@ iscsi_done(ccb_t *ccb)
DEB(9, ("iscsi_done\n"));
if (xs != NULL) {
+ ccb->xs = NULL;
xs->resid = ccb->residual;
switch (ccb->status) {
@@ -595,14 +596,14 @@ iscsi_done(ccb_t *ccb)
break;
}
+ unref_session(ccb->session);
+
DEB(99, ("Calling scsipi_done (%p), err = %d\n", xs, xs->error));
scsipi_done(xs);
DEB(99, ("scsipi_done returned\n"));
} else {
DEBOUT(("ISCSI: iscsi_done CCB %p without XS\n", ccb));
}
-
- unref_session(ccb->session);
}
SYSCTL_SETUP(sysctl_iscsi_setup, "ISCSI subtree setup")
Index: src/sys/dev/iscsi/iscsi_send.c
diff -u src/sys/dev/iscsi/iscsi_send.c:1.34 src/sys/dev/iscsi/iscsi_send.c:1.34.6.1
--- src/sys/dev/iscsi/iscsi_send.c:1.34 Sat Feb 25 12:03:57 2017
+++ src/sys/dev/iscsi/iscsi_send.c Thu Dec 21 19:17:43 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_send.c,v 1.34 2017/02/25 12:03:57 mlelstv Exp $ */
+/* $NetBSD: iscsi_send.c,v 1.34.6.1 2017/12/21 19:17:43 snj Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -395,7 +395,7 @@ iscsi_send_thread(void *par)
/* notify event handlers of connection shutdown */
DEBC(conn, 1, ("%s\n", (conn->destroy) ? "TERMINATED" : "RECOVER"));
add_event((conn->destroy) ? ISCSI_CONNECTION_TERMINATED
- : ISCSI_RECOVER_CONNECTION,
+ : ISCSI_RECOVER_CONNECTION,
sess->id, conn->id, conn->terminating);
DEBC(conn, 1, ("Waiting for conn_idle\n"));
@@ -1251,10 +1251,15 @@ send_task_management(connection_t *conn,
ccb = get_ccb(conn, xs == NULL);
/* can only happen if terminating... */
- if (ccb == NULL)
+ if (ccb == NULL) {
+ DEBC(conn, 0, ("send_task_management, ref_ccb=%p, xs=%p, term=%d. No CCB\n",
+ ref_ccb, xs, conn->terminating));
return conn->terminating;
+ }
ppdu = get_pdu(conn, xs == NULL);
if (ppdu == NULL) {
+ DEBC(conn, 0, ("send_task_management, ref_ccb=%p, xs=%p, term=%d. No PDU\n",
+ ref_ccb, xs, conn->terminating));
free_ccb(ccb);
return conn->terminating;
}
@@ -1489,6 +1494,7 @@ send_run_xfer(session_t *session, struct
if (xs->xs_control & XS_CTL_RESET) {
if (send_task_management(conn, NULL, xs, TARGET_WARM_RESET)) {
+ DEBC(conn, 0, ("send_task_management TARGET_WARM_RESET failed\n"));
xs->error = XS_SELTIMEOUT;
scsipi_done(xs);
unref_session(session);