Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: m_can: m_can_tx_work_queue(): fix tx_skb race condition

The m_can_start_xmit() function checks if the cdev->tx_skb is NULL and
returns with NETDEV_TX_BUSY in case tx_sbk is not NULL.

There is a race condition in the m_can_tx_work_queue(), where first
the skb is send to the driver and then the case tx_sbk is set to NULL.
A TX complete IRQ might come in between and wake the queue, which
results in tx_skb not being cleared yet.

Fixes: f524f829b75a ("can: m_can: Create a m_can platform framework")
Tested-by: Torin Cooper-Bennun <torin@maxiluxsystems.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

+2 -1
+2 -1
drivers/net/can/m_can/m_can.c
··· 1562 1562 int i; 1563 1563 int putidx; 1564 1564 1565 + cdev->tx_skb = NULL; 1566 + 1565 1567 /* Generate ID field for TX buffer Element */ 1566 1568 /* Common to all supported M_CAN versions */ 1567 1569 if (cf->can_id & CAN_EFF_FLAG) { ··· 1680 1678 tx_work); 1681 1679 1682 1680 m_can_tx_handler(cdev); 1683 - cdev->tx_skb = NULL; 1684 1681 } 1685 1682 1686 1683 static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,