Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Jun 2014 16:07:00 +0000 (UTC)
From:      Luigi Rizzo <luigi@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r267328 - head/sys/dev/netmap
Message-ID:  <201406101607.s5AG70fN080054@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: luigi
Date: Tue Jun 10 16:06:59 2014
New Revision: 267328
URL: http://svnweb.freebsd.org/changeset/base/267328

Log:
  change the netmap mbuf destructor so the same code works also on FreeBSD 9.
  For head and 10 this change has no effect, but on stable/9 it would cause
  panics when using emulated netmap on top of a standard device driver.

Modified:
  head/sys/dev/netmap/netmap_generic.c

Modified: head/sys/dev/netmap/netmap_generic.c
==============================================================================
--- head/sys/dev/netmap/netmap_generic.c	Tue Jun 10 15:20:41 2014	(r267327)
+++ head/sys/dev/netmap/netmap_generic.c	Tue Jun 10 16:06:59 2014	(r267328)
@@ -102,24 +102,30 @@ __FBSDID("$FreeBSD$");
  * mbuf wrappers
  */
 
-/* mbuf destructor, also need to change the type to EXT_EXTREF,
+/*
+ * mbuf destructor, also need to change the type to EXT_EXTREF,
  * add an M_NOFREE flag, and then clear the flag and
  * chain into uma_zfree(zone_pack, mf)
  * (or reinstall the buffer ?)
+ *
+ * On FreeBSD 9 the destructor is called as ext_free(ext_arg1, ext_arg2)
+ * whereas newer version have ext_free(m, ext_arg1, ext_arg2)
+ * For compatibility we set ext_arg1 = m on allocation so we have
+ * the same code on both.
  */
 #define SET_MBUF_DESTRUCTOR(m, fn)	do {		\
-	(m)->m_ext.ext_free = (void *)fn;	\
-	(m)->m_ext.ext_type = EXT_EXTREF;	\
-} while (0)
+		(m)->m_ext.ext_free = (void *)fn;	\
+		(m)->m_ext.ext_type = EXT_EXTREF;	\
+	} while (0)
 
 static void 
-netmap_default_mbuf_destructor(struct mbuf *m) 
+netmap_default_mbuf_destructor(struct mbuf *m)
 { 
-	/* restore original mbuf */
-	m->m_ext.ext_buf = m->m_data = m->m_ext.ext_arg1;
-	m->m_ext.ext_arg1 = NULL;
+	/* restore original data pointer and type */
+	m->m_ext.ext_buf = m->m_data = m->m_ext.ext_arg2;
 	m->m_ext.ext_type = EXT_PACKET;
 	m->m_ext.ext_free = NULL;
+	m->m_ext.ext_arg1 = m->m_ext.ext_arg2 = NULL;
 	if (*(m->m_ext.ref_cnt) == 0)
 		*(m->m_ext.ref_cnt) = 1;
 	uma_zfree(zone_pack, m);
@@ -131,7 +137,8 @@ netmap_get_mbuf(int len) 
 	struct mbuf *m;
 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR | M_NOFREE);
 	if (m) {
-		m->m_ext.ext_arg1 = m->m_ext.ext_buf; // XXX save
+		m->m_ext.ext_arg1 = m; /* FreeBSD 9 compat */
+		m->m_ext.ext_arg2 = m->m_ext.ext_buf; /* save original */
 		m->m_ext.ext_free = (void *)netmap_default_mbuf_destructor;
 		m->m_ext.ext_type = EXT_EXTREF;
 		ND(5, "create m %p refcnt %d", m, *m->m_ext.ref_cnt);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406101607.s5AG70fN080054>