This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new bbc0a581c54 drivers/can/ctucanfd_pci.c: fix interupt storm for
SocketCAN
bbc0a581c54 is described below
commit bbc0a581c54d638c8ce3b1936582bbe46bd3f629
Author: p-szafonimateusz <[email protected]>
AuthorDate: Wed Nov 12 12:18:08 2025 +0800
drivers/can/ctucanfd_pci.c: fix interupt storm for SocketCAN
Fix interrupt storm for SocketCAN when many CAN devices are enabled.
Many CAN devices share the same interrupt line, sow we have to disable
all available devices interrupts when we handle device interrupt.
Otherwise we may get stuck in a state where we are unable to exit
from the interrupt handler.
Cherry-picked from open-vela/nuttx commit
7aae5a84b5c4039008c1cef47ff930c02995939f
(https://github.com/open-vela/nuttx/commit/7aae5a84b5c4039008c1cef47ff930c02995939f).
Signed-off-by: p-szafonimateusz <[email protected]>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: raiden00pl <[email protected]>
---
drivers/can/ctucanfd_pci.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/can/ctucanfd_pci.c b/drivers/can/ctucanfd_pci.c
index 18be3272874..a8b92c8fe3d 100644
--- a/drivers/can/ctucanfd_pci.c
+++ b/drivers/can/ctucanfd_pci.c
@@ -931,6 +931,10 @@ static void ctucanfd_chardev_interrupt(FAR struct
ctucanfd_driver_s *priv)
stat = ctucanfd_getreg(&priv->devs[i], CTUCANFD_INTSTAT);
if (stat == 0)
{
+ /* Re-enable RX/TX interrupts */
+
+ ctucanfd_txint(&priv->devs[i], true);
+ ctucanfd_rxint(&priv->devs[i], true);
continue;
}
@@ -1486,6 +1490,10 @@ static void ctucanfd_sock_interrupt(FAR struct
ctucanfd_driver_s *priv)
stat = ctucanfd_getreg(&priv->devs[i], CTUCANFD_INTSTAT);
if (stat == 0)
{
+ /* Re-enable RX/TX interrupts */
+
+ ctucanfd_txint(&priv->devs[i], true);
+ ctucanfd_rxint(&priv->devs[i], true);
continue;
}
@@ -1547,21 +1555,11 @@ static int ctucanfd_interrupt(int irq, FAR void
*context, FAR void *arg)
DEBUGASSERT(priv != NULL);
+ /* Check for any pending interrupt */
+
for (i = 0; i < priv->count; i++)
{
regval |= ctucanfd_getreg(&priv->devs[i], CTUCANFD_INTSTAT);
-
- /* Break now if interrupt is pending */
-
- if (regval != 0)
- {
- /* Disable RX/TX interrupts until we are done */
-
- ctucanfd_rxint(&priv->devs[i], false);
- ctucanfd_txint(&priv->devs[i], false);
-
- break;
- }
}
/* Check for pending interrupts for this card */
@@ -1571,6 +1569,19 @@ static int ctucanfd_interrupt(int irq, FAR void
*context, FAR void *arg)
return OK;
}
+ else
+ {
+ /* Disable all RX/TX interrupts for this card until all pending
+ * interrupts are handled.
+ */
+
+ for (i = 0; i < priv->count; i++)
+ {
+ ctucanfd_rxint(&priv->devs[i], false);
+ ctucanfd_txint(&priv->devs[i], false);
+ }
+ }
+
#ifdef CONFIG_CAN_CTUCANFD_CHARDEV
/* Handle character device interrupt */