Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/iscsi Several improvements to the ISCSI driver.
details: https://anonhg.NetBSD.org/src/rev/1ff5bf318410
branches: trunk
changeset: 345452:1ff5bf318410
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sun May 29 13:51:16 2016 +0000
description:
Several improvements to the ISCSI driver.
- Enable debug messages but set log level to be quiet. Provide a
system (hw.iscsi.debug) to set the log level at run time.
- Replace old tsleep/wakeup synchronization with mutexes and condvars.
- Defer actions from callouts (basically timeouts) to the cleanup thread.
- Protect lists and unique ids with mutexes. protect connection usecount
by using atomic operations.
- Assert kernel lock when calling into scsipi and network code.
- Use this to make send/receive/cleanup threads MPSAFE.
- Fix handling of out-of-CCB/out-of-PDU conditions against the scsipi layer.
- Bump number of PDUs to 128 to avoid virtually all out-of-PDU conditions
- Make use of softc structure for attach/detach operations.
- Track open file handles to prevent detach when busy.
- Move some global variables to make them static.
- Fix 'Overlapping Commands Attempted' error by marking commands as
simply ordered (ATTR_SIMPLE) like FreeBSD.
diffstat:
sys/dev/iscsi/iscsi_globals.h | 61 +++--
sys/dev/iscsi/iscsi_ioctl.c | 423 +++++++++++++++++++++++++++++------------
sys/dev/iscsi/iscsi_main.c | 165 +++++++++++----
sys/dev/iscsi/iscsi_rcv.c | 34 ++-
sys/dev/iscsi/iscsi_send.c | 149 +++++++-------
sys/dev/iscsi/iscsi_text.c | 42 ++-
sys/dev/iscsi/iscsi_utils.c | 85 ++++---
7 files changed, 629 insertions(+), 330 deletions(-)
diffs (truncated from 2589 to 300 lines):
diff -r 9a89814a5be3 -r 1ff5bf318410 sys/dev/iscsi/iscsi_globals.h
--- a/sys/dev/iscsi/iscsi_globals.h Sun May 29 13:35:45 2016 +0000
+++ b/sys/dev/iscsi/iscsi_globals.h Sun May 29 13:51:16 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_globals.h,v 1.13 2015/05/30 20:09:47 joerg Exp $ */
+/* $NetBSD: iscsi_globals.h,v 1.14 2016/05/29 13:51:16 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
/* ------------------------ Code selection constants ------------------------ */
-/* #define ISCSI_DEBUG 1 */
+#define ISCSI_DEBUG 0
/* ------------------------- Global Constants ----------------------------- */
@@ -96,7 +96,7 @@
high values of First/MaxBurstLength and small values of
MaxRecvDataSegmentLength of the target.
*/
-#define PDUS_PER_CONNECTION 64 /* ToDo: Reasonable number?? */
+#define PDUS_PER_CONNECTION 128 /* ToDo: Reasonable number?? */
/* max outstanding serial nums before we give up on the connection */
#define SERNUM_BUFFER_LENGTH (CCBS_PER_SESSION / 2) /* ToDo: Reasonable?? */
@@ -181,7 +181,6 @@
typedef enum {
PDUDISP_UNUSED, /* 0 = In free pool */
- PDUDISP_SIGNAL, /* Free this PDU when done and wakeup(pdu) */
PDUDISP_FREE, /* Free this PDU when done */
PDUDISP_WAIT /* Waiting for acknowledge */
} pdu_disp_t;
@@ -253,6 +252,7 @@
ccb_disp_t disp; /* what to do with this ccb */
struct callout timeout; /* To make sure it isn't lost */
+ TAILQ_ENTRY(ccb_s) tchain;
int num_timeouts;
/* How often we've sent out SNACK without answer */
int total_tries;
@@ -309,6 +309,11 @@
struct connection_s {
TAILQ_ENTRY(connection_s) connections;
+ kmutex_t lock;
+ kcondvar_t conn_cv;
+ kcondvar_t ccb_cv;
+ kcondvar_t idle_cv;
+
pdu_list_t pdu_pool; /* the free PDU pool */
ccb_list_t ccbs_waiting;
@@ -358,7 +363,7 @@
/* if closing down: status */
int recover; /* recovery count */
/* (reset on first successful data transfer) */
- int usecount; /* number of active CCBs */
+ unsigned usecount; /* number of active CCBs */
bool destroy; /* conn will be destroyed */
bool in_session;
@@ -367,6 +372,7 @@
/* status of logout (for recovery) */
struct callout timeout;
/* Timeout for checking if connection is dead */
+ TAILQ_ENTRY(connection_s) tchain;
int num_timeouts;
/* How often we've sent out a NOP without answer */
uint32_t idle_timeout_val;
@@ -402,6 +408,10 @@
/* local stuff */
TAILQ_ENTRY(session_s) sessions; /* the list of sessions */
+ kmutex_t lock;
+ kcondvar_t sess_cv;
+ kcondvar_t ccb_cv;
+
ccb_list_t ccb_pool; /* The free CCB pool */
ccb_list_t ccbs_throttled;
/* CCBs waiting for MaxCmdSN to increase */
@@ -457,18 +467,6 @@
/*
- The softc structure. This driver doesn't really need one, because there's
- always just one instance, and for the time being it's only loaded as
- an LKM (which doesn't create a softc), but we need one to put into the
- scsipi interface structures, so here it is.
-*/
-
-typedef struct iscsi_softc {
- device_t sc_dev;
-} iscsi_softc_t;
-
-
-/*
Event notification structures
*/
@@ -502,7 +500,9 @@
/* /dev/iscsi0 state */
struct iscsifd {
- char dummy;
+ TAILQ_ENTRY(iscsifd) link;
+ device_t dev;
+ int unit;
};
/* ------------------------- Global Variables ----------------------------- */
@@ -512,12 +512,7 @@
extern struct cfattach iscsi_ca; /* the device attach structure */
extern session_list_t iscsi_sessions; /* the list of sessions */
-
-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 */
-
extern uint32_t iscsi_num_send_threads; /* the number of active send threads */
extern uint8_t iscsi_InitiatorName[ISCSI_STRING_LENGTH];
@@ -539,7 +534,7 @@
#define DEBC(conn,lev,x) { if (iscsi_debug_level >= lev) { printf("S%dC%d: ", \
conn ? conn->session->id : -1, \
conn ? conn->id : -1); printf x ;}}
-void dump(void *buf, int len);
+void iscsi_hexdump(void *buf, int len);
#define STATIC static
@@ -548,7 +543,7 @@
#define DEBOUT(x)
#define DEB(lev,x)
#define DEBC(conn,lev,x)
-#define dump(a,b)
+#define iscsi_hexdump(a,b)
#define STATIC static
@@ -634,6 +629,11 @@
/* in iscsi_ioctl.c */
+void iscsi_init_cleanup(void);
+void iscsi_destroy_cleanup(void);
+void iscsi_notify_cleanup(void);
+
+
/* Parameter for logout is reason code in logout PDU, -1 for don't send logout */
#define NO_LOGOUT -1
#define LOGOUT_SESSION 0
@@ -646,7 +646,7 @@
void kill_session(session_t *, uint32_t, int, bool);
void kill_all_sessions(void);
void handle_connection_error(connection_t *, uint32_t, int);
-void iscsi_cleanup_thread(void *);
+void add_connection_cleanup(connection_t *);
#ifndef ISCSI_MINIMAL
uint32_t map_databuf(struct proc *, void **, uint32_t);
@@ -664,7 +664,7 @@
int iscsidetach(device_t, int);
void iscsi_done(ccb_t *);
-int map_session(session_t *);
+int map_session(session_t *, device_t);
int unmap_session(session_t *);
/* in iscsi_send.c */
@@ -694,8 +694,11 @@
int send_io_command(session_t *, uint64_t, scsireq_t *, bool, uint32_t);
#endif
-void connection_timeout(void *);
-void ccb_timeout(void *);
+void connection_timeout_co(void *);
+void ccb_timeout_co(void *);
+
+void connection_timeout(connection_t *);
+void ccb_timeout(ccb_t *);
/* in iscsi_rcv.c */
diff -r 9a89814a5be3 -r 1ff5bf318410 sys/dev/iscsi/iscsi_ioctl.c
--- a/sys/dev/iscsi/iscsi_ioctl.c Sun May 29 13:35:45 2016 +0000
+++ b/sys/dev/iscsi/iscsi_ioctl.c Sun May 29 13:51:16 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: iscsi_ioctl.c,v 1.13 2015/09/19 18:32:42 dholland Exp $ */
+/* $NetBSD: iscsi_ioctl.c,v 1.14 2016/05/29 13:51:16 mlelstv Exp $ */
/*-
* Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -40,12 +40,29 @@
#include <uvm/uvm_pmap.h>
#endif
+static kmutex_t iscsi_cleanup_mtx;
+static kcondvar_t iscsi_cleanup_cv;
+static kcondvar_t iscsi_event_cv;
+static struct lwp *iscsi_cleanproc = NULL;
+
static uint16_t current_id = 0; /* Global session ID counter */
/* list of event handlers */
static event_handler_list_t event_handlers =
TAILQ_HEAD_INITIALIZER(event_handlers);
+static connection_list_t iscsi_timeout_conn_list =
+ TAILQ_HEAD_INITIALIZER(iscsi_timeout_conn_list);
+
+static ccb_list_t iscsi_timeout_ccb_list =
+ TAILQ_HEAD_INITIALIZER(iscsi_timeout_ccb_list);
+
+static session_list_t iscsi_cleanups_list =
+ TAILQ_HEAD_INITIALIZER(iscsi_cleanups_list);
+
+static connection_list_t iscsi_cleanupc_list =
+ TAILQ_HEAD_INITIALIZER(iscsi_cleanupc_list);
+
static uint32_t handler_id = 0; /* Handler ID counter */
/* -------------------------------------------------------------------------- */
@@ -64,11 +81,13 @@
*/
-STATIC event_handler_t *
+static event_handler_t *
find_handler(uint32_t id)
{
event_handler_t *curr;
+ KASSERT(mutex_owned(&iscsi_cleanup_mtx));
+
TAILQ_FOREACH(curr, &event_handlers, link)
if (curr->id == id)
break;
@@ -85,12 +104,11 @@
* par The parameter.
*/
-STATIC void
+static void
register_event(iscsi_register_event_parameters_t *par)
{
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,21 +119,19 @@
TAILQ_INIT(&handler->events);
+ mutex_enter(&iscsi_cleanup_mtx);
/* create a unique ID */
- s = splbio();
do {
++handler_id;
} while (!handler_id || find_handler(handler_id) != NULL);
par->event_id = handler->id = handler_id;
was_empty = TAILQ_FIRST(&event_handlers) == NULL;
-
TAILQ_INSERT_TAIL(&event_handlers, handler, link);
+ mutex_exit(&iscsi_cleanup_mtx);
- if (was_empty) {
- wakeup(&iscsi_cleanupc_list);
- }
- splx(s);
+ if (was_empty)
+ iscsi_notify_cleanup();
par->status = ISCSI_STATUS_SUCCESS;
DEB(5, ("Register Event OK, ID %d\n", par->event_id));
@@ -130,27 +146,27 @@
* par The parameter.
*/
-STATIC void
+static void
deregister_event(iscsi_register_event_parameters_t *par)
{
event_handler_t *handler;
event_t *evt;
- int s;
+ mutex_enter(&iscsi_cleanup_mtx);
handler = find_handler(par->event_id);
if (handler == NULL) {
+ mutex_exit(&iscsi_cleanup_mtx);
DEB(1, ("Deregister Event ID %d not found\n", par->event_id));
par->status = ISCSI_STATUS_INVALID_EVENT_ID;
Home |
Main Index |
Thread Index |
Old Index