svn commit: r256780 - in user/andre/mbuf_staging: dev/bxe dev/cas dev/lge dev/mwl dev/wb kern sys

Andre Oppermann andre at FreeBSD.org
Sun Oct 20 09:51:38 UTC 2013


Author: andre
Date: Sun Oct 20 09:51:36 2013
New Revision: 256780
URL: http://svnweb.freebsd.org/changeset/base/256780

Log:
  Give ext_free way more latitude in handling of external mbuf storage
  and associated refcounts.
  
  The behavior is managed by using the m_ext.ext_flags to signal various
  combinations of external storage and refcount management.  At every
  step (*ext_free) can capture the whole mbuf freeing process by using
  the return values EXT_FREE_CONT or EXT_FREE_DONE.
  
  With EXT_FLAG_EMBREF no external refcount storage is allocated by the
  mbuf system and a pointer must be supplied by the m_extadd() caller.
  The location of the refcount storage must be inside the attached external
  memory.  It is managed as usual by incrementing/decrementing the value
  at the location.
  
  With EXT_FLAG_EXTREF no external refcount storage is allocated by the
  mbuf system and a pointer must be supplied by the m_extadd() caller.
  The location of the refcount storage can be anywhere within KVM.  It
  must not disappear until after the associated external storage has been
  freed.  It is managed as usual by incrementing/decrementing the value
  at the location.
  
  With EXT_FLAG_REFCNT no external refcount storage is alloced by the
  mbuf system.  No pointer needs to be supplied.  Every in/decrement
  of the refcount is done through (*m_ext_free) and the new parameters
  EXT_FREE_REFINC, EXT_FREE_REFDEC, and EXT_FREE_REFDEL.
  
  The previous mbuf type EXT_EXTREF is removed and the m_ext.ext_flags
  are used instead.
  
  As long as the new features are not used the behavior remains the same
  as before.
  
  NB: This is API and implementation is still subject to changes and
  refinements.
  
  Other changes:
  
  Simplify m_free() by removing m_tag_delete_chain() which is done
  in the zone_mbuf dtor anyways.
  
  Add typedef ext_free_t for (*)(struct mbuf *, void *, void *, int).
  
  m_extadd() gains two more parameters: u_int refcnt, int ext_flags.
  
  Users of the m_extadd()/MEXTADD() APIs in the generic kernel are
  adjusted.  Within modules there is some fallout not yet fixed.

Modified:
  user/andre/mbuf_staging/dev/bxe/bxe.c
  user/andre/mbuf_staging/dev/cas/if_cas.c
  user/andre/mbuf_staging/dev/lge/if_lge.c
  user/andre/mbuf_staging/dev/mwl/if_mwl.c
  user/andre/mbuf_staging/dev/wb/if_wb.c
  user/andre/mbuf_staging/kern/kern_mbuf.c
  user/andre/mbuf_staging/kern/uipc_mbuf.c
  user/andre/mbuf_staging/kern/uipc_syscalls.c
  user/andre/mbuf_staging/sys/mbuf.h
  user/andre/mbuf_staging/sys/sf_buf.h

Modified: user/andre/mbuf_staging/dev/bxe/bxe.c
==============================================================================
--- user/andre/mbuf_staging/dev/bxe/bxe.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/dev/bxe/bxe.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -5052,7 +5052,6 @@ bxe_dump_mbuf(struct bxe_softc *sc,
             case EXT_NET_DRV:    type = "EXT_NET_DRV";    break;
             case EXT_MOD_TYPE:   type = "EXT_MOD_TYPE";   break;
             case EXT_DISPOSABLE: type = "EXT_DISPOSABLE"; break;
-            case EXT_EXTREF:     type = "EXT_EXTREF";     break;
             default:             type = "UNKNOWN";        break;
             }
 

Modified: user/andre/mbuf_staging/dev/cas/if_cas.c
==============================================================================
--- user/andre/mbuf_staging/dev/cas/if_cas.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/dev/cas/if_cas.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -132,7 +132,7 @@ static void	cas_detach(struct cas_softc 
 static int	cas_disable_rx(struct cas_softc *sc);
 static int	cas_disable_tx(struct cas_softc *sc);
 static void	cas_eint(struct cas_softc *sc, u_int status);
-static int	cas_free(struct mbuf *m, void *arg1, void* arg2);
+static int	cas_free(struct mbuf *m, void *arg1, void* arg2, int action);
 static void	cas_init(void *xsc);
 static void	cas_init_locked(struct cas_softc *sc);
 static void	cas_init_regs(struct cas_softc *sc);
@@ -1888,7 +1888,7 @@ cas_rint(struct cas_softc *sc)
 }
 
 static int
-cas_free(struct mbuf *m, void *arg1, void *arg2)
+cas_free(struct mbuf *m, void *arg1, void *arg2, int action)
 {
 	struct cas_rxdsoft *rxds;
 	struct cas_softc *sc;

Modified: user/andre/mbuf_staging/dev/lge/if_lge.c
==============================================================================
--- user/andre/mbuf_staging/dev/lge/if_lge.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/dev/lge/if_lge.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -122,7 +122,7 @@ static int lge_detach(device_t);
 static int lge_alloc_jumbo_mem(struct lge_softc *);
 static void lge_free_jumbo_mem(struct lge_softc *);
 static void *lge_jalloc(struct lge_softc *);
-static int lge_jfree(struct mbuf *, void *, void *);
+static int lge_jfree(struct mbuf *, void *, void *, int);
 
 static int lge_newbuf(struct lge_softc *, struct lge_rx_desc *, struct mbuf *);
 static int lge_encap(struct lge_softc *, struct mbuf *, u_int32_t *);
@@ -847,7 +847,7 @@ lge_jalloc(sc)
  * Release a jumbo buffer.
  */
 static int
-lge_jfree(struct mbuf *m, void *buf, void *args)
+lge_jfree(struct mbuf *m, void *buf, void *args, int action)
 {
 	struct lge_softc	*sc;
 	int		        i;

Modified: user/andre/mbuf_staging/dev/mwl/if_mwl.c
==============================================================================
--- user/andre/mbuf_staging/dev/mwl/if_mwl.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/dev/mwl/if_mwl.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -2622,7 +2622,7 @@ mwl_rxbuf_init(struct mwl_softc *sc, str
 }
 
 static int
-mwl_ext_free(struct mbuf *m, void *data, void *arg)
+mwl_ext_free(struct mbuf *m, void *data, void *arg, int action)
 {
 	struct mwl_softc *sc = arg;
 

Modified: user/andre/mbuf_staging/dev/wb/if_wb.c
==============================================================================
--- user/andre/mbuf_staging/dev/wb/if_wb.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/dev/wb/if_wb.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -142,7 +142,7 @@ static int wb_probe(device_t);
 static int wb_attach(device_t);
 static int wb_detach(device_t);
 
-static int wb_bfree(struct mbuf *, void *addr, void *args);
+static int wb_bfree(struct mbuf *, void *addr, void *args, int action);
 static int wb_newbuf(struct wb_softc *, struct wb_chain_onefrag *,
 		struct mbuf *);
 static int wb_encap(struct wb_softc *, struct wb_chain *, struct mbuf *);
@@ -823,7 +823,7 @@ wb_list_rx_init(sc)
 }
 
 static int
-wb_bfree(struct mbuf *m, void *buf, void *args)
+wb_bfree(struct mbuf *m, void *buf, void *args, int action)
 {
 
 	return (EXT_FREE_OK);

Modified: user/andre/mbuf_staging/kern/kern_mbuf.c
==============================================================================
--- user/andre/mbuf_staging/kern/kern_mbuf.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/kern/kern_mbuf.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -482,7 +482,7 @@ mb_dtor_pack(void *mem, int size, void *
 	struct mbuf *m;
 
 	m = (struct mbuf *)mem;
-	if ((m->m_flags & M_PKTHDR) != 0)
+	if ((m->m_flags & M_PKTHDR) && !SLIST_EMPTY(&m->m_pkthdr.tags))
 		m_tag_delete_chain(m, NULL);
 
 	/* Make sure we've got a clean cluster back. */
@@ -555,7 +555,7 @@ mb_ctor_clust(void *mem, int size, void 
 	}
 
 	m = (struct mbuf *)arg;
-	refcnt = uma_find_refcnt(zone, mem);
+	refcnt = uma_find_refcnt(zone, mem);	/* XXX */
 	*refcnt = 1;
 	if (m != NULL) {
 		m->m_ext.ext_buf = (caddr_t)mem;
@@ -920,7 +920,6 @@ m_cljset(struct mbuf *m, void *cl, int t
 	m->m_ext.ext_flags = 0;
 	m->m_ext.ref_cnt = uma_find_refcnt(zone, cl);
 	m->m_flags |= M_EXT;
-
 }
 
 /*
@@ -1039,12 +1038,11 @@ m_free(struct mbuf *m)
 {
 	struct mbuf *n = m->m_next;
 
-	if ((m->m_flags & (M_PKTHDR|M_NOFREE)) == (M_PKTHDR|M_NOFREE))
-		m_tag_delete_chain(m, NULL);
 	if (m->m_flags & M_EXT)
 		mb_free_ext(m);
-	else if ((m->m_flags & M_NOFREE) == 0)
-		uma_zfree(zone_mbuf, m);
+	else
+		uma_zfree(zone_mbuf, m);	/* free's tag chain */
+
 	return (n);
 }
 
@@ -1078,28 +1076,30 @@ m_freem(struct mbuf *mb)
  *    Nothing.
  */
 int
-m_extadd(struct mbuf *mb, caddr_t buf, u_int size,
-    int (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2,
-    int flags, int type, int wait)
+m_extadd(struct mbuf *mb, caddr_t buf, u_int size, ext_free_t freef,
+    void *arg1, void *arg2, int flags, int type, u_int *refcnt, int ext_flags,
+    int wait)
 {
-	KASSERT(type != EXT_CLUSTER, ("%s: EXT_CLUSTER not allowed", __func__));
 
-	if (type != EXT_EXTREF)
+	if (refcnt == NULL) {
 		mb->m_ext.ref_cnt = uma_zalloc(zone_ext_refcnt, wait);
+		if (mb->m_ext.ref_cnt == NULL)
+			return (ENOMEM);
+		*(mb->m_ext.ref_cnt) = 1;
+	} else
+		mb->m_ext.ref_cnt = refcnt;
 
-	if (mb->m_ext.ref_cnt == NULL)
-		return (ENOMEM);
+	KASSERT(mb->m_ext.ref_cnt != NULL, ("%s: ref_cnt is NULL", __func__));
+	KASSERT(*(mb->m_ext.ref_cnt) >= 1, ("%s: refcount is <1", __func__));
 
-	*(mb->m_ext.ref_cnt) = 1;
 	mb->m_flags |= (M_EXT | flags);
-	mb->m_ext.ext_buf = buf;
-	mb->m_data = mb->m_ext.ext_buf;
+	mb->m_data = mb->m_ext.ext_buf = buf;
 	mb->m_ext.ext_size = size;
 	mb->m_ext.ext_free = freef;
 	mb->m_ext.ext_arg1 = arg1;
 	mb->m_ext.ext_arg2 = arg2;
 	mb->m_ext.ext_type = type;
-	mb->m_ext.ext_flags = 0;
+	mb->m_ext.ext_flags = ext_flags;
 
 	return (0);
 }
@@ -1109,7 +1109,7 @@ m_extadd(struct mbuf *mb, caddr_t buf, u
  */
 void
 m_extaddref(struct mbuf *m, caddr_t buf, u_int size, u_int *ref_cnt,
-    int (*freef)(struct mbuf *, void *, void *), void *arg1, void *arg2)
+    ext_free_t freef, void *arg1, void *arg2)
 {
 
 	KASSERT(ref_cnt != NULL, ("%s: ref_cnt not provided", __func__));
@@ -1124,35 +1124,60 @@ m_extaddref(struct mbuf *m, caddr_t buf,
 	m->m_ext.ext_arg1 = arg1;
 	m->m_ext.ext_arg2 = arg2;
 	m->m_ext.ext_flags = 0;
-	m->m_ext.ext_type = EXT_EXTREF;
+	m->m_ext.ext_type = EXT_NET_DRV;
 }
 
 /*
  * Non-directly-exported function to clean up after mbufs with M_EXT
- * storage attached to them if the reference count hits 1.
+ * storage attached to them if the reference count is decremented or
+ * hits 1.
+ *
+ * The normal behavior for the built in types is to free the cluster
+ * to one of our cluster zones, free the refcount to the UMA external
+ * refcount zone, and to free the mbuf to the mbuf zone.  The exeption
+ * is the packet zone where the mbuf+cluster package is returned whole.
+ *
+ * To give advanced users of the mbuf system more latitude the behavior
+ * can be modified with these flags:
+ *
+ * With EXT_FLAG_EMBREF we don't call any refcount disposal function.
+ * With EXT_FLAG_REFCNT we call (*ext_free) on every decrement.
+ * With EXT_FLAG_EXTREF we call (*ext_free) on for refcount disposal.
+ *
+ * At ext_free (*ext_free) can return EXT_FREE_DONE letting us know
+ * that everthing has been handled and we can return immediately.
+ *
+ * NB: Two separate free/disposal steps are done here: 1) disposal of
+ * the external storage; 2) disposal of the refcount storage.
+ * NB: The ref_cnt pointer must be maintained and valid for reading at
+ * all times.
  */
 static void
 mb_free_ext(struct mbuf *m)
 {
-	int skipmbuf;
-	
+
 	KASSERT((m->m_flags & M_EXT) == M_EXT, ("%s: M_EXT not set", __func__));
-	KASSERT(m->m_ext.ref_cnt != NULL, ("%s: ref_cnt not set", __func__));
 
 	/*
-	 * check if the header is embedded in the cluster
+	 * If the (*ext_free) function does full refcount management,
+	 * allow it handle this mbuf at its discretion.
 	 */
-	skipmbuf = (m->m_flags & M_NOFREE);
+	if (m->m_ext.ext_flags & EXT_FLAG_REFCNT)
+		if ((*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1,
+		    m->m_ext.ext_arg2, EXT_FREE_REFDEC) == EXT_FREE_DONE)
+			return;
 
-	/* Free attached storage if this mbuf is the only reference to it. */
+	/*
+	 * Free attached storage if this mbuf is the only reference to it.
+	 * Otherwise we only decrement the reference count, detach and free
+	 * this mbuf.
+	 */
 	if (*(m->m_ext.ref_cnt) == 1 ||
 	    atomic_fetchadd_int(m->m_ext.ref_cnt, -1) == 1) {
 		switch (m->m_ext.ext_type) {
 		case EXT_PACKET:	/* The packet zone is special. */
-			if (*(m->m_ext.ref_cnt) == 0)
-				*(m->m_ext.ref_cnt) = 1;
-			uma_zfree(zone_pack, m);
-			return;		/* Job done. */
+			uma_zfree(zone_pack, m);	/* frees tag chain */
+			return;
 		case EXT_CLUSTER:
 			uma_zfree(zone_clust, m->m_ext.ext_buf);
 			break;
@@ -1169,28 +1194,46 @@ mb_free_ext(struct mbuf *m)
 		case EXT_NET_DRV:
 		case EXT_MOD_TYPE:
 		case EXT_DISPOSABLE:
-			*(m->m_ext.ref_cnt) = 0;
-			uma_zfree(zone_ext_refcnt, __DEVOLATILE(u_int *,
-				m->m_ext.ref_cnt));
-			/* FALLTHROUGH */
-		case EXT_EXTREF:
-			KASSERT(m->m_ext.ext_free != NULL,
-				("%s: ext_free not set", __func__));
-			(void)(*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1,
-			    m->m_ext.ext_arg2);
-			break;
+		case EXT_VENDOR1:
+		case EXT_VENDOR2:
+		case EXT_VENDOR3:
+		case EXT_VENDOR4:
+		case EXT_EXP1:
+		case EXT_EXP2:
+		case EXT_EXP3:
+		case EXT_EXP4:
 		default:
-			KASSERT(m->m_ext.ext_type == 0,
-				("%s: unknown ext_type", __func__));
+			if ((*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1,
+			    m->m_ext.ext_arg2, EXT_FREE_DISPOSE) ==
+			    EXT_FREE_DONE)
+				return;
+			break;
+		}
+
+		/*
+		 * Free the reference count storage.
+		 */
+		if (m->m_ext.ext_flags & EXT_FLAG_EMBREF) {
+#ifdef INVARIANTS
+			*(m->m_ext.ref_cnt) = 0;
+#endif
+		} else if (m->m_ext.ext_flags & EXT_FLAG_EXTREF) {
+			if ((*(m->m_ext.ext_free))(m, m->m_ext.ext_arg1,
+			    m->m_ext.ext_arg2, EXT_FREE_REFDEL) ==
+			    EXT_FREE_DONE)
+				return;
+		} else if (m->m_ext.ref_cnt != NULL) {
+			*(m->m_ext.ref_cnt) = 0;
+			uma_zfree(zone_ext_refcnt,
+			    __DEVOLATILE(u_int *, m->m_ext.ref_cnt));
 		}
 	}
-	if (skipmbuf)
-		return;
-	
+
 	/*
-	 * Free this mbuf back to the mbuf zone with all m_ext
-	 * information purged.
+	 * Free this mbuf back to the mbuf zone with all m_ext information
+	 * purged.
 	 */
+#ifdef INVARIANTS
 	m->m_ext.ext_buf = NULL;
 	m->m_ext.ext_free = NULL;
 	m->m_ext.ext_arg1 = NULL;
@@ -1199,8 +1242,9 @@ mb_free_ext(struct mbuf *m)
 	m->m_ext.ext_size = 0;
 	m->m_ext.ext_type = 0;
 	m->m_ext.ext_flags = 0;
+#endif
 	m->m_flags &= ~M_EXT;
-	uma_zfree(zone_mbuf, m);
+	uma_zfree(zone_mbuf, m);	/* frees tag chain */
 }
 
 /*

Modified: user/andre/mbuf_staging/kern/uipc_mbuf.c
==============================================================================
--- user/andre/mbuf_staging/kern/uipc_mbuf.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/kern/uipc_mbuf.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -95,7 +95,10 @@ mb_dupcl(struct mbuf *n, struct mbuf *m)
 	KASSERT(m->m_ext.ref_cnt != NULL, ("%s: ref_cnt not set", __func__));
 	KASSERT((n->m_flags & M_EXT) == 0, ("%s: M_EXT set", __func__));
 
-	if (*(m->m_ext.ref_cnt) == 1)
+	if (m->m_ext.ext_flags & EXT_FLAG_REFCNT)
+		(void)(*m->m_ext.ext_free)(m, m->m_ext.ext_arg1,
+		    m->m_ext.ext_arg2, EXT_FREE_REFINC);
+	else if (*(m->m_ext.ref_cnt) == 1)
 		*(m->m_ext.ref_cnt) += 1;
 	else
 		atomic_add_int(m->m_ext.ref_cnt, 1);
@@ -1777,6 +1780,10 @@ m_unshare(struct mbuf *m0, int how)
 	return (m0);
 }
 
+/*
+ * Check if the mbuf data section is writable or not.
+ * XXXAO: The non-atomic read of ref_cnt is safe enough for this purpose.
+ */
 int
 _m_writable(const struct mbuf *m)
 {

Modified: user/andre/mbuf_staging/kern/uipc_syscalls.c
==============================================================================
--- user/andre/mbuf_staging/kern/uipc_syscalls.c	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/kern/uipc_syscalls.c	Sun Oct 20 09:51:36 2013	(r256780)
@@ -1854,7 +1854,7 @@ struct sendfile_sync {
  * Detach mapped page and release resources back to the system.
  */
 int
-sf_buf_mext(struct mbuf *mb, void *addr, void *args)
+sf_buf_mext(struct mbuf *mb, void *addr, void *args, int flags)
 {
 	vm_page_t m;
 	struct sendfile_sync *sfs;
@@ -1879,7 +1879,7 @@ sf_buf_mext(struct mbuf *mb, void *addr,
 	if (--sfs->count == 0)
 		cv_signal(&sfs->cv);
 	mtx_unlock(&sfs->mtx);
-	return (EXT_FREE_OK);
+	return (EXT_FREE_CONT);
 }
 
 /*
@@ -2441,14 +2441,14 @@ retry_space:
 			m0 = m_get((mnw ? M_NOWAIT : M_WAITOK), MT_DATA);
 			if (m0 == NULL) {
 				error = (mnw ? EAGAIN : ENOBUFS);
-				(void)sf_buf_mext(NULL, NULL, sf);
+				(void)sf_buf_mext(NULL, NULL, sf, 0);
 				break;
 			}
 			if (m_extadd(m0, (caddr_t )sf_buf_kva(sf), PAGE_SIZE,
-			    sf_buf_mext, sfs, sf, M_RDONLY, EXT_SFBUF,
+			    sf_buf_mext, sfs, sf, M_RDONLY, EXT_SFBUF, NULL, 0,
 			    (mnw ? M_NOWAIT : M_WAITOK)) != 0) {
 				error = (mnw ? EAGAIN : ENOBUFS);
-				(void)sf_buf_mext(NULL, NULL, sf);
+				(void)sf_buf_mext(NULL, NULL, sf, 0);
 				m_freem(m0);
 				break;
 			}

Modified: user/andre/mbuf_staging/sys/mbuf.h
==============================================================================
--- user/andre/mbuf_staging/sys/mbuf.h	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/sys/mbuf.h	Sun Oct 20 09:51:36 2013	(r256780)
@@ -76,6 +76,9 @@ struct uio;
  */
 #define	mtod(m, t)	((t)((m)->m_data))
 #define	mtodo(m, o)	((void *)(((m)->m_data) + (o)))
+
+struct mbuf;
+typedef	int		(*ext_free_t)(struct mbuf *, void *, void *, int);
 #endif /* _KERNEL */
 
 /*
@@ -166,8 +169,7 @@ struct mh_ext {
 	uint32_t	 ext_size;	/* size of buffer, for ext_free */
 	uint32_t	 ext_type:8,	/* type of external storage */
 			 ext_flags:24;	/* external storage mbuf flags */
-	int		(*ext_free)	/* free routine if not the usual */
-			    (struct mbuf *, void *, void *);
+	ext_free_t	 ext_free;
 	void		*ext_arg1;	/* optional argument pointer */
 	void		*ext_arg2;	/* optional argument pointer */
 };
@@ -337,15 +339,14 @@ struct mbuf {
 #define	EXT_NET_DRV	252	/* custom ext_buf provided by net driver(s) */
 #define	EXT_MOD_TYPE	253	/* custom module's ext_buf type */
 #define	EXT_DISPOSABLE	254	/* can throw this buffer away w/page flipping */
-#define	EXT_EXTREF	255	/* has externally maintained ref_cnt ptr */
 
 /*
  * Flags for external mbuf buffer types.
  * NB: limited to the lower 24 bits.
  */
-#define	EXT_FLAG_EMBREF		0x000001	/* embedded ref_cnt, notyet */
-#define	EXT_FLAG_EXTREF		0x000002	/* external ref_cnt, notyet */
-#define	EXT_FLAG_NOFREE		0x000010	/* don't free mbuf to pool, notyet */
+#define	EXT_FLAG_EMBREF		0x000001	/* embedded ref_cnt */
+#define	EXT_FLAG_EXTREF		0x000002	/* external alloc ref_cnt */
+#define	EXT_FLAG_REFCNT		0x000004	/* ref_cnt mgnt by ext_free */
 
 #define	EXT_FLAG_VENDOR1	0x010000	/* for vendor-internal use */
 #define	EXT_FLAG_VENDOR2	0x020000	/* for vendor-internal use */
@@ -361,15 +362,25 @@ struct mbuf {
  * EXT flag description for use with printf(9) %b identifier.
  */
 #define	EXT_FLAG_BITS \
-    "\20\1EXT_FLAG_EMBREF\2EXT_FLAG_EXTREF\5EXT_FLAG_NOFREE" \
+    "\20\1EXT_FLAG_EMBREF\2EXT_FLAG_EXTREF\5EXT_FLAG_REFCNT" \
     "\21EXT_FLAG_VENDOR1\22EXT_FLAG_VENDOR2\23EXT_FLAG_VENDOR3" \
     "\24EXT_FLAG_VENDOR4\25EXT_FLAG_EXP1\26EXT_FLAG_EXP2\27EXT_FLAG_EXP3" \
     "\30EXT_FLAG_EXP4"
 
 /*
+ * Flags used when calling (*ext_free).
+ */
+#define	EXT_FREE_DISPOSE 0	/* Free the external storage */
+#define	EXT_FREE_REFINC	1	/* Increment externally managed refcount */
+#define	EXT_FREE_REFDEC	2	/* Decrement externally managed refocunt */
+#define	EXT_FREE_REFDEL	3	/* Delete externally managed refcount */
+
+/*
  * Return values for (*ext_free).
  */
-#define	EXT_FREE_OK	0	/* Normal return */
+#define	EXT_FREE_DONE	0	/* Work done and mb_free_ext shall return */
+#define	EXT_FREE_CONT	1	/* Work done and mb_free_ext shall continue */
+#define	EXT_FREE_OK	EXT_FREE_CONT
 
 /*
  * Flags indicating checksum, segmentation and other offload work to be
@@ -479,11 +490,10 @@ struct mbuf {
  * as implemented in kern/kern_mbuf.c.
  */
 int		 m_pkthdr_init(struct mbuf *, int);
-int		 m_extadd(struct mbuf *, caddr_t, u_int,
-		    int (*)(struct mbuf *, void *, void *), void *, void *,
-		    int, int, int);
+int		 m_extadd(struct mbuf *, caddr_t, u_int, ext_free_t,
+		    void *, void *, int, int, u_int *, int, int);
 void		 m_extaddref(struct mbuf *, caddr_t, u_int, u_int *,
-		    int (*)(struct mbuf *, void *, void *), void *, void *);
+		    ext_free_t, void *, void *);
 int		 m_init(struct mbuf *, int, int, short, int);
 struct mbuf 	*m_get(int, short);
 struct mbuf	*m_getclr(int, short);
@@ -509,7 +519,7 @@ struct mbuf	*m_uiotombuf(struct uio *, i
     m_getm2((m), (len), (how), (type), M_PKTHDR)
 #define	MEXTADD(m, buf, size, free, arg1, arg2, flags, type)		\
     (void )m_extadd((m), (caddr_t)(buf), (size), (free), (arg1), (arg2),\
-    (flags), (type), M_NOWAIT)
+    (flags), (type), NULL, 0, M_NOWAIT)
 #define	MBTOM(how)	(how)
 #define	M_DONTWAIT	M_NOWAIT
 #define	M_TRYWAIT	M_WAITOK

Modified: user/andre/mbuf_staging/sys/sf_buf.h
==============================================================================
--- user/andre/mbuf_staging/sys/sf_buf.h	Sun Oct 20 01:40:59 2013	(r256779)
+++ user/andre/mbuf_staging/sys/sf_buf.h	Sun Oct 20 09:51:36 2013	(r256780)
@@ -61,6 +61,6 @@ extern counter_u64_t sfstat[sizeof(struc
 #define	SFSTAT_INC(name)	SFSTAT_ADD(name, 1)
 #endif /* _KERNEL */
 
-int	sf_buf_mext(struct mbuf *mb, void *addr, void *args);
+int	sf_buf_mext(struct mbuf *mb, void *addr, void *args, int flags);
 
 #endif /* !_SYS_SF_BUF_H_ */


More information about the svn-src-user mailing list