diff options
author | sephe <sephe@FreeBSD.org> | 2016-06-15 05:16:37 +0000 |
---|---|---|
committer | sephe <sephe@FreeBSD.org> | 2016-06-15 05:16:37 +0000 |
commit | 6bb446b900c1a249fac0ca1fa639ca5c3e5b3417 (patch) | |
tree | db9d553fec5c0b0092a3037ec5d5549fe2da5ae3 /contrib/diff/lib | |
parent | 5cf8affbc8376295d083c698b4115114f54675a2 (diff) | |
download | FreeBSD-src-6bb446b900c1a249fac0ca1fa639ca5c3e5b3417.zip FreeBSD-src-6bb446b900c1a249fac0ca1fa639ca5c3e5b3417.tar.gz |
MFC 296178
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 'contrib/diff/lib')
0 files changed, 0 insertions, 0 deletions