| From 3ef17657c212b7d7e6ea7fb4873fa78df90c5539 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> | |
| Signed-off-by: Ingo Molnar <mingo@elte.hu> | |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> | |
| --- | |
| drivers/net/3c59x.c | 16 +++++++--------- | |
| 1 files changed, 7 insertions(+), 9 deletions(-) | |
| diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c | |
| index 5f92fdb..de4602f 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.0.4 | |