Module Name: src
Committed By: mlelstv
Date: Sun Jun 5 04:48:18 UTC 2016
Modified Files:
src/sys/dev/iscsi: iscsi_globals.h iscsi_ioctl.c iscsi_utils.c
Log Message:
When stopping a callout, wait until the cleanup thread has processed them.
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/iscsi/iscsi_globals.h
cvs rdiff -u -r1.17 -r1.18 src/sys/dev/iscsi/iscsi_ioctl.c
cvs rdiff -u -r1.12 -r1.13 src/sys/dev/iscsi/iscsi_utils.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_globals.h
diff -u src/sys/dev/iscsi/iscsi_globals.h:1.16 src/sys/dev/iscsi/iscsi_globals.h:1.17
--- src/sys/dev/iscsi/iscsi_globals.h:1.16 Wed Jun 1 05:13:07 2016
+++ src/sys/dev/iscsi/iscsi_globals.h Sun Jun 5 04:48:17 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_globals.h,v 1.16 2016/06/01 05:13:07 mlelstv Exp $ */
+/* $NetBSD: iscsi_globals.h,v 1.17 2016/06/05 04:48:17 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -185,6 +185,14 @@ typedef enum {
PDUDISP_WAIT /* Waiting for acknowledge */
} pdu_disp_t;
+/* Timeout state */
+
+typedef enum {
+ TOUT_NONE, /* Initial */
+ TOUT_ARMED, /* callout is scheduled */
+ TOUT_QUEUED, /* put into timeout queue */
+ TOUT_BUSY /* cleanup thread working */
+} tout_state_t;
typedef struct connection_s connection_t;
typedef struct session_s session_t;
@@ -253,7 +261,7 @@ struct ccb_s {
struct callout timeout; /* To make sure it isn't lost */
TAILQ_ENTRY(ccb_s) tchain;
- bool timedout;
+ tout_state_t timedout;
int num_timeouts;
/* How often we've sent out SNACK without answer */
int total_tries;
@@ -374,7 +382,7 @@ struct connection_s {
struct callout timeout;
/* Timeout for checking if connection is dead */
TAILQ_ENTRY(connection_s) tchain;
- bool timedout;
+ tout_state_t timedout;
int num_timeouts;
/* How often we've sent out a NOP without answer */
uint32_t idle_timeout_val;
Index: src/sys/dev/iscsi/iscsi_ioctl.c
diff -u src/sys/dev/iscsi/iscsi_ioctl.c:1.17 src/sys/dev/iscsi/iscsi_ioctl.c:1.18
--- src/sys/dev/iscsi/iscsi_ioctl.c:1.17 Fri Jun 3 06:55:16 2016
+++ src/sys/dev/iscsi/iscsi_ioctl.c Sun Jun 5 04:48:17 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_ioctl.c,v 1.17 2016/06/03 06:55:16 mlelstv Exp $ */
+/* $NetBSD: iscsi_ioctl.c,v 1.18 2016/06/05 04:48:17 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -1577,7 +1577,7 @@ connection_timeout_co(void *par)
connection_t *conn = par;
mutex_enter(&iscsi_cleanup_mtx);
- conn->timedout = true;
+ conn->timedout = TOUT_QUEUED;
TAILQ_INSERT_TAIL(&iscsi_timeout_conn_list, conn, tchain);
mutex_exit(&iscsi_cleanup_mtx);
iscsi_notify_cleanup();
@@ -1586,7 +1586,12 @@ connection_timeout_co(void *par)
void
connection_timeout_start(connection_t *conn, int ticks)
{
- callout_schedule(&conn->timeout, ticks);
+ mutex_enter(&iscsi_cleanup_mtx);
+ if (conn->timedout != TOUT_QUEUED) {
+ conn->timedout = TOUT_ARMED;
+ callout_schedule(&conn->timeout, ticks);
+ }
+ mutex_exit(&iscsi_cleanup_mtx);
}
void
@@ -1594,10 +1599,14 @@ connection_timeout_stop(connection_t *co
{
callout_halt(&conn->timeout, NULL);
mutex_enter(&iscsi_cleanup_mtx);
- if (conn->timedout) {
+ if (conn->timedout == TOUT_QUEUED) {
TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, tchain);
- conn->timedout = false;
+ conn->timedout = TOUT_NONE;
}
+ if (curlwp != iscsi_cleanproc) {
+ while (conn->timedout == TOUT_BUSY)
+ kpause("connbusy", false, 1, &iscsi_cleanup_mtx);
+ }
mutex_exit(&iscsi_cleanup_mtx);
}
@@ -1607,7 +1616,7 @@ ccb_timeout_co(void *par)
ccb_t *ccb = par;
mutex_enter(&iscsi_cleanup_mtx);
- ccb->timedout = true;
+ ccb->timedout = TOUT_QUEUED;
TAILQ_INSERT_TAIL(&iscsi_timeout_ccb_list, ccb, tchain);
mutex_exit(&iscsi_cleanup_mtx);
iscsi_notify_cleanup();
@@ -1616,7 +1625,12 @@ ccb_timeout_co(void *par)
void
ccb_timeout_start(ccb_t *ccb, int ticks)
{
- callout_schedule(&ccb->timeout, ticks);
+ mutex_enter(&iscsi_cleanup_mtx);
+ if (ccb->timedout != TOUT_QUEUED) {
+ ccb->timedout = TOUT_ARMED;
+ callout_schedule(&ccb->timeout, ticks);
+ }
+ mutex_exit(&iscsi_cleanup_mtx);
}
void
@@ -1624,10 +1638,14 @@ ccb_timeout_stop(ccb_t *ccb)
{
callout_halt(&ccb->timeout, NULL);
mutex_enter(&iscsi_cleanup_mtx);
- if (ccb->timedout) {
+ if (ccb->timedout == TOUT_QUEUED) {
TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, tchain);
- ccb->timedout = false;
+ ccb->timedout = TOUT_NONE;
}
+ if (curlwp != iscsi_cleanproc) {
+ while (ccb->timedout == TOUT_BUSY)
+ kpause("ccbbusy", false, 1, &iscsi_cleanup_mtx);
+ }
mutex_exit(&iscsi_cleanup_mtx);
}
@@ -1727,16 +1745,24 @@ iscsi_cleanup_thread(void *par)
/* handle ccb timeouts */
while ((ccb = TAILQ_FIRST(&iscsi_timeout_ccb_list)) != NULL) {
TAILQ_REMOVE(&iscsi_timeout_ccb_list, ccb, tchain);
+ KASSERT(ccb->timedout == TOUT_QUEUED);
+ ccb->timedout = TOUT_BUSY;
mutex_exit(&iscsi_cleanup_mtx);
ccb_timeout(ccb);
mutex_enter(&iscsi_cleanup_mtx);
+ if (ccb->timedout == TOUT_BUSY)
+ ccb->timedout = TOUT_NONE;
}
/* handle connection timeouts */
while ((conn = TAILQ_FIRST(&iscsi_timeout_conn_list)) != NULL) {
TAILQ_REMOVE(&iscsi_timeout_conn_list, conn, tchain);
+ KASSERT(conn->timedout == TOUT_QUEUED);
+ conn->timedout = TOUT_BUSY;
mutex_exit(&iscsi_cleanup_mtx);
connection_timeout(conn);
mutex_enter(&iscsi_cleanup_mtx);
+ if (conn->timedout == TOUT_BUSY)
+ conn->timedout = TOUT_NONE;
}
/* if timed out, not woken up */
Index: src/sys/dev/iscsi/iscsi_utils.c
diff -u src/sys/dev/iscsi/iscsi_utils.c:1.12 src/sys/dev/iscsi/iscsi_utils.c:1.13
--- src/sys/dev/iscsi/iscsi_utils.c:1.12 Sun Jun 5 04:36:05 2016
+++ src/sys/dev/iscsi/iscsi_utils.c Sun Jun 5 04:48:17 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_utils.c,v 1.12 2016/06/05 04:36:05 mlelstv Exp $ */
+/* $NetBSD: iscsi_utils.c,v 1.13 2016/06/05 04:48:17 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2008 The NetBSD Foundation, Inc.
@@ -239,6 +239,7 @@ get_ccb(connection_t *conn, bool waitok)
mutex_exit(&sess->lock);
ccb->flags = 0;
+ ccb->timedout = TOUT_NONE;
ccb->xs = NULL;
ccb->temp_data = NULL;
ccb->text_data = NULL;