From nobody Sat Sep 26 11:01:49 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1ADB637882B for ; Wed, 2 Sep 2026 08:05:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788336322; cv=none; b=PBgE/v1iAYFNcDOnRe2KEtV9OO5bTBWC7rcgbtvUpZsbZy4wynXwZkcwxpLtrUi4IuqGQLAlP79i7ty62wLfCeKMvHUR/+uzkkwVYqF60E/Gz4wJ0moXIUkpMJZa85jt6QgS57jcBm/QtHOfz209ZOcAifxvDJJc51ctDRsm34g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788336322; c=relaxed/simple; bh=pUZFzZt2uT4rZt+BibmZ5+dYY7JEFXJ02fYx4ES1Wsg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EN6b32BZqp5XgC52aarm6gXVKRxQz98f5TF8K7vGIWpc2xds3XCInXtH0Ps5D8HX1mOxyM9m84zmdwp+hEvfIJA2lRwv7NtkXM8uOCG1ePt7rjQzu0W/J5fGgTKR1gJt7z4E8/k9ew+sbKeV+bm9yoYLv78XgV3dZOsl5zibR1c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=lex.la; spf=pass smtp.mailfrom=lex.la; dkim=pass (2048-bit key) header.d=lex.la header.i=@lex.la header.b=elezhoy9; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=lex.la Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=lex.la Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=lex.la header.i=@lex.la header.b="elezhoy9" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-49b392ccaacso10357435e9.2 for ; Wed, 02 Sep 2026 01:05:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lex.la; s=google; t=1788336318; x=1788941118; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YsSeTjwDd30HnlbbrgFBLaTr0AjBlsC72GIeoJNNrpQ=; b=elezhoy9f6ED+F8fAWuPm+rv2O3qIwbDxwQ8I+vI06D8oLPoUXf4npvQ7lhXcMnap/ 2VbsBMOxHQqjK5jsiIQwKg+STgoW1vDD+InNjXxdIPdaowlP2nW7BBcZjI7H9TP+2H4a N4WVp2witNNIkVvds+iLdldnOLfXBFyPTZC6nAfiBDjuK1VvaaLLyUAVylFz3ys7SxqW saPK8nuxWoD/djcvJ6z7xoP3aeapaA8T2evJphjF0p2k34zXDUX8xUmPJAcr2QivNrwP eja6liUKMYAyvprCO28x5HameFcd9e0QSH9rk3Gz/gzDK4QCNio2RRFEuYTJw769EOXq ZtZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788336318; x=1788941118; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=YsSeTjwDd30HnlbbrgFBLaTr0AjBlsC72GIeoJNNrpQ=; b=Q6g/wxO+x+LwxBTDcj8vNV/VPPtTpVYE309gRd6yqzDmL3xjo9Dh3PEZUu0HRo9swV QTw9j6DKZkmFeIfF5iXVdWBRH4fmWSi0mN6/JfWhG8NyREABvFY+wg8cJZDkRlYKZ3Ys mCHAQdF/p+7C6WPm7U/6nW4KxXDKVgZuIScP3aKPyK7yvukLC9J3ggVoQgwdNBWMQhJN YCxtO1kqjsak6xzKEyd1qvMds/G4xSyH48a6HRGs74ESCPBPBD9N5WVRjqVJBdHl6rdP VlsZ5zPHQhWhjFqvLdqB5BvX5T2zJr77ae+x8gODW0l54ihVBZlOu9RhkGt+kAGy7fOB DP6Q== X-Forwarded-Encrypted: i=1; AHgh+RpL9hgIfOrYXTTj8Tv0OeGA2+4ImX/6DkqibKssf1GkRNrUhdKSijb+wlBPdTCKlC2KPWUUyPStMipgo8Y=@vger.kernel.org X-Gm-Message-State: AFuF++kb7uyHI7YcFaofIWqQ3f8e0uiwxLxvGF/r5znToLGXC5vWeMuW po4Gif/NSx5iL5telEboub/pNMOUFWJ5Gwy8VS2v6EmXYR/B+fFv+H/XWMW5l38EgeE= X-Gm-Gg: AR+sD13lJuts/4pFckB+mfCdxx9iRSUWWvt9Ble3EPzFCpYIPN9+lw3rAKb4nfTpEqC bBxbDjtukTdo+1q7OklA6Ma1s8zmkj9Fu4L6WD6Qu+ueRIGBp4Q0iD4WX0C/8EWzWnwRCYv0Ums 612IzUJ7xhF8/JxbGIFLPlgc5YPSesXiFCu2yFv9kK0t/Gj9BPotDiOQZN7haZkD3fW5YirV1OO 663ykFRoP2FDF7OPRw3VXc8qj9gkp37hx2m+PAjhqSl2vfNwVIbVD+j2GlgFk7geK7L7JhcMZii lsYWGQIqZsP4DpeaCDmbsBD70WUTRKcsBhSqdodpYSicnNiMr17tmQuEI4ebBoa73x0WbJTm4PR 3zE/Oy6nh3JrTuM+eHFFKRIpA3DTT2PJJvUCCfYnNku8m/eoGKq6pUlTmw6g0NZOqm/uvsVGoBx tJQl76+pCcoPryBR61qlIHCz6b53ZZzpPiJthocBbdKnQg6M8Cpw== X-Received: by 2002:a05:600c:5653:b0:49c:eb17:cf3b with SMTP id 5b1f17b1804b1-49ceb17cff4mr1786385e9.8.1788336318073; Wed, 02 Sep 2026 01:05:18 -0700 (PDT) Received: from remote-01 ([84.17.55.226]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48448e72df2sm5089494f8f.1.2026.09.02.01.05.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2026 01:05:17 -0700 (PDT) From: Aleksei Sviridkin To: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk Cc: olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net v4 1/2] net: phylink: unwind the PHY binding when bringup fails late Date: Wed, 2 Sep 2026 08:05:10 +0000 Message-ID: <20260902080511.2211261-2-f@lex.la> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260902080511.2211261-1-f@lex.la> References: <20260902080511.2211261-1-f@lex.la> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" phylink_bringup_phy() records the PHY in pl->phydev before its last fallible step: on a MAC whose phylink ops implement LPI, phy_eee_rx_clock_stop() can fail with a real MDIO error. The callers unwind with phy_detach(), which knows nothing about pl->phydev, so a pointer to a PHY that is no longer attached outlives the failed connect. What that costs depends on how the caller got here. phylink_connect_phy() and the SFP path go through phylink_attach_phy(), which refuses to attach while pl->phydev is set and turns a transient MDIO error into a permanent -EBUSY. phylink_fwnode_phy_connect() has no such check, so a later connect overwrites the stale pointer and hides the problem. A disconnect does not: phylink_disconnect_phy() hands that pointer to phy_disconnect(), and the second phy_detach() on the same PHY drops references the first one already released. Clear the binding on the failure path. This is the same operation phylink_disconnect_phy() performs, so both now share a helper. The PHY-side fields are left to phy_detach(), which every caller already runs on this path. Fixes: 03abf2a7c654 ("net: phylink: add EEE management") Signed-off-by: Aleksei Sviridkin Reviewed-by: Andrew Lunn --- drivers/net/phy/phylink.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 5b8e956902fb..a55e4a64028f 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -2083,6 +2083,18 @@ static int phylink_validate_phy(struct phylink *pl, = struct phy_device *phy, return phylink_validate(pl, supported, state); } =20 +/* Disassociate @phy from @pl. Caller must hold pl->phydev_mutex. */ +static void phylink_clear_phydev(struct phylink *pl, struct phy_device *ph= y) +{ + mutex_lock(&phy->lock); + mutex_lock(&pl->state_mutex); + pl->phydev =3D NULL; + pl->phy_enable_tx_lpi =3D false; + pl->mac_tx_clk_stop =3D false; + mutex_unlock(&pl->state_mutex); + mutex_unlock(&phy->lock); +} + static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, phy_interface_t interface) { @@ -2197,6 +2209,12 @@ static int phylink_bringup_phy(struct phylink *pl, s= truct phy_device *phy, if (ret =3D=3D 0 && phy_interrupt_is_valid(phy)) phy_request_interrupt(phy); =20 + if (ret) { + mutex_lock(&pl->phydev_mutex); + phylink_clear_phydev(pl, phy); + mutex_unlock(&pl->phydev_mutex); + } + return ret; } =20 @@ -2347,15 +2365,8 @@ void phylink_disconnect_phy(struct phylink *pl) =20 mutex_lock(&pl->phydev_mutex); phy =3D pl->phydev; - if (phy) { - mutex_lock(&phy->lock); - mutex_lock(&pl->state_mutex); - pl->phydev =3D NULL; - pl->phy_enable_tx_lpi =3D false; - pl->mac_tx_clk_stop =3D false; - mutex_unlock(&pl->state_mutex); - mutex_unlock(&phy->lock); - } + if (phy) + phylink_clear_phydev(pl, phy); mutex_unlock(&pl->phydev_mutex); =20 if (phy) { --=20 2.53.0 From nobody Sat Sep 26 11:01:49 2026 Received: from mail-ed1-f54.google.com (mail-ed1-f54.google.com [209.85.208.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E36AD3AAF60 for ; Wed, 2 Sep 2026 08:05:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788336323; cv=none; b=Cbhxd39SgYTR8V12lUCc0P9W+AJqCseMWDaHOodoTZMELnIwb/i7TCWjP4ZS+b+djFoJ3rG6KehxkCFu1SA3yC7FlivirA7KGE8aN6eVGX08UZaJR2RRZ++fIR9NnVfuUgpqXgsp4MHn6DmaA8gumA49lOqBBqlZcsrzNtI5oo4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788336323; c=relaxed/simple; bh=DSw3fF8JCXJsrODnA5Sf7B/l1fiB4DL8P+nRczSYmBE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kJWGFzC79RfYjNUwaER52vGxT9AWkez5Cv+UGf6L+nlsKRmmvMwKYuSiN98HMEDm4koyfP8yKbhPiO76/UKXGamjXa7jYavxeK/6Cq8OhjbOpAcfeY7Xfq/LEjpfvB9HcaMVG9B+EwI5TRhUxCmFh9f1eD7pOyMx4ZO6NQg20o0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=lex.la; spf=pass smtp.mailfrom=lex.la; dkim=pass (2048-bit key) header.d=lex.la header.i=@lex.la header.b=XahpOPH5; arc=none smtp.client-ip=209.85.208.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=lex.la Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=lex.la Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=lex.la header.i=@lex.la header.b="XahpOPH5" Received: by mail-ed1-f54.google.com with SMTP id 4fb4d7f45d1cf-6a65e66555cso987448a12.2 for ; Wed, 02 Sep 2026 01:05:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lex.la; s=google; t=1788336320; x=1788941120; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=YZ3n+xsQFOMjsGDSR8smrMMtR28URII33oxO3DV0Sgs=; b=XahpOPH58dgUjxtM5Q+GvnBHRfTi4k/j89Z42Tbyb6mZm4bHmyY0J08adXp1NbjtTI RwFELbSuOHMMiupN0kGe4pjg+6J7Gb7KvumpU/5Bt18whlE+pdze4s1PON+CQn6WiBRn He1LMk3P9S1dUfSnyn0zChWY4sT82gUOhvrn1kQ4IDAT9ShWurvH63C26T/t3jLUC8dl jVjCL5XgXYxdMggcys5XgpLJdPP3szEhcI9zvUSzcPnCcZWDt8l3ujLnEnQEeAu6mLgc Oye7i6fj4tzspSNxMjB+zSIP2ZkKQHICF2d2HK52JoCB+dGLRLvgcvOCjOyPZrlzD4U5 Bb4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788336320; x=1788941120; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=YZ3n+xsQFOMjsGDSR8smrMMtR28URII33oxO3DV0Sgs=; b=ffpXhZS73ngLyJraAYNdVHQtGenh+8IJAOLqsbJNKZ6zqUDH1BwNjOXvWIzJgWptxw 4W+9mgJ29ldU5BSOhdZ7EY287jsB1e04CLQEYL3YTRKle+yaoUf7twqf6OfjHq8TqMQ5 hN3rQuyOiAlTvJmsdauI40bjdKc1FSRmQiAHbjilfCcad03uvn/SdjClwqMqiRSSjFDr khkutoXeuDTCCwInuYuaKdWvQnGFeWl4i/CUwV9TEtPicoD3eivtL4n4rmIHL20E/0WZ 65dENXaw/qJwbhy6H+G3cPe08pFs6WQQAgE0NhymmQpUNSvMXvoAHNpdQZ8YIiHO+1RN j6oA== X-Forwarded-Encrypted: i=1; AKwUvByZjdFGONk/hJ9cfySj/Xlz+AFsLhu15z+FVG9g6j3QoyEjmosrJqwYDMySvc3/4uFogFn3KTWUuCo04Gk=@vger.kernel.org X-Gm-Message-State: AFuF++kNlfgQ02PQY9bJQ4ZApjcrAaGJ7U5rS1YoxSgX9+xjlWBb+YJI gEew7yxEs3QloQDorCLHUppVaI4n1vhA9q2/sfJlb1qTDLLW3H+pmLseDi6Z3QUUtqA= X-Gm-Gg: AYBFou3A41+MfSsX3dyHkymqkT7KZgOl7FNTfwSDaT+pp5vBtpim3mfkiQ1i4C7epiQ syR1f68EhRIKt6ml6FssehfUR6t3VucKMA8vC/0nTXLzHII/gkesaBuJU0bGnQhRCfB5RXMH2ca hYPrFBwrj9uwFC5XvU/keXPQN9+rLwp03RIdQk7Ew4/cs4oR+xmQE+jFgDDk2/HU8wr9C6/jhvy SsvZLaB2NDyrrsmRwF0zelD4URVWp5shMZB0AGvG8tXmbn70fphvb7XLWc/pqdLqnOrNrmQ1U7s tP62vTJxLOaFDlYh3Nq4TzgJjGjTYkchJXUvjPz65sD14/bGajyoari8HQEisdNJYFOO6uY3X+V YXbA5MlftT6DeSbCXKswJo84jcYPGgJfS+k/XToUO16jTT4xsGRoeFg0uGOnGxrSnGdPHs6jKV8 UZLIcz1dqkLvQaDbKbzOIx/FcSWjTB7nw3UIxk3btgEeLR3d9Zew== X-Received: by 2002:a05:6402:4382:b0:6a5:d7e0:626f with SMTP id 4fb4d7f45d1cf-6a68257aec8mr2037574a12.6.1788336319421; Wed, 02 Sep 2026 01:05:19 -0700 (PDT) Received: from remote-01 ([84.17.55.226]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48448e72df2sm5089494f8f.1.2026.09.02.01.05.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2026 01:05:19 -0700 (PDT) From: Aleksei Sviridkin To: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk Cc: olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net v4 2/2] net: phy: restore the interrupt after a generic-driver bind cycle Date: Wed, 2 Sep 2026 08:05:11 +0000 Message-ID: <20260902080511.2211261-3-f@lex.la> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260902080511.2211261-1-f@lex.la> References: <20260902080511.2211261-1-f@lex.la> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A PHY with no specific driver available at attach time gets the generic one, and phy_probe() sets phydev->irq to PHY_POLL because that driver has no interrupt callbacks. Neither end of that bind cycle puts the value back: phy_detach() releases the generic driver so a real one can bind later, and a generic probe that fails never reaches phy_detach() at all. The specific driver that binds afterwards therefore starts with irq =3D=3D PHY_POLL, and the PHY is polled for the rest of the uptime with no warning on that path. A DSA switch that connects its user ports before the rootfs holding the PHY driver module is mounted hits this on every boot. mdiobus_alloc() fills bus->irq[] with PHY_POLL for every address, and the bind cycle never writes to that table, so the entry still holds whatever the bus registered there. Restore phydev->irq from it on both exits, and only where the cycle left PHY_POLL. That guard preserves an interrupt mode a MAC installed on the attached PHY after connect, and it keeps a restored interrupt number out of the phy_connect_direct()/phy_disconnect() asymmetry, where such a MAC would have the interrupt requested and never freed. Fixes: 00db8189d984 ("This patch adds a PHY Abstraction Layer to the Linux = Kernel, enabling ethernet drivers to remain as ignorant as is reasonable of= the connected PHY's design and operation details.") Signed-off-by: Aleksei Sviridkin Reviewed-by: Andrew Lunn --- Both exits matter: phy_detach() for a generic driver that bound and is being released, and phy_attach_direct()'s error_module_put label for a generic probe that failed, which never calls phy_detach(). Which buses and MAC drivers the bus interrupt table covers, which other paths to PHY_POLL the guard also restores and why none of them is harmed, and the sysfs unbind case this does not cover, are worked through under v2: https://lore.kernel.org/netdev/20260824024029.41310-3-f@lex.la/ v4: reword the phy_restore_genphy_irq() comment; no code change. drivers/net/phy/phy_device.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 94b2e85e00a3..20fc29355f60 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1734,6 +1734,17 @@ static bool phy_drv_supports_irq(const struct phy_dr= iver *phydrv) return phydrv->config_intr && phydrv->handle_interrupt; } =20 +/* Undo the PHY_POLL that phy_probe() sets when a driver without + * interrupt callbacks binds. The bind cycle never writes bus->irq[], + * so the table still holds the pre-bind value; anything else the PHY + * carries did not come from the bind and must stand. + */ +static void phy_restore_genphy_irq(struct phy_device *phydev) +{ + if (phydev->irq =3D=3D PHY_POLL) + phydev->irq =3D phydev->mdio.bus->irq[phydev->mdio.addr]; +} + /** * phy_attach_direct - attach a network device to a given PHY device point= er * @dev: network device to attach @@ -1896,6 +1907,7 @@ int phy_attach_direct(struct net_device *dev, struct = phy_device *phydev, =20 error_module_put: module_put(d->driver->owner); + phy_restore_genphy_irq(phydev); phydev->is_genphy_driven =3D 0; d->driver =3D NULL; error_put_device: @@ -1965,6 +1977,7 @@ void phy_detach(struct phy_device *phydev) * real driver could be loaded */ if (phydev->is_genphy_driven) { + phy_restore_genphy_irq(phydev); device_release_driver(&phydev->mdio.dev); phydev->is_genphy_driven =3D 0; } --=20 2.53.0