summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-02-29 03:54:51 +0000
committersephe <sephe@FreeBSD.org>2016-02-29 03:54:51 +0000
commit0123218eb81ffcbe8643dfa06e722180f4a0b4f2 (patch)
tree77de2c9b3975e06502ae6969f455de2fcfce40d3 /sys/net
parent8bf1194fe59ab6a4905efd0ff00cd6b7462247e1 (diff)
downloadFreeBSD-src-0123218eb81ffcbe8643dfa06e722180f4a0b4f2.zip
FreeBSD-src-0123218eb81ffcbe8643dfa06e722180f4a0b4f2.tar.gz
buf_ring/drbr: Add buf_ring_peek_clear_sc and use it in drbr_peek
Unlike buf_ring_peek, it only supports single consumer mode, and it clears the cons_head if DEBUG_BUFRING/INVARIANTS is defined. The normal use case of drbr_peek for network drivers is: m = drbr_peek(br); err = hw_spec_encap(&m); /* could m_defrag/m_collapse */ (*) if (err) { if (m == NULL) drbr_advance(br); else drbr_putback(br, m); /* break the loop */ } drbr_advance(br); The race is: If hw_spec_encap() m_defrag or m_collapse the mbuf, i.e. the old mbuf was freed, or like the Hyper-V's network driver, that transmission- done does not even require the TX lock; then on the other CPU at the (*) time, the freed mbuf could be recycled and being drbr_enqueue even before the current CPU had the chance to call drbr_{advance,putback}. This triggers a panic in drbr_enqueue duplicated element check, if DEBUG_BUFRING/INVARIANTS is defined. Use buf_ring_peek_clear_sc() in drbr_peek() to fix the above race. This change is a NO-OP, if neither DEBUG_BUFRING nor INVARIANTS are defined. MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5416
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/ifq.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/net/ifq.h b/sys/net/ifq.h
index 769d5a5..98a84aa 100644
--- a/sys/net/ifq.h
+++ b/sys/net/ifq.h
@@ -369,7 +369,7 @@ drbr_peek(struct ifnet *ifp, struct buf_ring *br)
return (m);
}
#endif
- return(buf_ring_peek(br));
+ return(buf_ring_peek_clear_sc(br));
}
static __inline void
OpenPOWER on IntegriCloud