From owner-freebsd-net@FreeBSD.ORG Tue Apr 29 01:48:57 2008 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 580C6106566C for ; Tue, 29 Apr 2008 01:48:57 +0000 (UTC) (envelope-from julian@elischer.org) Received: from outK.internet-mail-service.net (outk.internet-mail-service.net [216.240.47.234]) by mx1.freebsd.org (Postfix) with ESMTP id 10D0D8FC16 for ; Tue, 29 Apr 2008 01:48:57 +0000 (UTC) (envelope-from julian@elischer.org) Received: from mx0.idiom.com (HELO idiom.com) (216.240.32.160) by out.internet-mail-service.net (qpsmtpd/0.40) with ESMTP; Mon, 28 Apr 2008 23:43:47 -0700 Received: from julian-mac.elischer.org (localhost [127.0.0.1]) by idiom.com (Postfix) with ESMTP id 6783B2D6017 for ; Mon, 28 Apr 2008 18:48:55 -0700 (PDT) Message-ID: <48167E87.40100@elischer.org> Date: Mon, 28 Apr 2008 18:48:55 -0700 From: Julian Elischer User-Agent: Thunderbird 2.0.0.12 (Macintosh/20080213) MIME-Version: 1.0 To: FreeBSD Net References: <48166916.8090801@elischer.org> In-Reply-To: <48166916.8090801@elischer.org> Content-Type: multipart/mixed; boundary="------------080802020406040206010104" Subject: Re: mbuf usage in packets.. X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Apr 2008 01:48:57 -0000 This is a multi-part message in MIME format. --------------080802020406040206010104 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Julian Elischer wrote: > > I wrote a cruddy little profiler to profile the packets being sent > on my system.. > after a bit of a live session including things like "ls -lR /usr" > [...] > > profiling diff attached.. > slightly imporved version that allows you to clear the stats without rebooting --------------080802020406040206010104 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="mbprofile.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mbprofile.diff" Index: kern/uipc_mbuf.c =================================================================== RCS file: /usr/local/cvsroot/freebsd/src/sys/kern/uipc_mbuf.c,v retrieving revision 1.177 diff -u -r1.177 uipc_mbuf.c --- kern/uipc_mbuf.c 25 Mar 2008 09:38:59 -0000 1.177 +++ kern/uipc_mbuf.c 29 Apr 2008 01:45:06 -0000 @@ -35,6 +35,7 @@ #include "opt_mac.h" #include "opt_param.h" #include "opt_mbuf_stress_test.h" +#include "opt_mbuf_profiling.h" #include #include @@ -1938,3 +1939,139 @@ } return (m0); } + +#ifdef MBUF_PROFILING + +#define MP_BUCKETS 32 /* don't just change this things may overflow.*/ +struct mbufprofile { + u_int64_t wasted[MP_BUCKETS]; + u_int64_t used[MP_BUCKETS]; + u_int64_t segments[MP_BUCKETS]; +} mbprof; + +#define MP_MAXDIGITS 21 /* strlen("16,000,000,000,000,000,000") == 21 */ +#define MP_NUMLINES 6 +#define MP_NUMSPERLINE 16 +#define MP_EXTRABYTES 64 /* > strlen("used:\nwasted:\nsegments:\n") */ +/* work out max space needed and add a bit of spare space too */ +#define MP_MAXLINE ((MP_MAXDIGITS+1) * MP_NUMSPERLINE) +#define MP_BUFSIZE ((MP_MAXLINE * MP_NUMLINES) + 1 + MP_EXTRABYTES) + +char mbprofbuf[MP_BUFSIZE]; + +void +m_profile(struct mbuf *m) +{ + int segments = 0; + int used = 0; + int wasted = 0; + + while (m) { + segments++; + used += m->m_len; + if (m->m_flags & M_EXT) { + wasted += MHLEN - sizeof(m->m_ext) + + m->m_ext.ext_size - m->m_len; + } else { + if (m->m_flags & M_PKTHDR) + wasted += MHLEN - m->m_len; + else + wasted += MLEN - m->m_len; + } + m = m->m_next; + } + /* be paranoid.. it helps */ + if (segments > MP_BUCKETS - 1) + segments = MP_BUCKETS - 1; + if (used > 10000000) + used = 10000000; + if (wasted > 10000000) + wasted = 10000000; + /* store in the appropriate bucket */ + /* don't bother locking. if it's slightly off, so what? */ + mbprof.segments[segments]++; + mbprof.used[fls(used)]++; + mbprof.wasted[fls(wasted)]++; +} + +static void +mbprof_textify(void) +{ + int offset; + char *c; + u_int64_t *p; + + + p = &mbprof.wasted[0]; + c = mbprofbuf; + offset = snprintf(c, MP_MAXLINE + 10, + "wasted:\n%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p = &mbprof.wasted[16]; + c += offset; + offset = snprintf(c, MP_MAXLINE, + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p = &mbprof.used[0]; + c += offset; + offset = snprintf(c, MP_MAXLINE + 10, + "used:\n%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p = &mbprof.used[16]; + c += offset; + offset = snprintf(c, MP_MAXLINE, + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p = &mbprof.segments[0]; + c += offset; + offset = snprintf(c, MP_MAXLINE + 10, + "segments:\n%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p = &mbprof.segments[16]; + c += offset; + offset = snprintf(c, MP_MAXLINE, + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); +} + +static int +mbprof_handler(SYSCTL_HANDLER_ARGS) +{ + int error; + + mbprof_textify(); + error = SYSCTL_OUT(req, mbprofbuf, strlen(mbprofbuf) + 1); + return (error); +} + +static int +mbprof_clr_handler(SYSCTL_HANDLER_ARGS) +{ + int clear, error; + + clear = 0; + error = sysctl_handle_int(oidp, &clear, 0, req); + if (error || !req->newptr) + return (error); + + if (clear) { + bzero(&mbprof, sizeof(mbprof)); + } + + return (error); +} + + +SYSCTL_PROC(_kern_ipc, OID_AUTO, mbufprofile, CTLTYPE_STRING|CTLFLAG_RD, + NULL, 0, mbprof_handler, "A", "mbuf profiling statistics"); + +SYSCTL_PROC(_kern_ipc, OID_AUTO, mbufprofileclr, CTLTYPE_INT|CTLFLAG_RW, + NULL, 0, mbprof_clr_handler, "I", "clear mbuf profiling statistics"); +#endif + Index: sys/mbuf.h =================================================================== RCS file: /usr/local/cvsroot/freebsd/src/sys/sys/mbuf.h,v retrieving revision 1.224 diff -u -r1.224 mbuf.h --- sys/mbuf.h 25 Mar 2008 09:39:02 -0000 1.224 +++ sys/mbuf.h 29 Apr 2008 01:45:06 -0000 @@ -959,4 +959,12 @@ #endif /* _KERNEL */ +#ifdef MBUF_PROFILING + void m_profile(struct mbuf *m); + #define M_PROFILE(m) m_profile(m) +#else + #define M_PROFILE(m) +#endif + + #endif /* !_SYS_MBUF_H_ */ Index: net/if_ethersubr.c =================================================================== RCS file: /usr/local/cvsroot/freebsd/src/sys/net/if_ethersubr.c,v retrieving revision 1.244 diff -u -r1.244 if_ethersubr.c --- net/if_ethersubr.c 20 Mar 2008 06:19:34 -0000 1.244 +++ net/if_ethersubr.c 29 Apr 2008 01:45:06 -0000 @@ -37,6 +37,7 @@ #include "opt_mac.h" #include "opt_netgraph.h" #include "opt_carp.h" +#include "opt_mbuf_profiling.h" #include #include @@ -162,6 +163,7 @@ senderr(error); #endif + M_PROFILE(m); if (ifp->if_flags & IFF_MONITOR) senderr(ENETDOWN); if (!((ifp->if_flags & IFF_UP) && --------------080802020406040206010104--