Skip to content

Commit 4adaae2

Browse files
lumagedoardocanepa
authored andcommitted
phy: use per-PHY lockdep keys
BugLink: https://bugs.launchpad.net/bugs/2123805 [ Upstream commit cf0233491b3a15933234a26efd9ecbc1c0764674 ] If the PHY driver uses another PHY internally (e.g. in case of eUSB2, repeaters are represented as PHYs), then it would trigger the following lockdep splat because all PHYs use a single static lockdep key and thus lockdep can not identify whether there is a dependency or not and reports a false positive. Make PHY subsystem use dynamic lockdep keys, assigning each driver a separate key. This way lockdep can correctly identify dependency graph between mutexes. ============================================ WARNING: possible recursive locking detected 6.15.0-rc7-next-20250522-12896-g3932f283970c #3455 Not tainted -------------------------------------------- kworker/u51:0/78 is trying to acquire lock: ffff0008116554f0 (&phy->mutex){+.+.}-{4:4}, at: phy_init+0x4c/0x12c but task is already holding lock: ffff000813c10cf0 (&phy->mutex){+.+.}-{4:4}, at: phy_init+0x4c/0x12c other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&phy->mutex); lock(&phy->mutex); *** DEADLOCK *** May be due to missing lock nesting notation 4 locks held by kworker/u51:0/78: #0: ffff000800010948 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x18c/0x5ec #1: ffff80008036bdb0 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work+0x1b4/0x5ec #2: ffff0008094ac8f8 (&dev->mutex){....}-{4:4}, at: __device_attach+0x38/0x188 #3: ffff000813c10cf0 (&phy->mutex){+.+.}-{4:4}, at: phy_init+0x4c/0x12c stack backtrace: CPU: 0 UID: 0 PID: 78 Comm: kworker/u51:0 Not tainted 6.15.0-rc7-next-20250522-12896-g3932f283970c #3455 PREEMPT Hardware name: Qualcomm CRD, BIOS 6.0.240904.BOOT.MXF.2.4-00528.1-HAMOA-1 09/ 4/2024 Workqueue: events_unbound deferred_probe_work_func Call trace: show_stack+0x18/0x24 (C) dump_stack_lvl+0x90/0xd0 dump_stack+0x18/0x24 print_deadlock_bug+0x258/0x348 __lock_acquire+0x10fc/0x1f84 lock_acquire+0x1c8/0x338 __mutex_lock+0xb8/0x59c mutex_lock_nested+0x24/0x30 phy_init+0x4c/0x12c snps_eusb2_hsphy_init+0x54/0x1a0 phy_init+0xe0/0x12c dwc3_core_init+0x450/0x10b4 dwc3_core_probe+0xce4/0x15fc dwc3_probe+0x64/0xb0 platform_probe+0x68/0xc4 really_probe+0xbc/0x298 __driver_probe_device+0x78/0x12c driver_probe_device+0x3c/0x160 __device_attach_driver+0xb8/0x138 bus_for_each_drv+0x84/0xe0 __device_attach+0x9c/0x188 device_initial_probe+0x14/0x20 bus_probe_device+0xac/0xb0 deferred_probe_work_func+0x8c/0xc8 process_one_work+0x208/0x5ec worker_thread+0x1c0/0x368 kthread+0x14c/0x20c ret_from_fork+0x10/0x20 Fixes: 3584f63 ("phy: qcom: phy-qcom-snps-eusb2: Add support for eUSB2 repeater") Fixes: e246355 ("phy: amlogic: Add Amlogic AXG PCIE PHY Driver") Reviewed-by: Neil Armstrong <[email protected]> Reviewed-by: Abel Vesa <[email protected]> Reported-by: Johan Hovold <[email protected]> Link: https://lore.kernel.org/lkml/[email protected]/ Reviewed-by: Johan Hovold <[email protected]> Tested-by: Johan Hovold <[email protected]> Signed-off-by: Dmitry Baryshkov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Noah Wager <[email protected]> Signed-off-by: Edoardo Canepa <[email protected]>
1 parent 1fdf5c8 commit 4adaae2

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

drivers/phy/phy-core.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,8 @@ struct phy *phy_create(struct device *dev, struct device_node *node,
10181018
}
10191019

10201020
device_initialize(&phy->dev);
1021-
mutex_init(&phy->mutex);
1021+
lockdep_register_key(&phy->lockdep_key);
1022+
mutex_init_with_key(&phy->mutex, &phy->lockdep_key);
10221023

10231024
phy->dev.class = &phy_class;
10241025
phy->dev.parent = dev;
@@ -1283,6 +1284,8 @@ static void phy_release(struct device *dev)
12831284
dev_vdbg(dev, "releasing '%s'\n", dev_name(dev));
12841285
debugfs_remove_recursive(phy->debugfs);
12851286
regulator_put(phy->pwr);
1287+
mutex_destroy(&phy->mutex);
1288+
lockdep_unregister_key(&phy->lockdep_key);
12861289
ida_free(&phy_ida, phy->id);
12871290
kfree(phy);
12881291
}

include/linux/phy/phy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ struct phy_attrs {
149149
* @id: id of the phy device
150150
* @ops: function pointers for performing phy operations
151151
* @mutex: mutex to protect phy_ops
152+
* @lockdep_key: lockdep information for this mutex
152153
* @init_count: used to protect when the PHY is used by multiple consumers
153154
* @power_count: used to protect when the PHY is used by multiple consumers
154155
* @attrs: used to specify PHY specific attributes
@@ -160,6 +161,7 @@ struct phy {
160161
int id;
161162
const struct phy_ops *ops;
162163
struct mutex mutex;
164+
struct lock_class_key lockdep_key;
163165
int init_count;
164166
int power_count;
165167
struct phy_attrs attrs;

0 commit comments

Comments
 (0)