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
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 <sys/param.h> #include <sys/systm.h> @@ -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 <sys/param.h> #include <sys/systm.h> @@ -162,6 +163,7 @@ senderr(error); #endif + M_PROFILE(m); if (ifp->if_flags & IFF_MONITOR) senderr(ENETDOWN); if (!((ifp->if_flags & IFF_UP) &&
_______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "[EMAIL PROTECTED]"