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