Home
last modified time | relevance | path

Searched hist:"7 a16807ce149d4e9cd53facca0cff6a4a647b6be" (Results 1 – 1 of 1) sorted by relevance

/linux/drivers/net/ethernet/freescale/
H A Dfec_main.cdiff 7a16807ce149d4e9cd53facca0cff6a4a647b6be Tue Jul 08 01:22:44 CEST 2014 Russell King <rmk+kernel@arm.linux.org.uk> net: fec: fix interrupt handling races

While running: while :; do iperf -c <HOST> -P 4; done, transmit timeouts
are regularly reported. With the tx ring dumping in place, we can see
that all entries are in use, and the hardware has finished transmitting
these packets. However, the driver has not reclaimed these ring
entries.

This can occur if the interrupt handler is invoked at the wrong moment -
eg:

CPU0 CPU1
fec_enet_tx()
interrupt, IEVENT = FEC_ENET_TXF
FEC_ENET_TXF cleared
napi_schedule_prep()
napi_complete()

The result is that we clear the transmit interrupt, but we don't trigger
any cleaning of the transmit ring. Instead, use a different strategy:

- When receiving a transmit or receive interrupt, disable both tx and rx
interrupts, but do not acknowledge them. Schedule a napi poll. Don't
loop.

- When we are polled, read IEVENT, acknowledging the pending transmit
and receive interrupts, before then going on to process the
appropriate rings.

This allows us to avoid the race, and has a number of other advantages:
- we cut down on the number of transmit interrupts we have to process.
- we only look at the rings which have pending events.
- we gain additional throughput: the iperf total bandwidth increases
from about 180Mbps to 240Mbps:

[ 3] 0.0-10.0 sec 68.1 MBytes 57.0 Mbits/sec
[ 5] 0.0-10.0 sec 72.4 MBytes 60.5 Mbits/sec
[ 4] 0.0-10.1 sec 76.1 MBytes 63.5 Mbits/sec
[ 6] 0.0-10.1 sec 71.9 MBytes 59.9 Mbits/sec
[SUM] 0.0-10.1 sec 288 MBytes 241 Mbits/sec

Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>