aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2006-09-19 08:55:22 -0400
committerJeff Garzik <jeff@garzik.org>2006-10-05 06:48:25 -0400
commit0a07bc645e818b88559d99f52ad45e35352e8228 (patch)
treec7c2c5ed96cd2df1b723c977e3eaef6672e60b9e
parent70fbf32703a9c4d3403663d1fc24fd8afc76d56f (diff)
[PATCH] forcedeth: hardirq lockdep warning
BUG: warning at kernel/lockdep.c:1816/trace_hardirqs_on() (Not tainted) Call Trace: show_trace dump_stack trace_hardirqs_on :forcedeth:nv_nic_irq_other handle_IRQ_event __do_IRQ do_IRQ ret_from_intr DWARF2 barf default_idle cpu_idle rest_init start_kernel _sinittext These 3 functions nv_nic_irq_tx(), nv_nic_irq_rx() and nv_nic_irq_other() are reachable from IRQ context and process context. Make use of the irq-save/restore spinlock variant. (Compile tested only, since I do not have the hardware) Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Jeff Garzik <jeff@garzik.org> Cc: Ingo Molnar <mingo@elte.hu> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Dave Jones <davej@redhat.com> Cc: Andrew Morton <akpm@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/forcedeth.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index eea1d66c530e..35467e0ac538 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2497,6 +2497,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs)
2497 u8 __iomem *base = get_hwbase(dev); 2497 u8 __iomem *base = get_hwbase(dev);
2498 u32 events; 2498 u32 events;
2499 int i; 2499 int i;
2500 unsigned long flags;
2500 2501
2501 dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name); 2502 dprintk(KERN_DEBUG "%s: nv_nic_irq_tx\n", dev->name);
2502 2503
@@ -2508,16 +2509,16 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs)
2508 if (!(events & np->irqmask)) 2509 if (!(events & np->irqmask))
2509 break; 2510 break;
2510 2511
2511 spin_lock_irq(&np->lock); 2512 spin_lock_irqsave(&np->lock, flags);
2512 nv_tx_done(dev); 2513 nv_tx_done(dev);
2513 spin_unlock_irq(&np->lock); 2514 spin_unlock_irqrestore(&np->lock, flags);
2514 2515
2515 if (events & (NVREG_IRQ_TX_ERR)) { 2516 if (events & (NVREG_IRQ_TX_ERR)) {
2516 dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", 2517 dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
2517 dev->name, events); 2518 dev->name, events);
2518 } 2519 }
2519 if (i > max_interrupt_work) { 2520 if (i > max_interrupt_work) {
2520 spin_lock_irq(&np->lock); 2521 spin_lock_irqsave(&np->lock, flags);
2521 /* disable interrupts on the nic */ 2522 /* disable interrupts on the nic */
2522 writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); 2523 writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask);
2523 pci_push(base); 2524 pci_push(base);
@@ -2527,7 +2528,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs)
2527 mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 2528 mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
2528 } 2529 }
2529 printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); 2530 printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
2530 spin_unlock_irq(&np->lock); 2531 spin_unlock_irqrestore(&np->lock, flags);
2531 break; 2532 break;
2532 } 2533 }
2533 2534
@@ -2601,6 +2602,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
2601 u8 __iomem *base = get_hwbase(dev); 2602 u8 __iomem *base = get_hwbase(dev);
2602 u32 events; 2603 u32 events;
2603 int i; 2604 int i;
2605 unsigned long flags;
2604 2606
2605 dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name); 2607 dprintk(KERN_DEBUG "%s: nv_nic_irq_rx\n", dev->name);
2606 2608
@@ -2614,14 +2616,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
2614 2616
2615 nv_rx_process(dev, dev->weight); 2617 nv_rx_process(dev, dev->weight);
2616 if (nv_alloc_rx(dev)) { 2618 if (nv_alloc_rx(dev)) {
2617 spin_lock_irq(&np->lock); 2619 spin_lock_irqsave(&np->lock, flags);
2618 if (!np->in_shutdown) 2620 if (!np->in_shutdown)
2619 mod_timer(&np->oom_kick, jiffies + OOM_REFILL); 2621 mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
2620 spin_unlock_irq(&np->lock); 2622 spin_unlock_irqrestore(&np->lock, flags);
2621 } 2623 }
2622 2624
2623 if (i > max_interrupt_work) { 2625 if (i > max_interrupt_work) {
2624 spin_lock_irq(&np->lock); 2626 spin_lock_irqsave(&np->lock, flags);
2625 /* disable interrupts on the nic */ 2627 /* disable interrupts on the nic */
2626 writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); 2628 writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
2627 pci_push(base); 2629 pci_push(base);
@@ -2631,7 +2633,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs)
2631 mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 2633 mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
2632 } 2634 }
2633 printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); 2635 printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
2634 spin_unlock_irq(&np->lock); 2636 spin_unlock_irqrestore(&np->lock, flags);
2635 break; 2637 break;
2636 } 2638 }
2637 } 2639 }
@@ -2648,6 +2650,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
2648 u8 __iomem *base = get_hwbase(dev); 2650 u8 __iomem *base = get_hwbase(dev);
2649 u32 events; 2651 u32 events;
2650 int i; 2652 int i;
2653 unsigned long flags;
2651 2654
2652 dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name); 2655 dprintk(KERN_DEBUG "%s: nv_nic_irq_other\n", dev->name);
2653 2656
@@ -2660,14 +2663,14 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
2660 break; 2663 break;
2661 2664
2662 if (events & NVREG_IRQ_LINK) { 2665 if (events & NVREG_IRQ_LINK) {
2663 spin_lock_irq(&np->lock); 2666 spin_lock_irqsave(&np->lock, flags);
2664 nv_link_irq(dev); 2667 nv_link_irq(dev);
2665 spin_unlock_irq(&np->lock); 2668 spin_unlock_irqrestore(&np->lock, flags);
2666 } 2669 }
2667 if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { 2670 if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
2668 spin_lock_irq(&np->lock); 2671 spin_lock_irqsave(&np->lock, flags);
2669 nv_linkchange(dev); 2672 nv_linkchange(dev);
2670 spin_unlock_irq(&np->lock); 2673 spin_unlock_irqrestore(&np->lock, flags);
2671 np->link_timeout = jiffies + LINK_TIMEOUT; 2674 np->link_timeout = jiffies + LINK_TIMEOUT;
2672 } 2675 }
2673 if (events & (NVREG_IRQ_UNKNOWN)) { 2676 if (events & (NVREG_IRQ_UNKNOWN)) {
@@ -2675,7 +2678,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
2675 dev->name, events); 2678 dev->name, events);
2676 } 2679 }
2677 if (i > max_interrupt_work) { 2680 if (i > max_interrupt_work) {
2678 spin_lock_irq(&np->lock); 2681 spin_lock_irqsave(&np->lock, flags);
2679 /* disable interrupts on the nic */ 2682 /* disable interrupts on the nic */
2680 writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); 2683 writel(NVREG_IRQ_OTHER, base + NvRegIrqMask);
2681 pci_push(base); 2684 pci_push(base);
@@ -2685,7 +2688,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs)
2685 mod_timer(&np->nic_poll, jiffies + POLL_WAIT); 2688 mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
2686 } 2689 }
2687 printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); 2690 printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
2688 spin_unlock_irq(&np->lock); 2691 spin_unlock_irqrestore(&np->lock, flags);
2689 break; 2692 break;
2690 } 2693 }
2691 2694