A AceLan Kao #
Message details and related content
From: "Chia-Lin Kao (AceLan)" <acelan.kao@canonical.com> The rtnl_lock() has been called in rtnetlink_rcv_msg(), and then in __dev_open() it calls pm_runtime_resume() to resume devices, and in some devices' resume function(igb_resum,igc_resume) they calls rtnl_lock() again. That leads to a recursive lock. It should leave the devices' resume function to decide if they need to call rtnl_lock()/rtnl_unlock(), so call rtnl_unlock() before calling pm_runtime_resume() and then call rtnl_lock() after it in __dev_open(). [ 967.723577] INFO: task ip:6024 blocked for more than 120 seconds. [ 967.723588] Not tainted 5.12.0-rc3+ #1 [ 967.723592] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 967.723594] task:ip state:D stack: 0 pid: 6024 ppid: 5957 flags:0x00004000 [ 967.723603] Call Trace: [ 967.723610] __schedule+0x2de/0x890 [ 967.723623] schedule+0x4f/0xc0 [ 967.723629] schedule_preempt_disabled+0xe/0x10 [ 967.723636] __mutex_lock.isra.0+0x190/0x510 [ 967.723644] __mutex_lock_slowpath+0x13/0x20 [ 967.723651] mutex_lock+0x32/0x40 [ 967.723657] rtnl_lock+0x15/0x20 [ 967.723665] igb_resume+0xee/0x1d0 [igb] [ 967.723687] ? pci_pm_default_resume+0x30/0x30 [ 967.723696] igb_runtime_resume+0xe/0x10 [igb] [ 967.723713] pci_pm_runtime_resume+0x74/0x90 [ 967.723718] __rpm_callback+0x53/0x1c0 [ 967.723725] rpm_callback+0x57/0x80 [ 967.723730] ? pci_pm_default_resume+0x30/0x30 [ 967.723735] rpm_resume+0x547/0x760 [ 967.723740] __pm_runtime_resume+0x52/0x80 [ 967.723745] __dev_open+0x56/0x160 [ 967.723753] ? _raw_spin_unlock_bh+0x1e/0x20 [ 967.723758] __dev_change_flags+0x188/0x1e0 [ 967.723766] dev_change_flags+0x26/0x60 [ 967.723773] do_setlink+0x723/0x10b0 [ 967.723782] ? __nla_validate_parse+0x5b/0xb80 [ 967.723792] __rtnl_newlink+0x594/0xa00 [ 967.723800] ? nla_put_ifalias+0x38/0xa0
diff --git a/net/core/dev.c b/net/core/dev.c
index 8f1a47ad6781..dd43a29419fd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c@@ -1585,8 +1585,11 @@ static int __dev_open(struct net_device *dev, struct netlink_ext_ack *extack) if (!netif_device_present(dev)) { /* may be detached because parent is runtime-suspended */ - if (dev->dev.parent) + if (dev->dev.parent) { + rtnl_unlock(); pm_runtime_resume(dev->dev.parent); + rtnl_lock(); + } if (!netif_device_present(dev)) return -ENODEV; }
--
2.25.1