Ahmed S. Darwish a9dc960c37 can: kvaser_usb: Fix tx queue start/stop race conditions
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>
2015-03-14 09:20:07 +01:00
..
2015-03-06 01:29:16 +01:00
2015-03-02 12:08:43 -05:00
2015-02-17 09:27:54 -08:00
2015-03-06 22:35:49 +01:00
2015-02-15 10:48:44 -08:00
2015-02-12 09:16:56 -08:00
2015-02-03 15:48:51 -08:00
2015-02-25 11:38:46 +11:00
2015-02-03 15:58:39 -08:00
2015-02-18 09:05:48 -08:00
2015-02-18 08:01:44 -08:00
2015-02-04 09:15:18 +01:00
2015-02-18 09:43:46 -08:00
2015-02-17 09:38:59 -08:00
2015-02-15 10:24:55 -08:00
2015-02-18 08:40:29 +01:00
2015-03-06 01:29:05 +01:00
2015-02-21 19:16:42 -08:00
2015-02-17 09:38:59 -08:00
2015-03-08 12:25:40 -07:00
2015-03-08 12:47:18 -07:00
2015-02-15 10:24:55 -08:00
2015-02-03 15:58:39 -08:00