| From 382784ee4ac867828e30f27b1bde61dc6fa232d9 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 5 May 2021 13:32:27 +0200 |
| Subject: can: m_can: m_can_tx_work_queue(): fix tx_skb race condition |
| |
| From: Marc Kleine-Budde <mkl@pengutronix.de> |
| |
| [ Upstream commit e04b2cfe61072c7966e1a5fb73dd1feb30c206ed ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/can/m_can/m_can.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c |
| index 6f0bf5db885c..62bcef4bb95f 100644 |
| --- a/drivers/net/can/m_can/m_can.c |
| +++ b/drivers/net/can/m_can/m_can.c |
| @@ -1466,6 +1466,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev) |
| int i; |
| int putidx; |
| |
| + cdev->tx_skb = NULL; |
| + |
| /* Generate ID field for TX buffer Element */ |
| /* Common to all supported M_CAN versions */ |
| if (cf->can_id & CAN_EFF_FLAG) { |
| @@ -1582,7 +1584,6 @@ static void m_can_tx_work_queue(struct work_struct *ws) |
| tx_work); |
| |
| m_can_tx_handler(cdev); |
| - cdev->tx_skb = NULL; |
| } |
| |
| static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, |
| -- |
| 2.30.2 |
| |