From fcffac1340f61923786af8a860c12056a9ef3706 Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Mon, 27 Mar 2017 06:07:47 +0200 Subject: [PATCH] kernel: fix e1000e hung at stats update. Signed-off-by: Arne Fitzenreiter --- lfs/linux | 4 +- ...-igb-e1000e_fix_lock_at_update_stats.patch | 47 +++++++++++++++++++ ...-4.9.17-igb_fix_lock_at_update_stats.patch | 33 ------------- 3 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 src/patches/linux/linux-4.9.17-igb-e1000e_fix_lock_at_update_stats.patch delete mode 100644 src/patches/linux/linux-4.9.17-igb_fix_lock_at_update_stats.patch diff --git a/lfs/linux b/lfs/linux index 08bb710f75..b97116d34f 100644 --- a/lfs/linux +++ b/lfs/linux @@ -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 diff --git a/src/patches/linux/linux-4.9.17-igb-e1000e_fix_lock_at_update_stats.patch b/src/patches/linux/linux-4.9.17-igb-e1000e_fix_lock_at_update_stats.patch new file mode 100644 index 0000000000..231d41087f --- /dev/null +++ b/src/patches/linux/linux-4.9.17-igb-e1000e_fix_lock_at_update_stats.patch @@ -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; + } diff --git a/src/patches/linux/linux-4.9.17-igb_fix_lock_at_update_stats.patch b/src/patches/linux/linux-4.9.17-igb_fix_lock_at_update_stats.patch deleted file mode 100644 index f8a090c7ab..0000000000 --- a/src/patches/linux/linux-4.9.17-igb_fix_lock_at_update_stats.patch +++ /dev/null @@ -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; - } - -- 2.39.2