aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-11-10 09:11:08 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-11 22:03:35 -0500
commit836cf7faf8c75743477ed6ed341cce491f3183fb (patch)
treee4a8dff4c36bd53080af4dbe1014b91381b79850
parent499428ed28d800eb5cf25889bb1e026637d99dfc (diff)
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>
-rw-r--r--drivers/net/gianfar.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index a5b0038a8d98..fde430a0b84b 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2943,14 +2943,22 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
2943 if (events & IEVENT_CRL) 2943 if (events & IEVENT_CRL)
2944 dev->stats.tx_aborted_errors++; 2944 dev->stats.tx_aborted_errors++;
2945 if (events & IEVENT_XFUN) { 2945 if (events & IEVENT_XFUN) {
2946 unsigned long flags;
2947
2946 if (netif_msg_tx_err(priv)) 2948 if (netif_msg_tx_err(priv))
2947 printk(KERN_DEBUG "%s: TX FIFO underrun, " 2949 printk(KERN_DEBUG "%s: TX FIFO underrun, "
2948 "packet dropped.\n", dev->name); 2950 "packet dropped.\n", dev->name);
2949 dev->stats.tx_dropped++; 2951 dev->stats.tx_dropped++;
2950 priv->extra_stats.tx_underrun++; 2952 priv->extra_stats.tx_underrun++;
2951 2953
2954 local_irq_save(flags);
2955 lock_tx_qs(priv);
2956
2952 /* Reactivate the Tx Queues */ 2957 /* Reactivate the Tx Queues */
2953 gfar_write(&regs->tstat, gfargrp->tstat); 2958 gfar_write(&regs->tstat, gfargrp->tstat);
2959
2960 unlock_tx_qs(priv);
2961 local_irq_restore(flags);
2954 } 2962 }
2955 if (netif_msg_tx_err(priv)) 2963 if (netif_msg_tx_err(priv))
2956 printk(KERN_DEBUG "%s: Transmit Error\n", dev->name); 2964 printk(KERN_DEBUG "%s: Transmit Error\n", dev->name);