Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers/net: use tasklet_kill in device remove/close process

Some driver uses tasklet_disable in device remove/close process,
tasklet_disable will inc tasklet->count and return. If the tasklet
is not handled yet because some softirq pressure, the tasklet will
placed on the tasklet_vec, never have a chance to excute. This might
lead to ksoftirqd heavy loaded, wakeup with pending_softirq, but
tasklet is disabled. tasklet_kill should be used in this case.

Signed-off-by: Xiaotian Feng <dannyfeng@tencent.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xiaotian Feng and committed by
David S. Miller
175c0dff d145f7ec

+9 -9
+4 -4
drivers/net/ethernet/jme.c
··· 1948 1948 1949 1949 JME_NAPI_DISABLE(jme); 1950 1950 1951 - tasklet_disable(&jme->linkch_task); 1952 - tasklet_disable(&jme->txclean_task); 1953 - tasklet_disable(&jme->rxclean_task); 1954 - tasklet_disable(&jme->rxempty_task); 1951 + tasklet_kill(&jme->linkch_task); 1952 + tasklet_kill(&jme->txclean_task); 1953 + tasklet_kill(&jme->rxclean_task); 1954 + tasklet_kill(&jme->rxempty_task); 1955 1955 1956 1956 jme_disable_rx_engine(jme); 1957 1957 jme_disable_tx_engine(jme);
+1 -1
drivers/net/ethernet/marvell/skge.c
··· 4026 4026 dev0 = hw->dev[0]; 4027 4027 unregister_netdev(dev0); 4028 4028 4029 - tasklet_disable(&hw->phy_task); 4029 + tasklet_kill(&hw->phy_task); 4030 4030 4031 4031 spin_lock_irq(&hw->hw_lock); 4032 4032 hw->intr_mask = 0;
+2 -2
drivers/net/ethernet/micrel/ksz884x.c
··· 5407 5407 /* Delay for receive task to stop scheduling itself. */ 5408 5408 msleep(2000 / HZ); 5409 5409 5410 - tasklet_disable(&hw_priv->rx_tasklet); 5411 - tasklet_disable(&hw_priv->tx_tasklet); 5410 + tasklet_kill(&hw_priv->rx_tasklet); 5411 + tasklet_kill(&hw_priv->tx_tasklet); 5412 5412 free_irq(dev->irq, hw_priv->dev); 5413 5413 5414 5414 transmit_cleanup(hw_priv, 0);
+1 -1
drivers/net/ethernet/xilinx/xilinx_axienet_main.c
··· 990 990 axienet_setoptions(ndev, lp->options & 991 991 ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); 992 992 993 - tasklet_disable(&lp->dma_err_tasklet); 993 + tasklet_kill(&lp->dma_err_tasklet); 994 994 995 995 free_irq(lp->tx_irq, ndev); 996 996 free_irq(lp->rx_irq, ndev);
+1 -1
drivers/net/wireless/b43legacy/pio.c
··· 382 382 { 383 383 struct b43legacy_pio_txpacket *packet, *tmp_packet; 384 384 385 - tasklet_disable(&queue->txtask); 385 + tasklet_kill(&queue->txtask); 386 386 387 387 list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) 388 388 free_txpacket(packet, 0);