Page MenuHomeFreeBSD

D44371.diff
No OneTemporary

D44371.diff

diff --git a/sys/dev/netmap/netmap_generic.c b/sys/dev/netmap/netmap_generic.c
--- a/sys/dev/netmap/netmap_generic.c
+++ b/sys/dev/netmap/netmap_generic.c
@@ -256,7 +256,7 @@
* TX event is consumed. */
mtx_lock_spin(&kring->tx_event_lock);
if (kring->tx_event) {
- SET_MBUF_DESTRUCTOR(kring->tx_event, NULL);
+ SET_MBUF_DESTRUCTOR(kring->tx_event, NULL, NULL);
}
kring->tx_event = NULL;
mtx_unlock_spin(&kring->tx_event_lock);
@@ -271,16 +271,18 @@
for_each_tx_kring(r, kring, na) {
callout_drain(&kring->tx_event_callout);
- mtx_destroy(&kring->tx_event_lock);
+
if (kring->tx_pool == NULL) {
continue;
}
for (i=0; i<na->num_tx_desc; i++) {
if (kring->tx_pool[i]) {
- m_freem(kring->tx_pool[i]);
+ m_free(kring->tx_pool[i]);
+ kring->tx_pool[i] = NULL;
}
}
+ mtx_destroy(&kring->tx_event_lock);
nm_os_free(kring->tx_pool);
kring->tx_pool = NULL;
}
@@ -434,7 +436,7 @@
static void
generic_mbuf_dtor(struct mbuf *m)
{
- struct netmap_adapter *na = NA(GEN_TX_MBUF_IFP(m));
+ struct netmap_adapter *na = GEN_TX_MBUF_NA(m);
struct netmap_kring *kring;
unsigned int r = MBUF_TXQ(m);
unsigned int r_orig = r;
@@ -458,6 +460,18 @@
kring = na->tx_rings[r];
mtx_lock_spin(&kring->tx_event_lock);
+
+ /*
+ * The netmap destructor can be called between us getting the
+ * reference and taking the lock, in that case the ring
+ * reference won't be valid. The destructor will free this mbuf
+ * so we can stop here.
+ */
+ if (GEN_TX_MBUF_NA(m) == NULL) {
+ mtx_unlock_spin(&kring->tx_event_lock);
+ return;
+ }
+
if (kring->tx_event == m) {
kring->tx_event = NULL;
match = true;
@@ -525,7 +539,7 @@
/* This mbuf has been dequeued but is still busy
* (refcount is 2).
* Leave it to the driver and replenish. */
- m_freem(m);
+ m_free(m);
tx_pool[nm_i] = NULL;
}
@@ -638,7 +652,8 @@
return;
}
- SET_MBUF_DESTRUCTOR(m, generic_mbuf_dtor);
+ SET_MBUF_DESTRUCTOR(m, generic_mbuf_dtor, kring->na);
+
kring->tx_event = m;
#ifdef __FreeBSD__
/*
@@ -664,7 +679,7 @@
/* Decrement the refcount. This will free it if we lose the race
* with the driver. */
- m_freem(m);
+ m_free(m);
}
/*
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -102,6 +102,7 @@
#define MBUF_TXQ(m) ((m)->m_pkthdr.flowid)
#define MBUF_TRANSMIT(na, ifp, m) ((na)->if_transmit(ifp, m))
#define GEN_TX_MBUF_IFP(m) ((m)->m_pkthdr.rcvif)
+#define GEN_TX_MBUF_NA(m) ((struct netmap_adapter *)(m)->m_ext.ext_arg1)
#define NM_ATOMIC_T volatile int /* required by atomic/bitops.h */
/* atomic operations */
@@ -2395,9 +2396,10 @@
uma_zfree(zone_clust, m->m_ext.ext_buf);
}
-#define SET_MBUF_DESTRUCTOR(m, fn) do { \
+#define SET_MBUF_DESTRUCTOR(m, fn, na) do { \
(m)->m_ext.ext_free = (fn != NULL) ? \
(void *)fn : (void *)nm_generic_mbuf_dtor; \
+ (m)->m_ext.ext_arg1 = na; \
} while (0)
static inline struct mbuf *

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 11, 12:00 AM (16 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15748135
Default Alt Text
D44371.diff (3 KB)

Event Timeline