The ring can have a pointer to txq in it instead of an mbuf.
When this happens, we absolutely don't want to pass it to m_free().
Details
- Reviewers
mmacy scottl gallatin sbruno - Commits
- rS338372: Fix potential data corruption in iflib
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
What keeps the normal, non-IFC_QFLUSH from hitting this condition? Is the txq pointer included in r->size?
The check at line 3671 prevents it, and yes, the txq pointer is added to the ring just as though it's an mbuf, so anything looking at the ring contents needs to test against txq before assuming it's an mbuf, and it's included in r->size.
Sorry, having the ring pointer in the ring is just so odd.. Can you explain why it is there? Maybe it would be better to just not have the ring pointer in the ring and not have to have all these special cases.
I'm fighting an iflib bug myself, and every time I have to dig into the code, i'm irritated at what seems to be complexity driven by premature optimization...
As I recall, it's used to wake up the ring to send laggards. Basically, if you add items to the mp ring while there's an active consumer, those items won't be sent until the next enqueue(). Since the time to the next packet is unbounded, the txq pointer is passed to enqueue() so they get sent at that point. I suspect txq was used simply because it's a non-NULL pointer we have laying around that we know will never be a valid mbuf. @mmacy may be able to add more colour to that.
It's one of those things that is on the Big List of Things To Change.
It's a sentinel value for the reason described above. It could be any non-mbuf value - Van Jacobsen's birthday if you like.
For what it is, Van's birthday might be a better choice. Eg, some non-valid pointer that would cause free or mfree to panic rather than accept it and corrupt data.