lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 4 Dec 2009 15:29:04 +0800
From:	Luming Yu <luming.yu@...il.com>
To:	Ingo Molnar <mingo@...e.hu>
Cc:	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	Christoph Hellwig <hch@...radead.org>,
	LKML <linux-kernel@...r.kernel.org>, linux-ia64@...r.kernel.org,
	"Yu, Fenghua" <fenghua.yu@...el.com>,
	"Luck, Tony" <tony.luck@...el.com>,
	Felix Blyakher <felixb@....com>,
	Shaohua Li <shaohua.li@...el.com>, Bob Picco <bob.picco@...com>
Subject: Re: [RFC PATCH] Add TRACE_IRQFLAGS_SUPPORT, LOCKDEP_SUPPORT then 
	enable ftrace for ia64

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@...alhost ~]# dmesg | head -2
Linux version 2.6.31 (root@...alhost.localdomain) (gcc version 4.1.2
20071124 (Red Hat 4.1.2-42)) #1 SMP Thu Dec 3 16:35:07 PST 2009

[root@...alhost ~]# dmesg | grep Kprobe
Kprobe smoke test started
Kprobe smoke test passed successfully

[root@...alhost ~]# 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@...alhost ~]# 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@...com>
Signed-off-by: Yu Luming <luming.yu@...el.com>

 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@...hat.com>
+ */
+#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

Download attachment "ia64-lockdep-linux-2.6.31.patch" of type "application/octet-stream" (16419 bytes)

Powered by blists - more mailing lists