Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/iscsi When stopping a callout, wait until the cleanu...



details:   https://anonhg.NetBSD.org/src/rev/75c3b3da295f
branches:  trunk
changeset: 815825:75c3b3da295f
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sun Jun 05 04:48:17 2016 +0000

description:
When stopping a callout, wait until the cleanup thread has processed them.

diffstat:

 sys/dev/iscsi/iscsi_globals.h |  14 ++++++++++--
 sys/dev/iscsi/iscsi_ioctl.c   |  44 ++++++++++++++++++++++++++++++++++--------
 sys/dev/iscsi/iscsi_utils.c   |   3 +-
 3 files changed, 48 insertions(+), 13 deletions(-)

diffs (173 lines):

diff -r 57b08294ca88 -r 75c3b3da295f sys/dev/iscsi/iscsi_globals.h
--- a/sys/dev/iscsi/iscsi_globals.h     Sun Jun 05 04:36:05 2016 +0000
+++ b/sys/dev/iscsi/iscsi_globals.h     Sun Jun 05 04:48:17 2016 +0000
@@ -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 @@
        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 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 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;
diff -r 57b08294ca88 -r 75c3b3da295f sys/dev/iscsi/iscsi_ioctl.c
--- a/sys/dev/iscsi/iscsi_ioctl.c       Sun Jun 05 04:36:05 2016 +0000
+++ b/sys/dev/iscsi/iscsi_ioctl.c       Sun Jun 05 04:48:17 2016 +0000
@@ -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_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 @@
 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 @@
 {                                                
        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_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 @@
 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 @@
 {
        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 @@
                        /* 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 */
diff -r 57b08294ca88 -r 75c3b3da295f sys/dev/iscsi/iscsi_utils.c
--- a/sys/dev/iscsi/iscsi_utils.c       Sun Jun 05 04:36:05 2016 +0000
+++ b/sys/dev/iscsi/iscsi_utils.c       Sun Jun 05 04:48:17 2016 +0000
@@ -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 @@
        mutex_exit(&sess->lock);
 
        ccb->flags = 0;
+       ccb->timedout = TOUT_NONE;
        ccb->xs = NULL;
        ccb->temp_data = NULL;
        ccb->text_data = NULL;



Home | Main Index | Thread Index | Old Index