Re: [PATCH net v2] net: usbnet: Fix the wrong netif_carrier_on() call placement
From: Simon Horman <horms@kernel.org>
Date: 2025-08-05 20:28:53
Also in:
linux-usb, lkml, stable
+ Linus On Mon, Aug 04, 2025 at 11:00:50AM +0100, Simon Horman wrote:
+ John Ernberg On Sat, Aug 02, 2025 at 02:03:10AM +0700, Ammar Faizi wrote:quoted
The commit in the Fixes tag breaks my laptop (found by git bisect). My home RJ45 LAN cable cannot connect after that commit. The call to netif_carrier_on() should be done when netif_carrier_ok() is false. Not when it's true. Because calling netif_carrier_on() when __LINK_STATE_NOCARRIER is not set actually does nothing. Cc: Armando Budianto <redacted> Cc: stable@vger.kernel.org Closes: https://lore.kernel.org/netdev/0752dee6-43d6-4e1f-81d2-4248142cccd2@gnuweeb.org (local) Fixes: 0d9cfc9b8cb1 ("net: usbnet: Avoid potential RCU stall on LINK_CHANGE event") Signed-off-by: Ammar Faizi <redacted> --- v2: - Rebase on top of the latest netdev/net tree. The previous patch was based on 0d9cfc9b8cb1. Line numbers have changed since then. drivers/net/usb/usbnet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
It seems this has escalated a bit as it broke things for Linus while he was travelling. He tested this patch and it resolved the problem. Which I think counts for something. https://lore.kernel.org/netdev/CAHk-=wgkvNuGCDUMMs9bW9Mz5o=LcMhcDK_b2ThO6_T7cquoEQ@mail.gmail.com/ (local) I have looked over the patch and it appears to me that it addresses a straightforward logic error: a check was added to turn the carrier on only if it is already on. Which seems a bit nonsensical. And presumably the intention was to add the check for the opposite case. This patch addresses that problem. So let me try and nudge this on a bit by providing a tag. Reviewed-by: Simon Horman <horms@kernel.org>
quoted
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index a38ffbf4b3f0..a1827684b92c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c@@ -1114,31 +1114,31 @@ static const struct ethtool_ops usbnet_ethtool_ops = { }; /*-------------------------------------------------------------------------*/ static void __handle_link_change(struct usbnet *dev) { if (!test_bit(EVENT_DEV_OPEN, &dev->flags)) return; if (!netif_carrier_ok(dev->net)) { + if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags)) + netif_carrier_on(dev->net); + /* kill URBs for reading packets to save bus bandwidth */ unlink_urbs(dev, &dev->rxq); /* * tx_timeout will unlink URBs for sending packets and * tx queue is stopped by netcore after link becomes off */ } else { - if (test_and_clear_bit(EVENT_LINK_CARRIER_ON, &dev->flags)) - netif_carrier_on(dev->net); - /* submitting URBs for reading packets */ queue_work(system_bh_wq, &dev->bh_work); } /* hard_mtu or rx_urb_size may change during link change */ usbnet_update_max_qlen(dev); clear_bit(EVENT_LINK_CHANGE, &dev->flags); }-- Ammar Faizi