edma_read_append_stats() is called from kernel timer (Bottom half context) but it used spin_lock() to take a lock. Using ethtool command rarely causes deadlock because of this. Change lock function to spin_lock_bh() to avoid this.
Signed-off-by: Masafumi UTSUGI <muts...@allied-telesis.co.jp> --- .../patches-4.14/715-essedma-fix-dead-lock.patch | 20 ++++++++++++++++++++ .../patches-4.19/715-essedma-fix-dead-lock.patch | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 target/linux/ipq40xx/patches-4.14/715-essedma-fix-dead-lock.patch create mode 100644 target/linux/ipq40xx/patches-4.19/715-essedma-fix-dead-lock.patch diff --git a/target/linux/ipq40xx/patches-4.14/715-essedma-fix-dead-lock.patch b/target/linux/ipq40xx/patches-4.14/715-essedma-fix-dead-lock.patch new file mode 100644 index 0000000..1c44924 --- /dev/null +++ b/target/linux/ipq40xx/patches-4.14/715-essedma-fix-dead-lock.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c ++++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c +@@ -230,7 +230,7 @@ + int i; + u32 stat; + +- spin_lock(&edma_cinfo->stats_lock); ++ spin_lock_bh(&edma_cinfo->stats_lock); + p = (uint32_t *)&(edma_cinfo->edma_ethstats); + + for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { +@@ -257,7 +257,7 @@ + p++; + } + +- spin_unlock(&edma_cinfo->stats_lock); ++ spin_unlock_bh(&edma_cinfo->stats_lock); + } + + static void edma_statistics_timer(unsigned long data) diff --git a/target/linux/ipq40xx/patches-4.19/715-essedma-fix-dead-lock.patch b/target/linux/ipq40xx/patches-4.19/715-essedma-fix-dead-lock.patch new file mode 100644 index 0000000..1c44924 --- /dev/null +++ b/target/linux/ipq40xx/patches-4.19/715-essedma-fix-dead-lock.patch @@ -0,0 +1,20 @@ +--- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c ++++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c +@@ -230,7 +230,7 @@ + int i; + u32 stat; + +- spin_lock(&edma_cinfo->stats_lock); ++ spin_lock_bh(&edma_cinfo->stats_lock); + p = (uint32_t *)&(edma_cinfo->edma_ethstats); + + for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { +@@ -257,7 +257,7 @@ + p++; + } + +- spin_unlock(&edma_cinfo->stats_lock); ++ spin_unlock_bh(&edma_cinfo->stats_lock); + } + + static void edma_statistics_timer(unsigned long data) -- 2.7.4 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel