Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
Linus Torvalds [Mon, 3 Jul 2006 22:28:34 +0000 (15:28 -0700)]
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
  powerpc: add defconfig for Freescale MPC8349E-mITX board
  powerpc: Add base support for the Freescale MPC8349E-mITX eval board
  Documentation: correct values in MPC8548E SEC example node
  [POWERPC] Actually copy over i8259.c to arch/ppc/syslib this time
  [POWERPC] Add new interrupt mapping core and change platforms to use it
  [POWERPC] Copy i8259 code back to arch/ppc
  [POWERPC] New device-tree interrupt parsing code
  [POWERPC] Use the genirq framework
  [PATCH] genirq: Allow fasteoi handler to retrigger disabled interrupts
  [POWERPC] Update the SWIM3 (powermac) floppy driver
  [POWERPC] Fix error handling in detecting legacy serial ports
  [POWERPC] Fix booting on Momentum "Apache" board (a Maple derivative)
  [POWERPC] Fix various offb and BootX-related issues
  [POWERPC] Add a default config for 32-bit CHRP machines
  [POWERPC] fix implicit declaration on cell.
  [POWERPC] change get_property to return void *

403 files changed:
Documentation/irqflags-tracing.txt [new file with mode: 0644]
Documentation/kernel-parameters.txt
Documentation/lockdep-design.txt [new file with mode: 0644]
Documentation/sysctl/vm.txt
MAINTAINERS
arch/alpha/kernel/process.c
arch/arm/common/time-acorn.c
arch/arm/mach-aaec2000/core.c
arch/arm/mach-at91rm9200/at91rm9200_time.c
arch/arm/mach-clps711x/time.c
arch/arm/mach-clps7500/core.c
arch/arm/mach-ebsa110/core.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-footbridge/dc21285-timer.c
arch/arm/mach-footbridge/dc21285.c
arch/arm/mach-footbridge/isa-timer.c
arch/arm/mach-h720x/cpu-h7201.c
arch/arm/mach-h720x/cpu-h7202.c
arch/arm/mach-imx/time.c
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/time.c
arch/arm/mach-iop3xx/iop321-time.c
arch/arm/mach-iop3xx/iop331-time.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-ixp23xx/core.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/nas100d-power.c
arch/arm/mach-ixp4xx/nslu2-power.c
arch/arm/mach-lh7a40x/time.c
arch/arm/mach-netx/time.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/fpga.c
arch/arm/mach-omap1/pm.c
arch/arm/mach-omap1/serial.c
arch/arm/mach-omap1/time.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/timer-gp.c
arch/arm/mach-pnx4008/time.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/sharpsl_pm.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/time.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-realview/core.c
arch/arm/mach-rpc/dma.c
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/time.c
arch/arm/mach-s3c2410/usb-simtec.c
arch/arm/mach-sa1100/collie_pm.c
arch/arm/mach-sa1100/dma.c
arch/arm/mach-sa1100/h3600.c
arch/arm/mach-sa1100/time.c
arch/arm/mach-shark/core.c
arch/arm/mach-versatile/core.c
arch/arm/mm/proc-arm720.S
arch/arm/mm/proc-sa110.S
arch/arm/mm/proc-sa1100.S
arch/arm/oprofile/op_model_xscale.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/pm.c
arch/arm/plat-omap/timer32k.c
arch/i386/Kconfig
arch/i386/Kconfig.debug
arch/i386/kernel/Makefile
arch/i386/kernel/alternative.c
arch/i386/kernel/entry.S
arch/i386/kernel/irq.c
arch/i386/kernel/nmi.c
arch/i386/kernel/stacktrace.c [new file with mode: 0644]
arch/i386/kernel/traps.c
arch/ia64/kernel/mca.c
arch/ia64/kernel/smpboot.c
arch/mips/kernel/entry.S
arch/mips/kernel/mips-mt.c
arch/powerpc/kernel/irq.c
arch/s390/Kconfig
arch/s390/Kconfig.debug
arch/s390/Makefile
arch/s390/kernel/Makefile
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/irq.c
arch/s390/kernel/process.c
arch/s390/kernel/stacktrace.c [new file with mode: 0644]
arch/um/kernel/tt/process_kern.c
arch/um/kernel/um_arch.c
arch/x86_64/Kconfig
arch/x86_64/Kconfig.debug
arch/x86_64/ia32/ia32entry.S
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/head64.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/stacktrace.c [new file with mode: 0644]
arch/x86_64/kernel/traps.c
arch/x86_64/lib/thunk.S
arch/x86_64/mm/fault.c
block/ll_rw_blk.c
drivers/block/floppy.c
drivers/char/agp/frontend.c
drivers/char/applicom.c
drivers/char/cs5535_gpio.c
drivers/char/ds1286.c
drivers/char/ds1302.c
drivers/char/ds1620.c
drivers/char/dsp56k.c
drivers/char/dtlk.c
drivers/char/efirtc.c
drivers/char/ftape/zftape/zftape-init.c
drivers/char/genrtc.c
drivers/char/hpet.c
drivers/char/hw_random/core.c
drivers/char/i8k.c
drivers/char/ip2/ip2main.c
drivers/char/ip27-rtc.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/ipmi/ipmi_watchdog.c
drivers/char/istallion.c
drivers/char/ite_gpio.c
drivers/char/lcd.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/mmtimer.c
drivers/char/mwave/mwavedd.c
drivers/char/nvram.c
drivers/char/nwbutton.c
drivers/char/nwflash.c
drivers/char/pc8736x_gpio.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/ppdev.c
drivers/char/random.c
drivers/char/raw.c
drivers/char/rio/rio_linux.c
drivers/char/rtc.c
drivers/char/scx200_gpio.c
drivers/char/snsc.c
drivers/char/sonypi.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/sysrq.c
drivers/char/tb0219.c
drivers/char/tipar.c
drivers/char/tlclk.c
drivers/char/toshiba.c
drivers/char/tpm/tpm_atmel.c
drivers/char/tpm/tpm_infineon.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tpm/tpm_tis.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/viotape.c
drivers/char/vr41xx_giu.c
drivers/char/vt.c
drivers/char/watchdog/acquirewdt.c
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/alim1535_wdt.c
drivers/char/watchdog/alim7101_wdt.c
drivers/char/watchdog/at91_wdt.c
drivers/char/watchdog/booke_wdt.c
drivers/char/watchdog/cpu5wdt.c
drivers/char/watchdog/ep93xx_wdt.c
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/i6300esb.c
drivers/char/watchdog/i8xx_tco.c
drivers/char/watchdog/ib700wdt.c
drivers/char/watchdog/ibmasr.c
drivers/char/watchdog/indydog.c
drivers/char/watchdog/ixp2000_wdt.c
drivers/char/watchdog/ixp4xx_wdt.c
drivers/char/watchdog/machzwd.c
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/mpc83xx_wdt.c
drivers/char/watchdog/mpc8xx_wdt.c
drivers/char/watchdog/mpcore_wdt.c
drivers/char/watchdog/mv64x60_wdt.c
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd_pci.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/s3c2410_wdt.c
drivers/char/watchdog/sa1100_wdt.c
drivers/char/watchdog/sbc60xxwdt.c
drivers/char/watchdog/sbc8360.c
drivers/char/watchdog/sbc_epx_c3.c
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/scx200_wdt.c
drivers/char/watchdog/shwdt.c
drivers/char/watchdog/softdog.c
drivers/char/watchdog/w83627hf_wdt.c
drivers/char/watchdog/w83877f_wdt.c
drivers/char/watchdog/w83977f_wdt.c
drivers/char/watchdog/wafer5823wdt.c
drivers/char/watchdog/wdrtas.c
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt285.c
drivers/char/watchdog/wdt977.c
drivers/char/watchdog/wdt_pci.c
drivers/ide/ide-floppy.c
drivers/ide/ide-io.c
drivers/ide/ide-taskfile.c
drivers/ieee1394/hosts.c
drivers/input/serio/i8042-sparcio.h
drivers/input/serio/libps2.c
drivers/md/md.c
drivers/mmc/mmc.c
drivers/mmc/sdhci.c
drivers/net/3c59x.c
drivers/net/8390.c
drivers/net/forcedeth.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/pnp/pnpacpi/rsparser.c
drivers/s390/char/sclp.c
drivers/s390/cio/cio.c
drivers/s390/net/qeth_main.c
drivers/s390/s390mach.c
drivers/scsi/libata-core.c
drivers/serial/8250_pnp.c
drivers/serial/serial_core.c
drivers/spi/spi.c
drivers/usb/core/inode.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/pnx4008/Makefile [new file with mode: 0644]
drivers/video/pnx4008/dum.h [new file with mode: 0644]
drivers/video/pnx4008/fbcommon.h [new file with mode: 0644]
drivers/video/pnx4008/pnxrgbfb.c [new file with mode: 0644]
drivers/video/pnx4008/sdum.c [new file with mode: 0644]
drivers/video/pnx4008/sdum.h [new file with mode: 0644]
fs/binfmt_elf.c
fs/block_dev.c
fs/dcache.c
fs/direct-io.c
fs/eventpoll.c
fs/ext2/super.c
fs/ext3/super.c
fs/namei.c
fs/ntfs/inode.c
fs/ntfs/super.c
fs/reiserfs/super.c
fs/super.c
fs/ufs/super.c
include/asm-alpha/rwsem.h
include/asm-arm/floppy.h
include/asm-arm/hw_irq.h
include/asm-arm/mach/time.h
include/asm-arm/signal.h
include/asm-generic/mutex-null.h
include/asm-generic/percpu.h
include/asm-i386/irqflags.h [new file with mode: 0644]
include/asm-i386/rwsem.h
include/asm-i386/spinlock.h
include/asm-i386/system.h
include/asm-ia64/irq.h
include/asm-ia64/percpu.h
include/asm-ia64/rwsem.h
include/asm-ia64/thread_info.h
include/asm-m32r/system.h
include/asm-powerpc/irqflags.h [new file with mode: 0644]
include/asm-powerpc/percpu.h
include/asm-powerpc/rwsem.h
include/asm-s390/irqflags.h [new file with mode: 0644]
include/asm-s390/percpu.h
include/asm-s390/rwsem.h
include/asm-s390/semaphore.h
include/asm-s390/system.h
include/asm-sh/rwsem.h
include/asm-sh/system.h
include/asm-sparc64/percpu.h
include/asm-x86_64/irqflags.h [new file with mode: 0644]
include/asm-x86_64/kdebug.h
include/asm-x86_64/percpu.h
include/asm-x86_64/system.h
include/asm-xtensa/rwsem.h
include/linux/completion.h
include/linux/dcache.h
include/linux/debug_locks.h [new file with mode: 0644]
include/linux/fs.h
include/linux/hardirq.h
include/linux/hrtimer.h
include/linux/ide.h
include/linux/idr.h
include/linux/init_task.h
include/linux/interrupt.h
include/linux/ioport.h
include/linux/irq.h
include/linux/irqflags.h [new file with mode: 0644]
include/linux/kallsyms.h
include/linux/lockdep.h [new file with mode: 0644]
include/linux/mm.h
include/linux/mmzone.h
include/linux/module.h
include/linux/mutex-debug.h
include/linux/mutex.h
include/linux/notifier.h
include/linux/pci_ids.h
include/linux/rtmutex.h
include/linux/rwsem-spinlock.h
include/linux/rwsem.h
include/linux/sched.h
include/linux/seqlock.h
include/linux/skbuff.h
include/linux/spinlock.h
include/linux/spinlock_api_smp.h
include/linux/spinlock_api_up.h
include/linux/spinlock_types.h
include/linux/spinlock_types_up.h
include/linux/spinlock_up.h
include/linux/stacktrace.h [new file with mode: 0644]
include/linux/swap.h
include/linux/sysctl.h
include/linux/wait.h
include/net/af_unix.h
include/net/sock.h
init/main.c
kernel/Makefile
kernel/capability.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/hrtimer.c
kernel/irq/handle.c
kernel/irq/manage.c
kernel/kmod.c
kernel/lockdep.c [new file with mode: 0644]
kernel/lockdep_internals.h [new file with mode: 0644]
kernel/lockdep_proc.c [new file with mode: 0644]
kernel/module.c
kernel/mutex-debug.c
kernel/mutex-debug.h
kernel/mutex.c
kernel/mutex.h
kernel/pid.c
kernel/printk.c
kernel/ptrace.c
kernel/rcupdate.c
kernel/rtmutex-debug.c
kernel/rtmutex-debug.h
kernel/rtmutex-tester.c
kernel/rtmutex.c
kernel/rtmutex.h
kernel/rwsem.c [new file with mode: 0644]
kernel/sched.c
kernel/softirq.c
kernel/spinlock.c
kernel/stacktrace.c [new file with mode: 0644]
kernel/sysctl.c
kernel/timer.c
kernel/wait.c
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/debug_locks.c [new file with mode: 0644]
lib/kernel_lock.c
lib/locking-selftest-hardirq.h [new file with mode: 0644]
lib/locking-selftest-mutex.h [new file with mode: 0644]
lib/locking-selftest-rlock-hardirq.h [new file with mode: 0644]
lib/locking-selftest-rlock-softirq.h [new file with mode: 0644]
lib/locking-selftest-rlock.h [new file with mode: 0644]
lib/locking-selftest-rsem.h [new file with mode: 0644]
lib/locking-selftest-softirq.h [new file with mode: 0644]
lib/locking-selftest-spin-hardirq.h [new file with mode: 0644]
lib/locking-selftest-spin-softirq.h [new file with mode: 0644]
lib/locking-selftest-spin.h [new file with mode: 0644]
lib/locking-selftest-wlock-hardirq.h [new file with mode: 0644]
lib/locking-selftest-wlock-softirq.h [new file with mode: 0644]
lib/locking-selftest-wlock.h [new file with mode: 0644]
lib/locking-selftest-wsem.h [new file with mode: 0644]
lib/locking-selftest.c [new file with mode: 0644]
lib/rwsem-spinlock.c
lib/rwsem.c
lib/spinlock_debug.c
mm/memory.c
mm/mremap.c
mm/oom_kill.c
mm/page_alloc.c
mm/slab.c
mm/swap_state.c
mm/vmalloc.c
mm/vmscan.c
net/8021q/vlan.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/route.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/netlink/af_netlink.c
net/sunrpc/rpc_pipe.c
net/unix/af_unix.c
sound/core/seq/seq_device.c
sound/core/seq/seq_ports.c
sound/sparc/amd7930.c
sound/sparc/cs4231.c
sound/sparc/dbri.c

diff --git a/Documentation/irqflags-tracing.txt b/Documentation/irqflags-tracing.txt
new file mode 100644 (file)
index 0000000..6a44487
--- /dev/null
@@ -0,0 +1,57 @@
+IRQ-flags state tracing
+
+started by Ingo Molnar <mingo@redhat.com>
+
+the "irq-flags tracing" feature "traces" hardirq and softirq state, in
+that it gives interested subsystems an opportunity to be notified of
+every hardirqs-off/hardirqs-on, softirqs-off/softirqs-on event that
+happens in the kernel.
+
+CONFIG_TRACE_IRQFLAGS_SUPPORT is needed for CONFIG_PROVE_SPIN_LOCKING
+and CONFIG_PROVE_RW_LOCKING to be offered by the generic lock debugging
+code. Otherwise only CONFIG_PROVE_MUTEX_LOCKING and
+CONFIG_PROVE_RWSEM_LOCKING will be offered on an architecture - these
+are locking APIs that are not used in IRQ context. (the one exception
+for rwsems is worked around)
+
+architecture support for this is certainly not in the "trivial"
+category, because lots of lowlevel assembly code deal with irq-flags
+state changes. But an architecture can be irq-flags-tracing enabled in a
+rather straightforward and risk-free manner.
+
+Architectures that want to support this need to do a couple of
+code-organizational changes first:
+
+- move their irq-flags manipulation code from their asm/system.h header
+  to asm/irqflags.h
+
+- rename local_irq_disable()/etc to raw_local_irq_disable()/etc. so that
+  the linux/irqflags.h code can inject callbacks and can construct the
+  real local_irq_disable()/etc APIs.
+
+- add and enable TRACE_IRQFLAGS_SUPPORT in their arch level Kconfig file
+
+and then a couple of functional changes are needed as well to implement
+irq-flags-tracing support:
+
+- in lowlevel entry code add (build-conditional) calls to the
+  trace_hardirqs_off()/trace_hardirqs_on() functions. The lock validator
+  closely guards whether the 'real' irq-flags matches the 'virtual'
+  irq-flags state, and complains loudly (and turns itself off) if the
+  two do not match. Usually most of the time for arch support for
+  irq-flags-tracing is spent in this state: look at the lockdep
+  complaint, try to figure out the assembly code we did not cover yet,
+  fix and repeat. Once the system has booted up and works without a
+  lockdep complaint in the irq-flags-tracing functions arch support is
+  complete.
+- if the architecture has non-maskable interrupts then those need to be
+  excluded from the irq-tracing [and lock validation] mechanism via
+  lockdep_off()/lockdep_on().
+
+in general there is no risk from having an incomplete irq-flags-tracing
+implementation in an architecture: lockdep will detect that and will
+turn itself off. I.e. the lock validator will still be reliable. There
+should be no crashes due to irq-tracing bugs. (except if the assembly
+changes break other code by modifying conditions or registers that
+shouldnt be)
+
index 86e9282..149f62b 100644 (file)
@@ -435,6 +435,15 @@ running once the system is up.
 
        debug           [KNL] Enable kernel debugging (events log level).
 
+       debug_locks_verbose=
+                       [KNL] verbose self-tests
+                       Format=<0|1>
+                       Print debugging info while doing the locking API
+                       self-tests.
+                       We default to 0 (no extra messages), setting it to
+                       1 will print _a lot_ more information - normally
+                       only useful to kernel developers.
+
        decnet=         [HW,NET]
                        Format: <area>[,<node>]
                        See also Documentation/networking/decnet.txt.
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt
new file mode 100644 (file)
index 0000000..00d9360
--- /dev/null
@@ -0,0 +1,197 @@
+Runtime locking correctness validator
+=====================================
+
+started by Ingo Molnar <mingo@redhat.com>
+additions by Arjan van de Ven <arjan@linux.intel.com>
+
+Lock-class
+----------
+
+The basic object the validator operates upon is a 'class' of locks.
+
+A class of locks is a group of locks that are logically the same with
+respect to locking rules, even if the locks may have multiple (possibly
+tens of thousands of) instantiations. For example a lock in the inode
+struct is one class, while each inode has its own instantiation of that
+lock class.
+
+The validator tracks the 'state' of lock-classes, and it tracks
+dependencies between different lock-classes. The validator maintains a
+rolling proof that the state and the dependencies are correct.
+
+Unlike an lock instantiation, the lock-class itself never goes away: when
+a lock-class is used for the first time after bootup it gets registered,
+and all subsequent uses of that lock-class will be attached to this
+lock-class.
+
+State
+-----
+
+The validator tracks lock-class usage history into 5 separate state bits:
+
+- 'ever held in hardirq context'                    [ == hardirq-safe   ]
+- 'ever held in softirq context'                    [ == softirq-safe   ]
+- 'ever held with hardirqs enabled'                 [ == hardirq-unsafe ]
+- 'ever held with softirqs and hardirqs enabled'    [ == softirq-unsafe ]
+
+- 'ever used'                                       [ == !unused        ]
+
+Single-lock state rules:
+------------------------
+
+A softirq-unsafe lock-class is automatically hardirq-unsafe as well. The
+following states are exclusive, and only one of them is allowed to be
+set for any lock-class:
+
+ <hardirq-safe> and <hardirq-unsafe>
+ <softirq-safe> and <softirq-unsafe>
+
+The validator detects and reports lock usage that violate these
+single-lock state rules.
+
+Multi-lock dependency rules:
+----------------------------
+
+The same lock-class must not be acquired twice, because this could lead
+to lock recursion deadlocks.
+
+Furthermore, two locks may not be taken in different order:
+
+ <L1> -> <L2>
+ <L2> -> <L1>
+
+because this could lead to lock inversion deadlocks. (The validator
+finds such dependencies in arbitrary complexity, i.e. there can be any
+other locking sequence between the acquire-lock operations, the
+validator will still track all dependencies between locks.)
+
+Furthermore, the following usage based lock dependencies are not allowed
+between any two lock-classes:
+
+   <hardirq-safe>   ->  <hardirq-unsafe>
+   <softirq-safe>   ->  <softirq-unsafe>
+
+The first rule comes from the fact the a hardirq-safe lock could be
+taken by a hardirq context, interrupting a hardirq-unsafe lock - and
+thus could result in a lock inversion deadlock. Likewise, a softirq-safe
+lock could be taken by an softirq context, interrupting a softirq-unsafe
+lock.
+
+The above rules are enforced for any locking sequence that occurs in the
+kernel: when acquiring a new lock, the validator checks whether there is
+any rule violation between the new lock and any of the held locks.
+
+When a lock-class changes its state, the following aspects of the above
+dependency rules are enforced:
+
+- if a new hardirq-safe lock is discovered, we check whether it
+  took any hardirq-unsafe lock in the past.
+
+- if a new softirq-safe lock is discovered, we check whether it took
+  any softirq-unsafe lock in the past.
+
+- if a new hardirq-unsafe lock is discovered, we check whether any
+  hardirq-safe lock took it in the past.
+
+- if a new softirq-unsafe lock is discovered, we check whether any
+  softirq-safe lock took it in the past.
+
+(Again, we do these checks too on the basis that an interrupt context
+could interrupt _any_ of the irq-unsafe or hardirq-unsafe locks, which
+could lead to a lock inversion deadlock - even if that lock scenario did
+not trigger in practice yet.)
+
+Exception: Nested data dependencies leading to nested locking
+-------------------------------------------------------------
+
+There are a few cases where the Linux kernel acquires more than one
+instance of the same lock-class. Such cases typically happen when there
+is some sort of hierarchy within objects of the same type. In these
+cases there is an inherent "natural" ordering between the two objects
+(defined by the properties of the hierarchy), and the kernel grabs the
+locks in this fixed order on each of the objects.
+
+An example of such an object hieararchy that results in "nested locking"
+is that of a "whole disk" block-dev object and a "partition" block-dev
+object; the partition is "part of" the whole device and as long as one
+always takes the whole disk lock as a higher lock than the partition
+lock, the lock ordering is fully correct. The validator does not
+automatically detect this natural ordering, as the locking rule behind
+the ordering is not static.
+
+In order to teach the validator about this correct usage model, new
+versions of the various locking primitives were added that allow you to
+specify a "nesting level". An example call, for the block device mutex,
+looks like this:
+
+enum bdev_bd_mutex_lock_class
+{
+       BD_MUTEX_NORMAL,
+       BD_MUTEX_WHOLE,
+       BD_MUTEX_PARTITION
+};
+
+ mutex_lock_nested(&bdev->bd_contains->bd_mutex, BD_MUTEX_PARTITION);
+
+In this case the locking is done on a bdev object that is known to be a
+partition.
+
+The validator treats a lock that is taken in such a nested fasion as a
+separate (sub)class for the purposes of validation.
+
+Note: When changing code to use the _nested() primitives, be careful and
+check really thoroughly that the hiearchy is correctly mapped; otherwise
+you can get false positives or false negatives.
+
+Proof of 100% correctness:
+--------------------------
+
+The validator achieves perfect, mathematical 'closure' (proof of locking
+correctness) in the sense that for every simple, standalone single-task
+locking sequence that occured at least once during the lifetime of the
+kernel, the validator proves it with a 100% certainty that no
+combination and timing of these locking sequences can cause any class of
+lock related deadlock. [*]
+
+I.e. complex multi-CPU and multi-task locking scenarios do not have to
+occur in practice to prove a deadlock: only the simple 'component'
+locking chains have to occur at least once (anytime, in any
+task/context) for the validator to be able to prove correctness. (For
+example, complex deadlocks that would normally need more than 3 CPUs and
+a very unlikely constellation of tasks, irq-contexts and timings to
+occur, can be detected on a plain, lightly loaded single-CPU system as
+well!)
+
+This radically decreases the complexity of locking related QA of the
+kernel: what has to be done during QA is to trigger as many "simple"
+single-task locking dependencies in the kernel as possible, at least
+once, to prove locking correctness - instead of having to trigger every
+possible combination of locking interaction between CPUs, combined with
+every possible hardirq and softirq nesting scenario (which is impossible
+to do in practice).
+
+[*] assuming that the validator itself is 100% correct, and no other
+    part of the system corrupts the state of the validator in any way.
+    We also assume that all NMI/SMM paths [which could interrupt
+    even hardirq-disabled codepaths] are correct and do not interfere
+    with the validator. We also assume that the 64-bit 'chain hash'
+    value is unique for every lock-chain in the system. Also, lock
+    recursion must not be higher than 20.
+
+Performance:
+------------
+
+The above rules require _massive_ amounts of runtime checking. If we did
+that for every lock taken and for every irqs-enable event, it would
+render the system practically unusably slow. The complexity of checking
+is O(N^2), so even with just a few hundred lock-classes we'd have to do
+tens of thousands of checks for every event.
+
+This problem is solved by checking any given 'locking scenario' (unique
+sequence of locks taken after each other) only once. A simple stack of
+held locks is maintained, and a lightweight 64-bit hash value is
+calculated, which hash is unique for every lock chain. The hash value,
+when the chain is validated for the first time, is then put into a hash
+table, which hash-table can be checked in a lockfree manner. If the
+locking chain occurs again later on, the hash table tells us that we
+dont have to validate the chain again.
index 86754eb..7cee902 100644 (file)
@@ -28,6 +28,7 @@ Currently, these files are in /proc/sys/vm:
 - block_dump
 - drop-caches
 - zone_reclaim_mode
+- min_unmapped_ratio
 - panic_on_oom
 
 ==============================================================
@@ -168,6 +169,19 @@ in all nodes of the system.
 
 =============================================================
 
+min_unmapped_ratio:
+
+This is available only on NUMA kernels.
+
+A percentage of the file backed pages in each zone.  Zone reclaim will only
+occur if more than this percentage of pages are file backed and unmapped.
+This is to insure that a minimal amount of local pages is still available for
+file I/O even if the node is overallocated.
+
+The default is 1 percent.
+
+=============================================================
+
 panic_on_oom
 
 This enables or disables panic on out-of-memory feature.  If this is set to 1,
index 42be131..5f76a4f 100644 (file)
@@ -861,6 +861,8 @@ S:  Maintained
 DOCBOOK FOR DOCUMENTATION
 P:     Martin Waitz
 M:     tali@admingilde.org
+P:     Randy Dunlap
+M:     rdunlap@xenotime.net
 T:     git http://tali.admingilde.org/git/linux-docbook.git
 S:     Maintained
 
@@ -2298,6 +2300,14 @@ M:       promise@pnd-pc.demon.co.uk
 W:     http://www.pnd-pc.demon.co.uk/promise/
 S:     Maintained
 
+PVRUSB2 VIDEO4LINUX DRIVER
+P:     Mike Isely
+M:     isely@pobox.com
+L:     pvrusb2@isely.net
+L:     video4linux-list@redhat.com
+W:     http://www.isely.net/pvrusb2/
+S:     Maintained
+
 PXA2xx SUPPORT
 P:     Nicolas Pitre
 M:     nico@cam.org
index 01c8c8b..41ebf51 100644 (file)
@@ -474,7 +474,7 @@ out:
  */
 
 unsigned long
-thread_saved_pc(task_t *t)
+thread_saved_pc(struct task_struct *t)
 {
        unsigned long base = (unsigned long)task_stack_page(t);
        unsigned long fp, sp = task_thread_info(t)->pcb.ksp;
index 31b65e2..3f60dd9 100644 (file)
@@ -77,7 +77,7 @@ ioc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction ioc_timer_irq = {
        .name           = "timer",
-       .flags          = SA_INTERRUPT,
+       .flags          = IRQF_DISABLED,
        .handler        = ioc_timer_interrupt
 };
 
index aa01d67..baa997c 100644 (file)
@@ -142,7 +142,7 @@ aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction aaec2000_timer_irq = {
        .name           = "AAEC-2000 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = aaec2000_timer_interrupt,
 };
 
index 0aa2265..a92a862 100644 (file)
@@ -85,7 +85,7 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_r
 
 static struct irqaction at91rm9200_timer_irq = {
        .name           = "at91_tick",
-       .flags          = SA_SHIRQ | SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
        .handler        = at91rm9200_timer_interrupt
 };
 
index b0f1db2..a071eac 100644 (file)
@@ -58,7 +58,7 @@ p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction clps711x_timer_irq = {
        .name           = "CLPS711x Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = p720t_timer_interrupt,
 };
 
index cd66df8..92eaebd 100644 (file)
@@ -316,7 +316,7 @@ clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction clps7500_timer_irq = {
        .name           = "CLPS7500 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = clps7500_timer_interrupt,
 };
 
index 6d620d8..70dd12e 100644 (file)
@@ -199,7 +199,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction ebsa110_timer_irq = {
        .name           = "EBSA110 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = ebsa110_timer_interrupt,
 };
 
index 26df3b6..a87a784 100644 (file)
@@ -116,7 +116,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction ep93xx_timer_irq = {
        .name           = "ep93xx timer",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = ep93xx_timer_interrupt,
 };
 
index e668d4a..2af6108 100644 (file)
@@ -44,7 +44,7 @@ timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static struct irqaction footbridge_timer_irq = {
        .name           = "Timer1 timer tick",
        .handler        = timer1_interrupt,
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
 };
 
 /*
index 5dace25..607ed1f 100644 (file)
@@ -332,15 +332,15 @@ void __init dc21285_preinit(void)
        /*
         * We don't care if these fail.
         */
-       request_irq(IRQ_PCI_SERR, dc21285_serr_irq, SA_INTERRUPT,
+       request_irq(IRQ_PCI_SERR, dc21285_serr_irq, IRQF_DISABLED,
                    "PCI system error", &serr_timer);
-       request_irq(IRQ_PCI_PERR, dc21285_parity_irq, SA_INTERRUPT,
+       request_irq(IRQ_PCI_PERR, dc21285_parity_irq, IRQF_DISABLED,
                    "PCI parity error", &perr_timer);
-       request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, SA_INTERRUPT,
+       request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, IRQF_DISABLED,
                    "PCI abort", NULL);
-       request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, SA_INTERRUPT,
+       request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, IRQF_DISABLED,
                    "Discard timer", NULL);
-       request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, SA_INTERRUPT,
+       request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, IRQF_DISABLED,
                    "PCI data parity", NULL);
 
        if (cfn_mode) {
index 282b473..c4810a4 100644 (file)
@@ -73,7 +73,7 @@ isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static struct irqaction isa_timer_irq = {
        .name           = "ISA timer tick",
        .handler        = isa_timer_interrupt,
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
 };
 
 static void __init isa_timer_init(void)
index af9e4a5..a9a8255 100644 (file)
@@ -41,7 +41,7 @@ h7201_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction h7201_timer_irq = {
        .name           = "h7201 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = h7201_timer_interrupt,
 };
 
index a4a7c01..da678d1 100644 (file)
@@ -171,7 +171,7 @@ static struct irqchip h7202_timerx_chip = {
 
 static struct irqaction h7202_timer_irq = {
        .name           = "h7202 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = h7202_timer_interrupt,
 };
 
index 5f9a047..6ed7523 100644 (file)
@@ -72,7 +72,7 @@ imx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction imx_timer_irq = {
        .name           = "i.MX Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = imx_timer_interrupt,
 };
 
index 2d7e505..42021fd 100644 (file)
@@ -282,7 +282,7 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction integrator_timer_irq = {
        .name           = "Integrator Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = integrator_timer_interrupt,
 };
 
index bc07f52..ee49cf7 100644 (file)
@@ -125,7 +125,7 @@ static int rtc_probe(struct amba_device *dev, void *id)
 
        xtime.tv_sec = __raw_readl(rtc_base + RTC_DR);
 
-       ret = request_irq(dev->irq[0], arm_rtc_interrupt, SA_INTERRUPT,
+       ret = request_irq(dev->irq[0], arm_rtc_interrupt, IRQF_DISABLED,
                          "rtc-pl030", dev);
        if (ret)
                goto map_out;
index d67ac0e..04b1a6f 100644 (file)
@@ -85,7 +85,7 @@ iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static struct irqaction iop321_timer_irq = {
        .name           = "IOP321 Timer Tick",
        .handler        = iop321_timer_interrupt,
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
 };
 
 static void __init iop321_timer_init(void)
index 3c1f0eb..0c09e74 100644 (file)
@@ -82,7 +82,7 @@ iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static struct irqaction iop331_timer_irq = {
        .name           = "IOP331 Timer Tick",
        .handler        = iop331_timer_interrupt,
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
 };
 
 static void __init iop331_timer_init(void)
index b31f31a..7f91f68 100644 (file)
@@ -224,7 +224,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction ixp2000_timer_irq = {
        .name           = "IXP2000 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = ixp2000_timer_interrupt,
 };
 
index 7c218ae..566a078 100644 (file)
@@ -363,7 +363,7 @@ ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static struct irqaction ixp23xx_timer_irq = {
        .name           = "IXP23xx Timer Tick",
        .handler        = ixp23xx_timer_interrupt,
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
 };
 
 void __init ixp23xx_init_timer(void)
index 13c7c62..7c25dbd 100644 (file)
@@ -287,7 +287,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs
 
 static struct irqaction ixp4xx_timer_irq = {
        .name           = "IXP4xx Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = ixp4xx_timer_interrupt,
 };
 
index f58a1d0..81ffcae 100644 (file)
@@ -42,7 +42,7 @@ static int __init nas100d_power_init(void)
        set_irq_type(NAS100D_RB_IRQ, IRQT_LOW);
 
        if (request_irq(NAS100D_RB_IRQ, &nas100d_reset_handler,
-               SA_INTERRUPT, "NAS100D reset button", NULL) < 0) {
+               IRQF_DISABLED, "NAS100D reset button", NULL) < 0) {
 
                printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
                        NAS100D_RB_IRQ);
index 6d38e97..e2a2230 100644 (file)
@@ -54,7 +54,7 @@ static int __init nslu2_power_init(void)
        set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
 
        if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
-               SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
+               IRQF_DISABLED, "NSLU2 reset button", NULL) < 0) {
 
                printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
                        NSLU2_RB_IRQ);
@@ -63,7 +63,7 @@ static int __init nslu2_power_init(void)
        }
 
        if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler,
-               SA_INTERRUPT, "NSLU2 power button", NULL) < 0) {
+               IRQF_DISABLED, "NSLU2 power button", NULL) < 0) {
 
                printk(KERN_DEBUG "Power Button IRQ %d not available\n",
                        NSLU2_PB_IRQ);
index 4d26c9f..ad5652e 100644 (file)
@@ -53,7 +53,7 @@ lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction lh7a40x_timer_irq = {
        .name           = "LHA740x Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = lh7a40x_timer_interrupt,
 };
 
index edfbdf4..6d72c81 100644 (file)
@@ -54,7 +54,7 @@ netx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction netx_timer_irq = {
        .name           = "NetX Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = netx_timer_interrupt,
 };
 
index 9193330..b742261 100644 (file)
@@ -357,7 +357,7 @@ static void __init osk_mistral_init(void)
                 */
                ret = request_irq(OMAP_GPIO_IRQ(OMAP_MPUIO(2)),
                                &osk_mistral_wake_interrupt,
-                               SA_SHIRQ, "mistral_wakeup",
+                               IRQF_SHARED, "mistral_wakeup",
                                &osk_mistral_wake_interrupt);
                if (ret != 0) {
                        omap_free_gpio(OMAP_MPUIO(2));
index 880cd2d..34eb79e 100644 (file)
@@ -133,7 +133,7 @@ static struct irqchip omap_fpga_irq = {
  * mask_ack routine for all of the FPGA interrupts has been changed from
  * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt
  * being serviced is left unmasked.  We can do this because the FPGA cascade
- * interrupt is installed with the SA_INTERRUPT flag, which leaves all
+ * interrupt is installed with the IRQF_DISABLED flag, which leaves all
  * interrupts masked at the CPU while an FPGA interrupt handler executes.
  *
  * Limited testing indicates that this workaround appears to be effective
index 1b4e1d5..cd76185 100644 (file)
@@ -690,7 +690,7 @@ static irqreturn_t  omap_wakeup_interrupt(int  irq, void *  dev,
 
 static struct irqaction omap_wakeup_irq = {
        .name           = "peripheral wakeup",
-       .flags          = SA_INTERRUPT,
+       .flags          = IRQF_DISABLED,
        .handler        = omap_wakeup_interrupt
 };
 
index 5615fb8..976edfb 100644 (file)
@@ -253,7 +253,7 @@ static void __init omap_serial_set_port_wakeup(int gpio_nr)
        }
        omap_set_gpio_direction(gpio_nr, 1);
        ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt,
-                         SA_TRIGGER_RISING, "serial wakeup", NULL);
+                         IRQF_TRIGGER_RISING, "serial wakeup", NULL);
        if (ret) {
                omap_free_gpio(gpio_nr);
                printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
index a01f0ef..4d91b9f 100644 (file)
@@ -177,7 +177,7 @@ static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id,
 
 static struct irqaction omap_mpu_timer_irq = {
        .name           = "mpu timer",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = omap_mpu_timer_interrupt,
 };
 
@@ -191,7 +191,7 @@ static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id,
 
 static struct irqaction omap_mpu_timer1_irq = {
        .name           = "mpu timer1 overflow",
-       .flags          = SA_INTERRUPT,
+       .flags          = IRQF_DISABLED,
        .handler        = omap_mpu_timer1_interrupt,
 };
 
index 6c6ba17..7993b7b 100644 (file)
@@ -234,17 +234,17 @@ static void __init apollon_sw_init(void)
 
        set_irq_type(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), IRQT_RISING);
        if (request_irq(OMAP_GPIO_IRQ(SW_ENTER_GPIO16), &apollon_sw_interrupt,
-                               SA_SHIRQ, "enter sw",
+                               IRQF_SHARED, "enter sw",
                                &apollon_sw_interrupt))
                return;
        set_irq_type(OMAP_GPIO_IRQ(SW_UP_GPIO17), IRQT_RISING);
        if (request_irq(OMAP_GPIO_IRQ(SW_UP_GPIO17), &apollon_sw_interrupt,
-                               SA_SHIRQ, "up sw",
+                               IRQF_SHARED, "up sw",
                                &apollon_sw_interrupt))
                return;
        set_irq_type(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), IRQT_RISING);
        if (request_irq(OMAP_GPIO_IRQ(SW_DOWN_GPIO58), &apollon_sw_interrupt,
-                               SA_SHIRQ, "down sw",
+                               IRQF_SHARED, "down sw",
                                &apollon_sw_interrupt))
                return;
 }
index cf78e6c..fe5fd6d 100644 (file)
@@ -52,7 +52,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
 
 static struct irqaction omap2_gp_timer_irq = {
        .name           = "gp timer",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = omap2_gp_timer_interrupt,
 };
 
index 4ce6806..888bf6c 100644 (file)
@@ -86,7 +86,7 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id,
 
 static struct irqaction pnx4008_timer_irq = {
        .name = "PNX4008 Tick Timer",
-       .flags = SA_INTERRUPT | SA_TIMER,
+       .flags = IRQF_DISABLED | IRQF_TIMER,
        .handler = pnx4008_timer_interrupt
 };
 
index bf6648a..cce2657 100644 (file)
@@ -225,7 +225,7 @@ static int corgi_mci_init(struct device *dev, irqreturn_t (*corgi_detect_int)(in
        corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
        err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
-                         SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+                         IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          "MMC card detect", data);
        if (err) {
                printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
index 1ab26c6..6a9a669 100644 (file)
@@ -419,7 +419,7 @@ static int lubbock_mci_init(struct device *dev,
        init_timer(&mmc_timer);
        mmc_timer.data = (unsigned long) data;
        return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
-                       SA_SAMPLE_RANDOM, "lubbock-sd-detect", data);
+                       IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data);
 }
 
 static int lubbock_mci_get_ro(struct device *dev)
index b307f11..21ddf3d 100644 (file)
@@ -331,7 +331,7 @@ static int mainstone_mci_init(struct device *dev, irqreturn_t (*mstone_detect_in
         */
        MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
 
-       err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, SA_INTERRUPT,
+       err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED,
                             "MMC card detect", data);
        if (err) {
                printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
index 9a9fa87..6dbff6d 100644 (file)
@@ -212,7 +212,7 @@ static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)(
        poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
        err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
-                         SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+                         IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          "MMC card detect", data);
        if (err) {
                printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
index 1e5e6ca..db6e8f5 100644 (file)
@@ -142,18 +142,18 @@ void sharpsl_pm_pxa_init(void)
        pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
 
        /* Register interrupt handlers */
-       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
+       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED, "AC Input Detect", sharpsl_ac_isr)) {
                dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
        }
        else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
 
-       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
+       if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED, "Battery Cover", sharpsl_fatal_isr)) {
                dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
        }
        else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
 
        if (sharpsl_pm.machinfo->gpio_fatal) {
-               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
+               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED, "Fatal Battery", sharpsl_fatal_isr)) {
                        dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
                }
                else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
@@ -162,7 +162,7 @@ void sharpsl_pm_pxa_init(void)
        if (sharpsl_pm.machinfo->batfull_irq)
        {
                /* Register interrupt handler. */
-               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
+               if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED, "CO", sharpsl_chrg_full_isr)) {
                        dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
                }
                else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
index eb9937f..1c32a93 100644 (file)
@@ -308,7 +308,7 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in
        spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
        err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
-                         SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+                         IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                          "MMC card detect", data);
        if (err) {
                printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
index 1ef85fc..5dbd191 100644 (file)
@@ -117,7 +117,7 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction pxa_timer_irq = {
        .name           = "PXA Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = pxa_timer_interrupt,
 };
 
index 7152bc1..2493536 100644 (file)
@@ -185,7 +185,7 @@ static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int,
 
        tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
-       err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, SA_INTERRUPT,
+       err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, IRQF_DISABLED,
                                "MMC/SD card detect", data);
        if (err) {
                printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
index 4ffff9e..7c3007d 100644 (file)
@@ -283,7 +283,9 @@ static int trizeps4_mci_init(struct device *dev, irqreturn_t (*mci_detect_int)(i
 
        pxa_gpio_mode(GPIO_MMC_DET | GPIO_IN);
 
-       err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int, SA_INTERRUPT | SA_TRIGGER_RISING, "MMC card detect", data);
+       err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
+                         IRQF_DISABLED | IRQF_TRIGGER_RISING,
+                         "MMC card detect", data);
        if (err) {
                printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
                return -1;
index eb09d38..da02869 100644 (file)
@@ -536,7 +536,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg
 
 static struct irqaction realview_timer_irq = {
        .name           = "RealView Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = realview_timer_interrupt,
 };
 
index bd86ffb..ac511d4 100644 (file)
@@ -128,7 +128,7 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
 static int iomd_request_dma(dmach_t channel, dma_t *dma)
 {
        return request_irq(dma->dma_irq, iomd_dma_handle,
-                          SA_INTERRUPT, dma->device_id, dma);
+                          IRQF_DISABLED, dma->device_id, dma);
 }
 
 static void iomd_free_dma(dmach_t channel, dma_t *dma)
index b0aaf43..094cc52 100644 (file)
@@ -718,7 +718,7 @@ int s3c2410_dma_request(unsigned int channel, s3c2410_dma_client_t *client,
                pr_debug("dma%d: %s : requesting irq %d\n",
                         channel, __FUNCTION__, chan->irq);
 
-               err = request_irq(chan->irq, s3c2410_dma_irq, SA_INTERRUPT,
+               err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
                                  client->name, (void *)chan);
 
                if (err) {
index c153c49..00d1cfc 100644 (file)
@@ -138,7 +138,7 @@ s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction s3c2410_timer_irq = {
        .name           = "S3C2410 Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = s3c2410_timer_interrupt,
 };
 
index 495f8c6..6b22d8f 100644 (file)
@@ -85,8 +85,8 @@ static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
 
        if (on) {
                ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
-                                 SA_INTERRUPT | SA_TRIGGER_RISING |
-                                  SA_TRIGGER_FALLING,
+                                 IRQF_DISABLED | IRQF_TRIGGER_RISING |
+                                  IRQF_TRIGGER_FALLING,
                                  "USB Over-current", info);
                if (ret != 0) {
                        printk(KERN_ERR "failed to request usb oc irq\n");
index 696d7d2..45b1e71 100644 (file)
@@ -45,12 +45,12 @@ static void collie_charger_init(void)
        }
 
        /* Register interrupt handler. */
-       if ((err = request_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr, SA_INTERRUPT,
+       if ((err = request_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr, IRQF_DISABLED,
                               "ACIN", sharpsl_ac_isr))) {
                printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_AC_IN);
                return;
        }
-       if ((err = request_irq(COLLIE_IRQ_GPIO_CO, sharpsl_chrg_full_isr, SA_INTERRUPT,
+       if ((err = request_irq(COLLIE_IRQ_GPIO_CO, sharpsl_chrg_full_isr, IRQF_DISABLED,
                               "CO", sharpsl_chrg_full_isr))) {
                free_irq(COLLIE_IRQ_GPIO_AC_IN, sharpsl_ac_isr);
                printk("Could not get irq %d.\n", COLLIE_IRQ_GPIO_CO);
index be0e442..3c6441d 100644 (file)
@@ -124,7 +124,7 @@ int sa1100_request_dma (dma_device_t device, const char *device_id,
 
        i = dma - dma_chan;
        regs = (dma_regs_t *)&DDAR(i);
-       err = request_irq(IRQ_DMA0 + i, dma_irq_handler, SA_INTERRUPT,
+       err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED,
                          device_id, regs);
        if (err) {
                printk(KERN_ERR
index e10d661..7364478 100644 (file)
@@ -740,7 +740,7 @@ static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc, struct pt_re
 static struct irqaction h3800_irq = {
        .name           = "h3800_asic",
        .handler        = h3800_IRQ_demux,
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
 };
 
 u32 kpio_int_shadow = 0;
index 688b1e1..49ae716 100644 (file)
@@ -111,7 +111,7 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction sa1100_timer_irq = {
        .name           = "SA11xx Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = sa1100_timer_interrupt,
 };
 
index 2f2c6e9..1095df3 100644 (file)
@@ -90,7 +90,7 @@ shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 static struct irqaction shark_timer_irq = {
        .name           = "Shark Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = shark_timer_interrupt,
 };
 
index 08de849..a432539 100644 (file)
@@ -869,7 +869,7 @@ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_re
 
 static struct irqaction versatile_timer_irq = {
        .name           = "Versatile Timer Tick",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = versatile_timer_interrupt,
 };
 
index 0e6946a..c2f0705 100644 (file)
@@ -41,6 +41,8 @@
 #include <asm/procinfo.h>
 #include <asm/ptrace.h>
 
+#include "proc-macros.S"
+
 /*
  * Function: arm720_proc_init (void)
  *        : arm720_proc_fin (void)
index e812246..c878064 100644 (file)
@@ -23,6 +23,8 @@
 #include <asm/pgtable.h>
 #include <asm/ptrace.h>
 
+#include "proc-macros.S"
+
 /*
  * the cache line size of the I and D cache
  */
index ba32cc6..b23b66a 100644 (file)
@@ -27,6 +27,8 @@
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
+#include "proc-macros.S"
+
 /*
  * the cache line size of the I and D cache
  */
index e0f0b32..34fdc73 100644 (file)
@@ -384,7 +384,7 @@ static int xscale_pmu_start(void)
        int ret;
        u32 pmnc = read_pmnc();
 
-       ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, SA_INTERRUPT,
+       ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, IRQF_DISABLED,
                        "XScale PMU", (void *)results);
 
        if (ret < 0) {
index c2c05ef..9eddc95 100644 (file)
@@ -939,7 +939,7 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id,
 static struct irqaction omap24xx_dma_irq = {
        .name = "DMA",
        .handler = omap2_dma_irq_handler,
-       .flags = SA_INTERRUPT
+       .flags = IRQF_DISABLED
 };
 
 #else
index cb0c21d..fec7970 100644 (file)
@@ -850,7 +850,8 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
                        /* Don't run the handler if it's already running
                         * or was disabled lazely.
                         */
-                       if (unlikely((d->disable_depth || d->running))) {
+                       if (unlikely((d->depth ||
+                                     (d->status & IRQ_INPROGRESS)))) {
                                irq_mask = 1 <<
                                        (gpio_irq - bank->virtual_irq_start);
                                /* The unmasking will be done by
@@ -859,22 +860,22 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
                                 * it's already running.
                                 */
                                _enable_gpio_irqbank(bank, irq_mask, 0);
-                               if (!d->disable_depth) {
+                               if (!d->depth) {
                                        /* Level triggered interrupts
                                         * won't ever be reentered
                                         */
                                        BUG_ON(level_mask & irq_mask);
-                                       d->pending = 1;
+                                       d->status |= IRQ_PENDING;
                                }
                                continue;
                        }
-                       d->running = 1;
+
                        desc_handle_irq(gpio_irq, d, regs);
-                       d->running = 0;
-                       if (unlikely(d->pending && !d->disable_depth)) {
+
+                       if (unlikely((d->status & IRQ_PENDING) && !d->depth)) {
                                irq_mask = 1 <<
                                        (gpio_irq - bank->virtual_irq_start);
-                               d->pending = 0;
+                               d->status &= ~IRQ_PENDING;
                                _enable_gpio_irqbank(bank, irq_mask, 1);
                                retrigger |= irq_mask;
                        }
index 1a24e2c..04b4102 100644 (file)
@@ -580,7 +580,7 @@ static irqreturn_t  omap_wakeup_interrupt(int  irq, void *  dev,
 
 static struct irqaction omap_wakeup_irq = {
        .name           = "peripheral wakeup",
-       .flags          = SA_INTERRUPT,
+       .flags          = IRQF_DISABLED,
        .handler        = omap_wakeup_interrupt
 };
 
index ddf4360..281ecc7 100644 (file)
@@ -258,7 +258,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = {
 
 static struct irqaction omap_32k_timer_irq = {
        .name           = "32KHz timer",
-       .flags          = SA_INTERRUPT | SA_TIMER,
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = omap_32k_timer_interrupt,
 };
 
index 27d8ddd..daa75ce 100644 (file)
@@ -18,6 +18,14 @@ config GENERIC_TIME
        bool
        default y
 
+config LOCKDEP_SUPPORT
+       bool
+       default y
+
+config STACKTRACE_SUPPORT
+       bool
+       default y
+
 config SEMAPHORE_SLEEPERS
        bool
        default y
index c92191b..b31c080 100644 (file)
@@ -1,5 +1,9 @@
 menu "Kernel hacking"
 
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default y
+
 source "lib/Kconfig.debug"
 
 config EARLY_PRINTK
@@ -31,15 +35,6 @@ config DEBUG_STACK_USAGE
 
          This option will slow down process creation somewhat.
 
-config STACK_BACKTRACE_COLS
-       int "Stack backtraces per line" if DEBUG_KERNEL
-       range 1 3
-       default 2
-       help
-         Selects how many stack backtrace entries per line to display.
-
-         This can save screen space when displaying traces.
-
 comment "Page alloc debug is incompatible with Software Suspend on i386"
        depends on DEBUG_KERNEL && SOFTWARE_SUSPEND
 
index cbc1184..1b452a1 100644 (file)
@@ -9,6 +9,7 @@ obj-y   := process.o semaphore.o signal.o entry.o traps.o irq.o \
                pci-dma.o i386_ksyms.o i387.o bootflag.o \
                quirks.o i8237.o topology.o alternative.o i8253.o tsc.o
 
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-y                          += cpu/
 obj-y                          += acpi/
 obj-$(CONFIG_X86_BIOS_REBOOT)  += reboot.o
index 7b421b3..28ab806 100644 (file)
@@ -303,6 +303,16 @@ void alternatives_smp_switch(int smp)
        struct smp_alt_module *mod;
        unsigned long flags;
 
+#ifdef CONFIG_LOCKDEP
+       /*
+        * A not yet fixed binutils section handling bug prevents
+        * alternatives-replacement from working reliably, so turn
+        * it off:
+        */
+       printk("lockdep: not fixing up alternatives.\n");
+       return;
+#endif
+
        if (no_replacement || smp_alt_once)
                return;
        BUG_ON(!smp && (num_online_cpus() > 1));
index 787190c..d9a260f 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
+#include <asm/irqflags.h>
 #include <asm/errno.h>
 #include <asm/segment.h>
 #include <asm/smp.h>
@@ -76,12 +77,21 @@ NT_MASK             = 0x00004000
 VM_MASK                = 0x00020000
 
 #ifdef CONFIG_PREEMPT
-#define preempt_stop           cli
+#define preempt_stop           cli; TRACE_IRQS_OFF
 #else
 #define preempt_stop
 #define resume_kernel          restore_nocheck
 #endif
 
+.macro TRACE_IRQS_IRET
+#ifdef CONFIG_TRACE_IRQFLAGS
+       testl $IF_MASK,EFLAGS(%esp)     # interrupts off?
+       jz 1f
+       TRACE_IRQS_ON
+1:
+#endif
+.endm
+
 #ifdef CONFIG_VM86
 #define resume_userspace_sig   check_userspace
 #else
@@ -257,6 +267,10 @@ ENTRY(sysenter_entry)
        CFI_REGISTER esp, ebp
        movl TSS_sysenter_esp0(%esp),%esp
 sysenter_past_esp:
+       /*
+        * No need to follow this irqs on/off section: the syscall
+        * disabled irqs and here we enable it straight after entry:
+        */
        sti
        pushl $(__USER_DS)
        CFI_ADJUST_CFA_OFFSET 4
@@ -303,6 +317,7 @@ sysenter_past_esp:
        call *sys_call_table(,%eax,4)
        movl %eax,EAX(%esp)
        cli
+       TRACE_IRQS_OFF
        movl TI_flags(%ebp), %ecx
        testw $_TIF_ALLWORK_MASK, %cx
        jne syscall_exit_work
@@ -310,6 +325,7 @@ sysenter_past_esp:
        movl EIP(%esp), %edx
        movl OLDESP(%esp), %ecx
        xorl %ebp,%ebp
+       TRACE_IRQS_ON
        sti
        sysexit
        CFI_ENDPROC
@@ -339,6 +355,7 @@ syscall_exit:
        cli                             # make sure we don't miss an interrupt
                                        # setting need_resched or sigpending
                                        # between sampling and the iret
+       TRACE_IRQS_OFF
        movl TI_flags(%ebp), %ecx
        testw $_TIF_ALLWORK_MASK, %cx   # current->work
        jne syscall_exit_work
@@ -355,12 +372,15 @@ restore_all:
        CFI_REMEMBER_STATE
        je ldt_ss                       # returning to user-space with LDT SS
 restore_nocheck:
+       TRACE_IRQS_IRET
+restore_nocheck_notrace:
        RESTORE_REGS
        addl $4, %esp
        CFI_ADJUST_CFA_OFFSET -4
 1:     iret
 .section .fixup,"ax"
 iret_exc:
+       TRACE_IRQS_ON
        sti
        pushl $0                        # no error code
        pushl $do_iret_error
@@ -386,11 +406,13 @@ ldt_ss:
        subl $8, %esp           # reserve space for switch16 pointer
        CFI_ADJUST_CFA_OFFSET 8
        cli
+       TRACE_IRQS_OFF
        movl %esp, %eax
        /* Set up the 16bit stack frame with switch32 pointer on top,
         * and a switch16 pointer on top of the current frame. */
        call setup_x86_bogus_stack
        CFI_ADJUST_CFA_OFFSET -8        # frame has moved
+       TRACE_IRQS_IRET
        RESTORE_REGS
        lss 20+4(%esp), %esp    # switch to 16bit stack
 1:     iret
@@ -411,6 +433,7 @@ work_resched:
        cli                             # make sure we don't miss an interrupt
                                        # setting need_resched or sigpending
                                        # between sampling and the iret
+       TRACE_IRQS_OFF
        movl TI_flags(%ebp), %ecx
        andl $_TIF_WORK_MASK, %ecx      # is there any work to be done other
                                        # than syscall tracing?
@@ -462,6 +485,7 @@ syscall_trace_entry:
 syscall_exit_work:
        testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
        jz work_pending
+       TRACE_IRQS_ON
        sti                             # could let do_syscall_trace() call
                                        # schedule() instead
        movl %esp, %eax
@@ -535,9 +559,14 @@ ENTRY(irq_entries_start)
 vector=vector+1
 .endr
 
+/*
+ * the CPU automatically disables interrupts when executing an IRQ vector,
+ * so IRQ-flags tracing has to follow that:
+ */
        ALIGN
 common_interrupt:
        SAVE_ALL
+       TRACE_IRQS_OFF
        movl %esp,%eax
        call do_IRQ
        jmp ret_from_intr
@@ -549,9 +578,10 @@ ENTRY(name)                                \
        pushl $~(nr);                   \
        CFI_ADJUST_CFA_OFFSET 4;        \
        SAVE_ALL;                       \
+       TRACE_IRQS_OFF                  \
        movl %esp,%eax;                 \
        call smp_/**/name;              \
-       jmp ret_from_intr;      \
+       jmp ret_from_intr;              \
        CFI_ENDPROC
 
 /* The include is where all of the SMP etc. interrupts come from */
@@ -726,7 +756,7 @@ nmi_stack_correct:
        xorl %edx,%edx          # zero error code
        movl %esp,%eax          # pt_regs pointer
        call do_nmi
-       jmp restore_all
+       jmp restore_nocheck_notrace
        CFI_ENDPROC
 
 nmi_stack_fixup:
index 16b4917..6cb529f 100644 (file)
@@ -166,7 +166,7 @@ void irq_ctx_init(int cpu)
        irqctx->tinfo.task              = NULL;
        irqctx->tinfo.exec_domain       = NULL;
        irqctx->tinfo.cpu               = cpu;
-       irqctx->tinfo.preempt_count     = SOFTIRQ_OFFSET;
+       irqctx->tinfo.preempt_count     = 0;
        irqctx->tinfo.addr_limit        = MAKE_MM_SEG(0);
 
        softirq_ctx[cpu] = irqctx;
@@ -211,6 +211,10 @@ asmlinkage void do_softirq(void)
                        : "0"(isp)
                        : "memory", "cc", "edx", "ecx", "eax"
                );
+               /*
+                * Shouldnt happen, we returned above if in_interrupt():
+                */
+               WARN_ON_ONCE(softirq_count());
        }
 
        local_irq_restore(flags);
index a76e931..2dd928a 100644 (file)
@@ -107,7 +107,7 @@ int nmi_active;
 static __init void nmi_cpu_busy(void *data)
 {
        volatile int *endflag = data;
-       local_irq_enable();
+       local_irq_enable_in_hardirq();
        /* Intentionally don't use cpu_relax here. This is
           to make sure that the performance counter really ticks,
           even if there is a simulator or similar that catches the
diff --git a/arch/i386/kernel/stacktrace.c b/arch/i386/kernel/stacktrace.c
new file mode 100644 (file)
index 0000000..e62a037
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * arch/i386/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
+{
+       return  p > (void *)tinfo &&
+               p < (void *)tinfo + THREAD_SIZE - 3;
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer:
+ */
+static inline unsigned long
+save_context_stack(struct stack_trace *trace, unsigned int skip,
+                  struct thread_info *tinfo, unsigned long *stack,
+                  unsigned long ebp)
+{
+       unsigned long addr;
+
+#ifdef CONFIG_FRAME_POINTER
+       while (valid_stack_ptr(tinfo, (void *)ebp)) {
+               addr = *(unsigned long *)(ebp + 4);
+               if (!skip)
+                       trace->entries[trace->nr_entries++] = addr;
+               else
+                       skip--;
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+               /*
+                * break out of recursive entries (such as
+                * end_of_stack_stop_unwind_function):
+                */
+               if (ebp == *(unsigned long *)ebp)
+                       break;
+
+               ebp = *(unsigned long *)ebp;
+       }
+#else
+       while (valid_stack_ptr(tinfo, stack)) {
+               addr = *stack++;
+               if (__kernel_text_address(addr)) {
+                       if (!skip)
+                               trace->entries[trace->nr_entries++] = addr;
+                       else
+                               skip--;
+                       if (trace->nr_entries >= trace->max_entries)
+                               break;
+               }
+       }
+#endif
+
+       return ebp;
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ * If all_contexts is set, all contexts (hardirq, softirq and process)
+ * are saved. If not set then only the current context is saved.
+ */
+void save_stack_trace(struct stack_trace *trace,
+                     struct task_struct *task, int all_contexts,
+                     unsigned int skip)
+{
+       unsigned long ebp;
+       unsigned long *stack = &ebp;
+
+       WARN_ON(trace->nr_entries || !trace->max_entries);
+
+       if (!task || task == current) {
+               /* Grab ebp right from our regs: */
+               asm ("movl %%ebp, %0" : "=r" (ebp));
+       } else {
+               /* ebp is the last reg pushed by switch_to(): */
+               ebp = *(unsigned long *) task->thread.esp;
+       }
+
+       while (1) {
+               struct thread_info *context = (struct thread_info *)
+                               ((unsigned long)stack & (~(THREAD_SIZE - 1)));
+
+               ebp = save_context_stack(trace, skip, context, stack, ebp);
+               stack = (unsigned long *)context->previous_esp;
+               if (!all_contexts || !stack ||
+                               trace->nr_entries >= trace->max_entries)
+                       break;
+               trace->entries[trace->nr_entries++] = ULONG_MAX;
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+       }
+}
+
index e8c6086..2bf8b55 100644 (file)
@@ -115,28 +115,13 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
 }
 
 /*
- * Print CONFIG_STACK_BACKTRACE_COLS address/symbol entries per line.
+ * Print one address/symbol entries per line.
  */
-static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
-                                       int printed)
+static inline void print_addr_and_symbol(unsigned long addr, char *log_lvl)
 {
-       if (!printed)
-               printk(log_lvl);
-
-#if CONFIG_STACK_BACKTRACE_COLS == 1
        printk(" [<%08lx>] ", addr);
-#else
-       printk(" <%08lx> ", addr);
-#endif
-       print_symbol("%s", addr);
 
-       printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
-       if (printed)
-               printk(" ");
-       else
-               printk("\n");
-
-       return printed;
+       print_symbol("%s\n", addr);
 }
 
 static inline unsigned long print_context_stack(struct thread_info *tinfo,
@@ -144,12 +129,11 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
                                char *log_lvl)
 {
        unsigned long addr;
-       int printed = 0; /* nr of entries already printed on current line */
 
 #ifdef CONFIG_FRAME_POINTER
        while (valid_stack_ptr(tinfo, (void *)ebp)) {
                addr = *(unsigned long *)(ebp + 4);
-               printed = print_addr_and_symbol(addr, log_lvl, printed);
+               print_addr_and_symbol(addr, log_lvl);
                /*
                 * break out of recursive entries (such as
                 * end_of_stack_stop_unwind_function):
@@ -162,28 +146,23 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
        while (valid_stack_ptr(tinfo, stack)) {
                addr = *stack++;
                if (__kernel_text_address(addr))
-                       printed = print_addr_and_symbol(addr, log_lvl, printed);
+                       print_addr_and_symbol(addr, log_lvl);
        }
 #endif
-       if (printed)
-               printk("\n");
-
        return ebp;
 }
 
-static asmlinkage int show_trace_unwind(struct unwind_frame_info *info, void *log_lvl)
+static asmlinkage int
+show_trace_unwind(struct unwind_frame_info *info, void *log_lvl)
 {
        int n = 0;
-       int printed = 0; /* nr of entries already printed on current line */
 
        while (unwind(info) == 0 && UNW_PC(info)) {
-               ++n;
-               printed = print_addr_and_symbol(UNW_PC(info), log_lvl, printed);
+               n++;
+               print_addr_and_symbol(UNW_PC(info), log_lvl);
                if (arch_unw_user_mode(info))
                        break;
        }
-       if (printed)
-               printk("\n");
        return n;
 }
 
index eb8e8dc..2fbe453 100644 (file)
@@ -678,7 +678,7 @@ copy_reg(const u64 *fr, u64 fnat, u64 *tr, u64 *tnat)
  */
 
 static void
-ia64_mca_modify_comm(const task_t *previous_current)
+ia64_mca_modify_comm(const struct task_struct *previous_current)
 {
        char *p, comm[sizeof(current->comm)];
        if (previous_current->pid)
@@ -709,7 +709,7 @@ ia64_mca_modify_comm(const task_t *previous_current)
  * that we can do backtrace on the MCA/INIT handler code itself.
  */
 
-static task_t *
+static struct task_struct *
 ia64_mca_modify_original_stack(struct pt_regs *regs,
                const struct switch_stack *sw,
                struct ia64_sal_os_state *sos,
@@ -719,7 +719,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs,
        ia64_va va;
        extern char ia64_leave_kernel[];        /* Need asm address, not function descriptor */
        const pal_min_state_area_t *ms = sos->pal_min_state;
-       task_t *previous_current;
+       struct task_struct *previous_current;
        struct pt_regs *old_regs;
        struct switch_stack *old_sw;
        unsigned size = sizeof(struct pt_regs) +
@@ -1023,7 +1023,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
        pal_processor_state_info_t *psp = (pal_processor_state_info_t *)
                &sos->proc_state_param;
        int recover, cpu = smp_processor_id();
-       task_t *previous_current;
+       struct task_struct *previous_current;
        struct ia64_mca_notify_die nd =
                { .sos = sos, .monarch_cpu = &monarch_cpu };
 
@@ -1352,7 +1352,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
 {
        static atomic_t slaves;
        static atomic_t monarchs;
-       task_t *previous_current;
+       struct task_struct *previous_current;
        int cpu = smp_processor_id();
        struct ia64_mca_notify_die nd =
                { .sos = sos, .monarch_cpu = &monarch_cpu };
index e196097..6203ed4 100644 (file)
@@ -124,7 +124,7 @@ extern void __devinit calibrate_delay (void);
 extern void start_ap (void);
 extern unsigned long ia64_iobase;
 
-task_t *task_for_booting_cpu;
+struct task_struct *task_for_booting_cpu;
 
 /*
  * State for each CPU
index ecfd637..01e7fa8 100644 (file)
@@ -65,7 +65,7 @@ need_resched:
 #endif
 
 FEXPORT(ret_from_fork)
-       jal     schedule_tail           # a0 = task_t *prev
+       jal     schedule_tail           # a0 = struct task_struct *prev
 
 FEXPORT(syscall_exit)
        local_irq_disable               # make sure need_resched and
index 02237a6..4dcc39f 100644 (file)
@@ -47,7 +47,7 @@ unsigned long mt_fpemul_threshold = 0;
  * used in sys_sched_set/getaffinity() in kernel/sched.c, so
  * cloned here.
  */
-static inline task_t *find_process_by_pid(pid_t pid)
+static inline struct task_struct *find_process_by_pid(pid_t pid)
 {
        return pid ? find_task_by_pid(pid) : current;
 }
@@ -62,7 +62,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
        cpumask_t new_mask;
        cpumask_t effective_mask;
        int retval;
-       task_t *p;
+       struct task_struct *p;
 
        if (len < sizeof(new_mask))
                return -EINVAL;
@@ -127,7 +127,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
        unsigned int real_len;
        cpumask_t mask;
        int retval;
-       task_t *p;
+       struct task_struct *p;
 
        real_len = sizeof(mask);
        if (len < real_len)
index 05a7009..8cf9878 100644 (file)
@@ -306,13 +306,8 @@ void do_softirq(void)
 
        local_irq_save(flags);
 
-       if (local_softirq_pending()) {
-               account_system_vtime(current);
-               local_bh_disable();
+       if (local_softirq_pending())
                do_softirq_onstack();
-               account_system_vtime(current);
-               __local_bh_enable();
-       }
 
        local_irq_restore(flags);
 }
index 821a141..224fbff 100644 (file)
@@ -7,6 +7,14 @@ config MMU
        bool
        default y
 
+config LOCKDEP_SUPPORT
+       bool
+       default y
+
+config STACKTRACE_SUPPORT
+       bool
+       default y
+
 config RWSEM_GENERIC_SPINLOCK
        bool
 
index f53b6d5..2283933 100644 (file)
@@ -1,5 +1,9 @@
 menu "Kernel hacking"
 
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default y
+
 source "lib/Kconfig.debug"
 
 endmenu
index b3791fb..74ef57d 100644 (file)
@@ -34,6 +34,11 @@ cflags-$(CONFIG_MARCH_G5)   += $(call cc-option,-march=g5)
 cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
 cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
 
+#
+# Prevent tail-call optimizations, to get clearer backtraces:
+#
+cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls
+
 # old style option for packed stacks
 ifeq ($(call cc-option-yn,-mkernel-backchain),y)
 cflags-$(CONFIG_PACK_STACK)  += -mkernel-backchain -D__PACK_STACK
index 9269b57..eabf00a 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_COMPAT)          += compat_linux.o compat_signal.o \
 obj-$(CONFIG_BINFMT_ELF32)     += binfmt_elf32.o
 
 obj-$(CONFIG_VIRT_TIMER)       += vtime.o
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
index d8948c3..5b5799a 100644 (file)
@@ -58,6 +58,21 @@ STACK_SIZE  = 1 << STACK_SHIFT
 
 #define BASED(name) name-system_call(%r13)
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       .macro  TRACE_IRQS_ON
+       l       %r1,BASED(.Ltrace_irq_on)
+       basr    %r14,%r1
+       .endm
+
+       .macro  TRACE_IRQS_OFF
+       l       %r1,BASED(.Ltrace_irq_off)
+       basr    %r14,%r1
+       .endm
+#else
+#define TRACE_IRQS_ON
+#define TRACE_IRQS_OFF
+#endif
+
 /*
  * Register usage in interrupt handlers:
  *    R9  - pointer to current task structure
@@ -361,6 +376,7 @@ ret_from_fork:
        st      %r15,SP_R15(%r15)       # store stack pointer for new kthread
 0:     l       %r1,BASED(.Lschedtail)
        basr    %r14,%r1
+       TRACE_IRQS_ON
         stosm   __SF_EMPTY(%r15),0x03     # reenable interrupts
        b       BASED(sysc_return)
 
@@ -516,6 +532,7 @@ pgm_no_vtime3:
        mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        b       BASED(sysc_do_svc)
 
@@ -539,9 +556,11 @@ io_int_handler:
 io_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
         l       %r1,BASED(.Ldo_IRQ)        # load address of do_IRQ
         la      %r2,SP_PTREGS(%r15) # address of register-save area
         basr    %r14,%r1          # branch to standard irq handler
+       TRACE_IRQS_ON
 
 io_return:
         tm      SP_PSW+1(%r15),0x01    # returning to user ?
@@ -651,10 +670,12 @@ ext_int_handler:
 ext_no_vtime:
 #endif
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
        la      %r2,SP_PTREGS(%r15)    # address of register-save area
        lh      %r3,__LC_EXT_INT_CODE  # get interruption code
        l       %r1,BASED(.Ldo_extint)
        basr    %r14,%r1
+       TRACE_IRQS_ON
        b       BASED(io_return)
 
 __critical_end:
@@ -731,8 +752,10 @@ mcck_no_vtime:
        stosm   __SF_EMPTY(%r15),0x04   # turn dat on
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bno     BASED(mcck_return)
+       TRACE_IRQS_OFF
        l       %r1,BASED(.Ls390_handle_mcck)
        basr    %r14,%r1                # call machine check handler
+       TRACE_IRQS_ON
 mcck_return:
        mvc     __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
        ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
@@ -1012,7 +1035,11 @@ cleanup_io_leave_insn:
 .Lvfork:       .long  sys_vfork
 .Lschedtail:   .long  schedule_tail
 .Lsysc_table:  .long  sys_call_table
-
+#ifdef CONFIG_TRACE_IRQFLAGS
+.Ltrace_irq_on:.long  trace_hardirqs_on
+.Ltrace_irq_off:
+              .long  trace_hardirqs_off
+#endif
 .Lcritical_start:
                .long  __critical_start + 0x80000000
 .Lcritical_end:
index 1ca499f..56f5f61 100644 (file)
@@ -58,6 +58,19 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
 
 #define BASED(name) name-system_call(%r13)
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       .macro  TRACE_IRQS_ON
+        brasl  %r14,trace_hardirqs_on
+       .endm
+
+       .macro  TRACE_IRQS_OFF
+        brasl  %r14,trace_hardirqs_off
+       .endm
+#else
+#define TRACE_IRQS_ON
+#define TRACE_IRQS_OFF
+#endif
+
        .macro  STORE_TIMER lc_offset
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        stpt    \lc_offset
@@ -354,6 +367,7 @@ ret_from_fork:
        jo      0f
        stg     %r15,SP_R15(%r15)       # store stack pointer for new kthread
 0:     brasl   %r14,schedule_tail
+       TRACE_IRQS_ON
         stosm   24(%r15),0x03     # reenable interrupts
        j       sysc_return
 
@@ -535,6 +549,7 @@ pgm_no_vtime3:
        mvc     __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        j       sysc_do_svc
 
@@ -557,8 +572,10 @@ io_int_handler:
 io_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
         la      %r2,SP_PTREGS(%r15)    # address of register-save area
        brasl   %r14,do_IRQ            # call standard irq handler
+       TRACE_IRQS_ON
 
 io_return:
         tm      SP_PSW+1(%r15),0x01    # returning to user ?
@@ -665,9 +682,11 @@ ext_int_handler:
 ext_no_vtime:
 #endif
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       TRACE_IRQS_OFF
        la      %r2,SP_PTREGS(%r15)    # address of register-save area
        llgh    %r3,__LC_EXT_INT_CODE  # get interruption code
        brasl   %r14,do_extint
+       TRACE_IRQS_ON
        j       io_return
 
 __critical_end:
@@ -743,7 +762,9 @@ mcck_no_vtime:
        stosm   __SF_EMPTY(%r15),0x04   # turn dat on
        tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
        jno     mcck_return
+       TRACE_IRQS_OFF
        brasl   %r14,s390_handle_mcck
+       TRACE_IRQS_ON
 mcck_return:
        mvc     __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
        ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
index 480b6a5..1eef509 100644 (file)
@@ -69,10 +69,6 @@ asmlinkage void do_softirq(void)
 
        local_irq_save(flags);
 
-       account_system_vtime(current);
-
-       local_bh_disable();
-
        if (local_softirq_pending()) {
                /* Get current stack pointer. */
                asm volatile("la %0,0(15)" : "=a" (old));
@@ -95,10 +91,6 @@ asmlinkage void do_softirq(void)
                        __do_softirq();
        }
 
-       account_system_vtime(current);
-
-       __local_bh_enable();
-
        local_irq_restore(flags);
 }
 
index 1f93991..78c8e55 100644 (file)
@@ -142,6 +142,7 @@ static void default_idle(void)
                return;
        }
 
+       trace_hardirqs_on();
        /* Wait for external, I/O or machine check interrupt. */
        __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
                        PSW_MASK_IO | PSW_MASK_EXT);
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
new file mode 100644 (file)
index 0000000..de83f38
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * arch/s390/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) IBM Corp. 2006
+ *  Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
+
+static inline unsigned long save_context_stack(struct stack_trace *trace,
+                                              unsigned int *skip,
+                                              unsigned long sp,
+                                              unsigned long low,
+                                              unsigned long high)
+{
+       struct stack_frame *sf;
+       struct pt_regs *regs;
+       unsigned long addr;
+
+       while(1) {
+               sp &= PSW_ADDR_INSN;
+               if (sp < low || sp > high)
+                       return sp;
+               sf = (struct stack_frame *)sp;
+               while(1) {
+                       addr = sf->gprs[8] & PSW_ADDR_INSN;
+                       if (!(*skip))
+                               trace->entries[trace->nr_entries++] = addr;
+                       else
+                               (*skip)--;
+                       if (trace->nr_entries >= trace->max_entries)
+                               return sp;
+                       low = sp;
+                       sp = sf->back_chain & PSW_ADDR_INSN;
+                       if (!sp)
+                               break;
+                       if (sp <= low || sp > high - sizeof(*sf))
+                               return sp;
+                       sf = (struct stack_frame *)sp;
+               }
+               /* Zero backchain detected, check for interrupt frame. */
+               sp = (unsigned long)(sf + 1);
+               if (sp <= low || sp > high - sizeof(*regs))
+                       return sp;
+               regs = (struct pt_regs *)sp;
+               addr = regs->psw.addr & PSW_ADDR_INSN;
+               if (!(*skip))
+                       trace->entries[trace->nr_entries++] = addr;
+               else
+                       (*skip)--;
+               if (trace->nr_entries >= trace->max_entries)
+                       return sp;
+               low = sp;
+               sp = regs->gprs[15];
+       }
+}
+
+void save_stack_trace(struct stack_trace *trace,
+                     struct task_struct *task, int all_contexts,
+                     unsigned int skip)
+{
+       register unsigned long sp asm ("15");
+       unsigned long orig_sp;
+
+       sp &= PSW_ADDR_INSN;
+       orig_sp = sp;
+
+       sp = save_context_stack(trace, &skip, sp,
+                               S390_lowcore.panic_stack - PAGE_SIZE,
+                               S390_lowcore.panic_stack);
+       if ((sp != orig_sp) && !all_contexts)
+               return;
+       sp = save_context_stack(trace, &skip, sp,
+                               S390_lowcore.async_stack - ASYNC_SIZE,
+                               S390_lowcore.async_stack);
+       if ((sp != orig_sp) && !all_contexts)
+               return;
+       if (task)
+               save_context_stack(trace, &skip, sp,
+                                  (unsigned long) task_stack_page(task),
+                                  (unsigned long) task_stack_page(task) + THREAD_SIZE);
+       else
+               save_context_stack(trace, &skip, sp, S390_lowcore.thread_info,
+                                  S390_lowcore.thread_info + THREAD_SIZE);
+       return;
+}
index a9c1443..8368c2d 100644 (file)
@@ -119,7 +119,7 @@ void suspend_new_thread(int fd)
                panic("read failed in suspend_new_thread, err = %d", -err);
 }
 
-void schedule_tail(task_t *prev);
+void schedule_tail(struct task_struct *prev);
 
 static void new_thread_handler(int sig)
 {
index 7d51dd7..37cfe77 100644 (file)
@@ -495,6 +495,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
 {
 }
 
+#ifdef CONFIG_SMP
 void alternatives_smp_module_add(struct module *mod, char *name,
                                 void *locks, void *locks_end,
                                 void *text,  void *text_end)
@@ -504,3 +505,4 @@ void alternatives_smp_module_add(struct module *mod, char *name,
 void alternatives_smp_module_del(struct module *mod)
 {
 }
+#endif
index e856804..28df7d8 100644 (file)
@@ -24,6 +24,14 @@ config X86
        bool
        default y
 
+config LOCKDEP_SUPPORT
+       bool
+       default y
+
+config STACKTRACE_SUPPORT
+       bool
+       default y
+
 config SEMAPHORE_SLEEPERS
        bool
        default y
index 1d92ab5..775d211 100644 (file)
@@ -1,5 +1,9 @@
 menu "Kernel hacking"
 
+config TRACE_IRQFLAGS_SUPPORT
+       bool
+       default y
+
 source "lib/Kconfig.debug"
 
 config DEBUG_RODATA
index c536fa9..9b5bb41 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/thread_info.h>   
 #include <asm/segment.h>
 #include <asm/vsyscall32.h>
+#include <asm/irqflags.h>
 #include <linux/linkage.h>
 
 #define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8)
@@ -75,6 +76,10 @@ ENTRY(ia32_sysenter_target)
        swapgs
        movq    %gs:pda_kernelstack, %rsp
        addq    $(PDA_STACKOFFSET),%rsp 
+       /*
+        * No need to follow this irqs on/off section: the syscall
+        * disabled irqs, here we enable it straight after entry:
+        */
        sti     
        movl    %ebp,%ebp               /* zero extension */
        pushq   $__USER32_DS
@@ -118,6 +123,7 @@ sysenter_do_call:
        movq    %rax,RAX-ARGOFFSET(%rsp)
        GET_THREAD_INFO(%r10)
        cli
+       TRACE_IRQS_OFF
        testl   $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
        jnz     int_ret_from_sys_call
        andl    $~TS_COMPAT,threadinfo_status(%r10)
@@ -132,6 +138,7 @@ sysenter_do_call:
        CFI_REGISTER rsp,rcx
        movl    $VSYSCALL32_SYSEXIT,%edx        /* User %eip */
        CFI_REGISTER rip,rdx
+       TRACE_IRQS_ON
        swapgs
        sti             /* sti only takes effect after the next instruction */
        /* sysexit */
@@ -186,6 +193,10 @@ ENTRY(ia32_cstar_target)
        movl    %esp,%r8d
        CFI_REGISTER    rsp,r8
        movq    %gs:pda_kernelstack,%rsp
+       /*
+        * No need to follow this irqs on/off section: the syscall
+        * disabled irqs and here we enable it straight after entry:
+        */
        sti
        SAVE_ARGS 8,1,1
        movl    %eax,%eax       /* zero extension */
@@ -220,6 +231,7 @@ cstar_do_call:
        movq %rax,RAX-ARGOFFSET(%rsp)
        GET_THREAD_INFO(%r10)
        cli
+       TRACE_IRQS_OFF
        testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
        jnz  int_ret_from_sys_call
        andl $~TS_COMPAT,threadinfo_status(%r10)
@@ -228,6 +240,7 @@ cstar_do_call:
        CFI_REGISTER rip,rcx
        movl EFLAGS-ARGOFFSET(%rsp),%r11d       
        /*CFI_REGISTER rflags,r11*/
+       TRACE_IRQS_ON
        movl RSP-ARGOFFSET(%rsp),%esp
        CFI_RESTORE rsp
        swapgs
@@ -286,7 +299,11 @@ ENTRY(ia32_syscall)
        /*CFI_REL_OFFSET        rflags,EFLAGS-RIP*/
        /*CFI_REL_OFFSET        cs,CS-RIP*/
        CFI_REL_OFFSET  rip,RIP-RIP
-       swapgs  
+       swapgs
+       /*
+        * No need to follow this irqs on/off section: the syscall
+        * disabled irqs and here we enable it straight after entry:
+        */
        sti
        movl %eax,%eax
        pushq %rax
index 819e84e..b5aaeaf 100644 (file)
@@ -10,6 +10,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
                setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
                pci-dma.o pci-nommu.o alternative.o
 
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-$(CONFIG_X86_MCE)         += mce.o
 obj-$(CONFIG_X86_MCE_INTEL)    += mce_intel.o
 obj-$(CONFIG_X86_MCE_AMD)      += mce_amd.o
index ed92c29..d464dde 100644 (file)
 #include <asm/thread_info.h>
 #include <asm/hw_irq.h>
 #include <asm/page.h>
+#include <asm/irqflags.h>
 
        .code64
 
 #ifndef CONFIG_PREEMPT
 #define retint_kernel retint_restore_args
 #endif 
-       
+
+
+.macro TRACE_IRQS_IRETQ offset=ARGOFFSET
+#ifdef CONFIG_TRACE_IRQFLAGS
+       bt   $9,EFLAGS-\offset(%rsp)    /* interrupts off? */
+       jnc  1f
+       TRACE_IRQS_ON
+1:
+#endif
+.endm
+
 /*
  * C code is not supposed to know about undefined top of stack. Every time 
  * a C function with an pt_regs argument is called from the SYSCALL based 
@@ -194,6 +205,10 @@ ENTRY(system_call)
        swapgs
        movq    %rsp,%gs:pda_oldrsp 
        movq    %gs:pda_kernelstack,%rsp
+       /*
+        * No need to follow this irqs off/on section - it's straight
+        * and short:
+        */
        sti                                     
        SAVE_ARGS 8,1
        movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
@@ -219,10 +234,15 @@ ret_from_sys_call:
 sysret_check:          
        GET_THREAD_INFO(%rcx)
        cli
+       TRACE_IRQS_OFF
        movl threadinfo_flags(%rcx),%edx
        andl %edi,%edx
        CFI_REMEMBER_STATE
        jnz  sysret_careful 
+       /*
+        * sysretq will re-enable interrupts:
+        */
+       TRACE_IRQS_ON
        movq RIP-ARGOFFSET(%rsp),%rcx
        CFI_REGISTER    rip,rcx
        RESTORE_ARGS 0,-ARG_SKIP,1
@@ -237,6 +257,7 @@ sysret_careful:
        CFI_RESTORE_STATE
        bt $TIF_NEED_RESCHED,%edx
        jnc sysret_signal
+       TRACE_IRQS_ON
        sti
        pushq %rdi
        CFI_ADJUST_CFA_OFFSET 8
@@ -247,6 +268,7 @@ sysret_careful:
 
        /* Handle a signal */ 
 sysret_signal:
+       TRACE_IRQS_ON
        sti
        testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
        jz    1f
@@ -261,6 +283,7 @@ sysret_signal:
        /* Use IRET because user could have changed frame. This
           works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
        cli
+       TRACE_IRQS_OFF
        jmp int_with_check
        
 badsys:
@@ -309,6 +332,7 @@ ENTRY(int_ret_from_sys_call)
        CFI_REL_OFFSET  r10,R10-ARGOFFSET
        CFI_REL_OFFSET  r11,R11-ARGOFFSET
        cli
+       TRACE_IRQS_OFF
        testl $3,CS-ARGOFFSET(%rsp)
        je retint_restore_args
        movl $_TIF_ALLWORK_MASK,%edi
@@ -327,6 +351,7 @@ int_with_check:
 int_careful:
        bt $TIF_NEED_RESCHED,%edx
        jnc  int_very_careful
+       TRACE_IRQS_ON
        sti
        pushq %rdi
        CFI_ADJUST_CFA_OFFSET 8
@@ -334,10 +359,12 @@ int_careful:
        popq %rdi
        CFI_ADJUST_CFA_OFFSET -8
        cli
+       TRACE_IRQS_OFF
        jmp int_with_check
 
        /* handle signals and tracing -- both require a full stack frame */
 int_very_careful:
+       TRACE_IRQS_ON
        sti
        SAVE_REST
        /* Check for syscall exit trace */      
@@ -351,6 +378,7 @@ int_very_careful:
        CFI_ADJUST_CFA_OFFSET -8
        andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
        cli
+       TRACE_IRQS_OFF
        jmp int_restore_rest
        
 int_signal:
@@ -363,6 +391,7 @@ int_signal:
 int_restore_rest:
        RESTORE_REST
        cli
+       TRACE_IRQS_OFF
        jmp int_with_check
        CFI_ENDPROC
 END(int_ret_from_sys_call)
@@ -484,6 +513,10 @@ END(stub_rt_sigreturn)
        swapgs  
 1:     incl    %gs:pda_irqcount        # RED-PEN should check preempt count
        cmoveq %gs:pda_irqstackptr,%rsp
+       /*
+        * We entered an interrupt context - irqs are off:
+        */
+       TRACE_IRQS_OFF
        call \func
        .endm
 
@@ -493,6 +526,7 @@ ENTRY(common_interrupt)
        /* 0(%rsp): oldrsp-ARGOFFSET */
 ret_from_intr:
        cli     
+       TRACE_IRQS_OFF
        decl %gs:pda_irqcount
        leaveq
        CFI_DEF_CFA_REGISTER    rsp
@@ -515,9 +549,21 @@ retint_check:
        CFI_REMEMBER_STATE
        jnz  retint_careful
 retint_swapgs:         
+       /*
+        * The iretq could re-enable interrupts:
+        */
+       cli
+       TRACE_IRQS_IRETQ
        swapgs 
+       jmp restore_args
+
 retint_restore_args:                           
        cli
+       /*
+        * The iretq could re-enable interrupts:
+        */
+       TRACE_IRQS_IRETQ
+restore_args:
        RESTORE_ARGS 0,8,0                                              
 iret_label:    
        iretq
@@ -530,6 +576,7 @@ iret_label:
        /* running with kernel gs */
 bad_iret:
        movq $11,%rdi   /* SIGSEGV */
+       TRACE_IRQS_ON
        sti
        jmp do_exit                     
        .previous       
@@ -539,6 +586,7 @@ retint_careful:
        CFI_RESTORE_STATE
        bt    $TIF_NEED_RESCHED,%edx
        jnc   retint_signal
+       TRACE_IRQS_ON
        sti
        pushq %rdi
        CFI_ADJUST_CFA_OFFSET   8
@@ -547,11 +595,13 @@ retint_careful:
        CFI_ADJUST_CFA_OFFSET   -8
        GET_THREAD_INFO(%rcx)
        cli
+       TRACE_IRQS_OFF
        jmp retint_check
        
 retint_signal:
        testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
        jz    retint_swapgs
+       TRACE_IRQS_ON
        sti
        SAVE_REST
        movq $-1,ORIG_RAX(%rsp)                         
@@ -560,6 +610,7 @@ retint_signal:
        call do_notify_resume
        RESTORE_REST
        cli
+       TRACE_IRQS_OFF
        movl $_TIF_NEED_RESCHED,%edi
        GET_THREAD_INFO(%rcx)
        jmp retint_check
@@ -666,7 +717,7 @@ END(spurious_interrupt)
 
        /* error code is on the stack already */
        /* handle NMI like exceptions that can happen everywhere */
-       .macro paranoidentry sym, ist=0
+       .macro paranoidentry sym, ist=0, irqtrace=1
        SAVE_ALL
        cld
        movl $1,%ebx
@@ -691,8 +742,73 @@ END(spurious_interrupt)
        addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
        .endif
        cli
+       .if \irqtrace
+       TRACE_IRQS_OFF
+       .endif
        .endm
-       
+
+       /*
+        * "Paranoid" exit path from exception stack.
+        * Paranoid because this is used by NMIs and cannot take
+        * any kernel state for granted.
+        * We don't do kernel preemption checks here, because only
+        * NMI should be common and it does not enable IRQs and
+        * cannot get reschedule ticks.
+        *
+        * "trace" is 0 for the NMI handler only, because irq-tracing
+        * is fundamentally NMI-unsafe. (we cannot change the soft and
+        * hard flags at once, atomically)
+        */
+       .macro paranoidexit trace=1
+       /* ebx: no swapgs flag */
+paranoid_exit\trace:
+       testl %ebx,%ebx                         /* swapgs needed? */
+       jnz paranoid_restore\trace
+       testl $3,CS(%rsp)
+       jnz   paranoid_userspace\trace
+paranoid_swapgs\trace:
+       TRACE_IRQS_IRETQ 0
+       swapgs
+paranoid_restore\trace:
+       RESTORE_ALL 8
+       iretq
+paranoid_userspace\trace:
+       GET_THREAD_INFO(%rcx)
+       movl threadinfo_flags(%rcx),%ebx
+       andl $_TIF_WORK_MASK,%ebx
+       jz paranoid_swapgs\trace
+       movq %rsp,%rdi                  /* &pt_regs */
+       call sync_regs
+       movq %rax,%rsp                  /* switch stack for scheduling */
+       testl $_TIF_NEED_RESCHED,%ebx
+       jnz paranoid_schedule\trace
+       movl %ebx,%edx                  /* arg3: thread flags */
+       .if \trace
+       TRACE_IRQS_ON
+       .endif
+       sti
+       xorl %esi,%esi                  /* arg2: oldset */
+       movq %rsp,%rdi                  /* arg1: &pt_regs */
+       call do_notify_resume
+       cli
+       .if \trace
+       TRACE_IRQS_OFF
+       .endif
+       jmp paranoid_userspace\trace
+paranoid_schedule\trace:
+       .if \trace
+       TRACE_IRQS_ON
+       .endif
+       sti
+       call schedule
+       cli
+       .if \trace
+       TRACE_IRQS_OFF
+       .endif
+       jmp paranoid_userspace\trace
+       CFI_ENDPROC
+       .endm
+
 /*
  * Exception entry point. This expects an error code/orig_rax on the stack
  * and the exception handler in %rax.  
@@ -748,6 +864,7 @@ error_exit:
        movl %ebx,%eax          
        RESTORE_REST
        cli
+       TRACE_IRQS_OFF
        GET_THREAD_INFO(%rcx)   
        testl %eax,%eax
        jne  retint_kernel
@@ -755,6 +872,10 @@ error_exit:
        movl  $_TIF_WORK_MASK,%edi
        andl  %edi,%edx
        jnz  retint_careful
+       /*
+        * The iret might restore flags:
+        */
+       TRACE_IRQS_IRETQ
        swapgs 
        RESTORE_ARGS 0,8,0                                              
        jmp iret_label
@@ -916,8 +1037,7 @@ KPROBE_ENTRY(debug)
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8         
        paranoidentry do_debug, DEBUG_STACK
-       jmp paranoid_exit
-       CFI_ENDPROC
+       paranoidexit
 END(debug)
        .previous .text
 
@@ -926,49 +1046,13 @@ KPROBE_ENTRY(nmi)
        INTR_FRAME
        pushq $-1
        CFI_ADJUST_CFA_OFFSET 8
-       paranoidentry do_nmi
-       /*
-        * "Paranoid" exit path from exception stack.
-        * Paranoid because this is used by NMIs and cannot take
-        * any kernel state for granted.
-        * We don't do kernel preemption checks here, because only
-        * NMI should be common and it does not enable IRQs and
-        * cannot get reschedule ticks.
-        */
-       /* ebx: no swapgs flag */
-paranoid_exit:
-       testl %ebx,%ebx                         /* swapgs needed? */
-       jnz paranoid_restore
-       testl $3,CS(%rsp)
-       jnz   paranoid_userspace
-paranoid_swapgs:       
-       swapgs
-paranoid_restore:      
-       RESTORE_ALL 8
-       iretq
-paranoid_userspace:    
-       GET_THREAD_INFO(%rcx)
-       movl threadinfo_flags(%rcx),%ebx
-       andl $_TIF_WORK_MASK,%ebx
-       jz paranoid_swapgs
-       movq %rsp,%rdi                  /* &pt_regs */
-       call sync_regs
-       movq %rax,%rsp                  /* switch stack for scheduling */
-       testl $_TIF_NEED_RESCHED,%ebx
-       jnz paranoid_schedule
-       movl %ebx,%edx                  /* arg3: thread flags */
-       sti
-       xorl %esi,%esi                  /* arg2: oldset */
-       movq %rsp,%rdi                  /* arg1: &pt_regs */
-       call do_notify_resume
-       cli
-       jmp paranoid_userspace
-paranoid_schedule:
-       sti
-       call schedule
-       cli
-       jmp paranoid_userspace
-       CFI_ENDPROC
+       paranoidentry do_nmi, 0, 0
+#ifdef CONFIG_TRACE_IRQFLAGS
+       paranoidexit 0
+#else
+       jmp paranoid_exit1
+       CFI_ENDPROC
+#endif
 END(nmi)
        .previous .text
 
@@ -977,7 +1061,7 @@ KPROBE_ENTRY(int3)
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8
        paranoidentry do_int3, DEBUG_STACK
-       jmp paranoid_exit
+       jmp paranoid_exit1
        CFI_ENDPROC
 END(int3)
        .previous .text
@@ -1006,7 +1090,7 @@ END(reserved)
 ENTRY(double_fault)
        XCPT_FRAME
        paranoidentry do_double_fault
-       jmp paranoid_exit
+       jmp paranoid_exit1
        CFI_ENDPROC
 END(double_fault)
 
@@ -1022,7 +1106,7 @@ END(segment_not_present)
 ENTRY(stack_segment)
        XCPT_FRAME
        paranoidentry do_stack_segment
-       jmp paranoid_exit
+       jmp paranoid_exit1
        CFI_ENDPROC
 END(stack_segment)
 
@@ -1050,7 +1134,7 @@ ENTRY(machine_check)
        pushq $0
        CFI_ADJUST_CFA_OFFSET 8 
        paranoidentry do_machine_check
-       jmp paranoid_exit
+       jmp paranoid_exit1
        CFI_ENDPROC
 END(machine_check)
 #endif
index e6a71c9..36647ce 100644 (file)
@@ -85,6 +85,11 @@ void __init x86_64_start_kernel(char * real_mode_data)
        clear_bss();
 
        /*
+        * This must be called really, really early:
+        */
+       lockdep_init();
+
+       /*
         * switch to init_level4_pgt from boot_level4_pgt
         */
        memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t));
index a1f1df5..5221a53 100644 (file)
@@ -177,8 +177,10 @@ asmlinkage void do_softirq(void)
        local_irq_save(flags);
        pending = local_softirq_pending();
        /* Switch to interrupt stack */
-       if (pending)
+       if (pending) {
                call_softirq();
+               WARN_ON_ONCE(softirq_count());
+       }
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(do_softirq);
index 476c147..5baa0c7 100644 (file)
@@ -127,7 +127,7 @@ void __cpuinit nmi_watchdog_default(void)
 static __init void nmi_cpu_busy(void *data)
 {
        volatile int *endflag = data;
-       local_irq_enable();
+       local_irq_enable_in_hardirq();
        /* Intentionally don't use cpu_relax here. This is
           to make sure that the performance counter really ticks,
           even if there is a simulator or similar that catches the
index ca56e19..bb6745d 100644 (file)
@@ -296,7 +296,7 @@ void __show_regs(struct pt_regs * regs)
                system_utsname.version);
        printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
        printk_address(regs->rip); 
-       printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
+       printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
                regs->eflags);
        printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
               regs->rax, regs->rbx, regs->rcx);
index 9705a6a..b7c7059 100644 (file)
@@ -775,6 +775,8 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
        };
        DECLARE_WORK(work, do_fork_idle, &c_idle);
 
+       lockdep_set_class(&c_idle.done.wait.lock, &waitqueue_lock_key);
+
        /* allocate memory for gdts of secondary cpus. Hotplug is considered */
        if (!cpu_gdt_descr[cpu].address &&
                !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c
new file mode 100644 (file)
index 0000000..32cf55e
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * arch/x86_64/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+#include <asm/smp.h>
+
+static inline int
+in_range(unsigned long start, unsigned long addr, unsigned long end)
+{
+       return addr >= start && addr <= end;
+}
+
+static unsigned long
+get_stack_end(struct task_struct *task, unsigned long stack)
+{
+       unsigned long stack_start, stack_end, flags;
+       int i, cpu;
+
+       /*
+        * The most common case is that we are in the task stack:
+        */
+       stack_start = (unsigned long)task->thread_info;
+       stack_end = stack_start + THREAD_SIZE;
+
+       if (in_range(stack_start, stack, stack_end))
+               return stack_end;
+
+       /*
+        * We are in an interrupt if irqstackptr is set:
+        */
+       raw_local_irq_save(flags);
+       cpu = safe_smp_processor_id();
+       stack_end = (unsigned long)cpu_pda(cpu)->irqstackptr;
+
+       if (stack_end) {
+               stack_start = stack_end & ~(IRQSTACKSIZE-1);
+               if (in_range(stack_start, stack, stack_end))
+                       goto out_restore;
+               /*
+                * We get here if we are in an IRQ context but we
+                * are also in an exception stack.
+                */
+       }
+
+       /*
+        * Iterate over all exception stacks, and figure out whether
+        * 'stack' is in one of them:
+        */
+       for (i = 0; i < N_EXCEPTION_STACKS; i++) {
+               /*
+                * set 'end' to the end of the exception stack.
+                */
+               stack_end = per_cpu(init_tss, cpu).ist[i];
+               stack_start = stack_end - EXCEPTION_STKSZ;
+
+               /*
+                * Is 'stack' above this exception frame's end?
+                * If yes then skip to the next frame.
+                */
+               if (stack >= stack_end)
+                       continue;
+               /*
+                * Is 'stack' above this exception frame's start address?
+                * If yes then we found the right frame.
+                */
+               if (stack >= stack_start)
+                       goto out_restore;
+
+               /*
+                * If this is a debug stack, and if it has a larger size than
+                * the usual exception stacks, then 'stack' might still
+                * be within the lower portion of the debug stack:
+                */
+#if DEBUG_STKSZ > EXCEPTION_STKSZ
+               if (i == DEBUG_STACK - 1 && stack >= stack_end - DEBUG_STKSZ) {
+                       /*
+                        * Black magic. A large debug stack is composed of
+                        * multiple exception stack entries, which we
+                        * iterate through now. Dont look:
+                        */
+                       do {
+                               stack_end -= EXCEPTION_STKSZ;
+                               stack_start -= EXCEPTION_STKSZ;
+                       } while (stack < stack_start);
+
+                       goto out_restore;
+               }
+#endif
+       }
+       /*
+        * Ok, 'stack' is not pointing to any of the system stacks.
+        */
+       stack_end = 0;
+
+out_restore:
+       raw_local_irq_restore(flags);
+
+       return stack_end;
+}
+
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer:
+ */
+static inline unsigned long
+save_context_stack(struct stack_trace *trace, unsigned int skip,
+                  unsigned long stack, unsigned long stack_end)
+{
+       unsigned long addr;
+
+#ifdef CONFIG_FRAME_POINTER
+       unsigned long prev_stack = 0;
+
+       while (in_range(prev_stack, stack, stack_end)) {
+               pr_debug("stack:          %p\n", (void *)stack);
+               addr = (unsigned long)(((unsigned long *)stack)[1]);
+               pr_debug("addr:           %p\n", (void *)addr);
+               if (!skip)
+                       trace->entries[trace->nr_entries++] = addr-1;
+               else
+                       skip--;
+               if (trace->nr_entries >= trace->max_entries)
+                       break;
+               if (!addr)
+                       return 0;
+               /*
+                * Stack frames must go forwards (otherwise a loop could
+                * happen if the stackframe is corrupted), so we move
+                * prev_stack forwards:
+                */
+               prev_stack = stack;
+               stack = (unsigned long)(((unsigned long *)stack)[0]);
+       }
+       pr_debug("invalid:        %p\n", (void *)stack);
+#else
+       while (stack < stack_end) {
+               addr = ((unsigned long *)stack)[0];
+               stack += sizeof(long);
+               if (__kernel_text_address(addr)) {
+                       if (!skip)
+                               trace->entries[trace->nr_entries++] = addr-1;
+                       else
+                               skip--;
+                       if (trace->nr_entries >= trace->max_entries)
+                               break;
+               }
+       }
+#endif
+       return stack;
+}
+
+#define MAX_STACKS 10
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ * If all_contexts is set, all contexts (hardirq, softirq and process)
+ * are saved. If not set then only the current context is saved.
+ */
+void save_stack_trace(struct stack_trace *trace,
+                     struct task_struct *task, int all_contexts,
+                     unsigned int skip)
+{
+       unsigned long stack = (unsigned long)&stack;
+       int i, nr_stacks = 0, stacks_done[MAX_STACKS];
+
+       WARN_ON(trace->nr_entries || !trace->max_entries);
+
+       if (!task)
+               task = current;
+
+       pr_debug("task: %p, ti: %p\n", task, task->thread_info);
+
+       if (!task || task == current) {
+               /* Grab rbp right from our regs: */
+               asm ("mov %%rbp, %0" : "=r" (stack));
+               pr_debug("rbp:            %p\n", (void *)stack);
+       } else {
+               /* rbp is the last reg pushed by switch_to(): */
+               stack = task->thread.rsp;
+               pr_debug("other task rsp: %p\n", (void *)stack);
+               stack = (unsigned long)(((unsigned long *)stack)[0]);
+               pr_debug("other task rbp: %p\n", (void *)stack);
+       }
+
+       while (1) {
+               unsigned long stack_end = get_stack_end(task, stack);
+
+               pr_debug("stack:          %p\n", (void *)stack);
+               pr_debug("stack end:      %p\n", (void *)stack_end);
+
+               /*
+                * Invalid stack addres?
+                */
+               if (!stack_end)
+                       return;
+               /*
+                * Were we in this stack already? (recursion)
+                */
+               for (i = 0; i < nr_stacks; i++)
+                       if (stacks_done[i] == stack_end)
+                               return;
+               stacks_done[nr_stacks] = stack_end;
+
+               stack = save_context_stack(trace, skip, stack, stack_end);
+               if (!all_contexts || !stack ||
+                               trace->nr_entries >= trace->max_entries)
+                       return;
+               trace->entries[trace->nr_entries++] = ULONG_MAX;
+               if (trace->nr_entries >= trace->max_entries)
+                       return;
+               if (++nr_stacks >= MAX_STACKS)
+                       return;
+       }
+}
+
index 5a5311d..79d05c4 100644 (file)
@@ -110,28 +110,31 @@ static int kstack_depth_to_print = 12;
 static int call_trace = 1;
 
 #ifdef CONFIG_KALLSYMS
-#include <linux/kallsyms.h> 
-int printk_address(unsigned long address)
-{ 
+# include <linux/kallsyms.h>
+void printk_address(unsigned long address)
+{
        unsigned long offset = 0, symsize;
        const char *symname;
        char *modname;
-       char *delim = ":"; 
+       char *delim = ":";
        char namebuf[128];
 
-       symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 
-       if (!symname) 
-               return printk("[<%016lx>]", address);
-       if (!modname) 
+       symname = kallsyms_lookup(address, &symsize, &offset,
+                                       &modname, namebuf);
+       if (!symname) {
+               printk(" [<%016lx>]\n", address);
+               return;
+       }
+       if (!modname)
                modname = delim = "";           
-        return printk("<%016lx>{%s%s%s%s%+ld}",
-                     address, delim, modname, delim, symname, offset); 
-} 
+       printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n",
+               address, delim, modname, delim, symname, offset, symsize);
+}
 #else
-int printk_address(unsigned long address)
-{ 
-       return printk("[<%016lx>]", address);
-} 
+void printk_address(unsigned long address)
+{
+       printk(" [<%016lx>]\n", address);
+}
 #endif
 
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
@@ -149,10 +152,22 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
        };
        unsigned k;
 
+       /*
+        * Iterate over all exception stacks, and figure out whether
+        * 'stack' is in one of them:
+        */
        for (k = 0; k < N_EXCEPTION_STACKS; k++) {
                unsigned long end;
 
+               /*
+                * set 'end' to the end of the exception stack.
+                */
                switch (k + 1) {
+               /*
+                * TODO: this block is not needed i think, because
+                * setup64.c:cpu_init() sets up t->ist[DEBUG_STACK]
+                * properly too.
+                */
 #if DEBUG_STKSZ > EXCEPTION_STKSZ
                case DEBUG_STACK:
                        end = cpu_pda(cpu)->debugstack + DEBUG_STKSZ;
@@ -162,19 +177,43 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
                        end = per_cpu(init_tss, cpu).ist[k];
                        break;
                }
+               /*
+                * Is 'stack' above this exception frame's end?
+                * If yes then skip to the next frame.
+                */
                if (stack >= end)
                        continue;
+               /*
+                * Is 'stack' above this exception frame's start address?
+                * If yes then we found the right frame.
+                */
                if (stack >= end - EXCEPTION_STKSZ) {
+                       /*
+                        * Make sure we only iterate through an exception
+                        * stack once. If it comes up for the second time
+                        * then there's something wrong going on - just
+                        * break out and return NULL:
+                        */
                        if (*usedp & (1U << k))
                                break;
                        *usedp |= 1U << k;
                        *idp = ids[k];
                        return (unsigned long *)end;
                }
+               /*
+                * If this is a debug stack, and if it has a larger size than
+                * the usual exception stacks, then 'stack' might still
+                * be within the lower portion of the debug stack:
+                */
 #if DEBUG_STKSZ > EXCEPTION_STKSZ
                if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) {
                        unsigned j = N_EXCEPTION_STACKS - 1;
 
+                       /*
+                        * Black magic. A large debug stack is composed of
+                        * multiple exception stack entries, which we
+                        * iterate through now. Dont look:
+                        */
                        do {
                                ++j;
                                end -= EXCEPTION_STKSZ;
@@ -193,20 +232,14 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 
 static int show_trace_unwind(struct unwind_frame_info *info, void *context)
 {
-       int i = 11, n = 0;
+       int n = 0;
 
        while (unwind(info) == 0 && UNW_PC(info)) {
-               ++n;
-               if (i > 50) {
-                       printk("\n       ");
-                       i = 7;
-               } else
-                       i += printk(" ");
-               i += printk_address(UNW_PC(info));
+               n++;
+               printk_address(UNW_PC(info));
                if (arch_unw_user_mode(info))
                        break;
        }
-       printk("\n");
        return n;
 }
 
@@ -224,7 +257,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
        int i = 11;
        unsigned used = 0;
 
-       printk("\nCall Trace:");
+       printk("\nCall Trace:\n");
 
        if (!tsk)
                tsk = current;
@@ -250,16 +283,15 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
                }
        }
 
+       /*
+        * Print function call entries within a stack. 'cond' is the
+        * "end of stackframe" condition, that the 'stack++'
+        * iteration will eventually trigger.
+        */
 #define HANDLE_STACK(cond) \
        do while (cond) { \
                unsigned long addr = *stack++; \
                if (kernel_text_address(addr)) { \
-                       if (i > 50) { \
-                               printk("\n       "); \
-                               i = 0; \
-                       } \
-                       else \
-                               i += printk(" "); \
                        /* \
                         * If the address is either in the text segment of the \
                         * kernel, or in the region which contains vmalloc'ed \
@@ -268,20 +300,30 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
                         * down the cause of the crash will be able to figure \
                         * out the call path that was taken. \
                         */ \
-                       i += printk_address(addr); \
+                       printk_address(addr); \
                } \
        } while (0)
 
-       for(; ; ) {
+       /*
+        * Print function call entries in all stacks, starting at the
+        * current stack address. If the stacks consist of nested
+        * exceptions
+        */
+       for ( ; ; ) {
                const char *id;
                unsigned long *estack_end;
                estack_end = in_exception_stack(cpu, (unsigned long)stack,
                                                &used, &id);
 
                if (estack_end) {
-                       i += printk(" <%s>", id);
+                       printk(" <%s>", id);
                        HANDLE_STACK (stack < estack_end);
-                       i += printk(" <EOE>");
+                       printk(" <EOE>");
+                       /*
+                        * We link to the next stack via the
+                        * second-to-last pointer (index -2 to end) in the
+                        * exception stack:
+                        */
                        stack = (unsigned long *) estack_end[-2];
                        continue;
                }
@@ -291,19 +333,28 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
                                (IRQSTACKSIZE - 64) / sizeof(*irqstack);
 
                        if (stack >= irqstack && stack < irqstack_end) {
-                               i += printk(" <IRQ>");
+                               printk(" <IRQ>");
                                HANDLE_STACK (stack < irqstack_end);
+                               /*
+                                * We link to the next stack (which would be
+                                * the process stack normally) the last
+                                * pointer (index -1 to end) in the IRQ stack:
+                                */
                                stack = (unsigned long *) (irqstack_end[-1]);
                                irqstack_end = NULL;
-                               i += printk(" <EOI>");
+                               printk(" <EOI>");
                                continue;
                        }
                }
                break;
        }
 
+       /*
+        * This prints the process stack:
+        */
        HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
 #undef HANDLE_STACK
+
        printk("\n");
 }
 
@@ -337,8 +388,8 @@ static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned
                        break;
                }
                if (i && ((i % 4) == 0))
-                       printk("\n       ");
-               printk("%016lx ", *stack++);
+                       printk("\n");
+               printk(" %016lx", *stack++);
                touch_nmi_watchdog();
        }
        show_trace(tsk, regs, rsp);
index e49af00..332ea5d 100644 (file)
        thunk_retrax __down_failed_interruptible,__down_interruptible
        thunk_retrax __down_failed_trylock,__down_trylock
        thunk __up_wakeup,__up
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+       thunk trace_hardirqs_on_thunk,trace_hardirqs_on
+       thunk trace_hardirqs_off_thunk,trace_hardirqs_off
+#endif
        
        /* SAVE_ARGS below is used only for the .cfi directives it contains. */
        CFI_STARTPROC
index 5afcf6e..ac8ea66 100644 (file)
@@ -570,7 +570,6 @@ no_context:
                printk(KERN_ALERT "Unable to handle kernel paging request");
        printk(" at %016lx RIP: \n" KERN_ALERT,address);
        printk_address(regs->rip);
-       printk("\n");
        dump_pagetable(address);
        tsk->thread.cr2 = address;
        tsk->thread.trap_no = 14;
index 5813d63..ab17c72 100644 (file)
@@ -2516,7 +2516,7 @@ EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
 int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk,
                   struct request *rq, int at_head)
 {
-       DECLARE_COMPLETION(wait);
+       DECLARE_COMPLETION_ONSTACK(wait);
        char sense[SCSI_SENSE_BUFFERSIZE];
        int err = 0;
 
index 0242cbb..5109fa3 100644 (file)
@@ -249,18 +249,6 @@ static int irqdma_allocated;
 #include <linux/cdrom.h>       /* for the compatibility eject ioctl */
 #include <linux/completion.h>
 
-/*
- * Interrupt freeing also means /proc VFS work - dont do it
- * from interrupt context. We push this work into keventd:
- */
-static void fd_free_irq_fn(void *data)
-{
-       fd_free_irq();
-}
-
-static DECLARE_WORK(fd_free_irq_work, fd_free_irq_fn, NULL);
-
-
 static struct request *current_req;
 static struct request_queue *floppy_queue;
 static void do_fd_request(request_queue_t * q);
@@ -826,15 +814,6 @@ static int set_dor(int fdc, char mask, char data)
                        UDRS->select_date = jiffies;
                }
        }
-       /*
-        *      We should propagate failures to grab the resources back
-        *      nicely from here. Actually we ought to rewrite the fd
-        *      driver some day too.
-        */
-       if (newdor & FLOPPY_MOTOR_MASK)
-               floppy_grab_irq_and_dma();
-       if (olddor & FLOPPY_MOTOR_MASK)
-               floppy_release_irq_and_dma();
        return olddor;
 }
 
@@ -892,8 +871,6 @@ static int _lock_fdc(int drive, int interruptible, int line)
                       line);
                return -1;
        }
-       if (floppy_grab_irq_and_dma() == -1)
-               return -EBUSY;
 
        if (test_and_set_bit(0, &fdc_busy)) {
                DECLARE_WAITQUEUE(wait, current);
@@ -915,6 +892,8 @@ static int _lock_fdc(int drive, int interruptible, int line)
 
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&fdc_wait, &wait);
+
+               flush_scheduled_work();
        }
        command_status = FD_COMMAND_NONE;
 
@@ -948,7 +927,6 @@ static inline void unlock_fdc(void)
        if (elv_next_request(floppy_queue))
                do_fd_request(floppy_queue);
        spin_unlock_irqrestore(&floppy_lock, flags);
-       floppy_release_irq_and_dma();
        wake_up(&fdc_wait);
 }
 
@@ -3694,8 +3672,8 @@ static int floppy_release(struct inode *inode, struct file *filp)
        }
        if (!UDRS->fd_ref)
                opened_bdev[drive] = NULL;
-       floppy_release_irq_and_dma();
        mutex_unlock(&open_lock);
+
        return 0;
 }
 
@@ -3726,9 +3704,6 @@ static int floppy_open(struct inode *inode, struct file *filp)
        if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
                goto out2;
 
-       if (floppy_grab_irq_and_dma())
-               goto out2;
-
        if (filp->f_flags & O_EXCL)
                UDRS->fd_ref = -1;
        else
@@ -3805,7 +3780,6 @@ out:
                UDRS->fd_ref--;
        if (!UDRS->fd_ref)
                opened_bdev[drive] = NULL;
-       floppy_release_irq_and_dma();
 out2:
        mutex_unlock(&open_lock);
        return res;
@@ -3822,14 +3796,9 @@ static int check_floppy_change(struct gendisk *disk)
                return 1;
 
        if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
-               if (floppy_grab_irq_and_dma()) {
-                       return 1;
-               }
-
                lock_fdc(drive, 0);
                poll_drive(0, 0);
                process_fd_request();
-               floppy_release_irq_and_dma();
        }
 
        if (UTESTF(FD_DISK_CHANGED) ||
@@ -4346,7 +4315,6 @@ static int __init floppy_init(void)
        fdc = 0;
        del_timer(&fd_timeout);
        current_drive = 0;
-       floppy_release_irq_and_dma();
        initialising = 0;
        if (have_no_fdc) {
                DPRINT("no floppy controllers found\n");
@@ -4504,7 +4472,7 @@ static void floppy_release_irq_and_dma(void)
        if (irqdma_allocated) {
                fd_disable_dma();
                fd_free_dma();
-               schedule_work(&fd_free_irq_work);
+               fd_free_irq();
                irqdma_allocated = 0;
        }
        set_dor(0, ~0, 8);
@@ -4600,8 +4568,6 @@ void cleanup_module(void)
        /* eject disk, if any */
        fd_eject(0);
 
-       flush_scheduled_work();         /* fd_free_irq() might be pending */
-
        wait_for_completion(&device_release);
 }
 
index ffcf15c..d9c5a91 100644 (file)
@@ -1059,7 +1059,7 @@ ioctl_out:
        return ret_val;
 }
 
-static struct file_operations agp_fops =
+static const struct file_operations agp_fops =
 {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
index bcc4668..10a389d 100644 (file)
@@ -112,7 +112,7 @@ static int ac_ioctl(struct inode *, struct file *, unsigned int,
                    unsigned long);
 static irqreturn_t ac_interrupt(int, void *, struct pt_regs *);
 
-static struct file_operations ac_fops = {
+static const struct file_operations ac_fops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .read = ac_read,
index 46d6603..8ce3f34 100644 (file)
@@ -158,7 +158,7 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file)
        return nonseekable_open(inode, file);
 }
 
-static struct file_operations cs5535_gpio_fops = {
+static const struct file_operations cs5535_gpio_fops = {
        .owner  = THIS_MODULE,
        .write  = cs5535_gpio_write,
        .read   = cs5535_gpio_read,
index d755cac..21c8229 100644 (file)
@@ -281,7 +281,7 @@ static unsigned int ds1286_poll(struct file *file, poll_table *wait)
  *     The various file operations we support.
  */
 
-static struct file_operations ds1286_fops = {
+static const struct file_operations ds1286_fops = {
        .llseek         = no_llseek,
        .read           = ds1286_read,
        .poll           = ds1286_poll,
index 625e8b5..bcdb107 100644 (file)
@@ -282,7 +282,7 @@ get_rtc_status(char *buf)
 
 /* The various file operations we support. */
 
-static struct file_operations rtc_fops = {
+static const struct file_operations rtc_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = rtc_ioctl,
 };
index 953e670..48cb8f0 100644 (file)
@@ -336,7 +336,7 @@ proc_therm_ds1620_read(char *buf, char **start, off_t offset,
 static struct proc_dir_entry *proc_therm_ds1620;
 #endif
 
-static struct file_operations ds1620_fops = {
+static const struct file_operations ds1620_fops = {
        .owner          = THIS_MODULE,
        .open           = nonseekable_open,
        .read           = ds1620_read,
index 09b4136..9b1bf60 100644 (file)
@@ -483,7 +483,7 @@ static int dsp56k_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations dsp56k_fops = {
+static const struct file_operations dsp56k_fops = {
        .owner          = THIS_MODULE,
        .read           = dsp56k_read,
        .write          = dsp56k_write,
index da2c89f..5e82c3b 100644 (file)
@@ -94,7 +94,7 @@ static int dtlk_release(struct inode *, struct file *);
 static int dtlk_ioctl(struct inode *inode, struct file *file,
                      unsigned int cmd, unsigned long arg);
 
-static struct file_operations dtlk_fops =
+static const struct file_operations dtlk_fops =
 {
        .owner          = THIS_MODULE,
        .read           = dtlk_read,
index 0090e7a..004141d 100644 (file)
@@ -285,7 +285,7 @@ efi_rtc_close(struct inode *inode, struct file *file)
  *     The various file operations we support.
  */
 
-static struct file_operations efi_rtc_fops = {
+static const struct file_operations efi_rtc_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = efi_rtc_ioctl,
        .open           = efi_rtc_open,
index 5527256..164a1aa 100644 (file)
@@ -86,7 +86,7 @@ static ssize_t zft_read (struct file *fp, char __user *buff,
 static ssize_t zft_write(struct file *fp, const char __user *buff,
                         size_t req_len, loff_t *ppos);
 
-static struct file_operations zft_cdev =
+static const struct file_operations zft_cdev =
 {
        .owner          = THIS_MODULE,
        .read           = zft_read,
index bebd7e3..817dc40 100644 (file)
@@ -482,7 +482,7 @@ static inline int gen_rtc_proc_init(void) { return 0; }
  *     The various file operations we support.
  */
 
-static struct file_operations gen_rtc_fops = {
+static const struct file_operations gen_rtc_fops = {
        .owner          = THIS_MODULE,
 #ifdef CONFIG_GEN_RTC_X
        .read           = gen_rtc_read,
index e5643f3..8afba33 100644 (file)
@@ -553,7 +553,7 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
        return err;
 }
 
-static struct file_operations hpet_fops = {
+static const struct file_operations hpet_fops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .read = hpet_read,
index 88b0266..154a81d 100644 (file)
@@ -149,7 +149,7 @@ out:
 }
 
 
-static struct file_operations rng_chrdev_ops = {
+static const struct file_operations rng_chrdev_ops = {
        .owner          = THIS_MODULE,
        .open           = rng_dev_open,
        .read           = rng_dev_read,
index f3c3aaf..353d9f3 100644 (file)
@@ -80,7 +80,7 @@ static int i8k_open_fs(struct inode *inode, struct file *file);
 static int i8k_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
 
-static struct file_operations i8k_fops = {
+static const struct file_operations i8k_fops = {
        .open           = i8k_open_fs,
        .read           = seq_read,
        .llseek         = seq_lseek,
index a4200a2..518ece7 100644 (file)
@@ -233,7 +233,7 @@ static void  *DevTableMem[IP2_MAX_BOARDS];
 /* This is the driver descriptor for the ip2ipl device, which is used to
  * download the loadware to the boards.
  */
-static struct file_operations ip2_ipl = {
+static const struct file_operations ip2_ipl = {
        .owner          = THIS_MODULE,
        .read           = ip2_ipl_read,
        .write          = ip2_ipl_write,
index 3acdac3..a48da02 100644 (file)
@@ -196,7 +196,7 @@ static int rtc_release(struct inode *inode, struct file *file)
  *     The various file operations we support.
  */
 
-static struct file_operations rtc_fops = {
+static const struct file_operations rtc_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = rtc_ioctl,
        .open           = rtc_open,
index 2fc894f..68d7c61 100644 (file)
@@ -765,7 +765,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
 }
 #endif
 
-static struct file_operations ipmi_fops = {
+static const struct file_operations ipmi_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = ipmi_ioctl,
 #ifdef CONFIG_COMPAT
index 74a889c..accaaf1 100644 (file)
@@ -807,7 +807,7 @@ static int ipmi_close(struct inode *ino, struct file *filep)
        return 0;
 }
 
-static struct file_operations ipmi_wdog_fops = {
+static const struct file_operations ipmi_wdog_fops = {
        .owner   = THIS_MODULE,
        .read    = ipmi_read,
        .poll    = ipmi_poll,
index fbce2f0..84dfc42 100644 (file)
@@ -748,7 +748,7 @@ static int  stli_initpcibrd(int brdtype, struct pci_dev *devp);
  *     will give access to the shared memory on the Stallion intelligent
  *     board. This is also a very useful debugging tool.
  */
-static struct file_operations  stli_fsiomem = {
+static const struct file_operations    stli_fsiomem = {
        .owner          = THIS_MODULE,
        .read           = stli_memread,
        .write          = stli_memwrite,
index 747ba45..cde562d 100644 (file)
@@ -357,7 +357,7 @@ DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i));
        }
 }
 
-static struct file_operations ite_gpio_fops = {
+static const struct file_operations ite_gpio_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = ite_gpio_ioctl,
        .open           = ite_gpio_open,
index 7d49b24..da601fd 100644 (file)
@@ -598,7 +598,7 @@ static ssize_t lcd_read(struct file *file, char *buf,
  *     The various file operations we support.
  */
 
-static struct file_operations lcd_fops = {
+static const struct file_operations lcd_fops = {
        .read = lcd_read,
        .ioctl = lcd_ioctl,
        .open = lcd_open,
index 582cdbd..f875fda 100644 (file)
@@ -666,7 +666,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
        return retval;
 }
 
-static struct file_operations lp_fops = {
+static const struct file_operations lp_fops = {
        .owner          = THIS_MODULE,
        .write          = lp_write,
        .ioctl          = lp_ioctl,
index 70f3954..e97c32c 100644 (file)
@@ -776,7 +776,7 @@ static int open_port(struct inode * inode, struct file * filp)
 #define open_kmem      open_mem
 #define open_oldmem    open_mem
 
-static struct file_operations mem_fops = {
+static const struct file_operations mem_fops = {
        .llseek         = memory_lseek,
        .read           = read_mem,
        .write          = write_mem,
@@ -784,7 +784,7 @@ static struct file_operations mem_fops = {
        .open           = open_mem,
 };
 
-static struct file_operations kmem_fops = {
+static const struct file_operations kmem_fops = {
        .llseek         = memory_lseek,
        .read           = read_kmem,
        .write          = write_kmem,
@@ -792,7 +792,7 @@ static struct file_operations kmem_fops = {
        .open           = open_kmem,
 };
 
-static struct file_operations null_fops = {
+static const struct file_operations null_fops = {
        .llseek         = null_lseek,
        .read           = read_null,
        .write          = write_null,
@@ -800,7 +800,7 @@ static struct file_operations null_fops = {
 };
 
 #if defined(CONFIG_ISA) || !defined(__mc68000__)
-static struct file_operations port_fops = {
+static const struct file_operations port_fops = {
        .llseek         = memory_lseek,
        .read           = read_port,
        .write          = write_port,
@@ -808,7 +808,7 @@ static struct file_operations port_fops = {
 };
 #endif
 
-static struct file_operations zero_fops = {
+static const struct file_operations zero_fops = {
        .llseek         = zero_lseek,
        .read           = read_zero,
        .write          = write_zero,
@@ -819,14 +819,14 @@ static struct backing_dev_info zero_bdi = {
        .capabilities   = BDI_CAP_MAP_COPY,
 };
 
-static struct file_operations full_fops = {
+static const struct file_operations full_fops = {
        .llseek         = full_lseek,
        .read           = read_full,
        .write          = write_full,
 };
 
 #ifdef CONFIG_CRASH_DUMP
-static struct file_operations oldmem_fops = {
+static const struct file_operations oldmem_fops = {
        .read   = read_oldmem,
        .open   = open_oldmem,
 };
@@ -853,7 +853,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
        return ret;
 }
 
-static struct file_operations kmsg_fops = {
+static const struct file_operations kmsg_fops = {
        .write =        kmsg_write,
 };
 
@@ -903,7 +903,7 @@ static int memory_open(struct inode * inode, struct file * filp)
        return 0;
 }
 
-static struct file_operations memory_fops = {
+static const struct file_operations memory_fops = {
        .open           = memory_open,  /* just a selector for the real open */
 };
 
index d5fa19d..62ebe09 100644 (file)
@@ -113,7 +113,7 @@ static int misc_seq_open(struct inode *inode, struct file *file)
        return seq_open(file, &misc_seq_ops);
 }
 
-static struct file_operations misc_proc_fops = {
+static const struct file_operations misc_proc_fops = {
        .owner   = THIS_MODULE,
        .open    = misc_seq_open,
        .read    = seq_read,
@@ -176,7 +176,7 @@ fail:
  */
 static struct class *misc_class;
 
-static struct file_operations misc_fops = {
+static const struct file_operations misc_fops = {
        .owner          = THIS_MODULE,
        .open           = misc_open,
 };
index 70b774f..1f0f2b6 100644 (file)
@@ -63,7 +63,7 @@ static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma);
  */
 static unsigned long mmtimer_femtoperiod = 0;
 
-static struct file_operations mmtimer_fops = {
+static const struct file_operations mmtimer_fops = {
        .owner =        THIS_MODULE,
        .mmap =         mmtimer_mmap,
        .ioctl =        mmtimer_ioctl,
index d3ba2f8..39a2e66 100644 (file)
@@ -454,7 +454,7 @@ static int register_serial_portandirq(unsigned int port, int irq)
 }
 
 
-static struct file_operations mwave_fops = {
+static const struct file_operations mwave_fops = {
        .owner          = THIS_MODULE,
        .read           = mwave_read,
        .write          = mwave_write,
index 8c5f102..a39f19c 100644 (file)
@@ -437,7 +437,7 @@ nvram_read_proc(char *buffer, char **start, off_t offset,
 
 #endif /* CONFIG_PROC_FS */
 
-static struct file_operations nvram_fops = {
+static const struct file_operations nvram_fops = {
        .owner          = THIS_MODULE,
        .llseek         = nvram_llseek,
        .read           = nvram_read,
index f240a10..7c57ebf 100644 (file)
@@ -183,7 +183,7 @@ static int button_read (struct file *filp, char __user *buffer,
  * attempts to perform these operations on the device.
  */
 
-static struct file_operations button_fops = {
+static const struct file_operations button_fops = {
        .owner          = THIS_MODULE,
        .read           = button_read,
 };
index 8865387..206cf6f 100644 (file)
@@ -642,7 +642,7 @@ static void kick_open(void)
        udelay(25);
 }
 
-static struct file_operations flash_fops =
+static const struct file_operations flash_fops =
 {
        .owner          = THIS_MODULE,
        .llseek         = flash_llseek,
index c860de6..4005ee0 100644 (file)
@@ -236,7 +236,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file)
        return nonseekable_open(inode, file);
 }
 
-static struct file_operations pc8736x_gpio_fops = {
+static const struct file_operations pc8736x_gpio_fops = {
        .owner  = THIS_MODULE,
        .open   = pc8736x_gpio_open,
        .write  = nsc_gpio_write,
index 31c8a21..50d20aa 100644 (file)
@@ -1938,7 +1938,7 @@ static void cm4000_detach(struct pcmcia_device *link)
        return;
 }
 
-static struct file_operations cm4000_fops = {
+static const struct file_operations cm4000_fops = {
        .owner  = THIS_MODULE,
        .read   = cmm_read,
        .write  = cmm_write,
index 47a8465..55cf4be 100644 (file)
@@ -688,7 +688,7 @@ static void reader_detach(struct pcmcia_device *link)
        return;
 }
 
-static struct file_operations reader_fops = {
+static const struct file_operations reader_fops = {
        .owner          = THIS_MODULE,
        .read           = cm4040_read,
        .write          = cm4040_write,
index 24231d9..520d2cf 100644 (file)
@@ -739,7 +739,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait)
 
 static struct class *ppdev_class;
 
-static struct file_operations pp_fops = {
+static const struct file_operations pp_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .read           = pp_read,
index 164bdda..4c3a5ca 100644 (file)
@@ -416,7 +416,7 @@ static struct entropy_store input_pool = {
        .poolinfo = &poolinfo_table[0],
        .name = "input",
        .limit = 1,
-       .lock = SPIN_LOCK_UNLOCKED,
+       .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
        .pool = input_pool_data
 };
 
@@ -425,7 +425,7 @@ static struct entropy_store blocking_pool = {
        .name = "blocking",
        .limit = 1,
        .pull = &input_pool,
-       .lock = SPIN_LOCK_UNLOCKED,
+       .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
        .pool = blocking_pool_data
 };
 
@@ -433,7 +433,7 @@ static struct entropy_store nonblocking_pool = {
        .poolinfo = &poolinfo_table[1],
        .name = "nonblocking",
        .pull = &input_pool,
-       .lock = SPIN_LOCK_UNLOCKED,
+       .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
        .pool = nonblocking_pool_data
 };
 
index 9bf97c5..579868a 100644 (file)
@@ -30,7 +30,7 @@ struct raw_device_data {
 static struct class *raw_class;
 static struct raw_device_data raw_devices[MAX_RAW_MINORS];
 static DEFINE_MUTEX(raw_mutex);
-static struct file_operations raw_ctl_fops;         /* forward declaration */
+static const struct file_operations raw_ctl_fops; /* forward declaration */
 
 /*
  * Open/close code for raw IO.
@@ -261,7 +261,7 @@ static ssize_t raw_file_aio_write(struct kiocb *iocb, const char __user *buf,
 }
 
 
-static struct file_operations raw_fops = {
+static const struct file_operations raw_fops = {
        .read   =       generic_file_read,
        .aio_read =     generic_file_aio_read,
        .write  =       raw_file_write,
@@ -274,7 +274,7 @@ static struct file_operations raw_fops = {
        .owner  =       THIS_MODULE,
 };
 
-static struct file_operations raw_ctl_fops = {
+static const struct file_operations raw_ctl_fops = {
        .ioctl  =       raw_ctl_ioctl,
        .open   =       raw_open,
        .owner  =       THIS_MODULE,
index 3afc6a4..3fa80aa 100644 (file)
@@ -243,7 +243,7 @@ static struct real_driver rio_real_driver = {
  *
  */
 
-static struct file_operations rio_fw_fops = {
+static const struct file_operations rio_fw_fops = {
        .owner = THIS_MODULE,
        .ioctl = rio_fw_ioctl,
 };
index aefac4a..cc7bd1a 100644 (file)
@@ -877,7 +877,7 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
  *     The various file operations we support.
  */
 
-static struct file_operations rtc_fops = {
+static const struct file_operations rtc_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .read           = rtc_read,
@@ -896,7 +896,7 @@ static struct miscdevice rtc_dev = {
        .fops           = &rtc_fops,
 };
 
-static struct file_operations rtc_proc_fops = {
+static const struct file_operations rtc_proc_fops = {
        .owner = THIS_MODULE,
        .open = rtc_proc_open,
        .read  = seq_read,
index 45083e5..425c587 100644 (file)
@@ -63,7 +63,7 @@ static int scx200_gpio_release(struct inode *inode, struct file *file)
 }
 
 
-static struct file_operations scx200_gpio_fops = {
+static const struct file_operations scx200_gpio_fops = {
        .owner   = THIS_MODULE,
        .write   = nsc_gpio_write,
        .read    = nsc_gpio_read,
index 203240b..afc6eda 100644 (file)
@@ -347,7 +347,7 @@ scdrv_poll(struct file *file, struct poll_table_struct *wait)
        return mask;
 }
 
-static struct file_operations scdrv_fops = {
+static const struct file_operations scdrv_fops = {
        .owner =        THIS_MODULE,
        .read =         scdrv_read,
        .write =        scdrv_write,
index 45508a0..d4e434d 100644 (file)
@@ -1106,7 +1106,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
        return ret;
 }
 
-static struct file_operations sonypi_misc_fops = {
+static const struct file_operations sonypi_misc_fops = {
        .owner          = THIS_MODULE,
        .read           = sonypi_misc_read,
        .poll           = sonypi_misc_poll,
index ed7b8ea..3beb220 100644 (file)
@@ -707,7 +707,7 @@ static unsigned int sc26198_baudtable[] = {
  *     Define the driver info for a user level control device. Used mainly
  *     to get at port stats - only not using the port device itself.
  */
-static struct file_operations  stl_fsiomem = {
+static const struct file_operations    stl_fsiomem = {
        .owner          = THIS_MODULE,
        .ioctl          = stl_memioctl,
 };
index 45c193a..e1cd2bc 100644 (file)
@@ -410,7 +410,7 @@ static struct real_driver sx_real_driver = {
  *
  */
 
-static struct file_operations sx_fw_fops = {
+static const struct file_operations sx_fw_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = sx_fw_ioctl,
 };
index a064ee9..ee3ca8f 100644 (file)
@@ -147,12 +147,13 @@ static struct sysrq_key_op sysrq_mountro_op = {
        .enable_mask    = SYSRQ_ENABLE_REMOUNT,
 };
 
-#ifdef CONFIG_DEBUG_MUTEXES
+#ifdef CONFIG_LOCKDEP
 static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs,
                                struct tty_struct *tty)
 {
-       mutex_debug_show_all_locks();
+       debug_show_all_locks();
 }
+
 static struct sysrq_key_op sysrq_showlocks_op = {
        .handler        = sysrq_handle_showlocks,
        .help_msg       = "show-all-locks(D)",
index a80c832..bb1bad4 100644 (file)
@@ -255,7 +255,7 @@ static int tanbac_tb0219_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations tb0219_fops = {
+static const struct file_operations tb0219_fops = {
        .owner          = THIS_MODULE,
        .read           = tanbac_tb0219_read,
        .write          = tanbac_tb0219_write,
index e0633a1..d30dc09 100644 (file)
@@ -381,7 +381,7 @@ tipar_ioctl(struct inode *inode, struct file *file,
 
 /* ----- kernel module registering ------------------------------------ */
 
-static struct file_operations tipar_fops = {
+static const struct file_operations tipar_fops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .read = tipar_read,
index 952b829..d2c5ba4 100644 (file)
@@ -247,7 +247,7 @@ static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t cou
        return 0;
 }
 
-static struct file_operations tlclk_fops = {
+static const struct file_operations tlclk_fops = {
        .read = tlclk_read,
        .write = tlclk_write,
        .open = tlclk_open,
index e2fb234..dd36fd0 100644 (file)
@@ -92,7 +92,7 @@ static int tosh_ioctl(struct inode *, struct file *, unsigned int,
        unsigned long);
 
 
-static struct file_operations tosh_fops = {
+static const struct file_operations tosh_fops = {
        .owner          = THIS_MODULE,
        .ioctl          = tosh_ioctl,
 };
index 58a258c..ad8ffe4 100644 (file)
@@ -116,7 +116,7 @@ static u8 tpm_atml_status(struct tpm_chip *chip)
        return ioread8(chip->vendor.iobase + 1);
 }
 
-static struct file_operations atmel_ops = {
+static const struct file_operations atmel_ops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .open = tpm_open,
index adfff21..1353b5a 100644 (file)
@@ -338,7 +338,7 @@ static struct attribute *inf_attrs[] = {
 
 static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
 
-static struct file_operations inf_ops = {
+static const struct file_operations inf_ops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .open = tpm_open,
index 4c8bc06..26287aa 100644 (file)
@@ -226,7 +226,7 @@ static u8 tpm_nsc_status(struct tpm_chip *chip)
        return inb(chip->vendor.base + NSC_STATUS);
 }
 
-static struct file_operations nsc_ops = {
+static const struct file_operations nsc_ops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .open = tpm_open,
index abb0f2a..3232b19 100644 (file)
@@ -330,7 +330,7 @@ out_err:
        return rc;
 }
 
-static struct file_operations tis_ops = {
+static const struct file_operations tis_ops = {
        .owner = THIS_MODULE,
        .llseek = no_llseek,
        .open = tpm_open,
index 615e934..bfdb902 100644 (file)
@@ -912,7 +912,7 @@ static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
        return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
 }
 
-static struct file_operations tty_fops = {
+static const struct file_operations tty_fops = {
        .llseek         = no_llseek,
        .read           = tty_read,
        .write          = tty_write,
@@ -924,7 +924,7 @@ static struct file_operations tty_fops = {
 };
 
 #ifdef CONFIG_UNIX98_PTYS
-static struct file_operations ptmx_fops = {
+static const struct file_operations ptmx_fops = {
        .llseek         = no_llseek,
        .read           = tty_read,
        .write          = tty_write,
@@ -936,7 +936,7 @@ static struct file_operations ptmx_fops = {
 };
 #endif
 
-static struct file_operations console_fops = {
+static const struct file_operations console_fops = {
        .llseek         = no_llseek,
        .read           = tty_read,
        .write          = redirected_tty_write,
@@ -947,7 +947,7 @@ static struct file_operations console_fops = {
        .fasync         = tty_fasync,
 };
 
-static struct file_operations hung_up_tty_fops = {
+static const struct file_operations hung_up_tty_fops = {
        .llseek         = no_llseek,
        .read           = hung_up_tty_read,
        .write          = hung_up_tty_write,
@@ -2336,7 +2336,7 @@ static int fionbio(struct file *file, int __user *p)
 
 static int tiocsctty(struct tty_struct *tty, int arg)
 {
-       task_t *p;
+       struct task_struct *p;
 
        if (current->signal->leader &&
            (current->signal->session == tty->session))
index 45e9bd8..a9247b5 100644 (file)
@@ -465,7 +465,7 @@ vcs_open(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static struct file_operations vcs_fops = {
+static const struct file_operations vcs_fops = {
        .llseek         = vcs_lseek,
        .read           = vcs_read,
        .write          = vcs_write,
index 7d42c8e..b72b204 100644 (file)
@@ -292,7 +292,7 @@ static int proc_viotape_open(struct inode *inode, struct file *file)
        return single_open(file, proc_viotape_show, NULL);
 }
 
-static struct file_operations proc_viotape_operations = {
+static const struct file_operations proc_viotape_operations = {
        .open           = proc_viotape_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
index 073da48..1b9b1f1 100644 (file)
@@ -605,7 +605,7 @@ static int gpio_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations gpio_fops = {
+static const struct file_operations gpio_fops = {
        .owner          = THIS_MODULE,
        .read           = gpio_read,
        .write          = gpio_write,
index 3ef823d..da7e66a 100644 (file)
@@ -886,6 +886,7 @@ void vc_disallocate(unsigned int currcons)
        if (vc_cons_allocated(currcons)) {
                struct vc_data *vc = vc_cons[currcons].d;
                vc->vc_sw->con_deinit(vc);
+               module_put(vc->vc_sw->owner);
                if (vc->vc_kmalloced)
                        kfree(vc->vc_screenbuf);
                if (currcons >= MIN_NR_CONSOLES)
index 7289f4a..c77fe3c 100644 (file)
@@ -231,7 +231,7 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code,
  *     Kernel Interfaces
  */
 
-static struct file_operations acq_fops = {
+static const struct file_operations acq_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = acq_write,
index 194a3fd..8069be4 100644 (file)
@@ -227,7 +227,7 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code,
  *     Kernel Interfaces
  */
 
-static struct file_operations advwdt_fops = {
+static const struct file_operations advwdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = advwdt_write,
index 8338ca3..c5c94e4 100644 (file)
@@ -362,7 +362,7 @@ static int __init ali_find_watchdog(void)
  *     Kernel Interfaces
  */
 
-static struct file_operations ali_fops = {
+static const struct file_operations ali_fops = {
        .owner =        THIS_MODULE,
        .llseek =       no_llseek,
        .write =        ali_write,
index c05ac18..ffd7684 100644 (file)
@@ -281,7 +281,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        }
 }
 
-static struct file_operations wdt_fops = {
+static const struct file_operations wdt_fops = {
        .owner=         THIS_MODULE,
        .llseek=        no_llseek,
        .write=         fop_write,
index f61dedc..cc26671 100644 (file)
@@ -183,7 +183,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l
 
 /* ......................................................................... */
 
-static struct file_operations at91wdt_fops = {
+static const struct file_operations at91wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .ioctl          = at91_wdt_ioctl,
index 537f5c6..e3cefc5 100644 (file)
@@ -145,7 +145,7 @@ static int booke_wdt_open (struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations booke_wdt_fops = {
+static const struct file_operations booke_wdt_fops = {
   .owner = THIS_MODULE,
   .llseek = no_llseek,
   .write = booke_wdt_write,
index 3e8410b..04c7e49 100644 (file)
@@ -198,7 +198,7 @@ static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t c
        return count;
 }
 
-static struct file_operations cpu5wdt_fops = {
+static const struct file_operations cpu5wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .ioctl          = cpu5wdt_ioctl,
index 9021dbb..77c8a95 100644 (file)
@@ -187,7 +187,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static struct file_operations ep93xx_wdt_fops = {
+static const struct file_operations ep93xx_wdt_fops = {
        .owner          = THIS_MODULE,
        .write          = ep93xx_wdt_write,
        .ioctl          = ep93xx_wdt_ioctl,
index ea670de..62dbccb 100644 (file)
@@ -356,7 +356,7 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
  */
 
 
-static struct file_operations eurwdt_fops = {
+static const struct file_operations eurwdt_fops = {
        .owner  = THIS_MODULE,
        .llseek = no_llseek,
        .write  = eurwdt_write,
index 93785f1..870539e 100644 (file)
@@ -337,7 +337,7 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void
  *      Kernel Interfaces
  */
 
-static struct file_operations esb_fops = {
+static const struct file_operations esb_fops = {
         .owner =        THIS_MODULE,
         .llseek =       no_llseek,
         .write =        esb_write,
index bfbdbbf..8385dd3 100644 (file)
@@ -378,7 +378,7 @@ static int i8xx_tco_notify_sys (struct notifier_block *this, unsigned long code,
  *     Kernel Interfaces
  */
 
-static struct file_operations i8xx_tco_fops = {
+static const struct file_operations i8xx_tco_fops = {
        .owner =        THIS_MODULE,
        .llseek =       no_llseek,
        .write =        i8xx_tco_write,
index a2e53c7..fd95f73 100644 (file)
@@ -255,7 +255,7 @@ ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
  *     Kernel Interfaces
  */
 
-static struct file_operations ibwdt_fops = {
+static const struct file_operations ibwdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = ibwdt_write,