Commit 836cf7faf8c75743477ed6ed341cce491f3183fb

Authored by Anton Vorontsov
Committed by David S. Miller
1 parent 499428ed28

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: Anton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 8 additions and 0 deletions Side-by-side Diff

drivers/net/gianfar.c
... ... @@ -2943,14 +2943,22 @@
2943 2943 if (events & IEVENT_CRL)
2944 2944 dev->stats.tx_aborted_errors++;
2945 2945 if (events & IEVENT_XFUN) {
  2946 + unsigned long flags;
  2947 +
2946 2948 if (netif_msg_tx_err(priv))
2947 2949 printk(KERN_DEBUG "%s: TX FIFO underrun, "
2948 2950 "packet dropped.\n", dev->name);
2949 2951 dev->stats.tx_dropped++;
2950 2952 priv->extra_stats.tx_underrun++;
2951 2953  
  2954 + local_irq_save(flags);
  2955 + lock_tx_qs(priv);
  2956 +
2952 2957 /* Reactivate the Tx Queues */
2953 2958 gfar_write(&regs->tstat, gfargrp->tstat);
  2959 +
  2960 + unlock_tx_qs(priv);
  2961 + local_irq_restore(flags);
2954 2962 }
2955 2963 if (netif_msg_tx_err(priv))
2956 2964 printk(KERN_DEBUG "%s: Transmit Error\n", dev->name);