igb: Move the calls to set the Tx and Rx queues into igb_open
This change helps to address locking issues seen with netif_set_real_num_tx_queues and netif_set_real_num_rx_queues when used in the igb_set_interrupt_capability function. To resolve these locking issues I have moved the two function calls into __igb_open so that they can be called while the RTNL lock is held. An added advantage to this is that the number of queues is not updated until the last possible moment so if there are any issues in allocating MSI-X interrupts or resources for the rings we have time to change the values prior to updating the netdev. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
5536d2102a
commit
0c2cc02e57
|
@ -948,7 +948,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter)
|
||||||
* Attempt to configure interrupts using the best available
|
* Attempt to configure interrupts using the best available
|
||||||
* capabilities of the hardware and kernel.
|
* capabilities of the hardware and kernel.
|
||||||
**/
|
**/
|
||||||
static int igb_set_interrupt_capability(struct igb_adapter *adapter)
|
static void igb_set_interrupt_capability(struct igb_adapter *adapter)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
int numvecs, i;
|
int numvecs, i;
|
||||||
|
@ -985,7 +985,7 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter)
|
||||||
adapter->msix_entries,
|
adapter->msix_entries,
|
||||||
numvecs);
|
numvecs);
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
goto out;
|
return;
|
||||||
|
|
||||||
igb_reset_interrupt_capability(adapter);
|
igb_reset_interrupt_capability(adapter);
|
||||||
|
|
||||||
|
@ -1015,14 +1015,6 @@ msi_only:
|
||||||
adapter->num_q_vectors = 1;
|
adapter->num_q_vectors = 1;
|
||||||
if (!pci_enable_msi(adapter->pdev))
|
if (!pci_enable_msi(adapter->pdev))
|
||||||
adapter->flags |= IGB_FLAG_HAS_MSI;
|
adapter->flags |= IGB_FLAG_HAS_MSI;
|
||||||
out:
|
|
||||||
/* Notify the stack of the (possibly) reduced queue counts. */
|
|
||||||
rtnl_lock();
|
|
||||||
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
|
|
||||||
err = netif_set_real_num_rx_queues(adapter->netdev,
|
|
||||||
adapter->num_rx_queues);
|
|
||||||
rtnl_unlock();
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void igb_add_ring(struct igb_ring *ring,
|
static void igb_add_ring(struct igb_ring *ring,
|
||||||
|
@ -1212,9 +1204,7 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter)
|
||||||
struct pci_dev *pdev = adapter->pdev;
|
struct pci_dev *pdev = adapter->pdev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = igb_set_interrupt_capability(adapter);
|
igb_set_interrupt_capability(adapter);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
err = igb_alloc_q_vectors(adapter);
|
err = igb_alloc_q_vectors(adapter);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -2543,6 +2533,17 @@ static int __igb_open(struct net_device *netdev, bool resuming)
|
||||||
if (err)
|
if (err)
|
||||||
goto err_req_irq;
|
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() */
|
/* From here on the code is the same as igb_up() */
|
||||||
clear_bit(__IGB_DOWN, &adapter->state);
|
clear_bit(__IGB_DOWN, &adapter->state);
|
||||||
|
|
||||||
|
@ -2572,6 +2573,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_set_queues:
|
||||||
|
igb_free_irq(adapter);
|
||||||
err_req_irq:
|
err_req_irq:
|
||||||
igb_release_hw_control(adapter);
|
igb_release_hw_control(adapter);
|
||||||
igb_power_down_link(adapter);
|
igb_power_down_link(adapter);
|
||||||
|
@ -6841,7 +6844,9 @@ static int igb_resume(struct device *dev)
|
||||||
wr32(E1000_WUS, ~0);
|
wr32(E1000_WUS, ~0);
|
||||||
|
|
||||||
if (netdev->flags & IFF_UP) {
|
if (netdev->flags & IFF_UP) {
|
||||||
|
rtnl_lock();
|
||||||
err = __igb_open(netdev, true);
|
err = __igb_open(netdev, true);
|
||||||
|
rtnl_unlock();
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue