diff options
author | Ben Hutchings <ben.hutchings@codethink.co.uk> | 2015-01-22 15:44:08 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-01-27 03:13:15 +0300 |
commit | 283e38db65e77be9bbe2d455452584ee7834e4e9 (patch) | |
tree | f1997cddb44f8d5fe7316658e9d0556f47a40051 /drivers/w1/masters | |
parent | 084236d8c53952f14b5cb1741311c80c7fbe8289 (diff) | |
download | linux-283e38db65e77be9bbe2d455452584ee7834e4e9.tar.xz |
sh_eth: Fix serialisation of interrupt disable with interrupt & NAPI handlers
In order to stop the RX path accessing the RX ring while it's being
stopped or resized, we clear the interrupt mask (EESIPR) and then call
free_irq() or synchronise_irq(). This is insufficient because the
interrupt handler or NAPI poller may set EESIPR again after we clear
it. Also, in sh_eth_set_ringparam() we currently don't disable NAPI
polling at all.
I could easily trigger a crash by running the loop:
while ethtool -G eth0 rx 128 && ethtool -G eth0 rx 64; do echo -n .; done
and 'ping -f' toward the sh_eth port from another machine.
To fix this:
- Add a software flag (irq_enabled) to signal whether interrupts
should be enabled
- In the interrupt handler, if the flag is clear then clear EESIPR
and return
- In the NAPI poller, if the flag is clear then don't set EESIPR
- Set the flag before enabling interrupts in sh_eth_dev_init() and
sh_eth_set_ringparam()
- Clear the flag and serialise with the interrupt and NAPI
handlers before clearing EESIPR in sh_eth_close() and
sh_eth_set_ringparam()
After this, I could run the loop for 100,000 iterations successfully.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/w1/masters')
0 files changed, 0 insertions, 0 deletions