| From 471d0d01f33b08a9aa3e6db54c8d172b8bcff7b3 Mon Sep 17 00:00:00 2001 |
| From: Vincent Chen <vincentc@andestech.com> |
| Date: Wed, 21 Nov 2018 09:38:11 +0800 |
| Subject: net: faraday: ftmac100: remove netif_running(netdev) check before |
| disabling interrupts |
| |
| [ Upstream commit 426a593e641ebf0d9288f0a2fcab644a86820220 ] |
| |
| In the original ftmac100_interrupt(), the interrupts are only disabled when |
| the condition "netif_running(netdev)" is true. However, this condition |
| causes kerenl hang in the following case. When the user requests to |
| disable the network device, kernel will clear the bit __LINK_STATE_START |
| from the dev->state and then call the driver's ndo_stop function. Network |
| device interrupts are not blocked during this process. If an interrupt |
| occurs between clearing __LINK_STATE_START and stopping network device, |
| kernel cannot disable the interrupts due to the condition |
| "netif_running(netdev)" in the ISR. Hence, kernel will hang due to the |
| continuous interruption of the network device. |
| |
| In order to solve the above problem, the interrupts of the network device |
| should always be disabled in the ISR without being restricted by the |
| condition "netif_running(netdev)". |
| |
| [V2] |
| Remove unnecessary curly braces. |
| |
| Signed-off-by: Vincent Chen <vincentc@andestech.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ethernet/faraday/ftmac100.c | 7 +++---- |
| 1 file changed, 3 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c |
| index 4ff1adc6bfca..9a0703f2da9a 100644 |
| --- a/drivers/net/ethernet/faraday/ftmac100.c |
| +++ b/drivers/net/ethernet/faraday/ftmac100.c |
| @@ -865,11 +865,10 @@ static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) |
| struct net_device *netdev = dev_id; |
| struct ftmac100 *priv = netdev_priv(netdev); |
| |
| - if (likely(netif_running(netdev))) { |
| - /* Disable interrupts for polling */ |
| - ftmac100_disable_all_int(priv); |
| + /* Disable interrupts for polling */ |
| + ftmac100_disable_all_int(priv); |
| + if (likely(netif_running(netdev))) |
| napi_schedule(&priv->napi); |
| - } |
| |
| return IRQ_HANDLED; |
| } |
| -- |
| 2.19.1 |
| |