[PATCH] net: sunplus: fix tx_poll spin_lock missing irqsave in NAPI context
Andrew Gaylard <[email protected]>
| Newsgroups | org.kernel.vger.netdev,org.infradead.lists.linux-arm-kernel |
|---|---|
| Message-ID | <[email protected]> |
spl2sw_tx_poll() runs in NAPI (softirq) context and acquires comm->tx_lock with plain spin_lock(). The hardirq handler spl2sw_ethernet_interrupt() acquires the same lock, so a hardirq on the same CPU while the NAPI poll holds the lock would deadlock with IRQs disabled. Use spin_lock_irqsave/spin_unlock_irqrestore. Signed-off-by: Andrew Gaylard <[email protected]> --- drivers/net/ethernet/sunplus/spl2sw_int.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/sunplus/spl2sw_int.c b/drivers/net/ethernet/sunplus/spl2sw_int.c index a37c9a4c281f..7e07cd941434 100644 --- a/drivers/net/ethernet/sunplus/spl2sw_int.c +++ b/drivers/net/ethernet/sunplus/spl2sw_int.c @@ -147,7 +147,7 @@ int spl2sw_tx_poll(struct napi_struct *napi, int budget) u32 cmd; int i; - spin_lock(&comm->tx_lock); + spin_lock_irqsave(&comm->tx_lock, flags); tx_done_pos = comm->tx_done_pos; while (((tx_done_pos != comm->tx_pos) || (comm->tx_desc_full == 1)) && budget_left) { @@ -196,7 +196,7 @@ int spl2sw_tx_poll(struct napi_struct *napi, int budget) if (netif_queue_stopped(comm->ndev[i])) netif_wake_queue(comm->ndev[i]); - spin_unlock(&comm->tx_lock); + spin_unlock_irqrestore(&comm->tx_lock, flags); spin_lock_irqsave(&comm->int_mask_lock, flags); mask = readl(comm->l2sw_reg_base + L2SW_SW_INT_MASK_0); -- 2.53.0