Created
September 20, 2011 17:39
-
-
Save ice799/1229754 to your computer and use it in GitHub Desktop.
fix for igb bugs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 7def9e7f9b8738201677a9fa8d3f0bbe4c881b9a | |
Author: Joe Damato <[email protected]> | |
Date: Tue Sep 20 17:32:20 2011 +0000 | |
Fix for igb 2 second reporting bug and ioctl/stats race condition. | |
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h | |
index b1c1eb8..ce42798 100644 | |
--- a/drivers/net/igb/igb.h | |
+++ b/drivers/net/igb/igb.h | |
@@ -284,6 +284,8 @@ struct igb_adapter { | |
struct timecompare compare; | |
struct hwtstamp_config hwtstamp_config; | |
+ spinlock_t stats_lock; | |
+ | |
/* structs defined in e1000_hw.h */ | |
struct e1000_hw hw; | |
struct e1000_hw_stats stats; | |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c | |
index 550ad93..f97b4c5 100644 | |
--- a/drivers/net/igb/igb_ethtool.c | |
+++ b/drivers/net/igb/igb_ethtool.c | |
@@ -1991,7 +1991,9 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |
u64 *queue_stat; | |
int i, j, k; | |
char *p; | |
+ unsigned long flags; | |
+ spin_lock_irqsave(&adapter->stats_lock, flags); | |
igb_update_stats(adapter); | |
for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { | |
@@ -2014,6 +2016,7 @@ static void igb_get_ethtool_stats(struct net_device *netdev, | |
for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++) | |
data[i] = queue_stat[k]; | |
} | |
+ spin_unlock_irqrestore(&adapter->stats_lock, flags); | |
} | |
static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c | |
index 4370842..b956888 100644 | |
--- a/drivers/net/igb/igb_main.c | |
+++ b/drivers/net/igb/igb_main.c | |
@@ -1157,6 +1157,7 @@ void igb_down(struct igb_adapter *adapter) | |
struct e1000_hw *hw = &adapter->hw; | |
u32 tctl, rctl; | |
int i; | |
+ unsigned long flags; | |
/* signal that we're down so the interrupt handler does not | |
* reschedule our watchdog timer */ | |
@@ -1191,7 +1192,9 @@ void igb_down(struct igb_adapter *adapter) | |
netif_carrier_off(netdev); | |
/* record the stats before reset*/ | |
+ spin_lock_irqsave(&adapter->stats_lock, flags); | |
igb_update_stats(adapter); | |
+ spin_unlock_irqrestore(&adapter->stats_lock, flags); | |
adapter->link_speed = 0; | |
adapter->link_duplex = 0; | |
@@ -1534,6 +1537,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |
goto err_eeprom; | |
} | |
+ spin_lock_init(&adapter->stats_lock); | |
+ | |
setup_timer(&adapter->watchdog_timer, &igb_watchdog, | |
(unsigned long) adapter); | |
setup_timer(&adapter->phy_info_timer, &igb_update_phy_info, | |
@@ -3120,7 +3125,10 @@ static void igb_watchdog_task(struct work_struct *work) | |
} | |
} | |
+ spin_lock(&adapter->stats_lock); | |
igb_update_stats(adapter); | |
+ spin_unlock(&adapter->stats_lock); | |
+ | |
igb_update_adaptive(hw); | |
for (i = 0; i < adapter->num_tx_queues; i++) { | |
@@ -3856,7 +3864,13 @@ static void igb_reset_task(struct work_struct *work) | |
**/ | |
static struct net_device_stats *igb_get_stats(struct net_device *netdev) | |
{ | |
- /* only return the current stats */ | |
+ struct igb_adapter *adapter = netdev_priv(netdev); | |
+ unsigned long flags; | |
+ | |
+ spin_lock_irqsave(&adapter->stats_lock, flags); | |
+ igb_update_stats(adapter); | |
+ spin_unlock_irqrestore(&adapter->stats_lock, flags); | |
+ | |
return &netdev->stats; | |
} | |
@@ -3930,7 +3944,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) | |
void igb_update_stats(struct igb_adapter *adapter) | |
{ | |
- struct net_device_stats *net_stats = igb_get_stats(adapter->netdev); | |
+ struct net_device_stats *net_stats = &adapter->netdev->stats; | |
struct e1000_hw *hw = &adapter->hw; | |
struct pci_dev *pdev = adapter->pdev; | |
u32 rnbc; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment