diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2014-02-05 08:17:31 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2014-02-05 08:17:31 +0000 |
commit | 22fc39fad2aa1fe22b7d3110814d65a571988da0 (patch) | |
tree | 9010ad85572441d9f3256747bb7784ad0069385e /sys/dev/rd.c | |
parent | ddef3ca64893ac32d946aa093c985a6868b01839 (diff) |
after running myx(4) without biglock in production for a few days
i discovered that there's a race between the interrupt code and
myx_start which causes the count of free tx descriptors to get
distorted, which eventually leads to a permanent setting of
IFF_OACTIVE, which in turn prevents the driver from transmitting
packets.
fixing that went horribly wrong when i then discovered that there's
a race between the interrupt handler and myx_down, where the interrupt
can tell myx_down to wake up and free all the rings while the
interrupt handler is still looking at them. free panics for all.
this moves the handling of the tx free count under the biglock (for
now), and moves myx_up and myx_down to managing a "driver state"
variable independantly of the IFF_UP and IFF_RUNNING flags, and
very very careful reordering of the checks of that state variable
and the hardware state.
as a bonus we get to avoid excessive calls to myx_txeof and myx_rxeof
in the isr, and less stuff checked unconditionally. on the other
hand, the sc_state handling added some more checks so it might not
be a win overall.
tested on smp sparc64 with msi and nonmsi interrupts, and on amd64 smp
in production again.
Diffstat (limited to 'sys/dev/rd.c')
0 files changed, 0 insertions, 0 deletions