# 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
--- /dev/null
+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;
+ }
+++ /dev/null
-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;
- }
-