iscsi: use return code to determine if all PDUs were flushed

This will enable some future enhancements where the main
iSCSI connection poller will not try to flush PDUs, we will
just start a separate poller to periodically flush PDUs in that
case.

This is all part of broader scheme to enable epoll() for
iSCSI.  Making these changes allows us to avoid using epoll()
to signal when TCP buffer space is available.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I6fe9314e386673fcc87bb15580ef808838c55a7b

Reviewed-on: https://review.gerrithub.io/395521
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Jim Harris 2018-01-17 22:57:41 -07:00
parent 902f8719f2
commit 936eb59d8d

View File

@ -1161,8 +1161,10 @@ spdk_iscsi_conn_handle_nop(struct spdk_iscsi_conn *conn)
* case, the partially flushed PDU will remain on the write_pdu_list with * case, the partially flushed PDU will remain on the write_pdu_list with
* an offset pointing to the next byte to be flushed. * an offset pointing to the next byte to be flushed.
* *
* Returns 0 if no exceptional error encountered. This includes cases where * Returns 0 if all PDUs were flushed.
* there are no PDUs to flush or not all PDUs could be flushed. *
* Returns 1 if some PDUs could not be flushed due to lack of send buffer
* space.
* *
* Returns -1 if an exception error occurred indicating the TCP connection * Returns -1 if an exception error occurred indicating the TCP connection
* should be closed. * should be closed.
@ -1225,7 +1227,7 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn)
bytes = spdk_sock_writev(conn->sock, iov, iovec_cnt); bytes = spdk_sock_writev(conn->sock, iov, iovec_cnt);
if (bytes == -1) { if (bytes == -1) {
if (errno == EWOULDBLOCK || errno == EAGAIN) { if (errno == EWOULDBLOCK || errno == EAGAIN) {
return 0; return 1;
} else { } else {
SPDK_ERRLOG("spdk_sock_writev() failed (fd=%d), errno %d: %s\n", SPDK_ERRLOG("spdk_sock_writev() failed (fd=%d), errno %d: %s\n",
conn->sock, errno, spdk_strerror(errno)); conn->sock, errno, spdk_strerror(errno));
@ -1270,7 +1272,7 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn)
} }
} }
return 0; return TAILQ_EMPTY(&conn->write_pdu_list) ? 0 : 1;
} }
/** /**
@ -1287,7 +1289,10 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn)
* During other connection states (EXITING or LOGGED_OUT), this * During other connection states (EXITING or LOGGED_OUT), this
* function will spin until all PDUs have successfully been flushed. * function will spin until all PDUs have successfully been flushed.
* *
* Returns 0 for success. * Returns 0 for success and when all PDUs were able to be flushed.
*
* Returns 1 for success but when some PDUs could not be flushed due
* to lack of TCP buffer space.
* *
* Returns -1 for an exceptional error indicating the TCP connection * Returns -1 for an exceptional error indicating the TCP connection
* should be closed. * should be closed.
@ -1300,20 +1305,15 @@ spdk_iscsi_conn_flush_pdus(struct spdk_iscsi_conn *conn)
if (conn->state == ISCSI_CONN_STATE_RUNNING) { if (conn->state == ISCSI_CONN_STATE_RUNNING) {
rc = spdk_iscsi_conn_flush_pdus_internal(conn); rc = spdk_iscsi_conn_flush_pdus_internal(conn);
} else { } else {
rc = 0;
/* /*
* If the connection state is not RUNNING, then * If the connection state is not RUNNING, then
* keep trying to flush PDUs until our list is * keep trying to flush PDUs until our list is
* empty - to make sure all data is sent before * empty - to make sure all data is sent before
* closing the connection. * closing the connection.
*/ */
while (!TAILQ_EMPTY(&conn->write_pdu_list)) { do {
rc = spdk_iscsi_conn_flush_pdus_internal(conn); rc = spdk_iscsi_conn_flush_pdus_internal(conn);
if (rc != 0) { } while (rc == 1);
break;
}
}
} }
return rc; return rc;
@ -1398,7 +1398,7 @@ spdk_iscsi_conn_execute(struct spdk_iscsi_conn *conn)
conn_active = true; conn_active = true;
} }
if (spdk_iscsi_conn_flush_pdus(conn) != 0) { if (spdk_iscsi_conn_flush_pdus(conn) < 0) {
conn->state = ISCSI_CONN_STATE_EXITING; conn->state = ISCSI_CONN_STATE_EXITING;
goto conn_exit; goto conn_exit;
} }