The patch titled lock validator: fix ns83820.c irq-flags bug has been added to the -mm tree. Its filename is lock-validator-fix-ns83820c-irq-flags-bug.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: lock validator: fix ns83820.c irq-flags bug From: Ingo Molnar <mingo@xxxxxxx> Barry K. Nathan reported the following lockdep warning: [ 197.343948] BUG: warning at kernel/lockdep.c:1856/trace_hardirqs_on() [ 197.345928] [<c010329b>] show_trace_log_lvl+0x5b/0x105 [ 197.346359] [<c0103896>] show_trace+0x1b/0x20 [ 197.346759] [<c01038ed>] dump_stack+0x1f/0x24 [ 197.347159] [<c012efa2>] trace_hardirqs_on+0xfb/0x185 [ 197.348873] [<c029b009>] _spin_unlock_irq+0x24/0x2d [ 197.350620] [<e09034e8>] do_tx_done+0x171/0x179 [ns83820] [ 197.350895] [<e090445c>] ns83820_irq+0x149/0x20b [ns83820] [ 197.351166] [<c013b4b8>] handle_IRQ_event+0x1d/0x52 [ 197.353216] [<c013c6c2>] handle_level_irq+0x97/0xe1 [ 197.355157] [<c01048c3>] do_IRQ+0x8b/0xac [ 197.355612] [<c0102d9d>] common_interrupt+0x25/0x2c this is caused because the ns83820 driver re-enables irq flags in hardirq context. While legal in theory, in practice it should only be done if the hardware is really old and has some very high overhead in its ISR. (such as PIO IDE) For modern hardware, running ISRs with irqs enabled is discouraged, because 1) new hardware is fast enough to not cause latency problems 2) allowing the nesting of hardware interrupts only 'spreads out' the handling of the current ISR, causing extra cachemisses that would otherwise not happen. Furthermore, on architectures where ISRs share the kernel stacks, enabling interrupts in ISRs introduces a much higher kernel-stack-nesting and thus kernel-stack-overflow risk. 3) not managing irq-flags via the _irqsave / _irqrestore variants is dangerous: it's easy to forget whether one function nests inside another, and irq flags might be mismanaged. In the few cases where re-enabling interrupts in an ISR is considered useful (and unavoidable), it has to be taught to the lock validator explicitly (because the lock validator needs the "no ISR ever enables hardirqs" artificial simplification to keep the IRQ/softirq locking dependencies manageable). This teaching is done via the explicit use local_irq_enable_in_hardirq(). On a stock kernel this maps to local_irq_enable(). If the lock validator is enabled then this does not enable interrupts. Now, the analysis of drivers/net/ns83820.c's irq flags use: the irq-enabling in irq context seems intentional, but i dont think it's justified. Furthermore, the driver suffers from problem #3 above too, in ns83820_tx_timeout() it disables irqs via local_irq_save(), but then it calls do_tx_done() which does a spin_unlock_irq(), re-enabling for a function that does not expect it! While currently this bug seems harmless (only some debug printout seems to be affected by it), it's nevertheless something to be fixed. So this patch makes the ns83820 ISR irq-flags-safe, and cleans up do_tx_done() use and locking to avoid the ns83820_tx_timeout() bug. Signed-off-by: Ingo Molnar <mingo@xxxxxxx> Cc: Benjamin LaHaise <bcrl@xxxxxxxxx> Cc: Jeff Garzik <jeff@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/net/ns83820.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff -puN drivers/net/ns83820.c~lock-validator-fix-ns83820c-irq-flags-bug drivers/net/ns83820.c --- devel/drivers/net/ns83820.c~lock-validator-fix-ns83820c-irq-flags-bug 2006-06-04 02:11:48.000000000 -0700 +++ devel-akpm/drivers/net/ns83820.c 2006-06-04 02:11:48.000000000 -0700 @@ -1017,8 +1017,6 @@ static void do_tx_done(struct net_device struct ns83820 *dev = PRIV(ndev); u32 cmdsts, tx_done_idx, *desc; - spin_lock_irq(&dev->tx_lock); - dprintk("do_tx_done(%p)\n", ndev); tx_done_idx = dev->tx_done_idx; desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); @@ -1074,7 +1072,6 @@ static void do_tx_done(struct net_device netif_start_queue(ndev); netif_wake_queue(ndev); } - spin_unlock_irq(&dev->tx_lock); } static void ns83820_cleanup_tx(struct ns83820 *dev) @@ -1462,6 +1459,8 @@ static irqreturn_t ns83820_irq(int foo, static void ns83820_do_isr(struct net_device *ndev, u32 isr) { struct ns83820 *dev = PRIV(ndev); + unsigned long flags; + #ifdef DEBUG if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC)) Dprintk("odd isr? 0x%08x\n", isr); @@ -1476,10 +1475,10 @@ static void ns83820_do_isr(struct net_de if ((ISR_RXDESC | ISR_RXOK) & isr) { prefetch(dev->rx_info.next_rx_desc); - spin_lock_irq(&dev->misc_lock); + spin_lock_irqsave(&dev->misc_lock, flags); dev->IMR_cache &= ~(ISR_RXDESC | ISR_RXOK); writel(dev->IMR_cache, dev->base + IMR); - spin_unlock_irq(&dev->misc_lock); + spin_unlock_irqrestore(&dev->misc_lock, flags); tasklet_schedule(&dev->rx_tasklet); //rx_irq(ndev); @@ -1525,16 +1524,18 @@ static void ns83820_do_isr(struct net_de * work has accumulated */ if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) { + spin_lock_irqsave(&dev->tx_lock, flags); do_tx_done(ndev); + spin_unlock_irqrestore(&dev->tx_lock, flags); /* Disable TxOk if there are no outstanding tx packets. */ if ((dev->tx_done_idx == dev->tx_free_idx) && (dev->IMR_cache & ISR_TXOK)) { - spin_lock_irq(&dev->misc_lock); + spin_lock_irqsave(&dev->misc_lock, flags); dev->IMR_cache &= ~ISR_TXOK; writel(dev->IMR_cache, dev->base + IMR); - spin_unlock_irq(&dev->misc_lock); + spin_unlock_irqrestore(&dev->misc_lock, flags); } } @@ -1545,10 +1546,10 @@ static void ns83820_do_isr(struct net_de * nature are expected, we must enable TxOk. */ if ((ISR_TXIDLE & isr) && (dev->tx_done_idx != dev->tx_free_idx)) { - spin_lock_irq(&dev->misc_lock); + spin_lock_irqsave(&dev->misc_lock, flags); dev->IMR_cache |= ISR_TXOK; writel(dev->IMR_cache, dev->base + IMR); - spin_unlock_irq(&dev->misc_lock); + spin_unlock_irqrestore(&dev->misc_lock, flags); } /* MIB interrupt: one of the statistics counters is about to overflow */ @@ -1610,7 +1611,7 @@ static void ns83820_tx_timeout(struct ne u32 tx_done_idx, *desc; unsigned long flags; - local_irq_save(flags); + spin_lock_irqsave(&dev->tx_lock, flags); tx_done_idx = dev->tx_done_idx; desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); @@ -1637,7 +1638,7 @@ static void ns83820_tx_timeout(struct ne ndev->name, tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); - local_irq_restore(flags); + spin_unlock_irqrestore(&dev->tx_lock, flags); } static void ns83820_tx_watch(unsigned long data) _ Patches currently in -mm which might be from mingo@xxxxxxx are origin.patch git-acpi.patch fix-drivers-mfd-ucb1x00-corec-irq-probing-bug.patch ieee1394-semaphore-to-mutex-conversion.patch git-infiniband.patch git-netdev-all.patch lock-validator-fix-ns83820c-irq-flags-bug.patch lock-validator-netlinkc-netlink_table_grab-fix.patch revert-gregkh-pci-pci-test-that-drivers-properly-call-pci_set_master.patch fall-back-to-old-style-call-trace-if-no-unwinding.patch allow-unwinder-to-build-without-module-support.patch lock-validator-lockdep-small-xfs-init_rwsem-cleanup.patch swapless-pm-add-r-w-migration-entries.patch mm-slabc-fix-early-init-assumption.patch i386-break-out-of-recursion-in-stackframe-walk.patch x86-re-enable-generic-numa.patch vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma.patch vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma-tidy.patch vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma-arch_vma_name-fix.patch vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma-vs-x86_64-mm-reliable-stack-trace-support-i386.patch vdso-randomize-the-i386-vdso-by-moving-it-into-a-vma-vs-x86_64-mm-reliable-stack-trace-support-i386-2.patch powerpc-vdso-updates.patch work-around-ppc64-bootup-bug-by-making-mutex-debugging-save-restore-irqs.patch kernel-kernel-cpuc-to-mutexes.patch cond-resched-might-sleep-fix.patch define-__raw_get_cpu_var-and-use-it.patch ide-cd-end-of-media-error-fix.patch spin-rwlock-init-cleanups.patch inotify-split-kernel-api-from-userspace-support.patch lock-validator-introduce-warn_on_oncecond.patch lock-validator-introduce-warn_on_oncecond-speedup.patch emu10k1-mark-midi_spinlock-as-used.patch epoll-use-unlocked-wqueue-operations.patch time-clocksource-infrastructure.patch sched-fix-smt-nice-lock-contention-and-optimization.patch sched-fix-smt-nice-lock-contention-and-optimization-tidy.patch sched-comment-bitmap-size-accounting.patch sched-fix-interactive-ceiling-code.patch sched-implement-smpnice.patch sched-protect-calculation-of-max_pull-from-integer-wrap.patch sched-store-weighted-load-on-up.patch sched-add-discrete-weighted-cpu-load-function.patch sched-prevent-high-load-weight-tasks-suppressing-balancing.patch sched-improve-stability-of-smpnice-load-balancing.patch sched-improve-smpnice-load-balancing-when-load-per-task.patch smpnice-dont-consider-sched-groups-which-are-lightly-loaded-for-balancing.patch smpnice-dont-consider-sched-groups-which-are-lightly-loaded-for-balancing-fix.patch sched-modify-move_tasks-to-improve-load-balancing-outcomes.patch sched-avoid-unnecessarily-moving-highest-priority-task-move_tasks.patch sched-avoid-unnecessarily-moving-highest-priority-task-move_tasks-fix-2.patch sched_domain-handle-kmalloc-failure.patch sched_domain-handle-kmalloc-failure-fix.patch sched_domain-dont-use-gfp_atomic.patch sched_domain-use-kmalloc_node.patch sched_domain-allocate-sched_group-structures-dynamically.patch sched-add-above-background-load-function.patch mm-implement-swap-prefetching-fix.patch pi-futex-futex-code-cleanups.patch pi-futex-robust-futex-docs-fix.patch pi-futex-introduce-debug_check_no_locks_freed.patch pi-futex-introduce-warn_on_smp.patch pi-futex-add-plist-implementation.patch pi-futex-scheduler-support-for-pi.patch pi-futex-rt-mutex-core.patch pi-futex-rt-mutex-docs.patch pi-futex-rt-mutex-docs-update.patch pi-futex-rt-mutex-debug.patch pi-futex-rt-mutex-tester.patch pi-futex-rt-mutex-futex-api.patch pi-futex-futex_lock_pi-futex_unlock_pi-support.patch futex_requeue-optimization.patch genirq-rename-desc-handler-to-desc-chip.patch genirq-rename-desc-handler-to-desc-chip-power-fix.patch genirq-rename-desc-handler-to-desc-chip-ia64-fix.patch genirq-rename-desc-handler-to-desc-chip-ia64-fix-2.patch genirq-sem2mutex-probe_sem-probing_active.patch genirq-cleanup-merge-irq_affinity-into-irq_desc.patch genirq-cleanup-remove-irq_descp.patch genirq-cleanup-remove-irq_descp-fix.patch genirq-cleanup-remove-fastcall.patch genirq-cleanup-misc-code-cleanups.patch genirq-cleanup-reduce-irq_desc_t-use-mark-it-obsolete.patch genirq-cleanup-include-linux-irqh.patch genirq-cleanup-merge-irq_dir-smp_affinity_entry-into-irq_desc.patch genirq-cleanup-merge-pending_irq_cpumask-into-irq_desc.patch genirq-cleanup-turn-arch_has_irq_per_cpu-into-config_irq_per_cpu.patch genirq-debug-better-debug-printout-in-enable_irq.patch genirq-add-retrigger-irq-op-to-consolidate-hw_irq_resend.patch genirq-doc-comment-include-linux-irqh-structures.patch genirq-doc-handle_irq_event-and-__do_irq-comments.patch genirq-cleanup-no_irq_type-cleanups.patch genirq-doc-add-design-documentation.patch genirq-add-genirq-sw-irq-retrigger.patch genirq-add-irq_noprobe-support.patch genirq-add-irq_norequest-support.patch genirq-add-irq_noautoen-support.patch genirq-update-copyrights.patch genirq-core.patch genirq-msi-fixes-2.patch genirq-add-irq-chip-support.patch genirq-add-irq-chip-support-fix.patch genirq-add-handle_bad_irq.patch genirq-add-irq-wake-power-management-support.patch genirq-add-sa_trigger-support.patch genirq-cleanup-no_irq_type-no_irq_chip-rename.patch genirq-convert-the-x86_64-architecture-to-irq-chips.patch genirq-convert-the-i386-architecture-to-irq-chips.patch genirq-convert-the-i386-architecture-to-irq-chips-fix-2.patch genirq-more-verbose-debugging-on-unexpected-irq-vectors.patch genirq-add-chip-eoi-fastack-fasteoi.patch genirq-add-chip-eoi-fastack-fasteoi-fix.patch lock-validator-floppyc-irq-release-fix.patch lock-validator-floppyc-irq-release-fix-fix.patch lock-validator-forcedethc-fix.patch lock-validator-mutex-section-binutils-workaround.patch lock-validator-add-__module_address-method.patch lock-validator-better-lock-debugging.patch lock-validator-locking-api-self-tests.patch lock-validator-locking-api-self-tests-self-test-fix.patch lock-validator-locking-init-debugging-improvement.patch lock-validator-beautify-x86_64-stacktraces.patch lock-validator-beautify-x86_64-stacktraces-fix.patch lock-validator-beautify-x86_64-stacktraces-fix-2.patch lock-validator-beautify-x86_64-stacktraces-fix-3.patch lock-validator-beautify-x86_64-stacktraces-fix-4.patch lock-validator-x86_64-document-stack-frame-internals.patch lock-validator-stacktrace.patch lock-validator-stacktrace-build-fix.patch lock-validator-stacktrace-warning-fix.patch lock-validator-stacktrace-fix-on-x86_64.patch lock-validator-fown-locking-workaround.patch lock-validator-sk_callback_lock-workaround.patch lock-validator-irqtrace-core.patch lock-validator-irqtrace-core-powerpc-fix-1.patch lock-validator-irqtrace-core-non-x86-fix.patch lock-validator-irqtrace-core-non-x86-fix-2.patch lock-validator-irqtrace-core-non-x86-fix-3.patch lock-validator-irqtrace-entrys-fix.patch lock-validator-irqtrace-core-remove-softirqc-warn_on.patch lock-validator-irqtrace-cleanup-include-asm-i386-irqflagsh.patch lock-validator-irqtrace-cleanup-include-asm-x86_64-irqflagsh.patch lock-validator-x86_64-irqflags-trace-entrys-fix.patch lock-validator-lockdep-add-local_irq_enable_in_hardirq-api.patch lock-validator-add-per_cpu_offset.patch lock-validator-add-per_cpu_offset-fix.patch lock-validator-core.patch lock-validator-core-early_boot_irqs_-build-fix.patch lock-validator-core-fix-compiler-warning.patch lock-validator-procfs.patch lock-validator-core-multichar-fix.patch lock-validator-core-count_matching_names-fix.patch lock-validator-design-docs.patch lock-validator-prove-rwsem-locking-correctness.patch lock-validator-prove-rwsem-locking-correctness-fix.patch lock-validator-prove-rwsem-locking-correctness-powerpc-fix.patch lock-validator-prove-spinlock-rwlock-locking-correctness.patch lock-validator-prove-mutex-locking-correctness.patch lock-validator-prove-mutex-locking-correctness-fix-null-type-name-bug.patch lock-validator-print-all-lock-types-on-sysrq-d.patch lock-validator-x86_64-early-init.patch lock-validator-smp-alternatives-workaround.patch lock-validator-do-not-recurse-in-printk.patch lock-validator-disable-nmi-watchdog-if-config_lockdep.patch lock-validator-disable-nmi-watchdog-if-config_lockdep-i386.patch lock-validator-disable-nmi-watchdog-if-config_lockdep-x86_64.patch lock-validator-special-locking-bdev.patch lock-validator-special-locking-direct-io.patch lock-validator-special-locking-serial.patch lock-validator-special-locking-serial-fix.patch lock-validator-special-locking-dcache.patch lock-validator-special-locking-i_mutex.patch lock-validator-special-locking-s_lock.patch lock-validator-special-locking-futex.patch lock-validator-special-locking-genirq.patch lock-validator-special-locking-completions.patch lock-validator-special-locking-waitqueues.patch lock-validator-special-locking-mm.patch lock-validator-special-locking-serio.patch lock-validator-special-locking-slab.patch lock-validator-special-locking-skb_queue_head_init.patch lock-validator-special-locking-net-ipv4-igmpcpatch.patch lock-validator-special-locking-net-ipv4-igmpc-2.patch lock-validator-special-locking-timerc.patch lock-validator-special-locking-schedc.patch lock-validator-special-locking-hrtimerc.patch lock-validator-special-locking-sock_lock_init.patch lock-validator-special-locking-af_unix.patch lock-validator-special-locking-bh_lock_sock.patch lock-validator-special-locking-mmap_sem.patch lock-validator-special-locking-sb-s_umount.patch lock-validator-special-locking-sb-s_umount-fix.patch lock-validator-special-locking-sb-s_umount-2.patch lock-validator-special-locking-sb-s_umount-2-fix.patch lockdep-annotate-rpc_populate-for.patch lock-validator-special-locking-jbd.patch lock-validator-special-locking-posix-timers.patch lock-validator-special-locking-sch_genericc.patch lock-validator-special-locking-xfrm.patch lockdep-add-i_mutex-ordering-annotations-to-the-sunrpc.patch lockdep-add-parent-child-annotations-to-usbfs.patch lock-validator-special-locking-sound-core-seq-seq_portsc.patch lock-validator-special-locking-sound-core-seq-seq_devicec.patch lock-validator-special-locking-sound-core-seq-seq_devicec-fix.patch lock-validator-fix-rt_hash_lock_sz.patch lock-validator-introduce-irq__lockdep.patch locking-validator-special-rule-8390c-disable_irq.patch locking-validator-special-rule-3c59xc-disable_irq.patch lock-validator-enable-lock-validator-in-kconfig.patch lock-validator-enable-lock-validator-in-kconfig-require-trace_irqflags_support.patch lock-validator-enable-lock-validator-in-kconfig-not-yet.patch lockdep-one-stacktrace-column-if-config_lockdep=y.patch i386-remove-multi-entry-backtraces.patch lockdep-further-improve-stacktrace-output.patch lock-validator-irqtrace-support-non-x86-architectures.patch lock-validator-disable-oprofile-if-lockdep=y.patch lock-validator-select-kallsyms_all.patch lock-validator-special-locking-kgdb.patch detect-atomic-counter-underflows.patch debug-shared-irqs.patch make-frame_pointer-default=y.patch mutex-subsystem-synchro-test-module.patch vdso-print-fatal-signals.patch vdso-improve-print_fatal_signals-support-by-adding-memory-maps.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html