Sorry for later response, hope we can make it in -33-rc I just have time update the patch based on your comments and known issues not fixed in previous patch. >> -#define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */ >> +#define PERCPU_PAGE_SHIFT 20 /*16 log2() of max. size of per-CPU area */ > > Why was this seemingly unrelated change done in a lockdep patch? Tony has answered it. >> >> +config LOCKDEP_SUPPORT >> + bool >> + default y >> + >> +config STACKTRACE_SUPPORT >> + bool >> + default y > > The (shorter) form we generally use when architectures enable a > feature is: > > config LOCKDEP_SUPPORT > def_bool y Updated in new patch. > > config STACKTRACE_SUPPORT > def_bool y > > ( Separate cleanup patch: it might make sense to offer this in > generic code and just select a HAVE_LOCKDEP_SUPPORT flag. This > affects all lockdep architectures so should be handled > separately. ) Will update in an incremental patch once this patch is in. >> +config TRACE_IRQFLAGS_SUPPORT >> + bool >> + default y > > (same comment as above.) Updated in new patch. >> +void save_stack_trace(struct stack_trace *trace) >> +{ >> +} >> +EXPORT_SYMBOL(save_stack_trace); >> +void __ia64_save_stack_nonlocal(struct stack_trace *trace) > > (nit: missing newline) Updated in new patch > >> +{ >> +} >> +EXPORT_SYMBOL(__ia64_save_stack_nonlocal); > > also, these functions should be implemented, for lockdep reports to > be readable. Generally this is done by librarizing the dump_stack() > et al architecture code into stacktrace.c. Yes, Will update in an incremental patch once this patch is in. > >> diff -BruN linux-2.6.31-rc6/include/asm-ia64/irqflags.h >> linux-2.6.31-rc6-lockdep/include/asm-ia64/irqflags.h >> --- linux-2.6.31-rc6/include/asm-ia64/irqflags.h 1969-12-31 >> 16:00:00.000000000 -0800 >> +++ linux-2.6.31-rc6-lockdep/include/asm-ia64/irqflags.h 2009-08-23 >> 18:59:14.000000000 -0700 >> @@ -0,0 +1,92 @@ >> +#ifndef _ASM_IRQFLAGS_H >> +#define _ASM_IRQFLAGS_H >> +#include <asm/kregs.h> >> +#include <asm/pal.h> >> +/* >> + * The group barrier in front of the rsm & ssm are necessary to ensure >> + * that none of the previous instructions in the same group are >> + * affected by the rsm/ssm. >> + */ >> +/* For spinlocks etc */ >> + > > ( nit: looks a bit disorganized - could be merged into a single > comment block? ) Updated in new patch > >> +/* >> + * - clearing psr.i is implicitly serialized (visible by next insn) >> + * - setting psr.i requires data serialization >> + * - we need a stop-bit before reading PSR because we sometimes >> + * write a floating-point register right before reading the PSR >> + * and that writes to PSR.mfl >> + */ >> +#define __local_irq_save(x) \ >> +do { \ >> + ia64_stop(); \ >> + (x) = ia64_getreg(_IA64_REG_PSR); \ >> + ia64_stop(); \ >> + ia64_rsm(IA64_PSR_I); \ >> +} while (0) > > please use C inline functions for all of irqflags.h (x86 does that > too). Macros have all sorts of disadvantages: they are harder to > read and also double evaluation side-effects are harder to keep > under control. Good point. There are a lot of such kind of Macros in IA64 architecture waiting thoroughly clean up. May I update this part later? >> + >> +# define raw_local_irq_disable() do { unsigned long x; >> raw_local_irq_save(x); } while (0) > > ( the patch seems line-wrapped, see Documentation/email-clients.txt > about how to send plain-text patches. ) I'm sorry for this. Please apply attached patch. I use web gmail since it is the most convenient way to me. >> -#define MAX_LOCKDEP_KEYS_BITS 13 >> +#define MAX_LOCKDEP_KEYS_BITS 10 > > Why did you have to do this bit? Without dynamic allocation both in Lockdep code and ia64 architecture in place, 13 bits requires far moe size than ia64 can support in Per CPU area (1M) Tony, is it correct? >> >> config DEBUG_LOCKDEP >> bool "Lock dependency engine debugging" >> - depends on DEBUG_KERNEL && LOCKDEP >> + depends on DEBUG_KERNEL && LOCKDEP && !IA64 >> help > > That should be fixed (and this chunk will then not be needed) before > this is merged. Updated in new patch > > Also, a few general comments: > > - There's no lockdep_sys_exit support implemented. (This callback > is needed to detect lock counts leaking to user-space. Just call > it in the return-from-syscall codepath(s).) Updated in new patch. But Temporarily commented out in call site. I tested it, but there is lock held before leaving kernel... Will root cause, and fix the problem later. > > - There's no changes to exception code assembly AFAICS - such as > debug traps, special exceptions, etc. You should review all > places in the IA64 code where there's open-coded or > hardware-implicit enable-irqs or disable-irqs instructions, not > just the main local_irq_*() functions. A starting point would be: > > git grep IA64_PSR_I arch/ia64/ | grep .S: > > but there may be instructions and trap entries where there's > implicit irq-flags behavior - those need to be examined too. Updated some in assembly code that modify PSR.I bit. But not all, because not all modifications of PSR.i bit would be interesting to lockdep code.. > > - Do kprobes work with this patch? Tested, yes. > > - No NMI support AFAICS - all NMI codepaths should be exempted from > irqflags coverage. Good point, I need to find out place to insert nmi_enter and nmi_exit., and do some testing. Not done yet. Will update in an incremental patch after the patch is accepted. > > Thanks, > > Ingo Thanks for review. > The following is some results with the new patch. [root@localhost ~]# dmesg | head -2 Linux version 2.6.31 (root@xxxxxxxxxxxxxxxxxxxxx) (gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)) #1 SMP Thu Dec 3 16:35:07 PST 2009 [root@localhost ~]# dmesg | grep Kprobe Kprobe smoke test started Kprobe smoke test passed successfully [root@localhost ~]# dmesg ..... Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar ... MAX_LOCKDEP_SUBCLASSES: 8 ... MAX_LOCK_DEPTH: 48 ... MAX_LOCKDEP_KEYS: 1023 ... CLASSHASH_SIZE: 512 ... MAX_LOCKDEP_ENTRIES: 16384 ... MAX_LOCKDEP_CHAINS: 32768 ... CHAINHASH_SIZE: 16384 memory used by lock dependency info: 2679 kB per task-struct memory footprint: 2688 bytes ------------------------ | Locking API testsuite: ---------------------------------------------------------------------------- | spin |wlock |rlock |mutex | wsem | rsem | -------------------------------------------------------------------------- A-A deadlock: ok | ok | ok | ok | ok | ok | A-B-B-A deadlock: ok | ok | ok | ok | ok | ok | A-B-B-C-C-A deadlock: ok | ok | ok | ok | ok | ok | A-B-C-A-B-C deadlock: ok | ok | ok | ok | ok | ok | A-B-B-C-C-D-D-A deadlock: ok | ok | ok | ok | ok | ok | A-B-C-D-B-D-D-A deadlock: ok | ok | ok | ok | ok | ok | A-B-C-D-B-C-D-A deadlock: ok | ok | ok | ok | ok | ok | double unlock: ok | ok | ok | ok | ok | ok | initialize held: ok | ok | ok | ok | ok | ok | bad unlock order: ok | ok | ok | ok | ok | ok | -------------------------------------------------------------------------- recursive read-lock: | ok | | ok | recursive read-lock #2: | ok | | ok | mixed read-write-lock: | ok | | ok | mixed write-read-lock: | ok | | ok | -------------------------------------------------------------------------- hard-irqs-on + irq-safe-A/12: ok | ok | ok | soft-irqs-on + irq-safe-A/12: ok | ok | ok | hard-irqs-on + irq-safe-A/21: ok | ok | ok | soft-irqs-on + irq-safe-A/21: ok | ok | ok | sirq-safe-A => hirqs-on/12: ok | ok | ok | sirq-safe-A => hirqs-on/21: ok | ok | ok | hard-safe-A + irqs-on/12: ok | ok | ok | soft-safe-A + irqs-on/12: ok | ok | ok | hard-safe-A + irqs-on/21: ok | ok | ok | soft-safe-A + irqs-on/21: ok | ok | ok | hard-safe-A + unsafe-B #1/123: ok | ok | ok | soft-safe-A + unsafe-B #1/123: ok | ok | ok | hard-safe-A + unsafe-B #1/132: ok | ok | ok | soft-safe-A + unsafe-B #1/132: ok | ok | ok | hard-safe-A + unsafe-B #1/213: ok | ok | ok | soft-safe-A + unsafe-B #1/213: ok | ok | ok | hard-safe-A + unsafe-B #1/231: ok | ok | ok | soft-safe-A + unsafe-B #1/231: ok | ok | ok | hard-safe-A + unsafe-B #1/312: ok | ok | ok | soft-safe-A + unsafe-B #1/312: ok | ok | ok | hard-safe-A + unsafe-B #1/321: ok | ok | ok | soft-safe-A + unsafe-B #1/321: ok | ok | ok | hard-safe-A + unsafe-B #2/123: ok | ok | ok | soft-safe-A + unsafe-B #2/123: ok | ok | ok | hard-safe-A + unsafe-B #2/132: ok | ok | ok | soft-safe-A + unsafe-B #2/132: ok | ok | ok | hard-safe-A + unsafe-B #2/213: ok | ok | ok | soft-safe-A + unsafe-B #2/213: ok | ok | ok | hard-safe-A + unsafe-B #2/231: ok | ok | ok | soft-safe-A + unsafe-B #2/231: ok | ok | ok | hard-safe-A + unsafe-B #2/312: ok | ok | ok | soft-safe-A + unsafe-B #2/312: ok | ok | ok | hard-safe-A + unsafe-B #2/321: ok | ok | ok | soft-safe-A + unsafe-B #2/321: ok | ok | ok | hard-irq lock-inversion/123: ok | ok | ok | soft-irq lock-inversion/123: ok | ok | ok | hard-irq lock-inversion/132: ok | ok | ok | soft-irq lock-inversion/132: ok | ok | ok | hard-irq lock-inversion/213: ok | ok | ok | soft-irq lock-inversion/213: ok | ok | ok | hard-irq lock-inversion/231: ok | ok | ok | soft-irq lock-inversion/231: ok | ok | ok | hard-irq lock-inversion/312: ok | ok | ok | soft-irq lock-inversion/312: ok | ok | ok | hard-irq lock-inversion/321: ok | ok | ok | soft-irq lock-inversion/321: ok | ok | ok | hard-irq read-recursion/123: ok | soft-irq read-recursion/123: ok | hard-irq read-recursion/132: ok | soft-irq read-recursion/132: ok | hard-irq read-recursion/213: ok | soft-irq read-recursion/213: ok | hard-irq read-recursion/231: ok | soft-irq read-recursion/231: ok | hard-irq read-recursion/312: ok | soft-irq read-recursion/312: ok | hard-irq read-recursion/321: ok | soft-irq read-recursion/321: ok | ------------------------------------------------------- Good, all 218 testcases passed! | [root@localhost ~]# cat /proc/lockdep_stats lock-classes: 546 [max: 1023] direct dependencies: 572 [max: 16384] indirect dependencies: 455 all direct dependencies: 2132 dependency chains: 1194 [max: 32768] dependency chain hlocks: 1928 [max: 163840] in-hardirq chains: 7 in-softirq chains: 3 in-process chains: 317 stack-trace entries: 0 [max: 262144] combined max dependencies: 10176 hardirq-safe locks: 8 hardirq-unsafe locks: 65 softirq-safe locks: 10 softirq-unsafe locks: 64 irq-safe locks: 16 irq-unsafe locks: 65 hardirq-read-safe locks: 0 hardirq-read-unsafe locks: 5 softirq-read-safe locks: 0 softirq-read-unsafe locks: 5 irq-read-safe locks: 0 irq-read-unsafe locks: 5 uncategorized locks: 41 unused locks: 0 max locking depth: 5 max recursion depth: 4 debug_locks: 0 Known issues: 0. dynamic allocate per CPU area in lockdep. 1. lock held in leave kernel. 2. enabling CONFIG_DEBUG_LOCKDEP triggers the lockdep warning. WARNING: at kernel/lockdep.c:2901 check_flags+0x1c0/0x480() Modules linked in: Call Trace: [<a000000100017310>] show_stack+0x70/0xc0 sp=a000000100be7c40 bsp=a000000100be1e00 [<a0000001000173b0>] dump_stack+0x50/0x80 sp=a000000100be7e10 bsp=a000000100be1dd8 [<a000000100095750>] warn_slowpath_common+0xf0/0x140 sp=a000000100be7e10 bsp=a000000100be1d98 [<a000000100095800>] warn_slowpath_null+0x60/0x80 sp=a000000100be7e10 bsp=a000000100be1d68 [<a0000001000ecf00>] check_flags+0x1c0/0x480 sp=a000000100be7e10 bsp=a000000100be1d40 [<a0000001000f34a0>] lockdep_trace_alloc+0x60/0x160 sp=a000000100be7e10 bsp=a000000100be1d10 [<a0000001001ec2d0>] kmem_cache_alloc_node+0x70/0x440 sp=a000000100be7e10 bsp=a000000100be1cb8 [<a0000001001ec740>] __kmalloc_node+0xa0/0x1a0 sp=a000000100be7e10 bsp=a000000100be1c68 [<a0000001001ee7e0>] alloc_arraycache+0x60/0xe0 sp=a000000100be7e20 bsp=a000000100be1c28 [<a0000001001f02c0>] alloc_alien_cache+0x160/0x280 sp=a000000100be7e20 bsp=a000000100be1bd0 [<a0000001001f0960>] do_tune_cpucache+0x580/0xba0 sp=a000000100be7e20 bsp=a000000100be1b58 [<a0000001001f1470>] enable_cpucache+0x130/0x200 sp=a000000100be7e20 bsp=a000000100be1b20 [<a000000100b06c20>] kmem_cache_init_late+0x60/0x3e0 sp=a000000100be7e20 bsp=a000000100be1ae0 [<a000000100ae12b0>] start_kernel+0x550/0x940 sp=a000000100be7e20 bsp=a000000100be1a60 [<a000000100841a60>] _start+0x760/0x780 sp=a000000100be7e30 bsp=a000000100be19c0 ---[ end trace 4eaa2a86a8e2da22 ]--- possible reason: unannotated irqs-on. Please review patch update. If make sense, please apply. Ps. The patch is enclosed in attachment. The inline one is c&p of it for reading. Thanks, Luming Signed-off-by: Bob Picco <bob.picco@xxxxxx> Signed-off-by: Yu Luming <luming.yu@xxxxxxxxx> arch/ia64/Kconfig | 6 ++ arch/ia64/Kconfig.debug | 3 + arch/ia64/include/asm/irqflags.h | 101 +++++++++++++++++++++++++++++++++++++ arch/ia64/include/asm/page.h | 2 arch/ia64/include/asm/rwsem.h | 27 ++++++--- arch/ia64/include/asm/stacktrace.h | 7 ++ arch/ia64/include/asm/system.h | 84 ------------------------------ arch/ia64/kernel/Makefile | 1 arch/ia64/kernel/entry.S | 6 ++ arch/ia64/kernel/ivt.S | 29 ++++++++++ arch/ia64/kernel/process.c | 6 +- arch/ia64/kernel/setup.c | 4 + arch/ia64/kernel/smpboot.c | 2 arch/ia64/kernel/stacktrace.c | 24 ++++++++ arch/ia64/kernel/time.c | 4 - include/linux/lockdep.h | 2 diff -BruN linux-2.6.31/arch/ia64/include/asm/irqflags.h testing/arch/ia64/include/asm/irqflags.h --- linux-2.6.31/arch/ia64/include/asm/irqflags.h 1969-12-31 16:00:00.000000000 -0800 +++ testing/arch/ia64/include/asm/irqflags.h 2009-12-03 15:40:45.000000000 -0800 @@ -0,0 +1,101 @@ +#ifndef _ASM_IRQFLAGS_H +#define _ASM_IRQFLAGS_H +#include <asm/kregs.h> +#include <asm/pal.h> +/* + * The group barrier in front of the rsm & ssm are necessary to ensure + * that none of the previous instructions in the same group are + * affected by the rsm/ssm. + * + * For spinlocks etc + * - clearing psr.i is implicitly serialized (visible by next insn) + * - setting psr.i requires data serialization + * - we need a stop-bit before reading PSR because we sometimes + * write a floating-point register right before reading the PSR + * and that writes to PSR.mfl + */ +#define __local_irq_save(x) \ +do { \ + ia64_stop(); \ + (x) = ia64_getreg(_IA64_REG_PSR); \ + ia64_stop(); \ + ia64_rsm(IA64_PSR_I); \ +} while (0) + +#define __local_irq_disable() \ +do { \ + ia64_stop(); \ + ia64_rsm(IA64_PSR_I); \ +} while (0) + +#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) + +#ifdef CONFIG_IA64_DEBUG_IRQ + + extern unsigned long last_cli_ip; + +# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP) + +# define raw_local_irq_save(x) \ +do { \ + unsigned long psr; \ + \ + __local_irq_save(psr); \ + if (psr & IA64_PSR_I) \ + __save_ip(); \ + (x) = psr; \ +} while (0) + +# define raw_local_irq_disable() do { unsigned long x; raw_local_irq_save(x); } while (0) + +# define raw_local_irq_restore(x) \ +do { \ + unsigned long old_psr, psr = (x); \ + \ + local_save_flags(old_psr); \ + __local_irq_restore(psr); \ + if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) \ + __save_ip(); \ +} while (0) + +#else /* !CONFIG_IA64_DEBUG_IRQ */ +# define raw_local_irq_save(x) __local_irq_save(x) +# define raw_local_irq_disable() __local_irq_disable() +# define raw_local_irq_restore(x) __local_irq_restore(x) +#endif /* !CONFIG_IA64_DEBUG_IRQ */ + +#define raw_local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) +#define raw_local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); }) + +#define raw_irqs_disabled() \ +({ \ + unsigned long __ia64_id_flags; \ + raw_local_save_flags(__ia64_id_flags); \ + (__ia64_id_flags & IA64_PSR_I) == 0; \ +}) + +#define raw_safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */ +#define raw_irqs_disabled_flags(flags) \ +({ \ + (int)((flags) & IA64_PSR_I) == 0; \ +}) + +#ifdef CONFIG_TRACE_IRQFLAGS +#define TRACE_IRQS_ON br.call.sptk.many b0=trace_hardirqs_on +#define TRACE_IRQS_OFF br.call.sptk.many b0=trace_hardirqs_off +#else +#define TRACE_IRQS_ON +#define TRACE_IRQS_OFF +#endif + +#define ARCH_LOCKDEP_SYS_EXIT br.call.sptk.many rp=lockdep_sys_exit + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +#define LOCKDEP_SYS_EXIT ARCH_LOCKDEP_SYS_EXIT +#else +#define LOCKDEP_SYS_EXIT +#endif + +#endif + + diff -BruN linux-2.6.31/arch/ia64/include/asm/page.h testing/arch/ia64/include/asm/page.h --- linux-2.6.31/arch/ia64/include/asm/page.h 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/include/asm/page.h 2009-12-03 12:01:50.000000000 -0800 @@ -41,7 +41,7 @@ #define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE - 1)) -#define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */ +#define PERCPU_PAGE_SHIFT 20 /*20 log2() of max. size of per-CPU area */ #define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT) diff -BruN linux-2.6.31/arch/ia64/include/asm/rwsem.h testing/arch/ia64/include/asm/rwsem.h --- linux-2.6.31/arch/ia64/include/asm/rwsem.h 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/include/asm/rwsem.h 2009-12-03 11:39:27.000000000 -0800 @@ -37,6 +37,9 @@ signed long count; spinlock_t wait_lock; struct list_head wait_list; +#ifdef CONFIG_DEBUG_LOCK_ALLOC + struct lockdep_map dep_map; +#endif }; #define RWSEM_UNLOCKED_VALUE __IA64_UL_CONST(0x0000000000000000) @@ -46,9 +49,15 @@ #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } +#else +# define __RWSEM_DEP_MAP_INIT(lockname) +#endif + #define __RWSEM_INITIALIZER(name) \ { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \ - LIST_HEAD_INIT((name).wait_list) } + LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name)} #define DECLARE_RWSEM(name) \ struct rw_semaphore name = __RWSEM_INITIALIZER(name) @@ -58,13 +67,15 @@ extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem); extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem); -static inline void -init_rwsem (struct rw_semaphore *sem) -{ - sem->count = RWSEM_UNLOCKED_VALUE; - spin_lock_init(&sem->wait_lock); - INIT_LIST_HEAD(&sem->wait_list); -} +extern void __init_rwsem(struct rw_semaphore *sem, const char *name, + struct lock_class_key *key); + +#define init_rwsem(sem) \ +do { \ + static struct lock_class_key __key; \ + \ + __init_rwsem((sem), #sem, &__key); \ +} while (0) /* * lock for reading diff -BruN linux-2.6.31/arch/ia64/include/asm/stacktrace.h testing/arch/ia64/include/asm/stacktrace.h --- linux-2.6.31/arch/ia64/include/asm/stacktrace.h 1969-12-31 16:00:00.000000000 -0800 +++ testing/arch/ia64/include/asm/stacktrace.h 2009-12-03 12:32:58.000000000 -0800 @@ -0,0 +1,7 @@ +#ifndef _ASM_STACKTRACE_H +#define _ASM_STACKTRACE_H 1 + +/* Generic stack tracer with callbacks */ + + +#endif diff -BruN linux-2.6.31/arch/ia64/include/asm/system.h testing/arch/ia64/include/asm/system.h --- linux-2.6.31/arch/ia64/include/asm/system.h 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/include/asm/system.h 2009-12-02 21:56:56.000000000 -0800 @@ -107,88 +107,6 @@ */ #define set_mb(var, value) do { (var) = (value); mb(); } while (0) -#define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */ - -/* - * The group barrier in front of the rsm & ssm are necessary to ensure - * that none of the previous instructions in the same group are - * affected by the rsm/ssm. - */ -/* For spinlocks etc */ - -/* - * - clearing psr.i is implicitly serialized (visible by next insn) - * - setting psr.i requires data serialization - * - we need a stop-bit before reading PSR because we sometimes - * write a floating-point register right before reading the PSR - * and that writes to PSR.mfl - */ -#ifdef CONFIG_PARAVIRT -#define __local_save_flags() ia64_get_psr_i() -#else -#define __local_save_flags() ia64_getreg(_IA64_REG_PSR) -#endif - -#define __local_irq_save(x) \ -do { \ - ia64_stop(); \ - (x) = __local_save_flags(); \ - ia64_stop(); \ - ia64_rsm(IA64_PSR_I); \ -} while (0) - -#define __local_irq_disable() \ -do { \ - ia64_stop(); \ - ia64_rsm(IA64_PSR_I); \ -} while (0) - -#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) - -#ifdef CONFIG_IA64_DEBUG_IRQ - - extern unsigned long last_cli_ip; - -# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP) - -# define local_irq_save(x) \ -do { \ - unsigned long __psr; \ - \ - __local_irq_save(__psr); \ - if (__psr & IA64_PSR_I) \ - __save_ip(); \ - (x) = __psr; \ -} while (0) - -# define local_irq_disable() do { unsigned long __x; local_irq_save(__x); } while (0) - -# define local_irq_restore(x) \ -do { \ - unsigned long __old_psr, __psr = (x); \ - \ - local_save_flags(__old_psr); \ - __local_irq_restore(__psr); \ - if ((__old_psr & IA64_PSR_I) && !(__psr & IA64_PSR_I)) \ - __save_ip(); \ -} while (0) - -#else /* !CONFIG_IA64_DEBUG_IRQ */ -# define local_irq_save(x) __local_irq_save(x) -# define local_irq_disable() __local_irq_disable() -# define local_irq_restore(x) __local_irq_restore(x) -#endif /* !CONFIG_IA64_DEBUG_IRQ */ - -#define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) -#define local_save_flags(flags) ({ ia64_stop(); (flags) = __local_save_flags(); }) - -#define irqs_disabled() \ -({ \ - unsigned long __ia64_id_flags; \ - local_save_flags(__ia64_id_flags); \ - (__ia64_id_flags & IA64_PSR_I) == 0; \ -}) - #ifdef __KERNEL__ #ifdef CONFIG_IA32_SUPPORT @@ -274,7 +192,7 @@ #define __ARCH_WANT_UNLOCKED_CTXSW #define ARCH_HAS_PREFETCH_SWITCH_STACK #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) - +#include <linux/irqflags.h> void cpu_idle_wait(void); #define arch_align_stack(x) (x) diff -BruN linux-2.6.31/arch/ia64/Kconfig testing/arch/ia64/Kconfig --- linux-2.6.31/arch/ia64/Kconfig 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/Kconfig 2009-12-03 11:43:38.000000000 -0800 @@ -143,6 +143,12 @@ endif +config LOCKDEP_SUPPORT + def_bool y + +config STACKTRACE_SUPPORT + def_bool y + choice prompt "System type" default IA64_GENERIC diff -BruN linux-2.6.31/arch/ia64/Kconfig.debug testing/arch/ia64/Kconfig.debug --- linux-2.6.31/arch/ia64/Kconfig.debug 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/Kconfig.debug 2009-12-03 11:44:16.000000000 -0800 @@ -2,6 +2,9 @@ source "lib/Kconfig.debug" +config TRACE_IRQFLAGS_SUPPORT + def_bool y + choice prompt "Physical memory granularity" default IA64_GRANULE_64MB diff -BruN linux-2.6.31/arch/ia64/kernel/entry.S testing/arch/ia64/kernel/entry.S --- linux-2.6.31/arch/ia64/kernel/entry.S 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/entry.S 2009-12-03 12:55:53.000000000 -0800 @@ -48,6 +48,7 @@ #include <asm/thread_info.h> #include <asm/unistd.h> #include <asm/ftrace.h> +#include <asm/irqflags.h> #include "minstate.h" @@ -897,6 +899,11 @@ cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) #else RSM_PSR_I(pUStk, r17, r31) +#if 0 //Todo: fix lock held when returning to user space + ;; + LOCKDEP_SYS_EXIT + ;; +#endif cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel (pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk #endif diff -BruN linux-2.6.31/arch/ia64/kernel/ivt.S testing/arch/ia64/kernel/ivt.S --- linux-2.6.31/arch/ia64/kernel/ivt.S 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/ivt.S 2009-12-03 11:50:40.000000000 -0800 @@ -855,6 +855,11 @@ mov rp=r3 // I0 set the real return addr (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT +#ifdef TRACE_IRQFLAGS_SUPPORT + ;; +(p15) br.call.sptk.many rp=trace_hardirqs_on + ;; +#endif SSM_PSR_I(p15, p15, r16) // M2 restore psr.i (p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic @@ -1555,6 +1560,11 @@ MOV_FROM_ISR(out1) SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3) adds r3=8,r2 // set up second base pointer +#ifdef TRACE_IRQFLAGS_SUPPORT + ;; +(p15) br.call.sptk.many rp=trace_hardirqs_on + ;; +#endif SSM_PSR_I(p15, p15, r14) // restore psr.i movl r14=ia64_leave_kernel ;; @@ -1582,6 +1592,11 @@ SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24) // guarantee that interruption collection is on +#ifdef TRACE_IRQFLAGS_SUPPORT + ;; +(p15) br.call.sptk.many rp=trace_hardirqs_on + ;; +#endif SSM_PSR_I(p15, p15, r15) // restore psr.i movl r15=ia64_leave_kernel ;; @@ -1630,6 +1645,11 @@ SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) // guarantee that interruption collection is on +#ifdef TRACE_IRQFLAGS_SUPPORT + ;; +(p15) br.call.sptk.many rp=trace_hardirqs_on + ;; +#endif SSM_PSR_I(p15, p15, r3) // restore psr.i adds r3=8,r2 // set up second base pointer ;; @@ -1665,6 +1685,11 @@ // guarantee that interruption collection is on mov out0=r15 ;; +#ifdef TRACE_IRQFLAGS_SUPPORT + ;; +(p15) br.call.sptk.many rp=trace_hardirqs_on + ;; +#endif SSM_PSR_I(p15, p15, r3) // restore psr.i adds r3=8,r2 // set up second base pointer for SAVE_REST ;; @@ -1733,7 +1758,11 @@ MOV_FROM_ISR(r14) SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24) // guarantee that interruption collection is on +#ifdef TRACE_IRQFLAGS_SUPPORT ;; +(p15) br.call.sptk.many rp=trace_hardirqs_on + ;; +#endif SSM_PSR_I(p15, p15, r3) adds r3=8,r2 // Base pointer for SAVE_REST ;; diff -BruN linux-2.6.31/arch/ia64/kernel/Makefile testing/arch/ia64/kernel/Makefile --- linux-2.6.31/arch/ia64/kernel/Makefile 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/Makefile 2009-12-02 21:56:56.000000000 -0800 @@ -40,6 +40,7 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o mca_recovery-y += mca_drv.o mca_drv_asm.o obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o \ paravirt_patch.o diff -BruN linux-2.6.31/arch/ia64/kernel/process.c testing/arch/ia64/kernel/process.c --- linux-2.6.31/arch/ia64/kernel/process.c 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/process.c 2009-12-03 11:51:28.000000000 -0800 @@ -225,14 +225,14 @@ void default_idle (void) { - local_irq_enable(); + raw_local_irq_enable(); while (!need_resched()) { if (can_do_pal_halt) { - local_irq_disable(); + raw_local_irq_disable(); if (!need_resched()) { safe_halt(); } - local_irq_enable(); + raw_local_irq_enable(); } else cpu_relax(); } diff -BruN linux-2.6.31/arch/ia64/kernel/setup.c testing/arch/ia64/kernel/setup.c --- linux-2.6.31/arch/ia64/kernel/setup.c 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/setup.c 2009-12-03 23:14:56.000000000 -0800 @@ -1021,7 +1021,11 @@ BUG_ON(current->mm); ia64_mmu_init(ia64_imva(cpu_data)); + + /* Temporarily suppress lockdep WARN_ON irqs disabled*/ + lockdep_off(); ia64_mca_cpu_init(ia64_imva(cpu_data)); + lockdep_on(); #ifdef CONFIG_IA32_SUPPORT ia32_cpu_init(); diff -BruN linux-2.6.31/arch/ia64/kernel/smpboot.c testing/arch/ia64/kernel/smpboot.c --- linux-2.6.31/arch/ia64/kernel/smpboot.c 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/smpboot.c 2009-12-02 21:56:56.000000000 -0800 @@ -504,7 +504,7 @@ struct create_idle c_idle = { .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, - .done = COMPLETION_INITIALIZER(c_idle.done), + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), }; c_idle.idle = get_idle_for_cpu(cpu); diff -BruN linux-2.6.31/arch/ia64/kernel/stacktrace.c testing/arch/ia64/kernel/stacktrace.c --- linux-2.6.31/arch/ia64/kernel/stacktrace.c 1969-12-31 16:00:00.000000000 -0800 +++ testing/arch/ia64/kernel/stacktrace.c 2009-12-03 12:33:55.000000000 -0800 @@ -0,0 +1,24 @@ +/* + * arch/x86_64/kernel/stacktrace.c + * + * Stack trace management functions + * + * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@xxxxxxxxxx> + */ +#include <linux/sched.h> +#include <linux/stacktrace.h> +#include <linux/module.h> +#include <asm/stacktrace.h> + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + */ +void save_stack_trace(struct stack_trace *trace) +{ +} +EXPORT_SYMBOL(save_stack_trace); + +void __ia64_save_stack_nonlocal(struct stack_trace *trace) +{ +} +EXPORT_SYMBOL(__ia64_save_stack_nonlocal); diff -BruN linux-2.6.31/arch/ia64/kernel/time.c testing/arch/ia64/kernel/time.c --- linux-2.6.31/arch/ia64/kernel/time.c 2009-09-09 15:13:59.000000000 -0700 +++ testing/arch/ia64/kernel/time.c 2009-12-03 11:52:41.000000000 -0800 @@ -210,8 +210,8 @@ /* * Allow IPIs to interrupt the timer loop. */ - local_irq_enable(); - local_irq_disable(); + raw_local_irq_enable(); + raw_local_irq_disable(); } skip_process_time_accounting: diff -BruN linux-2.6.31/include/linux/lockdep.h testing/include/linux/lockdep.h --- linux-2.6.31/include/linux/lockdep.h 2009-09-09 15:13:59.000000000 -0700 +++ testing/include/linux/lockdep.h 2009-12-02 21:57:38.000000000 -0800 @@ -162,7 +162,7 @@ u64 chain_key; }; -#define MAX_LOCKDEP_KEYS_BITS 13 +#define MAX_LOCKDEP_KEYS_BITS 10 /* * Subtract one because we offset hlock->class_idx by 1 in order * to make 0 mean no class. This avoids overflowing the class_idx
Attachment:
ia64-lockdep-linux-2.6.31.patch
Description: Binary data
![]() |