Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 836cf7fa authored by Anton Vorontsov's avatar Anton Vorontsov Committed by David S. Miller
Browse files

gianfar: Fix race between gfar_error() and gfar_start_xmit()



gfar_error() can arrive at the middle of gfar_start_xmit() processing,
and so it can trigger transfers of BDs that we don't yet expect to
be transmitted.

Fix this by locking the tx queues in gfar_error().

Signed-off-by: default avatarAnton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: default avatarKumar Gala <galak@kernel.crashing.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 499428ed
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2943,14 +2943,22 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
		if (events & IEVENT_CRL)
			dev->stats.tx_aborted_errors++;
		if (events & IEVENT_XFUN) {
			unsigned long flags;

			if (netif_msg_tx_err(priv))
				printk(KERN_DEBUG "%s: TX FIFO underrun, "
				       "packet dropped.\n", dev->name);
			dev->stats.tx_dropped++;
			priv->extra_stats.tx_underrun++;

			local_irq_save(flags);
			lock_tx_qs(priv);

			/* Reactivate the Tx Queues */
			gfar_write(&regs->tstat, gfargrp->tstat);

			unlock_tx_qs(priv);
			local_irq_restore(flags);
		}
		if (netif_msg_tx_err(priv))
			printk(KERN_DEBUG "%s: Transmit Error\n", dev->name);