From: Andrea Merello Date: Sat, 8 Jul 2017 08:11:11 +0000 (+0200) Subject: lantiq: fix sleep with spinlock held in xrx200 network driver X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=b81c04382b5ddea0164993c2af0df7270bb95ee4;p=openwrt%2Fstaging%2Fjogo.git 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 [fold into 0025-NET-MIPS-lantiq-adds-xrx200-net.patch, backport to kernel 4.4] Signed-off-by: Mathias Kresin --- 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 1550f26e36..ccb0733f75 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 80bcea0f4b..871176449c 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;