diff --git a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c --- a/sys/dev/cxgbe/cxgbei/icl_cxgbei.c +++ b/sys/dev/cxgbe/cxgbei/icl_cxgbei.c @@ -569,10 +569,6 @@ ic = &icc->ic; ic->ic_lock = lock; - /* XXXNP: review. Most of these icl_conn fields aren't really used */ - STAILQ_INIT(&ic->ic_to_send); - cv_init(&ic->ic_send_cv, "icl_cxgbei_tx"); - cv_init(&ic->ic_receive_cv, "icl_cxgbei_rx"); #ifdef DIAGNOSTIC refcount_init(&ic->ic_outstanding_pdus, 0); #endif @@ -594,9 +590,6 @@ CTR2(KTR_CXGBE, "%s: icc %p", __func__, icc); - cv_destroy(&ic->ic_send_cv); - cv_destroy(&ic->ic_receive_cv); - mtx_destroy(&icc->cmp_lock); hashdestroy(icc->cmp_table, M_CXGBEI, icc->cmp_hash_mask); kobj_delete((struct kobj *)icc, M_CXGBE); @@ -864,10 +857,6 @@ } ic->ic_disconnecting = true; - /* These are unused in this driver right now. */ - MPASS(STAILQ_EMPTY(&ic->ic_to_send)); - MPASS(ic->ic_receive_pdu == NULL); - #ifdef DIAGNOSTIC KASSERT(ic->ic_outstanding_pdus == 0, ("destroying session with %d outstanding PDUs", diff --git a/sys/dev/iscsi/icl.h b/sys/dev/iscsi/icl.h --- a/sys/dev/iscsi/icl.h +++ b/sys/dev/iscsi/icl.h @@ -82,13 +82,6 @@ void *ip_prv1; }; -#define ICL_CONN_STATE_INVALID 0 -#define ICL_CONN_STATE_BHS 1 -#define ICL_CONN_STATE_AHS 2 -#define ICL_CONN_STATE_HEADER_DIGEST 3 -#define ICL_CONN_STATE_DATA 4 -#define ICL_CONN_STATE_DATA_DIGEST 5 - #define ICL_NOCOPY (1 << 30) struct icl_conn { @@ -98,20 +91,11 @@ #ifdef DIAGNOSTIC volatile u_int ic_outstanding_pdus; #endif - STAILQ_HEAD(, icl_pdu) ic_to_send; - bool ic_check_send_space; - size_t ic_receive_len; - int ic_receive_state; - struct icl_pdu *ic_receive_pdu; - struct cv ic_send_cv; - struct cv ic_receive_cv; - bool ic_header_crc32c; - bool ic_data_crc32c; - bool ic_send_running; - bool ic_receive_running; uint32_t ic_max_recv_data_segment_length; uint32_t ic_max_send_data_segment_length; size_t ic_maxtags; + bool ic_header_crc32c; + bool ic_data_crc32c; bool ic_disconnecting; bool ic_iser; bool ic_unmapped; diff --git a/sys/dev/iscsi/icl_soft.c b/sys/dev/iscsi/icl_soft.c --- a/sys/dev/iscsi/icl_soft.c +++ b/sys/dev/iscsi/icl_soft.c @@ -63,6 +63,27 @@ #include #include +#define ICL_CONN_STATE_BHS 1 +#define ICL_CONN_STATE_AHS 2 +#define ICL_CONN_STATE_HEADER_DIGEST 3 +#define ICL_CONN_STATE_DATA 4 +#define ICL_CONN_STATE_DATA_DIGEST 5 + +struct icl_soft_conn { + struct icl_conn ic; + + /* soft specific stuff goes here. */ + STAILQ_HEAD(, icl_pdu) to_send; + struct cv send_cv; + struct cv receive_cv; + struct icl_pdu *receive_pdu; + size_t receive_len; + int receive_state; + bool receive_running; + bool check_send_space; + bool send_running; +}; + struct icl_soft_pdu { struct icl_pdu ip; @@ -150,7 +171,7 @@ { 0, 0 } }; -DEFINE_CLASS(icl_soft, icl_soft_methods, sizeof(struct icl_conn)); +DEFINE_CLASS(icl_soft, icl_soft_methods, sizeof(struct icl_soft_conn)); static void icl_conn_fail(struct icl_conn *ic) @@ -441,14 +462,14 @@ icl_pdu_receive_data_segment(struct icl_pdu *request, struct mbuf **r, size_t *rs, bool *more_neededp) { - struct icl_conn *ic; + struct icl_soft_conn *isc; size_t len, padding = 0; struct mbuf *m; - ic = request->ip_conn; + isc = (struct icl_soft_conn *)request->ip_conn; *more_neededp = false; - ic->ic_receive_len = 0; + isc->receive_len = 0; len = icl_pdu_data_segment_length(request); if (len == 0) @@ -497,8 +518,7 @@ ICL_DEBUG("len 0"); if (*more_neededp) - ic->ic_receive_len = - icl_pdu_data_segment_receive_len(request); + isc->receive_len = icl_pdu_data_segment_receive_len(request); return (0); } @@ -537,16 +557,17 @@ * "part" of PDU at a time; call it repeatedly until it returns non-NULL. */ static struct icl_pdu * -icl_conn_receive_pdu(struct icl_conn *ic, struct mbuf **r, size_t *rs) +icl_conn_receive_pdu(struct icl_soft_conn *isc, struct mbuf **r, size_t *rs) { + struct icl_conn *ic = &isc->ic; struct icl_pdu *request; size_t len; int error = 0; bool more_needed; - if (ic->ic_receive_state == ICL_CONN_STATE_BHS) { - KASSERT(ic->ic_receive_pdu == NULL, - ("ic->ic_receive_pdu != NULL")); + if (isc->receive_state == ICL_CONN_STATE_BHS) { + KASSERT(isc->receive_pdu == NULL, + ("isc->receive_pdu != NULL")); request = icl_soft_conn_new_pdu(ic, M_NOWAIT); if (request == NULL) { ICL_DEBUG("failed to allocate PDU; " @@ -554,14 +575,14 @@ icl_conn_fail(ic); return (NULL); } - ic->ic_receive_pdu = request; + isc->receive_pdu = request; } else { - KASSERT(ic->ic_receive_pdu != NULL, - ("ic->ic_receive_pdu == NULL")); - request = ic->ic_receive_pdu; + KASSERT(isc->receive_pdu != NULL, + ("isc->receive_pdu == NULL")); + request = isc->receive_pdu; } - switch (ic->ic_receive_state) { + switch (isc->receive_state) { case ICL_CONN_STATE_BHS: //ICL_DEBUG("receiving BHS"); icl_soft_receive_buf(r, rs, request->ip_bhs, @@ -581,18 +602,18 @@ break; } - ic->ic_receive_state = ICL_CONN_STATE_AHS; - ic->ic_receive_len = icl_pdu_ahs_length(request); + isc->receive_state = ICL_CONN_STATE_AHS; + isc->receive_len = icl_pdu_ahs_length(request); break; case ICL_CONN_STATE_AHS: //ICL_DEBUG("receiving AHS"); icl_pdu_receive_ahs(request, r, rs); - ic->ic_receive_state = ICL_CONN_STATE_HEADER_DIGEST; + isc->receive_state = ICL_CONN_STATE_HEADER_DIGEST; if (ic->ic_header_crc32c == false) - ic->ic_receive_len = 0; + isc->receive_len = 0; else - ic->ic_receive_len = ISCSI_HEADER_DIGEST_SIZE; + isc->receive_len = ISCSI_HEADER_DIGEST_SIZE; break; case ICL_CONN_STATE_HEADER_DIGEST: @@ -604,9 +625,8 @@ break; } - ic->ic_receive_state = ICL_CONN_STATE_DATA; - ic->ic_receive_len = - icl_pdu_data_segment_receive_len(request); + isc->receive_state = ICL_CONN_STATE_DATA; + isc->receive_len = icl_pdu_data_segment_receive_len(request); break; case ICL_CONN_STATE_DATA: @@ -622,11 +642,11 @@ if (more_needed) break; - ic->ic_receive_state = ICL_CONN_STATE_DATA_DIGEST; + isc->receive_state = ICL_CONN_STATE_DATA_DIGEST; if (request->ip_data_len == 0 || ic->ic_data_crc32c == false) - ic->ic_receive_len = 0; + isc->receive_len = 0; else - ic->ic_receive_len = ISCSI_DATA_DIGEST_SIZE; + isc->receive_len = ISCSI_DATA_DIGEST_SIZE; break; case ICL_CONN_STATE_DATA_DIGEST: @@ -642,18 +662,18 @@ * We've received complete PDU; reset the receive state machine * and return the PDU. */ - ic->ic_receive_state = ICL_CONN_STATE_BHS; - ic->ic_receive_len = sizeof(struct iscsi_bhs); - ic->ic_receive_pdu = NULL; + isc->receive_state = ICL_CONN_STATE_BHS; + isc->receive_len = sizeof(struct iscsi_bhs); + isc->receive_pdu = NULL; return (request); default: - panic("invalid ic_receive_state %d\n", ic->ic_receive_state); + panic("invalid receive_state %d\n", isc->receive_state); } if (error != 0) { /* - * Don't free the PDU; it's pointed to by ic->ic_receive_pdu + * Don't free the PDU; it's pointed to by isc->receive_pdu * and will get freed in icl_soft_conn_close(). */ icl_conn_fail(ic); @@ -663,8 +683,9 @@ } static void -icl_conn_receive_pdus(struct icl_conn *ic, struct mbuf **r, size_t *rs) +icl_conn_receive_pdus(struct icl_soft_conn *isc, struct mbuf **r, size_t *rs) { + struct icl_conn *ic = &isc->ic; struct icl_pdu *response; for (;;) { @@ -675,15 +696,15 @@ * Loop until we have a complete PDU or there is not enough * data in the socket buffer. */ - if (*rs < ic->ic_receive_len) { + if (*rs < isc->receive_len) { #if 0 ICL_DEBUG("not enough data; have %zd, need %zd", - *rs, ic->ic_receive_len); + *rs, isc->receive_len); #endif return; } - response = icl_conn_receive_pdu(ic, r, rs); + response = icl_conn_receive_pdu(isc, r, rs); if (response == NULL) continue; @@ -703,14 +724,14 @@ static void icl_receive_thread(void *arg) { - struct icl_conn *ic; + struct icl_soft_conn *isc = arg; + struct icl_conn *ic = &isc->ic; size_t available, read = 0; struct socket *so; struct mbuf *m, *r = NULL; struct uio uio; int error, flags; - ic = arg; so = ic->ic_socket; for (;;) { @@ -727,9 +748,9 @@ * is enough data received to read the PDU. */ available = sbavail(&so->so_rcv); - if (read + available < ic->ic_receive_len) { - so->so_rcv.sb_lowat = ic->ic_receive_len - read; - cv_wait(&ic->ic_receive_cv, SOCKBUF_MTX(&so->so_rcv)); + if (read + available < isc->receive_len) { + so->so_rcv.sb_lowat = isc->receive_len - read; + cv_wait(&isc->receive_cv, SOCKBUF_MTX(&so->so_rcv)); so->so_rcv.sb_lowat = so->so_rcv.sb_hiwat + 1; available = sbavail(&so->so_rcv); } @@ -764,15 +785,15 @@ r = m; read += available; - icl_conn_receive_pdus(ic, &r, &read); + icl_conn_receive_pdus(isc, &r, &read); } if (r) m_freem(r); ICL_CONN_LOCK(ic); - ic->ic_receive_running = false; - cv_signal(&ic->ic_send_cv); + isc->receive_running = false; + cv_signal(&isc->send_cv); ICL_CONN_UNLOCK(ic); kthread_exit(); } @@ -780,13 +801,13 @@ static int icl_soupcall_receive(struct socket *so, void *arg, int waitflag) { - struct icl_conn *ic; + struct icl_soft_conn *isc; if (!soreadable(so)) return (SU_OK); - ic = arg; - cv_signal(&ic->ic_receive_cv); + isc = arg; + cv_signal(&isc->receive_cv); return (SU_OK); } @@ -846,8 +867,9 @@ } static void -icl_conn_send_pdus(struct icl_conn *ic, struct icl_pdu_stailq *queue) +icl_conn_send_pdus(struct icl_soft_conn *isc, struct icl_pdu_stailq *queue) { + struct icl_conn *ic = &isc->ic; struct icl_pdu *request, *request2; struct mbuf *m; struct socket *so; @@ -866,7 +888,7 @@ * of error. */ available = sbspace(&so->so_snd); - ic->ic_check_send_space = false; + isc->check_send_space = false; /* * Notify the socket upcall that we don't need wakeups @@ -961,10 +983,12 @@ static void icl_send_thread(void *arg) { + struct icl_soft_conn *isc; struct icl_conn *ic; struct icl_pdu_stailq queue; - ic = arg; + isc = arg; + ic = &isc->ic; STAILQ_INIT(&queue); @@ -976,18 +1000,18 @@ * This way the icl_conn_send_pdus() can go through * all the queued PDUs without holding any locks. */ - if (STAILQ_EMPTY(&queue) || ic->ic_check_send_space) - STAILQ_CONCAT(&queue, &ic->ic_to_send); + if (STAILQ_EMPTY(&queue) || isc->check_send_space) + STAILQ_CONCAT(&queue, &isc->to_send); ICL_CONN_UNLOCK(ic); - icl_conn_send_pdus(ic, &queue); + icl_conn_send_pdus(isc, &queue); ICL_CONN_LOCK(ic); /* * The icl_soupcall_send() was called since the last * call to sbspace(); go around; */ - if (ic->ic_check_send_space) + if (isc->check_send_space) continue; /* @@ -995,7 +1019,7 @@ * in the main one; go around. */ if (STAILQ_EMPTY(&queue) && - !STAILQ_EMPTY(&ic->ic_to_send)) + !STAILQ_EMPTY(&isc->to_send)) continue; /* @@ -1011,17 +1035,17 @@ break; } - cv_wait(&ic->ic_send_cv, ic->ic_lock); + cv_wait(&isc->send_cv, ic->ic_lock); } /* * We're exiting; move PDUs back to the main queue, so they can * get freed properly. At this point ordering doesn't matter. */ - STAILQ_CONCAT(&ic->ic_to_send, &queue); + STAILQ_CONCAT(&isc->to_send, &queue); - ic->ic_send_running = false; - cv_signal(&ic->ic_send_cv); + isc->send_running = false; + cv_signal(&isc->send_cv); ICL_CONN_UNLOCK(ic); kthread_exit(); } @@ -1029,18 +1053,20 @@ static int icl_soupcall_send(struct socket *so, void *arg, int waitflag) { + struct icl_soft_conn *isc; struct icl_conn *ic; if (!sowriteable(so)) return (SU_OK); - ic = arg; + isc = arg; + ic = &isc->ic; ICL_CONN_LOCK(ic); - ic->ic_check_send_space = true; + isc->check_send_space = true; ICL_CONN_UNLOCK(ic); - cv_signal(&ic->ic_send_cv); + cv_signal(&isc->send_cv); return (SU_OK); } @@ -1112,6 +1138,7 @@ icl_soft_conn_pdu_queue_cb(struct icl_conn *ic, struct icl_pdu *ip, icl_pdu_cb cb) { + struct icl_soft_conn *isc = (struct icl_soft_conn *)ic; struct icl_soft_pdu *isp = (struct icl_soft_pdu *)ip; ICL_CONN_LOCK_ASSERT(ic); @@ -1124,8 +1151,8 @@ return; } - if (!STAILQ_EMPTY(&ic->ic_to_send)) { - STAILQ_INSERT_TAIL(&ic->ic_to_send, ip, ip_next); + if (!STAILQ_EMPTY(&isc->to_send)) { + STAILQ_INSERT_TAIL(&isc->to_send, ip, ip_next); /* * If the queue is not empty, someone else had already * signaled the send thread; no need to do that again, @@ -1134,23 +1161,27 @@ return; } - STAILQ_INSERT_TAIL(&ic->ic_to_send, ip, ip_next); - cv_signal(&ic->ic_send_cv); + STAILQ_INSERT_TAIL(&isc->to_send, ip, ip_next); + cv_signal(&isc->send_cv); } static struct icl_conn * icl_soft_new_conn(const char *name, struct mtx *lock) { + struct icl_soft_conn *isc; struct icl_conn *ic; refcount_acquire(&icl_ncons); - ic = (struct icl_conn *)kobj_create(&icl_soft_class, M_ICL_SOFT, M_WAITOK | M_ZERO); + isc = (struct icl_soft_conn *)kobj_create(&icl_soft_class, M_ICL_SOFT, + M_WAITOK | M_ZERO); + + STAILQ_INIT(&isc->to_send); + cv_init(&isc->send_cv, "icl_tx"); + cv_init(&isc->receive_cv, "icl_rx"); - STAILQ_INIT(&ic->ic_to_send); + ic = &isc->ic; ic->ic_lock = lock; - cv_init(&ic->ic_send_cv, "icl_tx"); - cv_init(&ic->ic_receive_cv, "icl_rx"); #ifdef DIAGNOSTIC refcount_init(&ic->ic_outstanding_pdus, 0); #endif @@ -1164,21 +1195,23 @@ void icl_soft_conn_free(struct icl_conn *ic) { + struct icl_soft_conn *isc = (struct icl_soft_conn *)ic; #ifdef DIAGNOSTIC KASSERT(ic->ic_outstanding_pdus == 0, ("destroying session with %d outstanding PDUs", ic->ic_outstanding_pdus)); #endif - cv_destroy(&ic->ic_send_cv); - cv_destroy(&ic->ic_receive_cv); - kobj_delete((struct kobj *)ic, M_ICL_SOFT); + cv_destroy(&isc->send_cv); + cv_destroy(&isc->receive_cv); + kobj_delete((struct kobj *)isc, M_ICL_SOFT); refcount_release(&icl_ncons); } static int icl_conn_start(struct icl_conn *ic) { + struct icl_soft_conn *isc = (struct icl_soft_conn *)ic; size_t minspace; struct sockopt opt; int error, one = 1; @@ -1193,8 +1226,8 @@ return (EINVAL); } - ic->ic_receive_state = ICL_CONN_STATE_BHS; - ic->ic_receive_len = sizeof(struct iscsi_bhs); + isc->receive_state = ICL_CONN_STATE_BHS; + isc->receive_len = sizeof(struct iscsi_bhs); ic->ic_disconnecting = false; ICL_CONN_UNLOCK(ic); @@ -1251,25 +1284,25 @@ * and free space to send outgoing ones. */ SOCKBUF_LOCK(&ic->ic_socket->so_snd); - soupcall_set(ic->ic_socket, SO_SND, icl_soupcall_send, ic); + soupcall_set(ic->ic_socket, SO_SND, icl_soupcall_send, isc); SOCKBUF_UNLOCK(&ic->ic_socket->so_snd); SOCKBUF_LOCK(&ic->ic_socket->so_rcv); - soupcall_set(ic->ic_socket, SO_RCV, icl_soupcall_receive, ic); + soupcall_set(ic->ic_socket, SO_RCV, icl_soupcall_receive, isc); SOCKBUF_UNLOCK(&ic->ic_socket->so_rcv); /* * Start threads. */ ICL_CONN_LOCK(ic); - ic->ic_send_running = ic->ic_receive_running = true; + isc->send_running = isc->receive_running = true; ICL_CONN_UNLOCK(ic); error = kthread_add(icl_send_thread, ic, NULL, NULL, 0, 0, "%stx", ic->ic_name); if (error != 0) { ICL_WARN("kthread_add(9) failed with error %d", error); ICL_CONN_LOCK(ic); - ic->ic_send_running = ic->ic_receive_running = false; - cv_signal(&ic->ic_send_cv); + isc->send_running = isc->receive_running = false; + cv_signal(&isc->send_cv); ICL_CONN_UNLOCK(ic); icl_soft_conn_close(ic); return (error); @@ -1279,8 +1312,8 @@ if (error != 0) { ICL_WARN("kthread_add(9) failed with error %d", error); ICL_CONN_LOCK(ic); - ic->ic_receive_running = false; - cv_signal(&ic->ic_send_cv); + isc->receive_running = false; + cv_signal(&isc->send_cv); ICL_CONN_UNLOCK(ic); icl_soft_conn_close(ic); return (error); @@ -1355,6 +1388,7 @@ void icl_soft_conn_close(struct icl_conn *ic) { + struct icl_soft_conn *isc = (struct icl_soft_conn *)ic; struct icl_pdu *pdu; struct socket *so; @@ -1371,10 +1405,10 @@ if (so) SOCKBUF_UNLOCK(&so->so_rcv); } - while (ic->ic_receive_running || ic->ic_send_running) { - cv_signal(&ic->ic_receive_cv); - cv_signal(&ic->ic_send_cv); - cv_wait(&ic->ic_send_cv, ic->ic_lock); + while (isc->receive_running || isc->send_running) { + cv_signal(&isc->receive_cv); + cv_signal(&isc->send_cv); + cv_wait(&isc->send_cv, ic->ic_lock); } /* Some other thread could close the connection same time. */ @@ -1400,22 +1434,22 @@ soclose(so); ICL_CONN_LOCK(ic); - if (ic->ic_receive_pdu != NULL) { + if (isc->receive_pdu != NULL) { //ICL_DEBUG("freeing partially received PDU"); - icl_soft_conn_pdu_free(ic, ic->ic_receive_pdu); - ic->ic_receive_pdu = NULL; + icl_soft_conn_pdu_free(ic, isc->receive_pdu); + isc->receive_pdu = NULL; } /* * Remove any outstanding PDUs from the send queue. */ - while (!STAILQ_EMPTY(&ic->ic_to_send)) { - pdu = STAILQ_FIRST(&ic->ic_to_send); - STAILQ_REMOVE_HEAD(&ic->ic_to_send, ip_next); + while (!STAILQ_EMPTY(&isc->to_send)) { + pdu = STAILQ_FIRST(&isc->to_send); + STAILQ_REMOVE_HEAD(&isc->to_send, ip_next); icl_soft_pdu_done(pdu, ENOTCONN); } - KASSERT(STAILQ_EMPTY(&ic->ic_to_send), + KASSERT(STAILQ_EMPTY(&isc->to_send), ("destroying session with non-empty send queue")); ICL_CONN_UNLOCK(ic); }