Page MenuHomeFreeBSD

rge: Preserve replacement mbufs after defragmentation
ClosedPublic

Authored by markj on Tue, Sep 29, 7:31 PM.
Referenced Files
F174152538: D60142.id188138.diff
Wed, Sep 30, 11:24 PM
F174151649: D60142.id188089.diff
Wed, Sep 30, 11:16 PM
F174151435: D60142.diff
Wed, Sep 30, 11:14 PM
F174102059: D60142.id188138.diff
Wed, Sep 30, 3:43 PM
F174101871: D60142.id188089.diff
Wed, Sep 30, 3:42 PM
Unknown Object (File)
Wed, Sep 30, 5:11 AM
Unknown Object (File)
Wed, Sep 30, 3:06 AM
Unknown Object (File)
Wed, Sep 30, 2:36 AM
Subscribers

Details

Summary

m_defrag() has pointer-return ownership semantics: success frees the
original chain and returns a replacement, while failure returns NULL and
leaves the original owned by the caller. rge_encap() compared that
pointer as an integer status and could return failure after success,
causing rge_tx_task() to free its stale old head.

Pass the mbuf by reference, retain the replacement returned by
m_defrag(), and publish it to the caller before retrying DMA mapping. A
later mapping failure is then cleaned up through the current chain, and
a successful transmission uses that same chain for BPF and TX ownership.

An unprivileged process can reach the EFBIG branch in mapped-sendfile
mode.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

markj requested review of this revision.Tue, Sep 29, 7:31 PM
adrian added a project: drivers.

nice catch! thanks!

This revision is now accepted and ready to land.Tue, Sep 29, 7:59 PM
sys/dev/rge/if_rge.c
2507–2508

Maybe add a note here, something like /* Note: m can change due to m_defrag() */

This revision was automatically updated to reflect the committed changes.
markj marked an inline comment as done.