kernel: fix e1000e hung at stats update.

Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
This commit is contained in:
Arne Fitzenreiter
2017-03-27 06:07:47 +02:00
parent d52f116913
commit fcffac1340
3 changed files with 49 additions and 35 deletions

View File

@@ -152,8 +152,8 @@ endif
# Add LED trigger
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-4.9.16-ledtrig_netdev.patch
# Fix igb crash
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-4.9.17-igb_fix_lock_at_update_stats.patch
# Fix igb and e1000e crash
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-4.9.17-igb-e1000e_fix_lock_at_update_stats.patch
# cs5535audio spams syslog if no ac97 was present (geos router)
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-4.9.8_cs5535audio_fix_logspam_on_geos.patch

View File

@@ -0,0 +1,47 @@
diff -Naur linux-4.9.17.org/drivers/net/ethernet/intel/e1000e/netdev.c linux-4.9.17/drivers/net/ethernet/intel/e1000e/netdev.c
--- linux-4.9.17.org/drivers/net/ethernet/intel/e1000e/netdev.c 2017-03-22 12:44:07.000000000 +0100
+++ linux-4.9.17/drivers/net/ethernet/intel/e1000e/netdev.c 2017-03-26 16:20:47.253511522 +0200
@@ -5924,10 +5924,14 @@
struct rtnl_link_stats64 *stats)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
+ int has_lock = 0;
memset(stats, 0, sizeof(struct rtnl_link_stats64));
- spin_lock(&adapter->stats64_lock);
- e1000e_update_stats(adapter);
+ if (spin_trylock(&adapter->stats64_lock)) {
+ e1000e_update_stats(adapter);
+ has_lock = 1;
+ }
+
/* Fill out the OS statistics structure */
stats->rx_bytes = adapter->stats.gorc;
stats->rx_packets = adapter->stats.gprc;
@@ -5957,7 +5961,7 @@
/* Tx Dropped needs to be maintained elsewhere */
- spin_unlock(&adapter->stats64_lock);
+ if (has_lock) spin_unlock(&adapter->stats64_lock);
return stats;
}
diff -Naur linux-4.9.17.org/drivers/net/ethernet/intel/igb/igb_main.c linux-4.9.17/drivers/net/ethernet/intel/igb/igb_main.c
--- linux-4.9.17.org/drivers/net/ethernet/intel/igb/igb_main.c 2017-03-22 12:44:07.000000000 +0100
+++ linux-4.9.17/drivers/net/ethernet/intel/igb/igb_main.c 2017-03-26 16:02:46.820093793 +0200
@@ -5391,10 +5391,11 @@
{
struct igb_adapter *adapter = netdev_priv(netdev);
- spin_lock(&adapter->stats64_lock);
- igb_update_stats(adapter, &adapter->stats64);
+ if (spin_trylock(&adapter->stats64_lock)) {
+ igb_update_stats(adapter, &adapter->stats64);
+ spin_unlock(&adapter->stats64_lock);
+ }
memcpy(stats, &adapter->stats64, sizeof(*stats));
- spin_unlock(&adapter->stats64_lock);
return stats;
}

View File

@@ -1,33 +0,0 @@
diff -Naur linux-4.9.17.org/drivers/net/ethernet/intel/igb/igb_main.c linux-4.9.17/drivers/net/ethernet/intel/igb/igb_main.c
--- linux-4.9.17.org/drivers/net/ethernet/intel/igb/igb_main.c 2017-03-22 12:44:07.000000000 +0100
+++ linux-4.9.17/drivers/net/ethernet/intel/igb/igb_main.c 2017-03-24 10:00:52.854812142 +0100
@@ -4609,9 +4609,10 @@
}
}
- spin_lock(&adapter->stats64_lock);
- igb_update_stats(adapter, &adapter->stats64);
- spin_unlock(&adapter->stats64_lock);
+ if (spin_trylock(&adapter->stats64_lock)) {
+ igb_update_stats(adapter, &adapter->stats64);
+ spin_unlock(&adapter->stats64_lock);
+ }
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *tx_ring = adapter->tx_ring[i];
@@ -5391,11 +5392,11 @@
{
struct igb_adapter *adapter = netdev_priv(netdev);
- spin_lock(&adapter->stats64_lock);
- igb_update_stats(adapter, &adapter->stats64);
+ if (spin_trylock(&adapter->stats64_lock)) {
+ igb_update_stats(adapter, &adapter->stats64);
+ spin_unlock(&adapter->stats64_lock);
+ }
memcpy(stats, &adapter->stats64, sizeof(*stats));
- spin_unlock(&adapter->stats64_lock);
-
return stats;
}