Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/iscsi - defer session cleanup to not force detachments



details:   https://anonhg.NetBSD.org/src/rev/a7b0bcc25f2b
branches:  trunk
changeset: 783561:a7b0bcc25f2b
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Dec 29 11:05:29 2012 +0000

description:
- defer session cleanup to not force detachments
- use more and explicit locking
- improve connection recovery
- use larger timeouts
- handle ccb buffer underflow correctly
- simplify throttling code

Sessions can now temporarily exist without a valid
connection, you also need to update iscsid(8).

diffstat:

 sys/dev/iscsi/iscsi_globals.h |   37 +++---
 sys/dev/iscsi/iscsi_ioctl.c   |  146 ++++++++++++++++++++----------
 sys/dev/iscsi/iscsi_main.c    |   24 +++-
 sys/dev/iscsi/iscsi_rcv.c     |  107 +++++++++++-----------
 sys/dev/iscsi/iscsi_send.c    |  183 ++++++++++++++++++++-----------------
 sys/dev/iscsi/iscsi_test.c    |   35 +++---
 sys/dev/iscsi/iscsi_utils.c   |  201 ++++++++++++++++-------------------------
 7 files changed, 384 insertions(+), 349 deletions(-)

diffs (truncated from 1840 to 300 lines):

diff -r 37095a7822c1 -r a7b0bcc25f2b sys/dev/iscsi/iscsi_globals.h
--- a/sys/dev/iscsi/iscsi_globals.h     Sat Dec 29 10:22:40 2012 +0000
+++ b/sys/dev/iscsi/iscsi_globals.h     Sat Dec 29 11:05:29 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iscsi_globals.h,v 1.5 2012/08/12 13:26:18 mlelstv Exp $        */
+/*     $NetBSD: iscsi_globals.h,v 1.6 2012/12/29 11:05:29 mlelstv Exp $        */
 
 /*-
  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -84,7 +84,7 @@
 effectively says "don't bother testing these values", and is used right
 now only in iscsi_send.c.
  */
-#define ISCSI_TROTTLING_ENABLED        1
+#define ISCSI_THROTTLING_ENABLED       1
 #define ISCSI_SERVER_TRUSTED   1
 
 /*
@@ -131,14 +131,15 @@
 
 /* CCB Flags */
 
-#define CCBF_COMPLETE   0x01   /* received status */
-#define CCBF_RESENT     0x02   /* ccb was resent */
-#define CCBF_SENDTARGET 0x04   /* SendTargets text request, not negotiation */
-#define CCBF_WAITING    0x08   /* CCB is waiting for MaxCmdSN, wake it up */
-#define CCBF_GOT_RSP    0x10   /* Got at least one response to this request */
-#define CCBF_REASSIGN  0x20    /* Command can be reassigned */
-#define CCBF_OTHERCONN 0x40    /* a logout for a different connection */
-
+#define CCBF_COMPLETE   0x0001 /* received status */
+#define CCBF_RESENT     0x0002 /* ccb was resent */
+#define CCBF_SENDTARGET 0x0004 /* SendTargets text request, not negotiation */
+#define CCBF_WAITING    0x0008 /* CCB is waiting for MaxCmdSN, wake it up */
+#define CCBF_GOT_RSP    0x0010 /* Got at least one response to this request */
+#define CCBF_REASSIGN   0x0020 /* Command can be reassigned */
+#define CCBF_OTHERCONN  0x0040 /* a logout for a different connection */
+#define CCBF_WAITQUEUE  0x0080 /* CCB is on waiting queue */
+#define CCBF_THROTTLING 0x0100 /* CCB is on throttling queue */
 
 /* ---------------------------  Global Types  ------------------------------- */
 
@@ -543,7 +544,8 @@
 
 extern session_list_t iscsi_sessions;          /* the list of sessions */
 
-extern connection_list_t iscsi_cleanup_list;   /* connections to clean up */
+extern connection_list_t iscsi_cleanupc_list;  /* connections to clean up */
+extern session_list_t iscsi_cleanups_list;     /* sessions to clean up */
 extern bool iscsi_detaching;                   /* signal to cleanup thread it should exit */
 extern struct lwp *iscsi_cleanproc;            /* pointer to cleanup proc */
 
@@ -602,9 +604,6 @@
 
 /* Critical section macros */
 
-#define CS_BEGIN     { int s = splbio ();
-#define CS_END       splx (s); }
-
 /* misc stuff */
 #define min(a, b) ((a) < (b)) ? (a) : (b)
 #define max(a, b) ((a) < (b)) ? (b) : (a)
@@ -757,7 +756,7 @@
 
 void iscsi_done(ccb_t *);
 int map_session(session_t *);
-void unmap_session(session_t *);
+int unmap_session(session_t *);
 
 /* in iscsi_send.c */
 
@@ -801,12 +800,12 @@
 void create_ccbs(session_t *);
 ccb_t *get_ccb(connection_t *, bool);
 void free_ccb(ccb_t *);
-void wake_ccb(ccb_t *);
-void complete_ccb(ccb_t *);
+void suspend_ccb(ccb_t *, bool);
+void throttle_ccb(ccb_t *, bool);
+void wake_ccb(ccb_t *, uint32_t);
 
 void create_pdus(connection_t *);
-pdu_t *get_pdu(connection_t *);
-pdu_t *get_pdu_c(connection_t *, bool);
+pdu_t *get_pdu(connection_t *, bool);
 void free_pdu(pdu_t *);
 
 void init_sernum(sernum_buffer_t *);
diff -r 37095a7822c1 -r a7b0bcc25f2b sys/dev/iscsi/iscsi_ioctl.c
--- a/sys/dev/iscsi/iscsi_ioctl.c       Sat Dec 29 10:22:40 2012 +0000
+++ b/sys/dev/iscsi/iscsi_ioctl.c       Sat Dec 29 11:05:29 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iscsi_ioctl.c,v 1.5 2012/08/12 13:26:18 mlelstv Exp $  */
+/*     $NetBSD: iscsi_ioctl.c,v 1.6 2012/12/29 11:05:29 mlelstv Exp $  */
 
 /*-
  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -90,6 +90,7 @@
 {
        event_handler_t *handler;
        int was_empty;
+       int s;
 
        handler = malloc(sizeof(event_handler_t), M_DEVBUF, M_WAITOK | M_ZERO);
        if (handler == NULL) {
@@ -101,7 +102,7 @@
        TAILQ_INIT(&handler->events);
 
        /* create a unique ID */
-       CS_BEGIN;
+       s = splbio();
        do {
                ++handler_id;
        } while (!handler_id || find_handler(handler_id) != NULL);
@@ -112,9 +113,9 @@
        TAILQ_INSERT_TAIL(&event_handlers, handler, link);
 
        if (was_empty) {
-               wakeup(&iscsi_cleanup_list);
+               wakeup(&iscsi_cleanupc_list);
        }
-       CS_END;
+       splx(s);
 
        par->status = ISCSI_STATUS_SUCCESS;
        DEB(5, ("Register Event OK, ID %d\n", par->event_id));
@@ -134,6 +135,7 @@
 {
        event_handler_t *handler;
        event_t *evt;
+       int s;
 
        handler = find_handler(par->event_id);
        if (handler == NULL) {
@@ -141,9 +143,11 @@
                par->status = ISCSI_STATUS_INVALID_EVENT_ID;
                return;
        }
-       CS_BEGIN;
+
+       s = splbio();
        TAILQ_REMOVE(&event_handlers, handler, link);
-       CS_END;
+       splx(s);
+
        if (handler->waiter != NULL) {
                handler->waiter->status = ISCSI_STATUS_EVENT_DEREGISTERED;
                wakeup(handler->waiter);
@@ -238,10 +242,12 @@
 {
        event_handler_t *curr;
        event_t *evt;
+       int s;
 
        DEB(9, ("Add_event kind %d, sid %d, cid %d, reason %d\n",
                kind, sid, cid, reason));
 
+       s = splbio();
        TAILQ_FOREACH(curr, &event_handlers, link) {
                evt = malloc(sizeof(*evt), M_TEMP, M_WAITOK);
                if (evt == NULL) {
@@ -251,14 +257,14 @@
                evt->session_id = sid;
                evt->connection_id = cid;
                evt->reason = reason;
-               CS_BEGIN;
+
                TAILQ_INSERT_TAIL(&curr->events, evt, link);
                if (curr->waiter != NULL) {
                        wakeup(curr->waiter);
                        curr->waiter = NULL;
                }
-               CS_END;
        }
+       splx(s);
 }
 
 
@@ -273,6 +279,8 @@
  *    list has changed at all. If not, the event is deregistered.
  *    Note that this will not detect dead handlers if no events are pending,
  *    but we don't care as long as events don't accumulate in the list.
+ *
+ *    this function must be called at splbio
  */
 
 STATIC void
@@ -367,11 +375,14 @@
 find_session(uint32_t id)
 {
        session_t *curr;
+       int s;
 
+       s = splbio();
        TAILQ_FOREACH(curr, &iscsi_sessions, sessions)
                if (curr->id == id) {
                        break;
                }
+       splx(s);
        return curr;
 }
 
@@ -389,11 +400,14 @@
 find_connection(session_t *session, uint32_t id)
 {
        connection_t *curr;
+       int s;
 
+       s = splbio();
        TAILQ_FOREACH(curr, &session->conn_list, connections)
                if (curr->id == id) {
                        break;
                }
+       splx(s);
        return curr;
 }
 
@@ -413,6 +427,7 @@
 kill_connection(connection_t *conn, uint32_t status, int logout, bool recover)
 {
        session_t *sess = conn->session;
+       int s;
 
        DEBC(conn, 1, ("Kill_connection: terminating=%d, status=%d, logout=%d, "
                           "state=%d\n",
@@ -427,13 +442,15 @@
        }
 
        if (!recover || conn->destroy) {
-               CS_BEGIN;
+
+               s = splbio();
                if (conn->in_session) {
                        conn->in_session = FALSE;
                        TAILQ_REMOVE(&sess->conn_list, conn, connections);
                        sess->mru_connection = TAILQ_FIRST(&sess->conn_list);
                }
-               CS_END;
+               splx(s);
+
                if (!conn->destroy) {
                        DEBC(conn, 1, ("Kill_connection setting destroy flag\n"));
                        conn->destroy = TRUE;
@@ -512,6 +529,7 @@
 {
        connection_t *curr;
        ccb_t *ccb;
+       int s;
 
        DEB(1, ("ISCSI: kill_session %d, status %d, logout %d, recover %d\n",
                        session->id, status, logout, recover));
@@ -543,16 +561,21 @@
        }
 
        /* remove from session list */
+       s = splbio();
        TAILQ_REMOVE(&iscsi_sessions, session, sessions);
+       splx(s);
        session->sessions.tqe_next = NULL;
        session->sessions.tqe_prev = NULL;
 
        /* complete any throttled CCBs */
+       s = splbio();
        while ((ccb = TAILQ_FIRST(&session->ccbs_throttled)) != NULL) {
-               ccb->status = ISCSI_STATUS_LOGOUT;
-               TAILQ_REMOVE(&session->ccbs_throttled, ccb, chain);
-               complete_ccb(ccb);
+               throttle_ccb(ccb, FALSE);
+               splx(s);
+               wake_ccb(ccb, ISCSI_STATUS_LOGOUT);
+               s = splbio();
        }
+       splx(s);
 
        /*
         * unmap first to give the system an opportunity to flush its buffers,
@@ -595,7 +618,7 @@
                                  PTHREADOBJ p)
 {
        connection_t *connection;
-       int rc;
+       int rc, s;
 
        DEB(1, ("Create Connection for Session %d\n", session->id));
 
@@ -683,7 +706,7 @@
                closef(connection->sock);
 
                /* give receive thread time to exit */
-               tsleep(connection, PWAIT, "settle", 20);
+               tsleep(connection, PWAIT, "settle", 2 * hz);
 
                release_socket(connection->sock);
                free(connection, M_DEVBUF);
@@ -709,15 +732,14 @@
                return -1;
        }
 
-       CS_BEGIN;
+       s = splbio();



Home | Main Index | Thread Index | Old Index