mirror of https://github.com/torvalds/linux.git
A number of tx queue wake-up events went missing due to the outlined scenario below. Start state is a pool of 16 tx URBs, active tx_urbs count = 15, with the netdev tx queue open. CPU #1 [softirq] CPU #2 [softirq] start_xmit() tx_acknowledge() ................ ................ atomic_inc(&tx_urbs); if (atomic_read(&tx_urbs) >= 16) { --> atomic_dec(&tx_urbs); netif_wake_queue(); return; <-- netif_stop_queue(); } At the end, the correct state expected is a 15 tx_urbs count value with the tx queue state _open_. Due to the race, we get the same tx_urbs value but with the tx queue state _stopped_. The wake-up event is completely lost. Thus avoid hand-rolled concurrency mechanisms and use a proper lock for contexts and tx queue protection. Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com> Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> |
||
|---|---|---|
| .. | ||
| c_can | ||
| cc770 | ||
| m_can | ||
| mscan | ||
| sja1000 | ||
| softing | ||
| spi | ||
| usb | ||
| Kconfig | ||
| Makefile | ||
| at91_can.c | ||
| bfin_can.c | ||
| dev.c | ||
| flexcan.c | ||
| grcan.c | ||
| janz-ican3.c | ||
| led.c | ||
| pch_can.c | ||
| rcar_can.c | ||
| slcan.c | ||
| ti_hecc.c | ||
| vcan.c | ||
| xilinx_can.c | ||