Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet * Instrument tcp_build_datapkt().



details:   https://anonhg.NetBSD.org/src/rev/c77ef71a9270
branches:  trunk
changeset: 526183:c77ef71a9270
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat Apr 27 01:47:58 2002 +0000

description:
* Instrument tcp_build_datapkt().
* Remove the code that allocates a cluster if the packet would
  fit in one; it totally defeats doing references to M_EXT mbufs
  in the socket buffer.  This drastically reduces the number of
  data copies in the tcp_output() path for applications which use
  large writes.  Kudos to Matt Thomas for pointing me in the right
  direction.

diffstat:

 sys/netinet/tcp_output.c |  45 +++++++++++++++++++++++++++++++++++++--------
 sys/netinet/tcp_subr.c   |  24 ++++++++++++++++++++++--
 2 files changed, 59 insertions(+), 10 deletions(-)

diffs (142 lines):

diff -r 5d7af3e8e6f3 -r c77ef71a9270 sys/netinet/tcp_output.c
--- a/sys/netinet/tcp_output.c  Sat Apr 27 01:00:46 2002 +0000
+++ b/sys/netinet/tcp_output.c  Sat Apr 27 01:47:58 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_output.c,v 1.78 2002/03/01 22:54:09 thorpej Exp $  */
+/*     $NetBSD: tcp_output.c,v 1.79 2002/04/27 01:47:58 thorpej Exp $  */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -142,7 +142,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.78 2002/03/01 22:54:09 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_output.c,v 1.79 2002/04/27 01:47:58 thorpej Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -200,6 +200,21 @@
 int    tcp_cwm = 1;
 int    tcp_cwm_burstsize = 4;
 
+#ifdef TCP_OUTPUT_COUNTERS
+#include <sys/device.h>
+
+extern struct evcnt tcp_output_bigheader;
+extern struct evcnt tcp_output_copysmall;
+extern struct evcnt tcp_output_copybig;
+extern struct evcnt tcp_output_refbig;
+
+#define        TCP_OUTPUT_COUNTER_INCR(ev)     (ev)->ev_count++
+#else
+
+#define        TCP_OUTPUT_COUNTER_INCR(ev)     /* nothing */
+
+#endif /* TCP_OUTPUT_COUNTERS */
+
 static
 #ifndef GPROF
 __inline
@@ -384,29 +399,43 @@
        m->m_data -= hdrlen;
 #else
        MGETHDR(m, M_DONTWAIT, MT_HEADER);
-       if (m != NULL &&
-           (max_linkhdr + hdrlen > MHLEN ||
-            max_linkhdr + hdrlen + len <= MCLBYTES)) {
+       if (__predict_false(m == NULL))
+               return (ENOBUFS);
+
+       /*
+        * XXX Because other code assumes headers will fit in
+        * XXX one header mbuf.
+        *
+        * (This code should almost *never* be run.)
+        */
+       if (__predict_false((max_linkhdr + hdrlen) > MHLEN)) {
+               TCP_OUTPUT_COUNTER_INCR(&tcp_output_bigheader);
                MCLGET(m, M_DONTWAIT);
                if ((m->m_flags & M_EXT) == 0) {
                        m_freem(m);
-                       m = NULL;
+                       return (ENOBUFS);
                }
        }
-       if (m == NULL)
-               return (ENOBUFS);
+
        m->m_data += max_linkhdr;
        m->m_len = hdrlen;
        if (len <= M_TRAILINGSPACE(m)) {
                m_copydata(so->so_snd.sb_mb, off, (int) len,
                    mtod(m, caddr_t) + hdrlen);
                m->m_len += len;
+               TCP_OUTPUT_COUNTER_INCR(&tcp_output_copysmall);
        } else {
                m->m_next = m_copy(so->so_snd.sb_mb, off, (int) len);
                if (m->m_next == NULL) {
                        m_freem(m);
                        return (ENOBUFS);
                }
+#ifdef TCP_OUTPUT_COUNTERS
+               if (m->m_next->m_flags & M_EXT)
+                       TCP_OUTPUT_COUNTER_INCR(&tcp_output_refbig);
+               else
+                       TCP_OUTPUT_COUNTER_INCR(&tcp_output_copybig);
+#endif /* TCP_OUTPUT_COUNTERS */
        }
 #endif
 
diff -r 5d7af3e8e6f3 -r c77ef71a9270 sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c    Sat Apr 27 01:00:46 2002 +0000
+++ b/sys/netinet/tcp_subr.c    Sat Apr 27 01:47:58 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tcp_subr.c,v 1.124 2002/03/15 09:25:41 itojun Exp $    */
+/*     $NetBSD: tcp_subr.c,v 1.125 2002/04/27 01:47:58 thorpej Exp $   */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.124 2002/03/15 09:25:41 itojun Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.125 2002/04/27 01:47:58 thorpej Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -227,6 +227,19 @@
     NULL, "tcp", "swcsum");
 #endif /* TCP_CSUM_COUNTERS */
 
+#ifdef TCP_OUTPUT_COUNTERS
+#include <sys/device.h>
+
+struct evcnt tcp_output_bigheader = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
+    NULL, "tcp", "output big header");
+struct evcnt tcp_output_copysmall = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
+    NULL, "tcp", "output copy small");
+struct evcnt tcp_output_copybig = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
+    NULL, "tcp", "output copy big");
+struct evcnt tcp_output_refbig = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
+    NULL, "tcp", "output reference big");
+#endif /* TCP_OUTPUT_COUNTERS */
+
 /*
  * Tcp initialization
  */
@@ -271,6 +284,13 @@
        evcnt_attach_static(&tcp_hwcsum_data);
        evcnt_attach_static(&tcp_swcsum);
 #endif /* TCP_CSUM_COUNTERS */
+
+#ifdef TCP_OUTPUT_COUNTERS
+       evcnt_attach_static(&tcp_output_bigheader);
+       evcnt_attach_static(&tcp_output_copysmall);
+       evcnt_attach_static(&tcp_output_copybig);
+       evcnt_attach_static(&tcp_output_refbig);
+#endif /* TCP_OUTPUT_COUNTERS */
 }
 
 /*



Home | Main Index | Thread Index | Old Index