Alexander Sverdlin
4dc0484e90
net: dsa: lan9303: consequently nested-lock physical MDIO
...
commit 5a22fbcc10f3f7d94c5d88afbbffa240a3677057 upstream.
When LAN9303 is MDIO-connected two callchains exist into
mdio->bus->write():
1. switch ports 1&2 ("physical" PHYs):
virtual (switch-internal) MDIO bus (lan9303_switch_ops->phy_{read|write})->
lan9303_mdio_phy_{read|write} -> mdiobus_{read|write}_nested
2. LAN9303 virtual PHY:
virtual MDIO bus (lan9303_phy_{read|write}) ->
lan9303_virt_phy_reg_{read|write} -> regmap -> lan9303_mdio_{read|write}
If the latter functions just take
mutex_lock(&sw_dev->device->bus->mdio_lock) it triggers a LOCKDEP
false-positive splat. It's false-positive because the first
mdio_lock in the second callchain above belongs to virtual MDIO bus, the
second mdio_lock belongs to physical MDIO bus.
Consequent annotation in lan9303_mdio_{read|write} as nested lock
(similar to lan9303_mdio_phy_{read|write}, it's the same physical MDIO bus)
prevents the following splat:
WARNING: possible circular locking dependency detected
5.15.71 #1 Not tainted
------------------------------------------------------
kworker/u4:3/609 is trying to acquire lock:
ffff000011531c68 (lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock){+.+.}-{3:3}, at: regmap_lock_mutex
but task is already holding lock:
ffff0000114c44d8 (&bus->mdio_lock){+.+.}-{3:3}, at: mdiobus_read
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&bus->mdio_lock){+.+.}-{3:3}:
lock_acquire
__mutex_lock
mutex_lock_nested
lan9303_mdio_read
_regmap_read
regmap_read
lan9303_probe
lan9303_mdio_probe
mdio_probe
really_probe
__driver_probe_device
driver_probe_device
__device_attach_driver
bus_for_each_drv
__device_attach
device_initial_probe
bus_probe_device
deferred_probe_work_func
process_one_work
worker_thread
kthread
ret_from_fork
-> #0 (lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock){+.+.}-{3:3}:
__lock_acquire
lock_acquire.part.0
lock_acquire
__mutex_lock
mutex_lock_nested
regmap_lock_mutex
regmap_read
lan9303_phy_read
dsa_slave_phy_read
__mdiobus_read
mdiobus_read
get_phy_device
mdiobus_scan
__mdiobus_register
dsa_register_switch
lan9303_probe
lan9303_mdio_probe
mdio_probe
really_probe
__driver_probe_device
driver_probe_device
__device_attach_driver
bus_for_each_drv
__device_attach
device_initial_probe
bus_probe_device
deferred_probe_work_func
process_one_work
worker_thread
kthread
ret_from_fork
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&bus->mdio_lock);
lock(lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock);
lock(&bus->mdio_lock);
lock(lan9303_mdio:131:(&lan9303_mdio_regmap_config)->lock);
*** DEADLOCK ***
5 locks held by kworker/u4:3/609:
#0 : ffff000002842938 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work
#1 : ffff80000bacbd60 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work
#2 : ffff000007645178 (&dev->mutex){....}-{3:3}, at: __device_attach
#3 : ffff8000096e6e78 (dsa2_mutex){+.+.}-{3:3}, at: dsa_register_switch
#4 : ffff0000114c44d8 (&bus->mdio_lock){+.+.}-{3:3}, at: mdiobus_read
stack backtrace:
CPU: 1 PID: 609 Comm: kworker/u4:3 Not tainted 5.15.71 #1
Workqueue: events_unbound deferred_probe_work_func
Call trace:
dump_backtrace
show_stack
dump_stack_lvl
dump_stack
print_circular_bug
check_noncircular
__lock_acquire
lock_acquire.part.0
lock_acquire
__mutex_lock
mutex_lock_nested
regmap_lock_mutex
regmap_read
lan9303_phy_read
dsa_slave_phy_read
__mdiobus_read
mdiobus_read
get_phy_device
mdiobus_scan
__mdiobus_register
dsa_register_switch
lan9303_probe
lan9303_mdio_probe
...
Cc: stable@vger.kernel.org
Fixes: dc70058315
("net: dsa: LAN9303: add MDIO managed mode support")
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com >
Reviewed-by: Andrew Lunn <andrew@lunn.ch >
Link: https://lore.kernel.org/r/20231027065741.534971-1-alexander.sverdlin@siemens.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com >
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org >
2023-11-28 16:55:00 +00:00
Thomas Gleixner
1802d0beec
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174
...
Based on 1 normalized pattern(s):
this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license version 2 as
published by the free software foundation this program is
distributed in the hope that it will be useful but without any
warranty without even the implied warranty of merchantability or
fitness for a particular purpose see the gnu general public license
for more details
extracted by the scancode license scanner the SPDX license identifier
GPL-2.0-only
has been chosen to replace the boilerplate/reference in 655 file(s).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de >
Reviewed-by: Allison Randal <allison@lohutok.net >
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org >
Reviewed-by: Richard Fontana <rfontana@redhat.com >
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190527070034.575739538@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org >
2019-05-30 11:26:41 -07:00
Egil Hjelmeland
92f25cafe8
net: dsa: lan9303: Adjust indenting
...
Remove scripts/checkpatch.pl CHECKs by adjusting indenting.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no >
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com >
Signed-off-by: David S. Miller <davem@davemloft.net >
2017-11-08 13:29:06 +09:00
Colin Ian King
161ae6b04d
net: dsa: lan9303: make functions lan9303_mdio_phy_{read|write} static
...
The functions lan9303_mdio_phy_write and lan9303_mdio_phy_read are local
to the source and do not need to be in global scope, so make them static.
Cleans up sparse warnings:
symbol 'lan9303_mdio_phy_write' was not declared. Should it be static?
symbol 'lan9303_mdio_phy_read' was not declared. Should it be static?
Signed-off-by: Colin Ian King <colin.king@canonical.com >
Reviewed-by: Andrew Lunn <andrew@lunn.ch >
Signed-off-by: David S. Miller <davem@davemloft.net >
2017-10-03 10:20:12 -07:00
Egil Hjelmeland
2c3408986c
net: dsa: lan9303: MDIO access phy registers directly
...
Indirect access (PMI) to phy register only work in I2C mode. In
MDIO mode phy registers must be accessed directly. Introduced
struct lan9303_phy_ops to handle the two modes.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no >
Reviewed-by: Andrew Lunn <andrew@lunn.ch >
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com >
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com >
Signed-off-by: David S. Miller <davem@davemloft.net >
2017-07-30 19:23:29 -07:00
Egil Hjelmeland
ab78acb152
net: dsa: lan9303: Multiply by 4 to get MDIO register
...
lan9303_mdio_write()/_read() must multiply register number by 4 to get
offset.
Added some commments to the register definitions.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no >
Reviewed-by: Andrew Lunn <andrew@lunn.ch >
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com >
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com >
Signed-off-by: David S. Miller <davem@davemloft.net >
2017-07-30 19:23:29 -07:00
Juergen Beisert
dc70058315
net: dsa: LAN9303: add MDIO managed mode support
...
When the LAN9303 device is in MDIO manged mode, all register accesses must
be done via MDIO.
Please note: this code is compile time tested only due to the absence of such
configured hardware. It is based on a patch from Stefan Roese from 2014.
Signed-off-by: Juergen Borleis <jbe@pengutronix.de >
CC: devicetree@vger.kernel.org
CC: robh+dt@kernel.org
CC: mark.rutland@arm.com
CC: sr@denx.de
Acked-by: Rob Herring <robh@kernel.org >
Signed-off-by: David S. Miller <davem@davemloft.net >
2017-04-20 13:48:55 -04:00