Skip to content

Commit

Permalink
igb: Move the calls to set the Tx and Rx queues into igb_open
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Oct 19, 2012
1 parent 5536d21 commit 0c2cc02
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter)
* Attempt to configure interrupts using the best available
* 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 numvecs, i;
Expand Down Expand Up @@ -985,7 +985,7 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter)
adapter->msix_entries,
numvecs);
if (err == 0)
goto out;
return;

igb_reset_interrupt_capability(adapter);

Expand Down Expand Up @@ -1015,14 +1015,6 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter)
adapter->num_q_vectors = 1;
if (!pci_enable_msi(adapter->pdev))
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,
Expand Down Expand Up @@ -1212,9 +1204,7 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter)
struct pci_dev *pdev = adapter->pdev;
int err;

err = igb_set_interrupt_capability(adapter);
if (err)
return err;
igb_set_interrupt_capability(adapter);

err = igb_alloc_q_vectors(adapter);
if (err) {
Expand Down Expand Up @@ -2543,6 +2533,17 @@ 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);

Expand Down Expand Up @@ -2572,6 +2573,8 @@ 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);
Expand Down Expand Up @@ -6841,7 +6844,9 @@ static int igb_resume(struct device *dev)
wr32(E1000_WUS, ~0);

if (netdev->flags & IFF_UP) {
rtnl_lock();
err = __igb_open(netdev, true);
rtnl_unlock();
if (err)
return err;
}
Expand Down

0 comments on commit 0c2cc02

Please sign in to comment.