[source] lantiq: fix sleep with spinlock held in xrx200 network driver

LEDE Commits lede-commits at lists.infradead.org
Thu Jul 20 10:13:13 PDT 2017


mkresin pushed a commit to source.git, branch master:
https://git.lede-project.org/b81c04382b5ddea0164993c2af0df7270bb95ee4

commit b81c04382b5ddea0164993c2af0df7270bb95ee4
Author: Andrea Merello <andrea.merello at gmail.com>
AuthorDate: Sat Jul 8 10:11:11 2017 +0200

    lantiq: fix sleep with spinlock held in xrx200 network driver
    
    In the xrx200_close() function we call napi_disable(), that could
    sleep, with priv->hw->chan[i].lock held. This could lead to deadlock
    and causes the kernel to complain.
    
    Look at the code I couldn't convince myself about why we
    need to protect that specific code part with the lock. IMHO there
    seems no reason to protect the refcount variables, because AFAIK
    ndo_close() and ndo_open() callbacks are already called with a
    semaphore held. Neither I could figure out why napi_disable() have to
    be called with that lock held. The only remaining code part for
    which I could guess the lock is useful for is ltq_dma_close()
    function call.
    
    This patch reduces the lock to the said function call, avoiding the
    sleep-with-spinlock-held situation
    
    Signed-off-by: Andrea Merello <andrea.merello at gmail.com>
    [fold into 0025-NET-MIPS-lantiq-adds-xrx200-net.patch, backport to
    kernel 4.4]
    Signed-off-by: Mathias Kresin <dev at kresin.me>
---
 .../lantiq/patches-4.4/0025-NET-MIPS-lantiq-adds-xrx200-net.patch  | 7 ++++---
 .../lantiq/patches-4.9/0025-NET-MIPS-lantiq-adds-xrx200-net.patch  | 7 ++++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/target/linux/lantiq/patches-4.4/0025-NET-MIPS-lantiq-adds-xrx200-net.patch b/target/linux/lantiq/patches-4.4/0025-NET-MIPS-lantiq-adds-xrx200-net.patch
index 1550f26..ccb0733 100644
--- a/target/linux/lantiq/patches-4.4/0025-NET-MIPS-lantiq-adds-xrx200-net.patch
+++ b/target/linux/lantiq/patches-4.4/0025-NET-MIPS-lantiq-adds-xrx200-net.patch
@@ -209,7 +209,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
 +};
 --- /dev/null
 +++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -0,0 +1,1852 @@
+@@ -0,0 +1,1853 @@
 +/*
 + *   This program is free software; you can redistribute it and/or modify it
 + *   under the terms of the GNU General Public License version 2 as published
@@ -1110,14 +1110,15 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
 +	for (i = 0; i < XRX200_MAX_DMA; i++) {
 +		if (!priv->hw->chan[i].dma.irq)
 +			continue;
-+		spin_lock_bh(&priv->hw->chan[i].lock);
++
 +		priv->hw->chan[i].refcount--;
 +		if (!priv->hw->chan[i].refcount) {
 +			if (XRX200_DMA_IS_RX(i))
 +				napi_disable(&priv->hw->chan[i].napi);
++			spin_lock_bh(&priv->hw->chan[i].lock);
 +			ltq_dma_close(&priv->hw->chan[XRX200_DMA_RX].dma);
++			spin_unlock_bh(&priv->hw->chan[i].lock);
 +		}
-+		spin_unlock_bh(&priv->hw->chan[i].lock);
 +	}
 +
 +	return 0;
diff --git a/target/linux/lantiq/patches-4.9/0025-NET-MIPS-lantiq-adds-xrx200-net.patch b/target/linux/lantiq/patches-4.9/0025-NET-MIPS-lantiq-adds-xrx200-net.patch
index 80bcea0..8711764 100644
--- a/target/linux/lantiq/patches-4.9/0025-NET-MIPS-lantiq-adds-xrx200-net.patch
+++ b/target/linux/lantiq/patches-4.9/0025-NET-MIPS-lantiq-adds-xrx200-net.patch
@@ -209,7 +209,7 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
 +};
 --- /dev/null
 +++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -0,0 +1,1851 @@
+@@ -0,0 +1,1852 @@
 +/*
 + *   This program is free software; you can redistribute it and/or modify it
 + *   under the terms of the GNU General Public License version 2 as published
@@ -1110,14 +1110,15 @@ Subject: [PATCH 25/36] NET: MIPS: lantiq: adds xrx200-net
 +	for (i = 0; i < XRX200_MAX_DMA; i++) {
 +		if (!priv->hw->chan[i].dma.irq)
 +			continue;
-+		spin_lock_bh(&priv->hw->chan[i].lock);
++
 +		priv->hw->chan[i].refcount--;
 +		if (!priv->hw->chan[i].refcount) {
 +			if (XRX200_DMA_IS_RX(i))
 +				napi_disable(&priv->hw->chan[i].napi);
++			spin_lock_bh(&priv->hw->chan[i].lock);
 +			ltq_dma_close(&priv->hw->chan[XRX200_DMA_RX].dma);
++			spin_unlock_bh(&priv->hw->chan[i].lock);
 +		}
-+		spin_unlock_bh(&priv->hw->chan[i].lock);
 +	}
 +
 +	return 0;



More information about the lede-commits mailing list