From 8b94b5836c23624d4619aca93f6a2a51681ada63 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 22 Nov 2014 15:09:18 +0000 Subject: [PATCH] For both iSCSI initiator and target increase socket buffer sizes before establishing connection. This is a workaround for Chelsio TOE driver, that does not update socket buffer size in hardware after connection established, and unless that is done beforehand, kernel code will stuck, attempting to send/receive full PDU at once. MFC after: 1 week --- sys/dev/iscsi/icl.c | 2 ++ usr.sbin/ctld/ctld.c | 12 +++++++++++- usr.sbin/ctld/ctld.h | 1 + usr.sbin/iscsid/iscsid.c | 10 +++++++++- usr.sbin/iscsid/iscsid.h | 1 + 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sys/dev/iscsi/icl.c b/sys/dev/iscsi/icl.c index 6bce18020425..7f5d01f5332e 100644 --- a/sys/dev/iscsi/icl.c +++ b/sys/dev/iscsi/icl.c @@ -1199,6 +1199,8 @@ icl_conn_start(struct icl_conn *ic) icl_conn_close(ic); return (error); } + ic->ic_socket->so_snd.sb_flags |= SB_AUTOSIZE; + ic->ic_socket->so_rcv.sb_flags |= SB_AUTOSIZE; /* * Disable Nagle. diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index ca55063a3ccd..2eca2d2aac06 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -1602,7 +1602,7 @@ conf_apply(struct conf *oldconf, struct conf *newconf) struct portal *oldp, *newp; struct isns *oldns, *newns; pid_t otherpid; - int changed, cumulated_error = 0, error; + int changed, cumulated_error = 0, error, sockbuf; int one = 1; if (oldconf->conf_debug != newconf->conf_debug) { @@ -1899,6 +1899,16 @@ conf_apply(struct conf *oldconf, struct conf *newconf) cumulated_error++; continue; } + sockbuf = SOCKBUF_SIZE; + if (setsockopt(newp->p_socket, SOL_SOCKET, SO_RCVBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_RCVBUF) failed " + "for %s", newp->p_listen); + sockbuf = SOCKBUF_SIZE; + if (setsockopt(newp->p_socket, SOL_SOCKET, SO_SNDBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_SNDBUF) failed " + "for %s", newp->p_listen); error = setsockopt(newp->p_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); if (error != 0) { diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index 600bd30c4f23..34c08919e518 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -48,6 +48,7 @@ #define MAX_NAME_LEN 223 #define MAX_DATA_SEGMENT_LENGTH (128 * 1024) #define MAX_BURST_LENGTH 16776192 +#define SOCKBUF_SIZE 1048576 struct auth { TAILQ_ENTRY(auth) a_next; diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c index a7f489e24039..a6feb6ab6d9e 100644 --- a/usr.sbin/iscsid/iscsid.c +++ b/usr.sbin/iscsid/iscsid.c @@ -160,7 +160,7 @@ connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, #ifdef ICL_KERNEL_PROXY struct iscsi_daemon_connect idc; #endif - int error; + int error, sockbuf; conn = calloc(1, sizeof(*conn)); if (conn == NULL) @@ -237,6 +237,14 @@ connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih, fail(conn, strerror(errno)); log_err(1, "failed to create socket for %s", from_addr); } + sockbuf = SOCKBUF_SIZE; + if (setsockopt(conn->conn_socket, SOL_SOCKET, SO_RCVBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_RCVBUF) failed"); + sockbuf = SOCKBUF_SIZE; + if (setsockopt(conn->conn_socket, SOL_SOCKET, SO_SNDBUF, + &sockbuf, sizeof(sockbuf)) == -1) + log_warn("setsockopt(SO_SNDBUF) failed"); if (from_ai != NULL) { error = bind(conn->conn_socket, from_ai->ai_addr, from_ai->ai_addrlen); diff --git a/usr.sbin/iscsid/iscsid.h b/usr.sbin/iscsid/iscsid.h index b05c222ce9cb..9ad3325cf17e 100644 --- a/usr.sbin/iscsid/iscsid.h +++ b/usr.sbin/iscsid/iscsid.h @@ -44,6 +44,7 @@ #define CONN_DIGEST_CRC32C 1 #define CONN_MUTUAL_CHALLENGE_LEN 1024 +#define SOCKBUF_SIZE 1048576 struct connection { int conn_iscsi_fd;