[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220921083609.419768-2-mkl@pengutronix.de>
Date: Wed, 21 Sep 2022 10:36:07 +0200
From: Marc Kleine-Budde <mkl@...gutronix.de>
To: netdev@...r.kernel.org
Cc: davem@...emloft.net, kuba@...nel.org, linux-can@...r.kernel.org,
kernel@...gutronix.de, Marc Kleine-Budde <mkl@...gutronix.de>,
stable@...r.kernel.org,
Uwe Kleine-König
<u.kleine-koenig@...gutronix.de>,
Thorsten Scherer <t.scherer@...elmann.de>
Subject: [PATCH net 1/3] can: flexcan: flexcan_mailbox_read() fix return value for drop = true
The following happened on an i.MX25 using flexcan with many packets on
the bus:
The rx-offload queue reached a length more than skb_queue_len_max. In
can_rx_offload_offload_one() the drop variable was set to true which
made the call to .mailbox_read() (here: flexcan_mailbox_read()) to
_always_ return ERR_PTR(-ENOBUFS) and drop the rx'ed CAN frame. So
can_rx_offload_offload_one() returned ERR_PTR(-ENOBUFS), too.
can_rx_offload_irq_offload_fifo() looks as follows:
| while (1) {
| skb = can_rx_offload_offload_one(offload, 0);
| if (IS_ERR(skb))
| continue;
| if (!skb)
| break;
| ...
| }
The flexcan driver wrongly always returns ERR_PTR(-ENOBUFS) if drop is
requested, even if there is no CAN frame pending. As the i.MX25 is a
single core CPU, while the rx-offload processing is active, there is
no thread to process packets from the offload queue. So the queue
doesn't get any shorter and this results is a tight loop.
Instead of always returning ERR_PTR(-ENOBUFS) if drop is requested,
return NULL if no CAN frame is pending.
Changes since v1: https://lore.kernel.org/all/20220810144536.389237-1-u.kleine-koenig@pengutronix.de
- don't break in can_rx_offload_irq_offload_fifo() in case of an error,
return NULL in flexcan_mailbox_read() in case of no pending CAN frame
instead
Fixes: 4e9c9484b085 ("can: rx-offload: Prepare for CAN FD support")
Link: https://lore.kernel.org/all/20220811094254.1864367-1-mkl@pengutronix.de
Cc: stable@...r.kernel.org # v5.5
Suggested-by: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
Tested-by: Thorsten Scherer <t.scherer@...elmann.de>
Signed-off-by: Marc Kleine-Budde <mkl@...gutronix.de>
---
drivers/net/can/flexcan/flexcan-core.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
index f857968efed7..ccb438eca517 100644
--- a/drivers/net/can/flexcan/flexcan-core.c
+++ b/drivers/net/can/flexcan/flexcan-core.c
@@ -941,11 +941,6 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
u32 reg_ctrl, reg_id, reg_iflag1;
int i;
- if (unlikely(drop)) {
- skb = ERR_PTR(-ENOBUFS);
- goto mark_as_read;
- }
-
mb = flexcan_get_mb(priv, n);
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
@@ -974,6 +969,11 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
reg_ctrl = priv->read(&mb->can_ctrl);
}
+ if (unlikely(drop)) {
+ skb = ERR_PTR(-ENOBUFS);
+ goto mark_as_read;
+ }
+
if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
skb = alloc_canfd_skb(offload->dev, &cfd);
else
base-commit: 6a1dbfefdae4f7809b3e277cc76785dac0ac1cd0
--
2.35.1
Powered by blists - more mailing lists