summaryrefslogtreecommitdiff
path: root/sys/dev/rd.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2014-02-05 08:17:31 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2014-02-05 08:17:31 +0000
commit22fc39fad2aa1fe22b7d3110814d65a571988da0 (patch)
tree9010ad85572441d9f3256747bb7784ad0069385e /sys/dev/rd.c
parentddef3ca64893ac32d946aa093c985a6868b01839 (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