ipq40xx: essedma: Fix dead lock
authorMasafumi UTSUGI <mutsugi@allied-telesis.co.jp>
Tue, 1 Oct 2019 09:59:18 +0000 (18:59 +0900)
committerChristian Lamparter <chunkeey@gmail.com>
Sun, 20 Oct 2019 11:01:43 +0000 (13:01 +0200)
edma_read_append_stats() gets called from two places in the driver.
The first place is the kernel timer that periodically updates
the statistics, so nothing gets lost due to overflows.
The second one it's part of the userspace ethtool ioctl handler
to provide up-to-date values.

For this configuration, the use of spin_lock() is not sufficient
and as per:
<https://mirrors.edge.kernel.org/pub/linux/kernel/people/rusty/kernel-locking/c214.html>
the locking has to be upgraded to spin_lock_bh().

Signed-off-by: Masafumi UTSUGI <mutsugi@allied-telesis.co.jp>
[folded patch into 710-, rewrote message]
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
target/linux/ipq40xx/patches-4.14/710-net-add-qualcomm-essedma-ethernet-driver.patch
target/linux/ipq40xx/patches-4.19/710-net-add-qualcomm-essedma-ethernet-driver.patch

index e304911f1d8fa91fe83a370b3c91c91bd98659e4..1e47f2fe90af0d01460414eb38d7f39b11753ce8 100644 (file)
@@ -2775,7 +2775,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
 +      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++) {
@@ -2802,7 +2802,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
 +              p++;
 +      }
 +
-+      spin_unlock(&edma_cinfo->stats_lock);
++      spin_unlock_bh(&edma_cinfo->stats_lock);
 +}
 +
 +static void edma_statistics_timer(unsigned long data)
index 9fe3a1a9d69a4344abca701d48de374497201c07..6ccf2cd480243ca8b6b68231f517e99503b7f837 100644 (file)
@@ -2774,7 +2774,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
 +      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++) {
@@ -2801,7 +2801,7 @@ Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
 +              p++;
 +      }
 +
-+      spin_unlock(&edma_cinfo->stats_lock);
++      spin_unlock_bh(&edma_cinfo->stats_lock);
 +}
 +
 +static void edma_statistics_timer(struct timer_list *t)