[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250924173035.4148131-3-stefan.maetje@esd.eu>
Date: Wed, 24 Sep 2025 19:30:34 +0200
From: Stefan Mätje <stefan.maetje@....eu>
To: Frank Jungclaus <frank.jungclaus@....eu>,
Marc Kleine-Budde <mkl@...gutronix.de>,
Vincent Mailhol <mailhol@...nel.org>,
linux-can@...r.kernel.org,
socketcan@....eu
Cc: "David S . Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Oliver Hartkopp <socketcan@...tkopp.net>,
Simon Horman <horms@...nel.org>,
Wolfgang Grandegger <wg@...ndegger.com>,
netdev@...r.kernel.org
Subject: [PATCH v3 2/3] can: esd_usb: Fix handling of TX context objects
For each TX CAN frame submitted to the USB device the driver saves the
echo skb index in struct esd_tx_urb_context context objects. If the
driver runs out of free context objects CAN transmission stops.
Fix some spots where such context objects are not freed correctly.
In esd_usb_tx_done_msg() move the check for netif_device_present()
after the identification and release of TX context and the release of
the echo skb. This is allowed even if netif_device_present() would
return false because the mentioned operations don't touch the device
itself but only free local acquired resources. This keeps the context
handling with the acknowledged TX jobs in sync.
esd_usb_start_xmit() performs a check to see whether a context
object could be allocated. Add a netif_stop_queue() there before the
function is aborted. This makes sure the network queue is stopped and
avoids getting tons of log messages in a situation without free TX
objects. The adjacent log message now also prints the active jobs
counter making a cross check between active jobs and "no free context"
condition possible and is rate limited by net_ratelimit().
In esd_usb_start_xmit() the error handling of usb_submit_urb() missed to
free the context object together with the echo skb and decreasing the
job count.
Fixes: 96d8e90382dc ("can: Add driver for esd CAN-USB/2 device")
Signed-off-by: Stefan Mätje <stefan.maetje@....eu>
Link: https://patch.msgid.link/20250821143422.3567029-3-stefan.maetje@esd.eu
[mkl: minor change patch description to imperative language]
Signed-off-by: Marc Kleine-Budde <mkl@...gutronix.de>
---
drivers/net/can/usb/esd_usb.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
index ed1d6ba779dc..588ec02b9b21 100644
--- a/drivers/net/can/usb/esd_usb.c
+++ b/drivers/net/can/usb/esd_usb.c
@@ -460,9 +460,6 @@ static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv,
struct net_device *netdev = priv->netdev;
struct esd_tx_urb_context *context;
- if (!netif_device_present(netdev))
- return;
-
context = &priv->tx_contexts[msg->txdone.hnd & (ESD_USB_MAX_TX_URBS - 1)];
if (!msg->txdone.status) {
@@ -478,6 +475,9 @@ static void esd_usb_tx_done_msg(struct esd_usb_net_priv *priv,
context->echo_index = ESD_USB_MAX_TX_URBS;
atomic_dec(&priv->active_tx_jobs);
+ if (!netif_device_present(netdev))
+ return;
+
netif_wake_queue(netdev);
}
@@ -975,9 +975,12 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
}
}
- /* This may never happen */
+ /* This should never happen */
if (!context) {
- netdev_warn(netdev, "couldn't find free context\n");
+ if (net_ratelimit())
+ netdev_warn(netdev, "No free context. Jobs: %d\n",
+ atomic_read(&priv->active_tx_jobs));
+ netif_stop_queue(netdev);
ret = NETDEV_TX_BUSY;
goto releasebuf;
}
@@ -1008,6 +1011,8 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
if (err) {
can_free_echo_skb(netdev, context->echo_index, NULL);
+ /* Release used context on error */
+ context->echo_index = ESD_USB_MAX_TX_URBS;
atomic_dec(&priv->active_tx_jobs);
usb_unanchor_urb(urb);
--
2.34.1
Powered by blists - more mailing lists