Page MenuHomeFreeBSD

bridgestp: Defer media queries outside the network epoch
Needs ReviewPublic

Authored by kbowling on Sun, Sep 20, 12:28 AM.
Tags
None
Referenced Files
F175361977: D59850.id187250.diff
Sat, Oct 10, 7:17 AM
Unknown Object (File)
Thu, Oct 8, 10:05 PM
Unknown Object (File)
Tue, Oct 6, 3:29 PM
Unknown Object (File)
Fri, Oct 2, 6:11 PM
Unknown Object (File)
Thu, Oct 1, 9:55 AM
Unknown Object (File)
Thu, Oct 1, 7:23 AM
Unknown Object (File)
Wed, Sep 30, 7:04 PM
Unknown Object (File)
Wed, Sep 30, 3:21 PM

Details

Summary
bridge_linkstate() calls bstp_linkstate() inside the network epoch, but
the SIOCGIFMEDIA ioctl can acquire sleepable driver locks and wait for
hardware. Reuse the port's media task on taskqueue_thread for link events
and existing media polling. Query in the interface's VNET without an
epoch or BSTP mutex, then recheck port activity and update STP under the
mutex and an epoch, since the state update can transmit BPDUs.

Run the subsequent STP state update for every media refresh, including
polling and reinitialization. This preserves query before update ordering
for link events and lets other refreshes process pending transitions
without waiting for the next STP tick. It does not add media queries or
increase the existing polling frequency.

Serialize link and packet input admission with port disable so late
callbacks cannot enqueue work after teardown drains it. Initialize STP
before publishing the bridge member. Drain media work before the
notifications it can generate, and keep the member's bridge pointer valid
until all of those callbacks finish. Wait for old epoch readers before
destroying the BSTP mutex, and protect the final root-port cleanup with
the mutex and an epoch.

PR:             264549
Reported by:    mfbott <bugaddress@posteo.net>
MFC after:      2 weeks

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

sys/net/bridgestp.c
1798

This feels kind of weird. bridge_linkstate() is already running as an asynchronous task; it enters a network epoch and now here we are deferring some of the work again because of that. Why can't bridge_linkstate() instead take the (sleepable) bridge lock?

2206

Can't you use taskqueue_drain() instead? NET_EPOCH_WAIT() is a heavy hammer.

Unfortunately, I'm not expert on bridge driver.

sys/net/bridgestp.c
1795

Maybe KASSERT that?