From owner-svn-src-all@FreeBSD.ORG Fri Apr 11 18:26:09 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DE7C0630; Fri, 11 Apr 2014 18:26:08 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BF10C1C8E; Fri, 11 Apr 2014 18:26:08 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3BIQ8f1079643; Fri, 11 Apr 2014 18:26:08 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3BIQ80F079642; Fri, 11 Apr 2014 18:26:08 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201404111826.s3BIQ80F079642@svn.freebsd.org> From: Alexander Motin Date: Fri, 11 Apr 2014 18:26:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264348 - head/sys/dev/iscsi X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Apr 2014 18:26:09 -0000 Author: mav Date: Fri Apr 11 18:26:08 2014 New Revision: 264348 URL: http://svnweb.freebsd.org/changeset/base/264348 Log: Improve use of socket buffer upcalls. Use soreadable()/sowriteable() in socket upcalls to avoid extra wakeups until we have enough data to read or space to write. Increase partial receive len from 1K to 128K to not wake up on every received packet. This significantly reduces locks congestion and CPU usage and improves throughput for large I/Os on NICs without TSO and LRO. Reviewed by: trasz Sponsored by: iXsystems, Inc. Modified: head/sys/dev/iscsi/icl.c Modified: head/sys/dev/iscsi/icl.c ============================================================================== --- head/sys/dev/iscsi/icl.c Fri Apr 11 18:19:21 2014 (r264347) +++ head/sys/dev/iscsi/icl.c Fri Apr 11 18:26:08 2014 (r264348) @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,7 @@ static int coalesce = 1; TUNABLE_INT("kern.icl.coalesce", &coalesce); SYSCTL_INT(_kern_icl, OID_AUTO, coalesce, CTLFLAG_RWTUN, &coalesce, 1, "Try to coalesce PDUs before sending"); -static int partial_receive_len = 1 * 1024; /* XXX: More? */ +static int partial_receive_len = 128 * 1024; TUNABLE_INT("kern.icl.partial_receive_len", &partial_receive_len); SYSCTL_INT(_kern_icl, OID_AUTO, partial_receive_len, CTLFLAG_RWTUN, &partial_receive_len, 1 * 1024, "Minimum read size for partially received " @@ -750,12 +751,19 @@ icl_receive_thread(void *arg) break; } + /* + * Set the low watermark, to be checked by + * soreadable() in icl_soupcall_receive() + * to avoid unneccessary wakeups until there + * is enough data received to read the PDU. + */ SOCKBUF_LOCK(&so->so_rcv); available = so->so_rcv.sb_cc; if (available < ic->ic_receive_len) { so->so_rcv.sb_lowat = ic->ic_receive_len; cv_wait(&ic->ic_receive_cv, &so->so_rcv.sb_mtx); - } + } else + so->so_rcv.sb_lowat = so->so_rcv.sb_hiwat + 1; SOCKBUF_UNLOCK(&so->so_rcv); icl_conn_receive_pdus(ic, available); @@ -772,6 +780,9 @@ icl_soupcall_receive(struct socket *so, { struct icl_conn *ic; + if (!soreadable(so)) + return (SU_OK); + ic = arg; cv_signal(&ic->ic_receive_cv); return (SU_OK); @@ -854,10 +865,10 @@ icl_conn_send_pdus(struct icl_conn *ic, available = sbspace(&so->so_snd); /* - * Notify the socket layer that it doesn't need to call - * send socket upcall for the time being. + * Notify the socket upcall that we don't need wakeups + * for the time being. */ - so->so_snd.sb_lowat = so->so_snd.sb_hiwat; + so->so_snd.sb_lowat = so->so_snd.sb_hiwat + 1; SOCKBUF_UNLOCK(&so->so_snd); while (!STAILQ_EMPTY(queue)) { @@ -873,7 +884,8 @@ icl_conn_send_pdus(struct icl_conn *ic, #endif /* - * Set the low watermark on the socket, + * Set the low watermark, to be checked by + * sowritable() in icl_soupcall_send() * to avoid unneccessary wakeups until there * is enough space for the PDU to fit. */ @@ -1016,6 +1028,9 @@ icl_soupcall_send(struct socket *so, voi { struct icl_conn *ic; + if (!sowriteable(so)) + return (SU_OK); + ic = arg; ICL_CONN_LOCK(ic);