Date: Thu, 2 Jan 2003 15:47:46 -0500 (EST) From: Andrew Gallatin <gallatin@cs.duke.edu> To: Bosko Milekic <bmilekic@unixdaemons.com> Cc: current@freebsd.org Subject: Re: mbuf header bloat ? Message-ID: <15892.42354.150878.922603@grasshopper.cs.duke.edu> In-Reply-To: <20030102152930.A25321@unixdaemons.com> References: <15840.8629.324788.887872@grasshopper.cs.duke.edu> <Pine.BSF.4.21.0211232306410.28833-100000@InterJet.elischer.org> <15841.17237.826666.653505@grasshopper.cs.duke.edu> <20021125130005.A75177@unixdaemons.com> <15842.27547.385354.151541@grasshopper.cs.duke.edu> <20021125160122.A75673@unixdaemons.com> <15842.51914.871010.137070@grasshopper.cs.duke.edu> <20021126191526.B78371@unixdaemons.com> <15892.35521.181516.714686@grasshopper.cs.duke.edu> <20030102152930.A25321@unixdaemons.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Bosko Milekic writes:
>
> On Thu, Jan 02, 2003 at 01:53:53PM -0500, Andrew Gallatin wrote:
> > I'm just tuning up my driver now to catch up to the "recent" interface
> > changes. While there, I went to add a ref count for my driver managed
> > M_EXT clusters. However, m_extadd() does not take a parameter for
> > assignment into mp->m_ext.ref_cnt Eg, I cannot call m_extadd() if I
> > want to use my own refcounter.
> >
> > Is there any chance this could be fixed? O/w, I'll have to
> > avoid calling m_extadd()..
>
> I dunno. I hate the whole story behind the reference counters in the
> mbuf code and I don't know what the correct approach here would be. A
> long long while back I think m_extadd (or its equivalent) did allow
> something like this. Then, we changed it so that counters would be
> allocated by the mbuf code 'transparently' (i.e., so that the Rest Of
> The World didn't have to worry about it). However, not long ago, I
> changed the way reference counters were allocated for mbuf clusters so
> that it would be faster. Counters for other objects are allocated
> with malloc(). The only 'correct' (half-assed) solution I can see is
> to allow m_extadd() to take a 'refcount' argument (again?) - perhaps
> leave a backwards-compatible m_extadd() and add a m_addext() or
> something - and only call malloc() for the counter if refcnt_provided
> == NULL.
>
> To be honest, I don't really like the idea but I don't see a better
> solution. Right now, ref counting for regular mbuf clusters works
> fine and is pretty damn fast, but I don't know how I could make it
> happen for other external buffer types other than the way I just
> described.
There's a second can of worms too. We don't want the mbuf system
freeing externally maintained refcnt pointers. So we need a type
or flag to distinguish them.
I've appended a minimal impact patch that I came up with. It just
adds a new type (EXT_EXTREF) and leaves the m_extadd() api/abi pretty
much unchanged. Callers that want to manage their own refcnt memory
call m_extadd() like this:
mp->m_ext.ref_cnt = &entry->ref_count;
MEXTADD(mp, (void *)entry->jbuf->buf, GM_JLEN,
gm_freebsd_ether_jfree, (void *)entry->jbuf,
0, EXT_EXTREF);
It seems to work just fine, and together with some patches from Alan
Cox for kmem_malloc(), allows me to make my network driver MPSAFE.
I'm still testing for other hidden Giant acquisitions or
GIANT_REQUIRED() assertions in rare codepaths, but its been up for 15
minutes now, and that's 14m 59sec longer than usual ;)
Would you be OK with this or something like it?
Thanks,
Drew
Index: kern/subr_mbuf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_mbuf.c,v
retrieving revision 1.34
diff -u -r1.34 subr_mbuf.c
--- kern/subr_mbuf.c 27 Nov 2002 04:26:00 -0000 1.34
+++ kern/subr_mbuf.c 2 Jan 2003 19:59:54 -0000
@@ -1062,7 +1062,8 @@
(((uintptr_t)(cl) - (uintptr_t)cl_refcntmap) >> MCLSHIFT)
#define _mext_dealloc_ref(m) \
- free((m)->m_ext.ref_cnt, M_MBUF)
+ if ((m)->m_ext.ext_type != EXT_EXTREF) \
+ free((m)->m_ext.ref_cnt, M_MBUF)
/******************************************************************************
* Internal routines.
@@ -1508,9 +1509,13 @@
m_extadd(struct mbuf *mb, caddr_t buf, u_int size,
void (*freef)(void *, void *), void *args, int flags, int type)
{
+ u_int *ref_cnt = NULL;
- _mext_init_ref(mb, ((type != EXT_CLUSTER) ?
- NULL : &cl_refcntmap[cl2ref(mb->m_ext.ext_buf)]));
+ if (type == EXT_CLUSTER)
+ ref_cnt = &cl_refcntmap[cl2ref(mb->m_ext.ext_buf)];
+ else if (type == EXT_EXTREF)
+ ref_cnt = mb->m_ext.ref_cnt;
+ _mext_init_ref(mb, ref_cnt);
if (mb->m_ext.ref_cnt != NULL) {
mb->m_flags |= (M_EXT | flags);
mb->m_ext.ext_buf = buf;
Index: sys/mbuf.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/mbuf.h,v
retrieving revision 1.109
diff -u -r1.109 mbuf.h
--- sys/mbuf.h 30 Dec 2002 20:22:40 -0000 1.109
+++ sys/mbuf.h 2 Jan 2003 19:40:20 -0000
@@ -173,6 +173,7 @@
#define EXT_NET_DRV 100 /* custom ext_buf provided by net driver(s) */
#define EXT_MOD_TYPE 200 /* custom module's ext_buf type */
#define EXT_DISPOSABLE 300 /* can throw this buffer away w/page flipping */
+#define EXT_EXTREF 400 /* has externally maintained ref_cnt ptr*/
/*
* Flags copied when copying m_pkthdr.
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?15892.42354.150878.922603>
