aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-09-24 20:31:22 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2012-10-19 07:40:46 -0400
commit0c2cc02e571aee1f2193a004508d4d604eff6a8f (patch)
tree8493571b6eeef186e78daa02ba13e376ddf82f3a
parent5536d2102a2d37a02e2c233ead4e1e4cabbdcd5b (diff)
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>
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 4a25b8fa9084..e7b102723481 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -948,7 +948,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter)
948 * Attempt to configure interrupts using the best available 948 * Attempt to configure interrupts using the best available
949 * capabilities of the hardware and kernel. 949 * capabilities of the hardware and kernel.
950 **/ 950 **/
951static int igb_set_interrupt_capability(struct igb_adapter *adapter) 951static void igb_set_interrupt_capability(struct igb_adapter *adapter)
952{ 952{
953 int err; 953 int err;
954 int numvecs, i; 954 int numvecs, i;
@@ -985,7 +985,7 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter)
985 adapter->msix_entries, 985 adapter->msix_entries,
986 numvecs); 986 numvecs);
987 if (err == 0) 987 if (err == 0)
988 goto out; 988 return;
989 989
990 igb_reset_interrupt_capability(adapter); 990 igb_reset_interrupt_capability(adapter);
991 991
@@ -1015,14 +1015,6 @@ msi_only:
1015 adapter->num_q_vectors = 1; 1015 adapter->num_q_vectors = 1;
1016 if (!pci_enable_msi(adapter->pdev)) 1016 if (!pci_enable_msi(adapter->pdev))
1017 adapter->flags |= IGB_FLAG_HAS_MSI; 1017 adapter->flags |= IGB_FLAG_HAS_MSI;
1018out:
1019 /* Notify the stack of the (possibly) reduced queue counts. */
1020 rtnl_lock();
1021 netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
1022 err = netif_set_real_num_rx_queues(adapter->netdev,
1023 adapter->num_rx_queues);
1024 rtnl_unlock();
1025 return err;
1026} 1018}
1027 1019
1028static void igb_add_ring(struct igb_ring *ring, 1020static void igb_add_ring(struct igb_ring *ring,
@@ -1212,9 +1204,7 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter)
1212 struct pci_dev *pdev = adapter->pdev; 1204 struct pci_dev *pdev = adapter->pdev;
1213 int err; 1205 int err;
1214 1206
1215 err = igb_set_interrupt_capability(adapter); 1207 igb_set_interrupt_capability(adapter);
1216 if (err)
1217 return err;
1218 1208
1219 err = igb_alloc_q_vectors(adapter); 1209 err = igb_alloc_q_vectors(adapter);
1220 if (err) { 1210 if (err) {
@@ -2543,6 +2533,17 @@ static int __igb_open(struct net_device *netdev, bool resuming)
2543 if (err) 2533 if (err)
2544 goto err_req_irq; 2534 goto err_req_irq;
2545 2535
2536 /* Notify the stack of the actual queue counts. */
2537 err = netif_set_real_num_tx_queues(adapter->netdev,
2538 adapter->num_tx_queues);
2539 if (err)
2540 goto err_set_queues;
2541
2542 err = netif_set_real_num_rx_queues(adapter->netdev,
2543 adapter->num_rx_queues);
2544 if (err)
2545 goto err_set_queues;
2546
2546 /* From here on the code is the same as igb_up() */ 2547 /* From here on the code is the same as igb_up() */
2547 clear_bit(__IGB_DOWN, &adapter->state); 2548 clear_bit(__IGB_DOWN, &adapter->state);
2548 2549
@@ -2572,6 +2573,8 @@ static int __igb_open(struct net_device *netdev, bool resuming)
2572 2573
2573 return 0; 2574 return 0;
2574 2575
2576err_set_queues:
2577 igb_free_irq(adapter);
2575err_req_irq: 2578err_req_irq:
2576 igb_release_hw_control(adapter); 2579 igb_release_hw_control(adapter);
2577 igb_power_down_link(adapter); 2580 igb_power_down_link(adapter);
@@ -6841,7 +6844,9 @@ static int igb_resume(struct device *dev)
6841 wr32(E1000_WUS, ~0); 6844 wr32(E1000_WUS, ~0);
6842 6845
6843 if (netdev->flags & IFF_UP) { 6846 if (netdev->flags & IFF_UP) {
6847 rtnl_lock();
6844 err = __igb_open(netdev, true); 6848 err = __igb_open(netdev, true);
6849 rtnl_unlock();
6845 if (err) 6850 if (err)
6846 return err; 6851 return err;
6847 } 6852 }