Since commit ac8c58f5b535 ("igb: fix deadlock caused by taking RTNL in RPM resume path") __igb_resume() doesn't take RTNL for runtime resume, but __igb_open() still calls netif_set_real_num_{tx,rx}_queues(), which require it. An asynchronous runtime resume (e.g. after the link comes back) then triggers "RTNL: assertion failed". The queue counts only change on paths that re-open the device under RTNL (ethtool -L, SR-IOV reconfiguration): set them in igb_open() only, as igc does since commit 6f31d6b643a3 ("igc: Refactor runtime power management flow"). Fixes: ac8c58f5b535 ("igb: fix deadlock caused by taking RTNL in RPM resume path") Cc: stable@vger.kernel.org Closes: https://bugzilla.ipfire.org/show_bug.cgi?id=13562 Signed-off-by: Antonio Quartulli --- drivers/net/ethernet/intel/igb/igb_main.c | 24 +++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 78f0786..bd1185d 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -4178,17 +4178,6 @@ static int __igb_open(struct net_device *netdev, bool resuming) if (err) goto err_req_irq; - /* Notify the stack of the actual queue counts. */ - err = netif_set_real_num_tx_queues(adapter->netdev, - adapter->num_tx_queues); - if (err) - goto err_set_queues; - - err = netif_set_real_num_rx_queues(adapter->netdev, - adapter->num_rx_queues); - if (err) - goto err_set_queues; - /* From here on the code is the same as igb_up() */ clear_bit(__IGB_DOWN, &adapter->state); @@ -4223,8 +4212,6 @@ static int __igb_open(struct net_device *netdev, bool resuming) return 0; -err_set_queues: - igb_free_irq(adapter); err_req_irq: igb_release_hw_control(adapter); igb_power_down_link(adapter); @@ -4241,6 +4228,17 @@ err_setup_tx: int igb_open(struct net_device *netdev) { + struct igb_adapter *adapter = netdev_priv(netdev); + int err; + + /* Notify the stack of the actual queue counts. */ + err = netif_set_real_num_queues(netdev, adapter->num_tx_queues, + adapter->num_rx_queues); + if (err) { + netdev_err(netdev, "error setting real queue count\n"); + return err; + } + return __igb_open(netdev, false); } -- 2.56.0