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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to