summaryrefslogtreecommitdiffstats
path: root/sys/dev/iscsi
diff options
context:
space:
mode:
authortrasz <trasz@FreeBSD.org>2014-05-07 06:29:01 +0000
committertrasz <trasz@FreeBSD.org>2014-05-07 06:29:01 +0000
commit76ebd34835b2e2e1d405517d42868a02764eec0d (patch)
tree024a0087d2e808206d35754ee547c926eaad4427 /sys/dev/iscsi
parentdfa8f3f0a1d3923f791360de1316b13345c93065 (diff)
downloadFreeBSD-src-76ebd34835b2e2e1d405517d42868a02764eec0d.zip
FreeBSD-src-76ebd34835b2e2e1d405517d42868a02764eec0d.tar.gz
MFC r264022:
Get rid of ICL lock; use upper-layer (initiator or target) lock instead. This avoids extra locking in icl_pdu_queue(); the upper layer needs to call it while holding its own lock anyway, to avoid sending PDUs out of order. Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/dev/iscsi')
-rw-r--r--sys/dev/iscsi/icl.c27
-rw-r--r--sys/dev/iscsi/icl.h4
-rw-r--r--sys/dev/iscsi/iscsi.c2
3 files changed, 20 insertions, 13 deletions
diff --git a/sys/dev/iscsi/icl.c b/sys/dev/iscsi/icl.c
index 76f4af1..3576b4f 100644
--- a/sys/dev/iscsi/icl.c
+++ b/sys/dev/iscsi/icl.c
@@ -85,9 +85,10 @@ static volatile u_int icl_ncons;
__func__, ## __VA_ARGS__); \
} while (0)
-#define ICL_CONN_LOCK(X) mtx_lock(&X->ic_lock)
-#define ICL_CONN_UNLOCK(X) mtx_unlock(&X->ic_lock)
-#define ICL_CONN_LOCK_ASSERT(X) mtx_assert(&X->ic_lock, MA_OWNED)
+#define ICL_CONN_LOCK(X) mtx_lock(X->ic_lock)
+#define ICL_CONN_UNLOCK(X) mtx_unlock(X->ic_lock)
+#define ICL_CONN_LOCK_ASSERT(X) mtx_assert(X->ic_lock, MA_OWNED)
+#define ICL_CONN_LOCK_ASSERT_NOT(X) mtx_assert(X->ic_lock, MA_NOTOWNED)
static void
icl_conn_fail(struct icl_conn *ic)
@@ -893,7 +894,7 @@ icl_send_thread(void *arg)
break;
}
icl_conn_send_pdus(ic);
- cv_wait(&ic->ic_send_cv, &ic->ic_lock);
+ cv_wait(&ic->ic_send_cv, ic->ic_lock);
}
ic->ic_send_running = false;
@@ -958,20 +959,19 @@ icl_pdu_queue(struct icl_pdu *ip)
ic = ip->ip_conn;
- ICL_CONN_LOCK(ic);
+ ICL_CONN_LOCK_ASSERT(ic);
+
if (ic->ic_disconnecting || ic->ic_socket == NULL) {
ICL_DEBUG("icl_pdu_queue on closed connection");
- ICL_CONN_UNLOCK(ic);
icl_pdu_free(ip);
return;
}
TAILQ_INSERT_TAIL(&ic->ic_to_send, ip, ip_next);
- ICL_CONN_UNLOCK(ic);
cv_signal(&ic->ic_send_cv);
}
struct icl_conn *
-icl_conn_new(void)
+icl_conn_new(struct mtx *lock)
{
struct icl_conn *ic;
@@ -980,7 +980,7 @@ icl_conn_new(void)
ic = uma_zalloc(icl_conn_zone, M_WAITOK | M_ZERO);
TAILQ_INIT(&ic->ic_to_send);
- mtx_init(&ic->ic_lock, "icl_lock", NULL, MTX_DEF);
+ ic->ic_lock = lock;
cv_init(&ic->ic_send_cv, "icl_tx");
cv_init(&ic->ic_receive_cv, "icl_rx");
#ifdef DIAGNOSTIC
@@ -995,7 +995,6 @@ void
icl_conn_free(struct icl_conn *ic)
{
- mtx_destroy(&ic->ic_lock);
cv_destroy(&ic->ic_send_cv);
cv_destroy(&ic->ic_receive_cv);
uma_zfree(icl_conn_zone, ic);
@@ -1099,6 +1098,8 @@ icl_conn_handoff(struct icl_conn *ic, int fd)
cap_rights_t rights;
int error;
+ ICL_CONN_LOCK_ASSERT_NOT(ic);
+
/*
* Steal the socket from userland.
*/
@@ -1138,6 +1139,7 @@ icl_conn_handoff(struct icl_conn *ic, int fd)
void
icl_conn_shutdown(struct icl_conn *ic)
{
+ ICL_CONN_LOCK_ASSERT_NOT(ic);
ICL_CONN_LOCK(ic);
if (ic->ic_socket == NULL) {
@@ -1154,6 +1156,8 @@ icl_conn_close(struct icl_conn *ic)
{
struct icl_pdu *pdu;
+ ICL_CONN_LOCK_ASSERT_NOT(ic);
+
ICL_CONN_LOCK(ic);
if (ic->ic_socket == NULL) {
ICL_CONN_UNLOCK(ic);
@@ -1211,6 +1215,7 @@ icl_conn_close(struct icl_conn *ic)
bool
icl_conn_connected(struct icl_conn *ic)
{
+ ICL_CONN_LOCK_ASSERT_NOT(ic);
ICL_CONN_LOCK(ic);
if (ic->ic_socket == NULL) {
@@ -1231,6 +1236,8 @@ icl_conn_handoff_sock(struct icl_conn *ic, struct socket *so)
{
int error;
+ ICL_CONN_LOCK_ASSERT_NOT(ic);
+
if (so->so_type != SOCK_STREAM)
return (EINVAL);
diff --git a/sys/dev/iscsi/icl.h b/sys/dev/iscsi/icl.h
index ab61cd8..2bfc5dc 100644
--- a/sys/dev/iscsi/icl.h
+++ b/sys/dev/iscsi/icl.h
@@ -74,7 +74,7 @@ void icl_pdu_free(struct icl_pdu *ip);
#define ICL_MAX_DATA_SEGMENT_LENGTH (128 * 1024)
struct icl_conn {
- struct mtx ic_lock;
+ struct mtx *ic_lock;
struct socket *ic_socket;
#ifdef DIAGNOSTIC
volatile u_int ic_outstanding_pdus;
@@ -102,7 +102,7 @@ struct icl_conn {
void *ic_prv0;
};
-struct icl_conn *icl_conn_new(void);
+struct icl_conn *icl_conn_new(struct mtx *lock);
void icl_conn_free(struct icl_conn *ic);
int icl_conn_handoff(struct icl_conn *ic, int fd);
void icl_conn_shutdown(struct icl_conn *ic);
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c
index 2b808f5..df881ed 100644
--- a/sys/dev/iscsi/iscsi.c
+++ b/sys/dev/iscsi/iscsi.c
@@ -1633,7 +1633,7 @@ iscsi_ioctl_session_add(struct iscsi_softc *sc, struct iscsi_session_add *isa)
return (EBUSY);
}
- is->is_conn = icl_conn_new();
+ is->is_conn = icl_conn_new(&is->is_lock);
is->is_conn->ic_receive = iscsi_receive_callback;
is->is_conn->ic_error = iscsi_error_callback;
is->is_conn->ic_prv0 = is;
OpenPOWER on IntegriCloud