Skip site navigation (1)Skip section navigation (2)
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>