From owner-svn-src-head@FreeBSD.ORG Wed Oct 9 11:57:54 2013 Return-Path: Delivered-To: svn-src-head@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 ESMTP id 3A1B5713; Wed, 9 Oct 2013 11:57:54 +0000 (UTC) (envelope-from glebius@FreeBSD.org) 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)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 264FB20A4; Wed, 9 Oct 2013 11:57:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r99Bvsw4036947; Wed, 9 Oct 2013 11:57:54 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r99BvrSp036941; Wed, 9 Oct 2013 11:57:53 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201310091157.r99BvrSp036941@svn.freebsd.org> From: Gleb Smirnoff Date: Wed, 9 Oct 2013 11:57:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r256185 - in head/sys: kern sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Oct 2013 11:57:54 -0000 Author: glebius Date: Wed Oct 9 11:57:53 2013 New Revision: 256185 URL: http://svnweb.freebsd.org/changeset/base/256185 Log: - Substitute sbdrop_internal() with sbcut_internal(). The latter doesn't free mbufs, but return chain of free mbufs to a caller. Caller can either reuse them or return to allocator in a batch manner. - Implement sbdrop()/sbdrop_locked() as a wrapper around sbcut_internal(). - Expose sbcut_locked() for outside usage. Sponsored by: Netflix Sponsored by: Nginx, Inc. Approved by: re (marius) Modified: head/sys/kern/uipc_sockbuf.c head/sys/sys/sockbuf.h Modified: head/sys/kern/uipc_sockbuf.c ============================================================================== --- head/sys/kern/uipc_sockbuf.c Wed Oct 9 09:13:12 2013 (r256184) +++ head/sys/kern/uipc_sockbuf.c Wed Oct 9 11:57:53 2013 (r256185) @@ -65,7 +65,7 @@ u_long sb_max_adj = static u_long sb_efficiency = 8; /* parameter for sbreserve() */ -static void sbdrop_internal(struct sockbuf *sb, int len); +static struct mbuf *sbcut_internal(struct sockbuf *sb, int len); static void sbflush_internal(struct sockbuf *sb); /* @@ -818,7 +818,7 @@ sbflush_internal(struct sockbuf *sb) */ if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len)) break; - sbdrop_internal(sb, (int)sb->sb_cc); + m_freem(sbcut_internal(sb, (int)sb->sb_cc)); } if (sb->sb_cc || sb->sb_mb || sb->sb_mbcnt) panic("sbflush_internal: cc %u || mb %p || mbcnt %u", @@ -843,15 +843,16 @@ sbflush(struct sockbuf *sb) } /* - * Drop data from (the front of) a sockbuf. + * Cut data from (the front of) a sockbuf. */ -static void -sbdrop_internal(struct sockbuf *sb, int len) +static struct mbuf * +sbcut_internal(struct sockbuf *sb, int len) { - struct mbuf *m; - struct mbuf *next; + struct mbuf *m, *n, *next, *mfree; next = (m = sb->sb_mb) ? m->m_nextpkt : 0; + mfree = NULL; + while (len > 0) { if (m == 0) { if (next == 0) @@ -872,11 +873,17 @@ sbdrop_internal(struct sockbuf *sb, int } len -= m->m_len; sbfree(sb, m); - m = m_free(m); + n = m->m_next; + m->m_next = mfree; + mfree = m; + m = n; } while (m && m->m_len == 0) { sbfree(sb, m); - m = m_free(m); + n = m->m_next; + m->m_next = mfree; + mfree = m; + m = n; } if (m) { sb->sb_mb = m; @@ -894,6 +901,8 @@ sbdrop_internal(struct sockbuf *sb, int } else if (m->m_nextpkt == NULL) { sb->sb_lastrecord = m; } + + return (mfree); } /* @@ -904,17 +913,31 @@ sbdrop_locked(struct sockbuf *sb, int le { SOCKBUF_LOCK_ASSERT(sb); + m_freem(sbcut_internal(sb, len)); +} - sbdrop_internal(sb, len); +/* + * Drop data from (the front of) a sockbuf, + * and return it to caller. + */ +struct mbuf * +sbcut_locked(struct sockbuf *sb, int len) +{ + + SOCKBUF_LOCK_ASSERT(sb); + return (sbcut_internal(sb, len)); } void sbdrop(struct sockbuf *sb, int len) { + struct mbuf *mfree; SOCKBUF_LOCK(sb); - sbdrop_locked(sb, len); + mfree = sbcut_internal(sb, len); SOCKBUF_UNLOCK(sb); + + m_freem(mfree); } /* Modified: head/sys/sys/sockbuf.h ============================================================================== --- head/sys/sys/sockbuf.h Wed Oct 9 09:13:12 2013 (r256184) +++ head/sys/sys/sockbuf.h Wed Oct 9 11:57:53 2013 (r256185) @@ -140,6 +140,8 @@ struct mbuf * void sbdestroy(struct sockbuf *sb, struct socket *so); void sbdrop(struct sockbuf *sb, int len); void sbdrop_locked(struct sockbuf *sb, int len); +struct mbuf * + sbcut_locked(struct sockbuf *sb, int len); void sbdroprecord(struct sockbuf *sb); void sbdroprecord_locked(struct sockbuf *sb); void sbflush(struct sockbuf *sb);