| From 459833e39814ffe6c88be4e8edd3d5b9ef01e098 Mon Sep 17 00:00:00 2001 |
| From: Steven Rostedt <rostedt@goodmis.org> |
| Date: Fri, 3 Jul 2009 08:30:00 -0500 |
| Subject: [PATCH] drivers/net: vortex fix locking issues |
| |
| commit 99c5059eca9de458b1ccd5e1e929d6f27ea56d12 in tip. |
| |
| Argh, cut and paste wasn't enough... |
| |
| Use this patch instead. It needs an irq disable. But, believe it or not, |
| on SMP this is actually better. If the irq is shared (as it is in Mark's |
| case), we don't stop the irq of other devices from being handled on |
| another CPU (unfortunately for Mark, he pinned all interrupts to one CPU). |
| |
| Signed-off-by: Steven Rostedt <rostedt@goodmis.org> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| |
| drivers/net/3c59x.c | 16 +++++++--------- |
| 1 file changed, 7 insertions(+), 9 deletions(-) |
| |
| Signed-off-by: Ingo Molnar <mingo@elte.hu> |
| |
| diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c |
| index 39db0e9..43dcc78 100644 |
| --- a/drivers/net/3c59x.c |
| +++ b/drivers/net/3c59x.c |
| @@ -797,9 +797,9 @@ static void poll_vortex(struct net_device *dev) |
| { |
| struct vortex_private *vp = netdev_priv(dev); |
| unsigned long flags; |
| - local_irq_save(flags); |
| + local_irq_save_nort(flags); |
| (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev); |
| - local_irq_restore(flags); |
| + local_irq_restore_nort(flags); |
| } |
| #endif |
| |
| @@ -1764,6 +1764,7 @@ vortex_timer(unsigned long data) |
| int next_tick = 60*HZ; |
| int ok = 0; |
| int media_status, old_window; |
| + unsigned long flags; |
| |
| if (vortex_debug > 2) { |
| pr_debug("%s: Media selection timer tick happened, %s.\n", |
| @@ -1771,7 +1772,7 @@ vortex_timer(unsigned long data) |
| pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo); |
| } |
| |
| - disable_irq_lockdep(dev->irq); |
| + spin_lock_irqsave(&vp->lock, flags); |
| old_window = ioread16(ioaddr + EL3_CMD) >> 13; |
| EL3WINDOW(4); |
| media_status = ioread16(ioaddr + Wn4_Media); |
| @@ -1794,10 +1795,7 @@ vortex_timer(unsigned long data) |
| case XCVR_MII: case XCVR_NWAY: |
| { |
| ok = 1; |
| - /* Interrupts are already disabled */ |
| - spin_lock(&vp->lock); |
| vortex_check_media(dev, 0); |
| - spin_unlock(&vp->lock); |
| } |
| break; |
| default: /* Other media types handled by Tx timeouts. */ |
| @@ -1851,7 +1849,7 @@ leave_media_alone: |
| dev->name, media_tbl[dev->if_port].name); |
| |
| EL3WINDOW(old_window); |
| - enable_irq_lockdep(dev->irq); |
| + spin_unlock_irqrestore(&vp->lock, flags); |
| mod_timer(&vp->timer, RUN_AT(next_tick)); |
| if (vp->deferred) |
| iowrite16(FakeIntr, ioaddr + EL3_CMD); |
| @@ -1885,12 +1883,12 @@ static void vortex_tx_timeout(struct net_device *dev) |
| * Block interrupts because vortex_interrupt does a bare spin_lock() |
| */ |
| unsigned long flags; |
| - local_irq_save(flags); |
| + local_irq_save_nort(flags); |
| if (vp->full_bus_master_tx) |
| boomerang_interrupt(dev->irq, dev); |
| else |
| vortex_interrupt(dev->irq, dev); |
| - local_irq_restore(flags); |
| + local_irq_restore_nort(flags); |
| } |
| } |
| |
| -- |
| 1.7.1.1 |
| |