linux-uconsole/drivers/net/phy
Francesco Dolcini 49750c5e9a net: phy: Fix race condition on link status change
commit 91a7cda1f4 upstream.

This fixes the following error caused by a race condition between
phydev->adjust_link() and a MDIO transaction in the phy interrupt
handler. The issue was reproduced with the ethernet FEC driver and a
micrel KSZ9031 phy.

[  146.195696] fec 2188000.ethernet eth0: MDIO read timeout
[  146.201779] ------------[ cut here ]------------
[  146.206671] WARNING: CPU: 0 PID: 571 at drivers/net/phy/phy.c:942 phy_error+0x24/0x6c
[  146.214744] Modules linked in: bnep imx_vdoa imx_sdma evbug
[  146.220640] CPU: 0 PID: 571 Comm: irq/128-2188000 Not tainted 5.18.0-rc3-00080-gd569e86915b7 #9
[  146.229563] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[  146.236257]  unwind_backtrace from show_stack+0x10/0x14
[  146.241640]  show_stack from dump_stack_lvl+0x58/0x70
[  146.246841]  dump_stack_lvl from __warn+0xb4/0x24c
[  146.251772]  __warn from warn_slowpath_fmt+0x5c/0xd4
[  146.256873]  warn_slowpath_fmt from phy_error+0x24/0x6c
[  146.262249]  phy_error from kszphy_handle_interrupt+0x40/0x48
[  146.268159]  kszphy_handle_interrupt from irq_thread_fn+0x1c/0x78
[  146.274417]  irq_thread_fn from irq_thread+0xf0/0x1dc
[  146.279605]  irq_thread from kthread+0xe4/0x104
[  146.284267]  kthread from ret_from_fork+0x14/0x28
[  146.289164] Exception stack(0xe6fa1fb0 to 0xe6fa1ff8)
[  146.294448] 1fa0:                                     00000000 00000000 00000000 00000000
[  146.302842] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  146.311281] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[  146.318262] irq event stamp: 12325
[  146.321780] hardirqs last  enabled at (12333): [<c01984c4>] __up_console_sem+0x50/0x60
[  146.330013] hardirqs last disabled at (12342): [<c01984b0>] __up_console_sem+0x3c/0x60
[  146.338259] softirqs last  enabled at (12324): [<c01017f0>] __do_softirq+0x2c0/0x624
[  146.346311] softirqs last disabled at (12319): [<c01300ac>] __irq_exit_rcu+0x138/0x178
[  146.354447] ---[ end trace 0000000000000000 ]---

With the FEC driver phydev->adjust_link() calls fec_enet_adjust_link()
calls fec_stop()/fec_restart() and both these function reset and
temporary disable the FEC disrupting any MII transaction that
could be happening at the same time.

fec_enet_adjust_link() and phy_read() can be running at the same time
when we have one additional interrupt before the phy_state_machine() is
able to terminate.

Thread 1 (phylib WQ)       | Thread 2 (phy interrupt)
                           |
                           | phy_interrupt()            <-- PHY IRQ
                           |  handle_interrupt()
                           |   phy_read()
                           |   phy_trigger_machine()
                           |    --> schedule phylib WQ
                           |
                           |
phy_state_machine()        |
 phy_check_link_status()   |
  phy_link_change()        |
   phydev->adjust_link()   |
    fec_enet_adjust_link() |
     --> FEC reset         | phy_interrupt()            <-- PHY IRQ
                           |  phy_read()
                           |

Fix this by acquiring the phydev lock in phy_interrupt().

Link: https://lore.kernel.org/all/20220422152612.GA510015@francesco-nb.int.toradex.com/
Fixes: c974bdbc3e ("net: phy: Use threaded IRQ, to allow IRQ from sleeping devices")
cc: <stable@vger.kernel.org>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20220506060815.327382-1-francesco.dolcini@toradex.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[fd: backport: adapt locking before did_interrupt()/ack_interrupt()
 callbacks removal ]
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-05-18 10:23:48 +02:00
..
mscc net: phy: mscc: Add MODULE_FIRMWARE macros 2022-03-23 09:13:28 +01:00
adin.c
amd.c
aquantia.h
aquantia_hwmon.c
aquantia_main.c
at803x.c
ax88796b.c
bcm-cygnus.c
bcm-phy-lib.c net: phy: broadcom: Only advertise EEE for supported modes 2021-04-14 08:42:08 +02:00
bcm-phy-lib.h
bcm7xxx.c net: phy: bcm7xxx: Fixed indirect MMD operations 2021-10-06 15:55:58 +02:00
bcm63xx.c
bcm87xx.c
bcm54140.c
bcm84881.c
broadcom.c net: phy: broadcom: Fix brcm_fet_config_init() 2022-04-08 14:40:29 +02:00
cicada.c
cortina.c
davicom.c
dp83tc811.c
dp83640.c
dp83640_reg.h ptp: dp83640: don't define PAGE0 2021-09-22 12:27:56 +02:00
dp83822.c net: phy: DP83822: clear MISR2 register to disable interrupts 2022-03-16 14:15:59 +01:00
dp83848.c
dp83867.c net: phy: dp83867: perform soft reset and retain established link 2021-06-30 08:47:21 -04:00
dp83869.c net: phy: introduce phydev->port 2021-03-30 14:32:05 +02:00
et1011c.c
fixed_phy.c
icplus.c
intel-xway.c net: phy: intel-xway: enable integrated led functions 2021-05-14 09:50:41 +02:00
Kconfig
linkmode.c
lxt.c net: phy: introduce phydev->port 2021-03-30 14:32:05 +02:00
Makefile
marvell.c net: phy: marvell: Fix invalid comparison in the resume and suspend functions 2022-03-23 09:13:27 +01:00
marvell10g.c net: phy: marvell10g: fix return value on error 2022-05-09 09:05:05 +02:00
mdio-boardinfo.c
mdio-boardinfo.h
mdio_bus.c net: mdio: Demote probed message to debug print 2022-01-27 10:54:19 +01:00
mdio_device.c net: mdio: introduce a shutdown method to mdio device drivers 2021-10-09 14:40:56 +02:00
mdio_devres.c
meson-gxl.c
micrel.c phy: micrel: ksz8041nl: do not use power down mode 2021-11-18 14:04:09 +01:00
microchip.c
microchip_t1.c
mii_timestamper.c
national.c
nxp-tja11xx.c
phy-c45.c
phy-core.c net: phy: prefer 1000baseT over 1000baseKX 2022-01-27 10:54:15 +01:00
phy.c net: phy: Fix race condition on link status change 2022-05-18 10:23:48 +02:00
phy_device.c phylib: fix potential use-after-free 2022-02-01 17:25:45 +01:00
phy_led_triggers.c
phylink.c net: phylink: Force retrigger in case of latched link-fail indicator 2021-12-01 09:19:07 +01:00
qsemi.c
realtek.c net: phy: realtek: add delay to fix RXC generation issue 2021-07-19 09:44:49 +02:00
rockchip.c
sfp-bus.c net: sfp: add 2500base-X quirk for Lantech SFP module 2022-04-13 21:01:00 +02:00
sfp.c net: sfp: Add tx-fault workaround for Huawei MA5671A SFP ONT 2022-05-18 10:23:45 +02:00
sfp.h
smsc.c net: phy: lan87xx: fix access to wrong register of LAN87xx 2021-05-14 09:50:31 +02:00
spi_ks8995.c
ste10Xp.c
swphy.c
swphy.h
teranetics.c
uPD60620.c
vitesse.c
xilinx_gmii2rgmii.c