From 8353d56e77f0bef5ab9fa8b34cfd846b6a84a636 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 14 Mar 2019 18:02:33 +0900 Subject: [PATCH] iscsi: Fix performance degradation due to sock_readv spdk_iscsi_conn_read_data was changed to use sock_readv instead of sock_recv as a refactoring effort. However this change caused about 3% performance degradation for write I/O. Hence this patch changes spdk_iscsi_conn_read_data to use sock_recv and changes spdk_iscsi_conn_readv_data to call spdk_iscsi_conn_read_data if iovcnt is 1. Change-Id: I5fcad03ff23dee4e9954eee879225d3c493be52e Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/448021 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Ziye Yang Reviewed-by: Tomasz Zawadzki Reviewed-by: Ben Walker Reviewed-by: Jim Harris --- lib/iscsi/conn.c | 53 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 1518f2ee5..7e08fb664 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -875,6 +875,42 @@ spdk_iscsi_drop_conns(struct spdk_iscsi_conn *conn, const char *conn_match, * * Otherwise returns the number of bytes successfully read. */ +int +spdk_iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int bytes, + void *buf) +{ + int ret; + + if (bytes == 0) { + return 0; + } + + ret = spdk_sock_recv(conn->sock, buf, bytes); + + if (ret > 0) { + spdk_trace_record(TRACE_ISCSI_READ_FROM_SOCKET_DONE, conn->id, ret, 0, 0); + return ret; + } + + if (ret < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return 0; + } + + /* For connect reset issue, do not output error log */ + if (errno == ECONNRESET) { + SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "spdk_sock_recv() failed, errno %d: %s\n", + errno, spdk_strerror(errno)); + } else { + SPDK_ERRLOG("spdk_sock_recv() failed, errno %d: %s\n", + errno, spdk_strerror(errno)); + } + } + + /* connection closed */ + return SPDK_ISCSI_CONNECTION_FATAL; +} + int spdk_iscsi_conn_readv_data(struct spdk_iscsi_conn *conn, struct iovec *iov, int iovcnt) @@ -885,6 +921,11 @@ spdk_iscsi_conn_readv_data(struct spdk_iscsi_conn *conn, return 0; } + if (iovcnt == 1) { + return spdk_iscsi_conn_read_data(conn, iov[0].iov_len, + iov[0].iov_base); + } + ret = spdk_sock_readv(conn->sock, iov, iovcnt); if (ret > 0) { @@ -911,18 +952,6 @@ spdk_iscsi_conn_readv_data(struct spdk_iscsi_conn *conn, return SPDK_ISCSI_CONNECTION_FATAL; } -int -spdk_iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int bytes, - void *buf) -{ - struct iovec iov; - - iov.iov_base = buf; - iov.iov_len = bytes; - - return spdk_iscsi_conn_readv_data(conn, &iov, 1); -} - void spdk_iscsi_task_mgmt_cpl(struct spdk_scsi_task *scsi_task) {