Sepherosa Ziehau 1321c5029e 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
2016-02-29 03:54:51 +00:00
..
2015-08-24 23:40:36 +00:00
2014-11-21 01:22:33 +00:00
2014-10-05 21:27:26 +00:00
2015-09-10 05:59:39 +00:00
2015-10-03 09:15:23 +00:00
2015-04-21 10:35:23 +00:00
2015-04-07 21:31:17 +00:00
2015-12-16 09:18:20 +00:00
2014-10-20 14:42:42 +00:00
2016-01-22 15:11:40 +00:00
2016-02-03 11:49:51 +00:00