* powerpc stacktrace and lockdep support
@ 2007-01-08 13:54 Christoph Hellwig
2007-06-26 22:47 ` Johannes Berg
0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2007-01-08 13:54 UTC (permalink / raw)
To: linuxppc-dev
I recently tried to work on lockdep for powerpc. I have preliminary
version of the stacktrace code, but had to give up on trace irqflags
support because I'm not that knowledgeable on lowlevel ppc details.
Maybe someone more faimilar with the code wants to give it another try?
My stacktrace code is below:
Index: linux-2.6/arch/powerpc/Kconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/Kconfig 2006-12-25 13:47:19.000000000 +0100
+++ linux-2.6/arch/powerpc/Kconfig 2006-12-25 13:47:53.000000000 +0100
@@ -34,6 +34,10 @@
bool
default y
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
Index: linux-2.6/arch/powerpc/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/Makefile 2006-12-25 13:47:19.000000000 +0100
+++ linux-2.6/arch/powerpc/kernel/Makefile 2006-12-25 13:47:53.000000000 +0100
@@ -58,6 +58,7 @@
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
Index: linux-2.6/arch/powerpc/kernel/stacktrace.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/arch/powerpc/kernel/stacktrace.c 2006-12-25 13:51:06.000000000 +0100
@@ -0,0 +1,52 @@
+
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+
+#ifdef CONFIG_PPC64
+#define MIN_STACK_FRAME 112 /* same as STACK_FRAME_OVERHEAD, in fact */
+#define FRAME_LR_SAVE 2
+#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
+#define REGS_MARKER 0x7265677368657265ul
+#define FRAME_MARKER 12
+#else
+#define MIN_STACK_FRAME 16
+#define FRAME_LR_SAVE 1
+#define INT_FRAME_SIZE (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD)
+#define REGS_MARKER 0x72656773ul
+#define FRAME_MARKER 2
+#endif
+
+
+/*
+ * 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)
+{
+ unsigned long sp;
+
+ asm("mr %0,1" : "=r" (sp));
+
+ for (;;) {
+ unsigned long *stack = (unsigned long *) sp;
+ unsigned long newsp, ip;
+
+ if (!validate_sp(sp, current, MIN_STACK_FRAME))
+ return;
+
+ newsp = stack[0];
+ ip = stack[FRAME_LR_SAVE];
+
+ if (!trace->skip)
+ trace->entries[trace->nr_entries++] = ip;
+ else
+ trace->skip--;
+
+ if (trace->nr_entries >= trace->max_entries)
+ return;
+
+ sp = newsp;
+ }
+}
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-01-08 13:54 powerpc stacktrace and lockdep support Christoph Hellwig
@ 2007-06-26 22:47 ` Johannes Berg
2007-06-27 19:00 ` Johannes Berg
0 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2007-06-26 22:47 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev
On Mon, 2007-01-08 at 14:54 +0100, Christoph Hellwig wrote:
> I recently tried to work on lockdep for powerpc. I have preliminary
> version of the stacktrace code
That seems to work.
> , but had to give up on trace irqflags
> support because I'm not that knowledgeable on lowlevel ppc details.
I gave it a try. Actually what I had wanted to do was add lockdep
support for things like
function A:
lock()
flush_scheduled_work()
unlock()
function B: (work function that is scheduled)
...
lock()
...
unlock()
...
which can obviously deadlock but isn't caught by any debugging
mechanisms right now.
So anyway, lockdep doesn't work here since I only own powerpc machines,
hence I tried to make it work. Below is the patch, it's quite ugly and
only works on 64-bit right now, it'll probably totally screw up on
32-bit (though hopefully it only makes lockdep complain and stop itself
on 32-bit).
I currently get a lockdep report in XFS with this code. Not sure if
there's a bug in this code or if it actually complains rightfully, the
self-tests all pass...
---
arch/powerpc/Kconfig | 8 +++++
arch/powerpc/kernel/Makefile | 1
arch/powerpc/kernel/entry_64.S | 23 ++++++++++++++++
arch/powerpc/kernel/head_64.S | 55 ++++++++++++++++++++++++++++++++--------
arch/powerpc/kernel/irq.c | 2 -
arch/powerpc/kernel/irqtrace.S | 42 ++++++++++++++++++++++++++++++
arch/powerpc/kernel/ppc_ksyms.c | 2 -
arch/powerpc/kernel/setup_64.c | 6 ++++
include/asm-powerpc/hw_irq.h | 34 +++++++++++++-----------
include/asm-powerpc/irqflags.h | 11 ++++----
include/asm-powerpc/rwsem.h | 34 ++++++++++++++++++------
include/asm-powerpc/spinlock.h | 1
12 files changed, 177 insertions(+), 42 deletions(-)
--- linux-2.6-git.orig/arch/powerpc/Kconfig 2007-06-26 18:12:10.424850274 +0200
+++ linux-2.6-git/arch/powerpc/Kconfig 2007-06-26 20:01:50.544814034 +0200
@@ -38,6 +38,14 @@ config STACKTRACE_SUPPORT
bool
default y
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ default y
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
--- linux-2.6-git.orig/arch/powerpc/kernel/irq.c 2007-06-26 18:12:10.491850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/irq.c 2007-06-26 18:12:11.376850274 +0200
@@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsi
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}
-void local_irq_restore(unsigned long en)
+void raw_local_irq_restore(unsigned long en)
{
/*
* get_paca()->soft_enabled = en;
--- linux-2.6-git.orig/arch/powerpc/kernel/ppc_ksyms.c 2007-06-26 18:12:10.513850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/ppc_ksyms.c 2007-06-26 18:12:11.377850274 +0200
@@ -50,7 +50,7 @@
#endif
#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(local_irq_restore);
+EXPORT_SYMBOL(raw_local_irq_restore);
#endif
#ifdef CONFIG_PPC32
--- linux-2.6-git.orig/include/asm-powerpc/hw_irq.h 2007-06-26 18:12:10.618850274 +0200
+++ linux-2.6-git/include/asm-powerpc/hw_irq.h 2007-06-26 18:12:11.443850274 +0200
@@ -27,7 +27,7 @@ static inline unsigned long local_get_fl
return flags;
}
-static inline unsigned long local_irq_disable(void)
+static inline unsigned long raw_local_irq_disable(void)
{
unsigned long flags, zero;
@@ -39,14 +39,15 @@ static inline unsigned long local_irq_di
return flags;
}
-extern void local_irq_restore(unsigned long);
+extern void raw_local_irq_restore(unsigned long);
extern void iseries_handle_interrupts(void);
-#define local_irq_enable() local_irq_restore(1)
-#define local_save_flags(flags) ((flags) = local_get_flags())
-#define local_irq_save(flags) ((flags) = local_irq_disable())
+#define raw_local_irq_enable() raw_local_irq_restore(1)
+#define raw_local_save_flags(flags) ((flags) = local_get_flags())
+#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
-#define irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled_flags(flags) ((flags) == 0)
#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
@@ -62,13 +63,13 @@ extern void iseries_handle_interrupts(vo
#if defined(CONFIG_BOOKE)
#define SET_MSR_EE(x) mtmsr(x)
-#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
#else
#define SET_MSR_EE(x) mtmsr(x)
-#define local_irq_restore(flags) mtmsr(flags)
+#define raw_local_irq_restore(flags) mtmsr(flags)
#endif
-static inline void local_irq_disable(void)
+static inline void raw_local_irq_disable(void)
{
#ifdef CONFIG_BOOKE
__asm__ __volatile__("wrteei 0": : :"memory");
@@ -80,7 +81,7 @@ static inline void local_irq_disable(voi
#endif
}
-static inline void local_irq_enable(void)
+static inline void raw_local_irq_enable(void)
{
#ifdef CONFIG_BOOKE
__asm__ __volatile__("wrteei 1": : :"memory");
@@ -92,7 +93,7 @@ static inline void local_irq_enable(void
#endif
}
-static inline void local_irq_save_ptr(unsigned long *flags)
+static inline void raw_local_irq_save_ptr(unsigned long *flags)
{
unsigned long msr;
msr = mfmsr();
@@ -105,12 +106,13 @@ static inline void local_irq_save_ptr(un
__asm__ __volatile__("": : :"memory");
}
-#define local_save_flags(flags) ((flags) = mfmsr())
-#define local_irq_save(flags) local_irq_save_ptr(&flags)
-#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define raw_local_save_flags(flags) ((flags) = mfmsr())
+#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags)
+#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
-#define hard_irq_enable() local_irq_enable()
-#define hard_irq_disable() local_irq_disable()
+#define hard_irq_enable() raw_local_irq_enable()
+#define hard_irq_disable() raw_local_irq_disable()
#endif /* CONFIG_PPC64 */
--- linux-2.6-git.orig/include/asm-powerpc/irqflags.h 2007-06-26 18:12:10.669850274 +0200
+++ linux-2.6-git/include/asm-powerpc/irqflags.h 2007-06-27 00:35:50.806820710 +0200
@@ -10,19 +10,20 @@
#ifndef _ASM_IRQFLAGS_H
#define _ASM_IRQFLAGS_H
+#ifndef __ASSEMBLY__
/*
* Get definitions for raw_local_save_flags(x), etc.
*/
#include <asm-powerpc/hw_irq.h>
+#endif
/*
- * Do the CPU's IRQ-state tracing from assembly code. We call a
- * C function, so save all the C-clobbered registers:
+ * Do the CPU's IRQ-state tracing from assembly code. Also
+ * note the code in arch/powerpc/kernel/irqtrace.S.
*/
#ifdef CONFIG_TRACE_IRQFLAGS
-
-#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
-
+# define TRACE_IRQS_ON bl .powerpc_trace_irqs_on
+# define TRACE_IRQS_OFF bl .powerpc_trace_irqs_off
#else
# define TRACE_IRQS_ON
# define TRACE_IRQS_OFF
--- linux-2.6-git.orig/include/asm-powerpc/rwsem.h 2007-06-26 18:12:10.747850274 +0200
+++ linux-2.6-git/include/asm-powerpc/rwsem.h 2007-06-27 00:13:57.397341965 +0200
@@ -28,11 +28,21 @@ struct rw_semaphore {
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
spinlock_t wait_lock;
struct list_head wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
};
+#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)
@@ -42,12 +52,15 @@ extern struct rw_semaphore *rwsem_down_w
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
@@ -74,7 +87,7 @@ static inline int __down_read_trylock(st
/*
* lock for writing
*/
-static inline void __down_write(struct rw_semaphore *sem)
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
int tmp;
@@ -84,6 +97,11 @@ static inline void __down_write(struct r
rwsem_down_write_failed(sem);
}
+static inline void __down_write(struct rw_semaphore *sem)
+{
+ __down_write_nested(sem, 0);
+}
+
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
int tmp;
--- linux-2.6-git.orig/include/asm-powerpc/spinlock.h 2007-06-26 18:12:10.639850274 +0200
+++ linux-2.6-git/include/asm-powerpc/spinlock.h 2007-06-26 18:12:11.446850274 +0200
@@ -19,6 +19,7 @@
*
* (the type definitions are in asm/spinlock_types.h)
*/
+#include <linux/irqflags.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/hvcall.h>
--- linux-2.6-git.orig/arch/powerpc/kernel/head_64.S 2007-06-26 18:12:10.537850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/head_64.S 2007-06-27 00:34:57.402820710 +0200
@@ -34,6 +34,7 @@
#include <asm/iseries/lpar_map.h>
#include <asm/thread_info.h>
#include <asm/firmware.h>
+#include <asm/irqflags.h>
#define DO_SOFT_DISABLE
@@ -394,6 +395,12 @@ label##_iSeries: \
EXCEPTION_PROLOG_ISERIES_2; \
b label##_common; \
+#ifdef CONFIG_TRACE_IRQFLAGS
+#define TRACE_DISABLE_INTS bl .powerpc_trace_irqs_off
+#else
+#define TRACE_DISABLE_INTS
+#endif
+
#ifdef CONFIG_PPC_ISERIES
#define DISABLE_INTS \
li r11,0; \
@@ -405,14 +412,15 @@ BEGIN_FW_FTR_SECTION; \
mfmsr r10; \
ori r10,r10,MSR_EE; \
mtmsrd r10,1; \
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
+ TRACE_DISABLE_INTS
#else
#define DISABLE_INTS \
li r11,0; \
stb r11,PACASOFTIRQEN(r13); \
- stb r11,PACAHARDIRQEN(r13)
-
+ stb r11,PACAHARDIRQEN(r13); \
+ TRACE_DISABLE_INTS
#endif /* CONFIG_PPC_ISERIES */
#define ENABLE_INTS \
@@ -965,24 +973,38 @@ bad_stack:
*/
fast_exc_return_irq: /* restores irq state too */
ld r3,SOFTE(r1)
- ld r12,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 1f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+1:
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+ cmpdi r3,0
+ bne 2f
+ bl .trace_hardirqs_off
+ ld r3,SOFTE(r1)
+2:
+#else
+ stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+#endif
+ ld r12,_MSR(r1)
rldicl r4,r12,49,63 /* get MSR_EE to LSB */
stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
- b 1f
+ b 3f
.globl fast_exception_return
fast_exception_return:
ld r12,_MSR(r1)
-1: ld r11,_NIP(r1)
+3: ld r11,_NIP(r1)
andi. r3,r12,MSR_RI /* check if RI is set */
beq- unrecov_fer
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
andi. r3,r12,MSR_PR
- beq 2f
+ beq 4f
ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+4:
#endif
ld r3,_CCR(r1)
@@ -1387,11 +1409,24 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
/*
* hash_page couldn't handle it, set soft interrupt enable back
- * to what it was before the trap. Note that .local_irq_restore
+ * to what it was before the trap. Note that .raw_local_irq_restore
* handles any interrupts pending at this point.
*/
ld r3,SOFTE(r1)
- bl .local_irq_restore
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 14f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+14:
+ bl .raw_local_irq_restore
+ cmpdi r3,0
+ bne 15f
+ bl .trace_hardirqs_off
+15:
+#else
+ bl .raw_local_irq_restore
+#endif
b 11f
/* Here we have a page fault that hash_page can't handle. */
--- linux-2.6-git.orig/arch/powerpc/kernel/setup_64.c 2007-06-26 18:12:10.594850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/setup_64.c 2007-06-26 18:12:11.451850274 +0200
@@ -33,6 +33,7 @@
#include <linux/serial_8250.h>
#include <linux/bootmem.h>
#include <linux/pci.h>
+#include <linux/lockdep.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
@@ -359,6 +360,11 @@ void __init setup_system(void)
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
/*
+ * start lockdep
+ */
+ lockdep_init();
+
+ /*
* Unflatten the device-tree passed by prom_init or kexec
*/
unflatten_device_tree();
--- linux-2.6-git.orig/arch/powerpc/kernel/entry_64.S 2007-06-26 18:20:59.030850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/entry_64.S 2007-06-26 21:25:58.630569893 +0200
@@ -29,6 +29,7 @@
#include <asm/cputable.h>
#include <asm/firmware.h>
#include <asm/bug.h>
+#include <asm/irqflags.h>
/*
* System calls.
@@ -91,6 +92,13 @@ system_call_common:
li r10,1
stb r10,PACASOFTIRQEN(r13)
stb r10,PACAHARDIRQEN(r13)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .trace_hardirqs_on
+ REST_GPR(0,r1)
+ REST_4GPRS(3,r1)
+ REST_2GPRS(7,r1)
+ addi r9,r1,STACK_FRAME_OVERHEAD
+#endif
std r10,SOFTE(r1)
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
@@ -491,8 +499,20 @@ BEGIN_FW_FTR_SECTION
4:
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r5,0
+ beq 5f
+ bl .trace_hardirqs_on
+ ld r5,SOFTE(r1)
stb r5,PACASOFTIRQEN(r13)
-
+ b 6f
+5:
+ stb r5,PACASOFTIRQEN(r13)
+ bl .trace_hardirqs_off
+6:
+#else
+ stb r5,PACASOFTIRQEN(r13)
+#endif
/* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
@@ -560,6 +580,7 @@ do_work:
bne restore
/* here we are preempting the current task */
1:
+ TRACE_IRQS_ON
li r0,1
stb r0,PACASOFTIRQEN(r13)
stb r0,PACAHARDIRQEN(r13)
--- linux-2.6-git.orig/arch/powerpc/kernel/Makefile 2007-06-26 19:27:54.032776841 +0200
+++ linux-2.6-git/arch/powerpc/kernel/Makefile 2007-06-27 00:30:19.115820710 +0200
@@ -62,6 +62,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_TRACE_IRQFLAGS) += irqtrace.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-git/arch/powerpc/kernel/irqtrace.S 2007-06-27 00:32:07.125820710 +0200
@@ -0,0 +1,42 @@
+/*
+ * crappy helper for irq-trace
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#define STACKSPACE GPR0 + 16*8
+
+#ifdef __powerpc64__
+#define ST std
+#define L ld
+#else
+#define ST stw
+#define L lw
+#endif
+
+#define PRE \
+ subi r1,r1,STACKSPACE ; \
+ SAVE_GPR(0, r1) ; \
+ SAVE_8GPRS(2, r1) ; \
+ SAVE_4GPRS(10, r1) ; \
+ mfcr r0 ; \
+ ST r0, (14*8)(r1) ; \
+ mflr r0 ; \
+ ST r0, (15*8)(r1)
+
+#define POST \
+ REST_8GPRS(2, r1) ; \
+ REST_4GPRS(10, r1) ; \
+ L r0, (14*8)(r1) ; \
+ mtcr r0 ; \
+ L r0, (15*8)(r1) ; \
+ mtlr r0 ; \
+ REST_GPR(0, r1) ; \
+ addi r1,r1,STACKSPACE
+
+_GLOBAL(powerpc_trace_irqs_off)
+ PRE
+ bl .trace_hardirqs_off
+ POST
+ blr
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-06-26 22:47 ` Johannes Berg
@ 2007-06-27 19:00 ` Johannes Berg
2007-06-28 16:20 ` Johannes Berg
0 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2007-06-27 19:00 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev
Here's a somewhat cleaned-up version that also works with preempt, still
64-bit only, still breaks 32-bit compile (I think, untested).
Works fine on my quad G5 and I've actually made a patch to lockdep to
support flagging my workqueue deadlock, that works too. And the XFS
report I had previously was also "correct" in the sense that it occurs
on all machines and has been patched (although there never was a
possible deadlock.)
---
arch/powerpc/Kconfig | 8 +++++
arch/powerpc/kernel/Makefile | 1
arch/powerpc/kernel/entry_64.S | 24 +++++++++++++++++
arch/powerpc/kernel/head_64.S | 54 ++++++++++++++++++++++++++++++++--------
arch/powerpc/kernel/irq.c | 2 -
arch/powerpc/kernel/irqtrace.S | 47 ++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/ppc_ksyms.c | 2 -
arch/powerpc/kernel/setup_64.c | 6 ++++
include/asm-powerpc/hw_irq.h | 34 +++++++++++++------------
include/asm-powerpc/irqflags.h | 13 ---------
include/asm-powerpc/rwsem.h | 34 +++++++++++++++++++------
include/asm-powerpc/spinlock.h | 1
12 files changed, 176 insertions(+), 50 deletions(-)
--- linux-2.6-git.orig/arch/powerpc/Kconfig 2007-06-27 17:37:39.884965668 +0200
+++ linux-2.6-git/arch/powerpc/Kconfig 2007-06-27 17:38:07.929965668 +0200
@@ -38,6 +38,14 @@ config STACKTRACE_SUPPORT
bool
default y
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ default y
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
--- linux-2.6-git.orig/arch/powerpc/kernel/irq.c 2007-06-27 17:37:39.907965668 +0200
+++ linux-2.6-git/arch/powerpc/kernel/irq.c 2007-06-27 17:38:07.953965668 +0200
@@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsi
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}
-void local_irq_restore(unsigned long en)
+void raw_local_irq_restore(unsigned long en)
{
/*
* get_paca()->soft_enabled = en;
--- linux-2.6-git.orig/arch/powerpc/kernel/ppc_ksyms.c 2007-06-27 17:37:39.930965668 +0200
+++ linux-2.6-git/arch/powerpc/kernel/ppc_ksyms.c 2007-06-27 17:38:07.954965668 +0200
@@ -50,7 +50,7 @@
#endif
#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(local_irq_restore);
+EXPORT_SYMBOL(raw_local_irq_restore);
#endif
#ifdef CONFIG_PPC32
--- linux-2.6-git.orig/include/asm-powerpc/hw_irq.h 2007-06-27 17:37:40.209965668 +0200
+++ linux-2.6-git/include/asm-powerpc/hw_irq.h 2007-06-27 17:38:08.025965668 +0200
@@ -27,7 +27,7 @@ static inline unsigned long local_get_fl
return flags;
}
-static inline unsigned long local_irq_disable(void)
+static inline unsigned long raw_local_irq_disable(void)
{
unsigned long flags, zero;
@@ -39,14 +39,15 @@ static inline unsigned long local_irq_di
return flags;
}
-extern void local_irq_restore(unsigned long);
+extern void raw_local_irq_restore(unsigned long);
extern void iseries_handle_interrupts(void);
-#define local_irq_enable() local_irq_restore(1)
-#define local_save_flags(flags) ((flags) = local_get_flags())
-#define local_irq_save(flags) ((flags) = local_irq_disable())
+#define raw_local_irq_enable() raw_local_irq_restore(1)
+#define raw_local_save_flags(flags) ((flags) = local_get_flags())
+#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
-#define irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled_flags(flags) ((flags) == 0)
#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
@@ -62,13 +63,13 @@ extern void iseries_handle_interrupts(vo
#if defined(CONFIG_BOOKE)
#define SET_MSR_EE(x) mtmsr(x)
-#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
#else
#define SET_MSR_EE(x) mtmsr(x)
-#define local_irq_restore(flags) mtmsr(flags)
+#define raw_local_irq_restore(flags) mtmsr(flags)
#endif
-static inline void local_irq_disable(void)
+static inline void raw_local_irq_disable(void)
{
#ifdef CONFIG_BOOKE
__asm__ __volatile__("wrteei 0": : :"memory");
@@ -80,7 +81,7 @@ static inline void local_irq_disable(voi
#endif
}
-static inline void local_irq_enable(void)
+static inline void raw_local_irq_enable(void)
{
#ifdef CONFIG_BOOKE
__asm__ __volatile__("wrteei 1": : :"memory");
@@ -92,7 +93,7 @@ static inline void local_irq_enable(void
#endif
}
-static inline void local_irq_save_ptr(unsigned long *flags)
+static inline void raw_local_irq_save_ptr(unsigned long *flags)
{
unsigned long msr;
msr = mfmsr();
@@ -105,12 +106,13 @@ static inline void local_irq_save_ptr(un
__asm__ __volatile__("": : :"memory");
}
-#define local_save_flags(flags) ((flags) = mfmsr())
-#define local_irq_save(flags) local_irq_save_ptr(&flags)
-#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define raw_local_save_flags(flags) ((flags) = mfmsr())
+#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags)
+#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
-#define hard_irq_enable() local_irq_enable()
-#define hard_irq_disable() local_irq_disable()
+#define hard_irq_enable() raw_local_irq_enable()
+#define hard_irq_disable() raw_local_irq_disable()
#endif /* CONFIG_PPC64 */
--- linux-2.6-git.orig/include/asm-powerpc/irqflags.h 2007-06-27 17:37:40.234965668 +0200
+++ linux-2.6-git/include/asm-powerpc/irqflags.h 2007-06-27 17:39:18.499965668 +0200
@@ -15,17 +15,4 @@
*/
#include <asm-powerpc/hw_irq.h>
-/*
- * Do the CPU's IRQ-state tracing from assembly code. We call a
- * C function, so save all the C-clobbered registers:
- */
-#ifdef CONFIG_TRACE_IRQFLAGS
-
-#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
-
-#else
-# define TRACE_IRQS_ON
-# define TRACE_IRQS_OFF
-#endif
-
#endif
--- linux-2.6-git.orig/include/asm-powerpc/rwsem.h 2007-06-27 17:37:40.256965668 +0200
+++ linux-2.6-git/include/asm-powerpc/rwsem.h 2007-06-27 17:38:08.051965668 +0200
@@ -28,11 +28,21 @@ struct rw_semaphore {
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
spinlock_t wait_lock;
struct list_head wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
};
+#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)
@@ -42,12 +52,15 @@ extern struct rw_semaphore *rwsem_down_w
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
@@ -74,7 +87,7 @@ static inline int __down_read_trylock(st
/*
* lock for writing
*/
-static inline void __down_write(struct rw_semaphore *sem)
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
int tmp;
@@ -84,6 +97,11 @@ static inline void __down_write(struct r
rwsem_down_write_failed(sem);
}
+static inline void __down_write(struct rw_semaphore *sem)
+{
+ __down_write_nested(sem, 0);
+}
+
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
int tmp;
--- linux-2.6-git.orig/include/asm-powerpc/spinlock.h 2007-06-27 17:37:40.293965668 +0200
+++ linux-2.6-git/include/asm-powerpc/spinlock.h 2007-06-27 17:38:08.056965668 +0200
@@ -19,6 +19,7 @@
*
* (the type definitions are in asm/spinlock_types.h)
*/
+#include <linux/irqflags.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/hvcall.h>
--- linux-2.6-git.orig/arch/powerpc/kernel/head_64.S 2007-06-27 17:37:39.953965668 +0200
+++ linux-2.6-git/arch/powerpc/kernel/head_64.S 2007-06-27 17:52:08.742965668 +0200
@@ -394,6 +394,12 @@ label##_iSeries: \
EXCEPTION_PROLOG_ISERIES_2; \
b label##_common; \
+#ifdef CONFIG_TRACE_IRQFLAGS
+#define TRACE_DISABLE_INTS bl .powerpc_trace_hardirqs_off
+#else
+#define TRACE_DISABLE_INTS
+#endif
+
#ifdef CONFIG_PPC_ISERIES
#define DISABLE_INTS \
li r11,0; \
@@ -405,14 +411,15 @@ BEGIN_FW_FTR_SECTION; \
mfmsr r10; \
ori r10,r10,MSR_EE; \
mtmsrd r10,1; \
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
+ TRACE_DISABLE_INTS
#else
#define DISABLE_INTS \
li r11,0; \
stb r11,PACASOFTIRQEN(r13); \
- stb r11,PACAHARDIRQEN(r13)
-
+ stb r11,PACAHARDIRQEN(r13); \
+ TRACE_DISABLE_INTS
#endif /* CONFIG_PPC_ISERIES */
#define ENABLE_INTS \
@@ -965,24 +972,38 @@ bad_stack:
*/
fast_exc_return_irq: /* restores irq state too */
ld r3,SOFTE(r1)
- ld r12,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 1f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+1:
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+ cmpdi r3,0
+ bne 2f
+ bl .trace_hardirqs_off
+ ld r3,SOFTE(r1)
+2:
+#else
+ stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+#endif
+ ld r12,_MSR(r1)
rldicl r4,r12,49,63 /* get MSR_EE to LSB */
stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
- b 1f
+ b 3f
.globl fast_exception_return
fast_exception_return:
ld r12,_MSR(r1)
-1: ld r11,_NIP(r1)
+3: ld r11,_NIP(r1)
andi. r3,r12,MSR_RI /* check if RI is set */
beq- unrecov_fer
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
andi. r3,r12,MSR_PR
- beq 2f
+ beq 4f
ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+4:
#endif
ld r3,_CCR(r1)
@@ -1387,11 +1408,24 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
/*
* hash_page couldn't handle it, set soft interrupt enable back
- * to what it was before the trap. Note that .local_irq_restore
+ * to what it was before the trap. Note that .raw_local_irq_restore
* handles any interrupts pending at this point.
*/
ld r3,SOFTE(r1)
- bl .local_irq_restore
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 14f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+14:
+ bl .raw_local_irq_restore
+ cmpdi r3,0
+ bne 15f
+ bl .trace_hardirqs_off
+15:
+#else
+ bl .raw_local_irq_restore
+#endif
b 11f
/* Here we have a page fault that hash_page can't handle. */
--- linux-2.6-git.orig/arch/powerpc/kernel/setup_64.c 2007-06-27 17:37:39.976965668 +0200
+++ linux-2.6-git/arch/powerpc/kernel/setup_64.c 2007-06-27 17:38:08.062965668 +0200
@@ -33,6 +33,7 @@
#include <linux/serial_8250.h>
#include <linux/bootmem.h>
#include <linux/pci.h>
+#include <linux/lockdep.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
@@ -359,6 +360,11 @@ void __init setup_system(void)
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
/*
+ * start lockdep
+ */
+ lockdep_init();
+
+ /*
* Unflatten the device-tree passed by prom_init or kexec
*/
unflatten_device_tree();
--- linux-2.6-git.orig/arch/powerpc/kernel/entry_64.S 2007-06-27 17:37:40.045965668 +0200
+++ linux-2.6-git/arch/powerpc/kernel/entry_64.S 2007-06-27 17:50:16.499965668 +0200
@@ -91,6 +91,13 @@ system_call_common:
li r10,1
stb r10,PACASOFTIRQEN(r13)
stb r10,PACAHARDIRQEN(r13)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .trace_hardirqs_on
+ REST_GPR(0,r1)
+ REST_4GPRS(3,r1)
+ REST_2GPRS(7,r1)
+ addi r9,r1,STACK_FRAME_OVERHEAD
+#endif
std r10,SOFTE(r1)
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
@@ -491,8 +498,20 @@ BEGIN_FW_FTR_SECTION
4:
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r5,0
+ beq 5f
+ bl .trace_hardirqs_on
+ ld r5,SOFTE(r1)
stb r5,PACASOFTIRQEN(r13)
-
+ b 6f
+5:
+ stb r5,PACASOFTIRQEN(r13)
+ bl .trace_hardirqs_off
+6:
+#else
+ stb r5,PACASOFTIRQEN(r13)
+#endif
/* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
@@ -560,6 +579,9 @@ do_work:
bne restore
/* here we are preempting the current task */
1:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .powerpc_trace_hardirqs_on
+#endif
li r0,1
stb r0,PACASOFTIRQEN(r13)
stb r0,PACAHARDIRQEN(r13)
--- linux-2.6-git.orig/arch/powerpc/kernel/Makefile 2007-06-27 17:37:40.100965668 +0200
+++ linux-2.6-git/arch/powerpc/kernel/Makefile 2007-06-27 17:38:08.064965668 +0200
@@ -62,6 +62,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_TRACE_IRQFLAGS) += irqtrace.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-git/arch/powerpc/kernel/irqtrace.S 2007-06-27 17:49:15.650965668 +0200
@@ -0,0 +1,47 @@
+/*
+ * crappy helper for irq-trace
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#define STACKSPACE GPR0 + 16*8
+
+#ifdef __powerpc64__
+#define ST std
+#define L ld
+#else
+#define ST stw
+#define L lw
+#endif
+
+#define PRE \
+ subi r1,r1,STACKSPACE ; \
+ SAVE_GPR(0, r1) ; \
+ SAVE_8GPRS(2, r1) ; \
+ SAVE_4GPRS(10, r1) ; \
+ mfcr r0 ; \
+ ST r0, (14*8)(r1) ; \
+ mflr r0 ; \
+ ST r0, (15*8)(r1)
+
+#define POST \
+ REST_8GPRS(2, r1) ; \
+ REST_4GPRS(10, r1) ; \
+ L r0, (14*8)(r1) ; \
+ mtcr r0 ; \
+ L r0, (15*8)(r1) ; \
+ mtlr r0 ; \
+ REST_GPR(0, r1) ; \
+ addi r1,r1,STACKSPACE
+
+_GLOBAL(powerpc_trace_hardirqs_off)
+ PRE
+ bl .trace_hardirqs_off
+ POST
+ blr
+_GLOBAL(powerpc_trace_hardirqs_on)
+ PRE
+ bl .trace_hardirqs_on
+ POST
+ blr
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-06-27 19:00 ` Johannes Berg
@ 2007-06-28 16:20 ` Johannes Berg
2007-06-30 8:58 ` Christoph Hellwig
2007-07-05 19:26 ` Sergei Shtylyov
0 siblings, 2 replies; 10+ messages in thread
From: Johannes Berg @ 2007-06-28 16:20 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev
This one doesn't break 32-bit build by simply disabling irqtrace for
32-bit.
---
arch/powerpc/Kconfig | 9 ++++++
arch/powerpc/kernel/Makefile | 1
arch/powerpc/kernel/entry_64.S | 24 +++++++++++++++++
arch/powerpc/kernel/head_64.S | 54 ++++++++++++++++++++++++++++++++--------
arch/powerpc/kernel/irq.c | 2 -
arch/powerpc/kernel/irqtrace.S | 47 ++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/ppc_ksyms.c | 2 -
arch/powerpc/kernel/setup_64.c | 6 ++++
include/asm-powerpc/hw_irq.h | 14 +++++-----
include/asm-powerpc/irqflags.h | 13 ---------
include/asm-powerpc/rwsem.h | 34 +++++++++++++++++++------
include/asm-powerpc/spinlock.h | 1
12 files changed, 167 insertions(+), 40 deletions(-)
--- linux-2.6-git32.orig/arch/powerpc/Kconfig 2007-06-28 14:53:58.603430447 +0200
+++ linux-2.6-git32/arch/powerpc/Kconfig 2007-06-28 14:58:02.683430447 +0200
@@ -38,6 +38,15 @@ config STACKTRACE_SUPPORT
bool
default y
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ depends on PPC64
+ default y
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
--- linux-2.6-git32.orig/arch/powerpc/kernel/irq.c 2007-06-28 14:53:58.604430447 +0200
+++ linux-2.6-git32/arch/powerpc/kernel/irq.c 2007-06-28 14:48:38.709430447 +0200
@@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsi
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}
-void local_irq_restore(unsigned long en)
+void raw_local_irq_restore(unsigned long en)
{
/*
* get_paca()->soft_enabled = en;
--- linux-2.6-git32.orig/arch/powerpc/kernel/ppc_ksyms.c 2007-06-28 14:53:58.678430447 +0200
+++ linux-2.6-git32/arch/powerpc/kernel/ppc_ksyms.c 2007-06-28 14:49:24.887430447 +0200
@@ -50,7 +50,7 @@
#endif
#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(local_irq_restore);
+EXPORT_SYMBOL(raw_local_irq_restore);
#endif
#ifdef CONFIG_PPC32
--- linux-2.6-git32.orig/include/asm-powerpc/hw_irq.h 2007-06-28 14:53:58.730430447 +0200
+++ linux-2.6-git32/include/asm-powerpc/hw_irq.h 2007-06-28 14:58:41.508430447 +0200
@@ -27,7 +27,7 @@ static inline unsigned long local_get_fl
return flags;
}
-static inline unsigned long local_irq_disable(void)
+static inline unsigned long raw_local_irq_disable(void)
{
unsigned long flags, zero;
@@ -39,14 +39,15 @@ static inline unsigned long local_irq_di
return flags;
}
-extern void local_irq_restore(unsigned long);
+extern void raw_local_irq_restore(unsigned long);
extern void iseries_handle_interrupts(void);
-#define local_irq_enable() local_irq_restore(1)
-#define local_save_flags(flags) ((flags) = local_get_flags())
-#define local_irq_save(flags) ((flags) = local_irq_disable())
+#define raw_local_irq_enable() raw_local_irq_restore(1)
+#define raw_local_save_flags(flags) ((flags) = local_get_flags())
+#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
-#define irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled_flags(flags) ((flags) == 0)
#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
@@ -108,6 +109,7 @@ static inline void local_irq_save_ptr(un
#define local_save_flags(flags) ((flags) = mfmsr())
#define local_irq_save(flags) local_irq_save_ptr(&flags)
#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
#define hard_irq_enable() local_irq_enable()
#define hard_irq_disable() local_irq_disable()
--- linux-2.6-git32.orig/include/asm-powerpc/irqflags.h 2007-06-28 14:53:58.779430447 +0200
+++ linux-2.6-git32/include/asm-powerpc/irqflags.h 2007-06-28 14:52:51.821430447 +0200
@@ -15,17 +15,4 @@
*/
#include <asm-powerpc/hw_irq.h>
-/*
- * Do the CPU's IRQ-state tracing from assembly code. We call a
- * C function, so save all the C-clobbered registers:
- */
-#ifdef CONFIG_TRACE_IRQFLAGS
-
-#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
-
-#else
-# define TRACE_IRQS_ON
-# define TRACE_IRQS_OFF
-#endif
-
#endif
--- linux-2.6-git32.orig/include/asm-powerpc/rwsem.h 2007-06-28 14:53:58.779430447 +0200
+++ linux-2.6-git32/include/asm-powerpc/rwsem.h 2007-06-28 14:52:51.588430447 +0200
@@ -28,11 +28,21 @@ struct rw_semaphore {
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
spinlock_t wait_lock;
struct list_head wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
};
+#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)
@@ -42,12 +52,15 @@ extern struct rw_semaphore *rwsem_down_w
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
@@ -74,7 +87,7 @@ static inline int __down_read_trylock(st
/*
* lock for writing
*/
-static inline void __down_write(struct rw_semaphore *sem)
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
int tmp;
@@ -84,6 +97,11 @@ static inline void __down_write(struct r
rwsem_down_write_failed(sem);
}
+static inline void __down_write(struct rw_semaphore *sem)
+{
+ __down_write_nested(sem, 0);
+}
+
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
int tmp;
--- linux-2.6-git32.orig/include/asm-powerpc/spinlock.h 2007-06-28 14:53:58.780430447 +0200
+++ linux-2.6-git32/include/asm-powerpc/spinlock.h 2007-06-28 14:52:51.641430447 +0200
@@ -19,6 +19,7 @@
*
* (the type definitions are in asm/spinlock_types.h)
*/
+#include <linux/irqflags.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/hvcall.h>
--- linux-2.6-git32.orig/arch/powerpc/kernel/head_64.S 2007-06-28 14:53:58.679430447 +0200
+++ linux-2.6-git32/arch/powerpc/kernel/head_64.S 2007-06-28 14:48:33.858430447 +0200
@@ -394,6 +394,12 @@ label##_iSeries: \
EXCEPTION_PROLOG_ISERIES_2; \
b label##_common; \
+#ifdef CONFIG_TRACE_IRQFLAGS
+#define TRACE_DISABLE_INTS bl .powerpc_trace_hardirqs_off
+#else
+#define TRACE_DISABLE_INTS
+#endif
+
#ifdef CONFIG_PPC_ISERIES
#define DISABLE_INTS \
li r11,0; \
@@ -405,14 +411,15 @@ BEGIN_FW_FTR_SECTION; \
mfmsr r10; \
ori r10,r10,MSR_EE; \
mtmsrd r10,1; \
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
+ TRACE_DISABLE_INTS
#else
#define DISABLE_INTS \
li r11,0; \
stb r11,PACASOFTIRQEN(r13); \
- stb r11,PACAHARDIRQEN(r13)
-
+ stb r11,PACAHARDIRQEN(r13); \
+ TRACE_DISABLE_INTS
#endif /* CONFIG_PPC_ISERIES */
#define ENABLE_INTS \
@@ -965,24 +972,38 @@ bad_stack:
*/
fast_exc_return_irq: /* restores irq state too */
ld r3,SOFTE(r1)
- ld r12,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 1f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+1:
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+ cmpdi r3,0
+ bne 2f
+ bl .trace_hardirqs_off
+ ld r3,SOFTE(r1)
+2:
+#else
+ stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+#endif
+ ld r12,_MSR(r1)
rldicl r4,r12,49,63 /* get MSR_EE to LSB */
stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
- b 1f
+ b 3f
.globl fast_exception_return
fast_exception_return:
ld r12,_MSR(r1)
-1: ld r11,_NIP(r1)
+3: ld r11,_NIP(r1)
andi. r3,r12,MSR_RI /* check if RI is set */
beq- unrecov_fer
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
andi. r3,r12,MSR_PR
- beq 2f
+ beq 4f
ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+4:
#endif
ld r3,_CCR(r1)
@@ -1387,11 +1408,24 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
/*
* hash_page couldn't handle it, set soft interrupt enable back
- * to what it was before the trap. Note that .local_irq_restore
+ * to what it was before the trap. Note that .raw_local_irq_restore
* handles any interrupts pending at this point.
*/
ld r3,SOFTE(r1)
- bl .local_irq_restore
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 14f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+14:
+ bl .raw_local_irq_restore
+ cmpdi r3,0
+ bne 15f
+ bl .trace_hardirqs_off
+15:
+#else
+ bl .raw_local_irq_restore
+#endif
b 11f
/* Here we have a page fault that hash_page can't handle. */
--- linux-2.6-git32.orig/arch/powerpc/kernel/setup_64.c 2007-06-28 14:53:58.729430447 +0200
+++ linux-2.6-git32/arch/powerpc/kernel/setup_64.c 2007-06-28 14:49:08.305430447 +0200
@@ -33,6 +33,7 @@
#include <linux/serial_8250.h>
#include <linux/bootmem.h>
#include <linux/pci.h>
+#include <linux/lockdep.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
@@ -359,6 +360,11 @@ void __init setup_system(void)
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
/*
+ * start lockdep
+ */
+ lockdep_init();
+
+ /*
* Unflatten the device-tree passed by prom_init or kexec
*/
unflatten_device_tree();
--- linux-2.6-git32.orig/arch/powerpc/kernel/entry_64.S 2007-06-28 14:53:58.729430447 +0200
+++ linux-2.6-git32/arch/powerpc/kernel/entry_64.S 2007-06-28 14:49:13.125430447 +0200
@@ -91,6 +91,13 @@ system_call_common:
li r10,1
stb r10,PACASOFTIRQEN(r13)
stb r10,PACAHARDIRQEN(r13)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .trace_hardirqs_on
+ REST_GPR(0,r1)
+ REST_4GPRS(3,r1)
+ REST_2GPRS(7,r1)
+ addi r9,r1,STACK_FRAME_OVERHEAD
+#endif
std r10,SOFTE(r1)
#ifdef CONFIG_PPC_ISERIES
BEGIN_FW_FTR_SECTION
@@ -491,8 +498,20 @@ BEGIN_FW_FTR_SECTION
4:
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r5,0
+ beq 5f
+ bl .trace_hardirqs_on
+ ld r5,SOFTE(r1)
stb r5,PACASOFTIRQEN(r13)
-
+ b 6f
+5:
+ stb r5,PACASOFTIRQEN(r13)
+ bl .trace_hardirqs_off
+6:
+#else
+ stb r5,PACASOFTIRQEN(r13)
+#endif
/* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
@@ -560,6 +579,9 @@ do_work:
bne restore
/* here we are preempting the current task */
1:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .powerpc_trace_hardirqs_on
+#endif
li r0,1
stb r0,PACASOFTIRQEN(r13)
stb r0,PACAHARDIRQEN(r13)
--- linux-2.6-git32.orig/arch/powerpc/kernel/Makefile 2007-06-28 14:53:58.729430447 +0200
+++ linux-2.6-git32/arch/powerpc/kernel/Makefile 2007-06-28 14:48:41.691430447 +0200
@@ -62,6 +62,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_TRACE_IRQFLAGS) += irqtrace.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-git32/arch/powerpc/kernel/irqtrace.S 2007-06-28 14:49:25.754430447 +0200
@@ -0,0 +1,47 @@
+/*
+ * crappy helper for irq-trace
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#define STACKSPACE GPR0 + 16*8
+
+#ifdef __powerpc64__
+#define ST std
+#define L ld
+#else
+#define ST stw
+#define L lw
+#endif
+
+#define PRE \
+ subi r1,r1,STACKSPACE ; \
+ SAVE_GPR(0, r1) ; \
+ SAVE_8GPRS(2, r1) ; \
+ SAVE_4GPRS(10, r1) ; \
+ mfcr r0 ; \
+ ST r0, (14*8)(r1) ; \
+ mflr r0 ; \
+ ST r0, (15*8)(r1)
+
+#define POST \
+ REST_8GPRS(2, r1) ; \
+ REST_4GPRS(10, r1) ; \
+ L r0, (14*8)(r1) ; \
+ mtcr r0 ; \
+ L r0, (15*8)(r1) ; \
+ mtlr r0 ; \
+ REST_GPR(0, r1) ; \
+ addi r1,r1,STACKSPACE
+
+_GLOBAL(powerpc_trace_hardirqs_off)
+ PRE
+ bl .trace_hardirqs_off
+ POST
+ blr
+_GLOBAL(powerpc_trace_hardirqs_on)
+ PRE
+ bl .trace_hardirqs_on
+ POST
+ blr
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-06-28 16:20 ` Johannes Berg
@ 2007-06-30 8:58 ` Christoph Hellwig
2007-07-04 22:40 ` Johannes Berg
2007-07-05 19:26 ` Sergei Shtylyov
1 sibling, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2007-06-30 8:58 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev, Christoph Hellwig
On Thu, Jun 28, 2007 at 06:20:42PM +0200, Johannes Berg wrote:
> This one doesn't break 32-bit build by simply disabling irqtrace for
> 32-bit.
This looks really cool to me. I'd love to see this in 2.6.23.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-06-30 8:58 ` Christoph Hellwig
@ 2007-07-04 22:40 ` Johannes Berg
2007-07-06 9:23 ` Johannes Berg
0 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2007-07-04 22:40 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 820 bytes --]
On Sat, 2007-06-30 at 10:58 +0200, Christoph Hellwig wrote:
> On Thu, Jun 28, 2007 at 06:20:42PM +0200, Johannes Berg wrote:
> > This one doesn't break 32-bit build by simply disabling irqtrace for
> > 32-bit.
>
> This looks really cool to me. I'd love to see this in 2.6.23.
Hmm. Looks like I just found a case where I forgot to trace in some
place:
[ 241.629380] hardirqs last enabled at (1319): [<c0000000000b3718>] .get_page_from_freelist+0x298/0x620
[ 241.629714] hardirqs last disabled at (1320): [<c000000000033690>] .native_hpte_invalidate+0x60/0x320
[ 241.629732] softirqs last enabled at (1282): [<c000000000059e28>] .__do_softirq+0x198/0x1e0
[ 241.629748] softirqs last disabled at (1273): [<c00000000000c7e4>] .do_softirq+0xd4/0xe0
I'll look into it when I get around.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-06-28 16:20 ` Johannes Berg
2007-06-30 8:58 ` Christoph Hellwig
@ 2007-07-05 19:26 ` Sergei Shtylyov
2007-07-06 10:59 ` Johannes Berg
1 sibling, 1 reply; 10+ messages in thread
From: Sergei Shtylyov @ 2007-07-05 19:26 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev, Christoph Hellwig
Johannes Berg wrote:
> This one doesn't break 32-bit build by simply disabling irqtrace for
> 32-bit.
> --- linux-2.6-git32.orig/include/asm-powerpc/hw_irq.h 2007-06-28 14:53:58.730430447 +0200
> +++ linux-2.6-git32/include/asm-powerpc/hw_irq.h 2007-06-28 14:58:41.508430447 +0200
> @@ -27,7 +27,7 @@ static inline unsigned long local_get_fl
> return flags;
> }
>
> -static inline unsigned long local_irq_disable(void)
> +static inline unsigned long raw_local_irq_disable(void)
> {
> unsigned long flags, zero;
>
> @@ -39,14 +39,15 @@ static inline unsigned long local_irq_di
> return flags;
> }
>
> -extern void local_irq_restore(unsigned long);
> +extern void raw_local_irq_restore(unsigned long);
> extern void iseries_handle_interrupts(void);
>
> -#define local_irq_enable() local_irq_restore(1)
> -#define local_save_flags(flags) ((flags) = local_get_flags())
> -#define local_irq_save(flags) ((flags) = local_irq_disable())
> +#define raw_local_irq_enable() raw_local_irq_restore(1)
> +#define raw_local_save_flags(flags) ((flags) = local_get_flags())
> +#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
>
> -#define irqs_disabled() (local_get_flags() == 0)
> +#define raw_irqs_disabled() (local_get_flags() == 0)
> +#define raw_irqs_disabled_flags(flags) ((flags) == 0)
>
> #define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
> #define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
> @@ -108,6 +109,7 @@ static inline void local_irq_save_ptr(un
> #define local_save_flags(flags) ((flags) = mfmsr())
> #define local_irq_save(flags) local_irq_save_ptr(&flags)
> #define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
> +#define irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
>
> #define hard_irq_enable() local_irq_enable()
> #define hard_irq_disable() local_irq_disable()
> --- linux-2.6-git32.orig/include/asm-powerpc/irqflags.h 2007-06-28 14:53:58.779430447 +0200
> +++ linux-2.6-git32/include/asm-powerpc/irqflags.h 2007-06-28 14:52:51.821430447 +0200
> @@ -15,17 +15,4 @@
> */
> #include <asm-powerpc/hw_irq.h>
>
> -/*
> - * Do the CPU's IRQ-state tracing from assembly code. We call a
> - * C function, so save all the C-clobbered registers:
> - */
> -#ifdef CONFIG_TRACE_IRQFLAGS
> -
> -#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
> -
> -#else
> -# define TRACE_IRQS_ON
> -# define TRACE_IRQS_OFF
> -#endif
> -
> #endif
I suggest to also remove these 3 lines from the heading comment in this
file -- they're not true anyway:
* This file gets included from lowlevel asm headers too, to provide
* wrapped versions of the local_irq_*() APIs, based on the
* raw_local_irq_*() macros from the lowlevel headers.
> --- linux-2.6-git32.orig/arch/powerpc/kernel/head_64.S 2007-06-28 14:53:58.679430447 +0200
> +++ linux-2.6-git32/arch/powerpc/kernel/head_64.S 2007-06-28 14:48:33.858430447 +0200
> @@ -394,6 +394,12 @@ label##_iSeries: \
> EXCEPTION_PROLOG_ISERIES_2; \
> b label##_common; \
>
> +#ifdef CONFIG_TRACE_IRQFLAGS
> +#define TRACE_DISABLE_INTS bl .powerpc_trace_hardirqs_off
> +#else
> +#define TRACE_DISABLE_INTS
> +#endif
> +
Erm, weren't those supposed to be in <asm-powerpc/irqflags.h>?
> #ifdef CONFIG_PPC_ISERIES
> #define DISABLE_INTS \
> li r11,0; \
> @@ -405,14 +411,15 @@ BEGIN_FW_FTR_SECTION; \
> mfmsr r10; \
> ori r10,r10,MSR_EE; \
> mtmsrd r10,1; \
> -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
> +END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
> + TRACE_DISABLE_INTS
>
> #else
> #define DISABLE_INTS \
> li r11,0; \
> stb r11,PACASOFTIRQEN(r13); \
> - stb r11,PACAHARDIRQEN(r13)
> -
> + stb r11,PACAHARDIRQEN(r13); \
> + TRACE_DISABLE_INTS
> #endif /* CONFIG_PPC_ISERIES */
>
> #define ENABLE_INTS \
> @@ -965,24 +972,38 @@ bad_stack:
The following code seemed over-engineered:
> */
> fast_exc_return_irq: /* restores irq state too */
> ld r3,SOFTE(r1)
> - ld r12,_MSR(r1)
> +#ifdef CONFIG_TRACE_IRQFLAGS
> + cmpdi r3,0
> + beq 1f
> + bl .trace_hardirqs_on
b 2f
1:
> + bl .trace_hardirqs_off
2:
> + ld r3,SOFTE(r1)
> +#endif
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
> + ld r12,_MSR(r1)
> rldicl r4,r12,49,63 /* get MSR_EE to LSB */
> stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
> - b 1f
> + b 3f
[...]
> --- linux-2.6-git32.orig/arch/powerpc/kernel/entry_64.S 2007-06-28 14:53:58.729430447 +0200
> +++ linux-2.6-git32/arch/powerpc/kernel/entry_64.S 2007-06-28 14:49:13.125430447 +0200
[...]
> @@ -491,8 +498,20 @@ BEGIN_FW_FTR_SECTION
> 4:
> END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
> #endif
> +#ifdef CONFIG_TRACE_IRQFLAGS
> + cmpdi r5,0
> + beq 5f
> + bl .trace_hardirqs_on
> + ld r5,SOFTE(r1)
> stb r5,PACASOFTIRQEN(r13)
> -
> + b 6f
> +5:
> + stb r5,PACASOFTIRQEN(r13)
> + bl .trace_hardirqs_off
> +6:
> +#else
> + stb r5,PACASOFTIRQEN(r13)
> +#endif
Again, could have been more compact... unless trace_hardirqs_*() calls
need to be in certain order WRT writes to PACASOFTIRQEN -- if so, in the 1st
case that I've pointed out the order was not identical (probably wrong?)...
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-2.6-git32/arch/powerpc/kernel/irqtrace.S 2007-06-28 14:49:25.754430447 +0200
> @@ -0,0 +1,47 @@
> +/*
> + * crappy helper for irq-trace
> + */
> +
> +#include <asm/ppc_asm.h>
> +#include <asm/asm-offsets.h>
> +
> +#define STACKSPACE GPR0 + 16*8
I guess this should be 16*4 for PPC32.
> +
> +#ifdef __powerpc64__
> +#define ST std
> +#define L ld
> +#else
> +#define ST stw
> +#define L lw
> +#endif
> +
> +#define PRE \
> + subi r1,r1,STACKSPACE ; \
> + SAVE_GPR(0, r1) ; \
> + SAVE_8GPRS(2, r1) ; \
> + SAVE_4GPRS(10, r1) ; \
> + mfcr r0 ; \
> + ST r0, (14*8)(r1) ; \
> + mflr r0 ; \
> + ST r0, (15*8)(r1)
Didn't you forget to add GPR0 to the offsets here?
> +#define POST \
> + REST_8GPRS(2, r1) ; \
> + REST_4GPRS(10, r1) ; \
> + L r0, (14*8)(r1) ; \
> + mtcr r0 ; \
> + L r0, (15*8)(r1) ; \
> + mtlr r0 ; \
> + REST_GPR(0, r1) ; \
> + addi r1,r1,STACKSPACE
You certainly did. I bet you're clobbering GPR11/12 (if I didn't miscount)...
WBR, Sergei
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-07-04 22:40 ` Johannes Berg
@ 2007-07-06 9:23 ` Johannes Berg
2007-07-06 9:54 ` Johannes Berg
0 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2007-07-06 9:23 UTC (permalink / raw)
To: Christoph Hellwig, Benjamin Herrenschmidt; +Cc: linuxppc-dev
On Thu, 2007-07-05 at 00:40 +0200, Johannes Berg wrote:
> On Sat, 2007-06-30 at 10:58 +0200, Christoph Hellwig wrote:
> > On Thu, Jun 28, 2007 at 06:20:42PM +0200, Johannes Berg wrote:
> > > This one doesn't break 32-bit build by simply disabling irqtrace for
> > > 32-bit.
> >
> > This looks really cool to me. I'd love to see this in 2.6.23.
>
> Hmm. Looks like I just found a case where I forgot to trace in some
> place:
>
> [ 241.629380] hardirqs last enabled at (1319): [<c0000000000b3718>] .get_page_from_freelist+0x298/0x620
> [ 241.629714] hardirqs last disabled at (1320): [<c000000000033690>] .native_hpte_invalidate+0x60/0x320
> [ 241.629732] softirqs last enabled at (1282): [<c000000000059e28>] .__do_softirq+0x198/0x1e0
> [ 241.629748] softirqs last disabled at (1273): [<c00000000000c7e4>] .do_softirq+0xd4/0xe0
Not sure what that was, but I found one place where it could have come
from (do an interdiff if you want to know). Below patch is a bit nicer,
especially those trace_hardirqs wrappers. However, the presence of those
itself is indication that I haven't given most of the hooks I added much
thought. Though, in case somebody wants to develop it further I'll even
sign it off.
For me it's doing what I want, it allows me to develop with and for
lockdep, take advantage of lockdep and still use my machine (with forced
preemption) as expected; however I don't think I'd be comfortable with
anybody else using it except on test machines unless somebody else gives
it a thorough look first. Especially for say iSeries which is quite
different in the low-level code and I can't even test.
johannes
Subject: powerpc: 64-bit irqtrace support
From: Johannes Berg <johannes@sipsolutions.net>
This adds irqtrace support to 64-bit powerpc.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
arch/powerpc/Kconfig | 9 ++++
arch/powerpc/kernel/Makefile | 1
arch/powerpc/kernel/entry_64.S | 24 +++++++++++
arch/powerpc/kernel/head_64.S | 54 +++++++++++++++++++++-----
arch/powerpc/kernel/irq.c | 2
arch/powerpc/kernel/irqtrace.S | 82 ++++++++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/ppc_ksyms.c | 2
arch/powerpc/kernel/setup_64.c | 6 ++
include/asm-powerpc/hw_irq.h | 14 +++---
include/asm-powerpc/irqflags.h | 13 ------
include/asm-powerpc/rwsem.h | 34 ++++++++++++----
include/asm-powerpc/spinlock.h | 1
12 files changed, 202 insertions(+), 40 deletions(-)
--- linux-2.6-git.orig/arch/powerpc/Kconfig 2007-07-05 23:01:18.001397556 +0200
+++ linux-2.6-git/arch/powerpc/Kconfig 2007-07-05 23:01:18.068397556 +0200
@@ -38,6 +38,15 @@ config STACKTRACE_SUPPORT
bool
default y
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ depends on PPC64
+ default y
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
config RWSEM_GENERIC_SPINLOCK
bool
--- linux-2.6-git.orig/arch/powerpc/kernel/irq.c 2007-07-05 23:01:11.727397556 +0200
+++ linux-2.6-git/arch/powerpc/kernel/irq.c 2007-07-05 23:01:18.084397556 +0200
@@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsi
: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
}
-void local_irq_restore(unsigned long en)
+void raw_local_irq_restore(unsigned long en)
{
/*
* get_paca()->soft_enabled = en;
--- linux-2.6-git.orig/arch/powerpc/kernel/ppc_ksyms.c 2007-07-05 23:01:11.759397556 +0200
+++ linux-2.6-git/arch/powerpc/kernel/ppc_ksyms.c 2007-07-05 23:01:18.094397556 +0200
@@ -50,7 +50,7 @@
#endif
#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(local_irq_restore);
+EXPORT_SYMBOL(raw_local_irq_restore);
#endif
#ifdef CONFIG_PPC32
--- linux-2.6-git.orig/include/asm-powerpc/hw_irq.h 2007-07-05 23:01:11.985397556 +0200
+++ linux-2.6-git/include/asm-powerpc/hw_irq.h 2007-07-05 23:01:18.108397556 +0200
@@ -27,7 +27,7 @@ static inline unsigned long local_get_fl
return flags;
}
-static inline unsigned long local_irq_disable(void)
+static inline unsigned long raw_local_irq_disable(void)
{
unsigned long flags, zero;
@@ -39,14 +39,15 @@ static inline unsigned long local_irq_di
return flags;
}
-extern void local_irq_restore(unsigned long);
+extern void raw_local_irq_restore(unsigned long);
extern void iseries_handle_interrupts(void);
-#define local_irq_enable() local_irq_restore(1)
-#define local_save_flags(flags) ((flags) = local_get_flags())
-#define local_irq_save(flags) ((flags) = local_irq_disable())
+#define raw_local_irq_enable() raw_local_irq_restore(1)
+#define raw_local_save_flags(flags) ((flags) = local_get_flags())
+#define raw_local_irq_save(flags) ((flags) = raw_local_irq_disable())
-#define irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled() (local_get_flags() == 0)
+#define raw_irqs_disabled_flags(flags) ((flags) == 0)
#define __hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
#define __hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
@@ -108,6 +109,7 @@ static inline void local_irq_save_ptr(un
#define local_save_flags(flags) ((flags) = mfmsr())
#define local_irq_save(flags) local_irq_save_ptr(&flags)
#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
#define hard_irq_enable() local_irq_enable()
#define hard_irq_disable() local_irq_disable()
--- linux-2.6-git.orig/include/asm-powerpc/irqflags.h 2007-07-05 23:01:12.018397556 +0200
+++ linux-2.6-git/include/asm-powerpc/irqflags.h 2007-07-05 23:01:18.141397556 +0200
@@ -15,17 +15,4 @@
*/
#include <asm-powerpc/hw_irq.h>
-/*
- * Do the CPU's IRQ-state tracing from assembly code. We call a
- * C function, so save all the C-clobbered registers:
- */
-#ifdef CONFIG_TRACE_IRQFLAGS
-
-#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
-
-#else
-# define TRACE_IRQS_ON
-# define TRACE_IRQS_OFF
-#endif
-
#endif
--- linux-2.6-git.orig/include/asm-powerpc/rwsem.h 2007-07-05 23:01:12.050397556 +0200
+++ linux-2.6-git/include/asm-powerpc/rwsem.h 2007-07-05 23:01:18.149397556 +0200
@@ -28,11 +28,21 @@ struct rw_semaphore {
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
spinlock_t wait_lock;
struct list_head wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
};
+#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)
@@ -42,12 +52,15 @@ extern struct rw_semaphore *rwsem_down_w
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
@@ -74,7 +87,7 @@ static inline int __down_read_trylock(st
/*
* lock for writing
*/
-static inline void __down_write(struct rw_semaphore *sem)
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
{
int tmp;
@@ -84,6 +97,11 @@ static inline void __down_write(struct r
rwsem_down_write_failed(sem);
}
+static inline void __down_write(struct rw_semaphore *sem)
+{
+ __down_write_nested(sem, 0);
+}
+
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
int tmp;
--- linux-2.6-git.orig/include/asm-powerpc/spinlock.h 2007-07-05 23:01:12.097397556 +0200
+++ linux-2.6-git/include/asm-powerpc/spinlock.h 2007-07-05 23:01:18.152397556 +0200
@@ -19,6 +19,7 @@
*
* (the type definitions are in asm/spinlock_types.h)
*/
+#include <linux/irqflags.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/hvcall.h>
--- linux-2.6-git.orig/arch/powerpc/kernel/head_64.S 2007-07-05 23:01:11.796397556 +0200
+++ linux-2.6-git/arch/powerpc/kernel/head_64.S 2007-07-05 23:01:18.173397556 +0200
@@ -394,6 +394,12 @@ label##_iSeries: \
EXCEPTION_PROLOG_ISERIES_2; \
b label##_common; \
+#ifdef CONFIG_TRACE_IRQFLAGS
+#define TRACE_DISABLE_INTS bl .powerpc_trace_hardirqs_off
+#else
+#define TRACE_DISABLE_INTS
+#endif
+
#ifdef CONFIG_PPC_ISERIES
#define DISABLE_INTS \
li r11,0; \
@@ -405,14 +411,15 @@ BEGIN_FW_FTR_SECTION; \
mfmsr r10; \
ori r10,r10,MSR_EE; \
mtmsrd r10,1; \
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
+ TRACE_DISABLE_INTS
#else
#define DISABLE_INTS \
li r11,0; \
stb r11,PACASOFTIRQEN(r13); \
- stb r11,PACAHARDIRQEN(r13)
-
+ stb r11,PACAHARDIRQEN(r13); \
+ TRACE_DISABLE_INTS
#endif /* CONFIG_PPC_ISERIES */
#define ENABLE_INTS \
@@ -965,24 +972,38 @@ bad_stack:
*/
fast_exc_return_irq: /* restores irq state too */
ld r3,SOFTE(r1)
- ld r12,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 1f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+1:
stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+ cmpdi r3,0
+ bne 2f
+ bl .trace_hardirqs_off
+ ld r3,SOFTE(r1)
+2:
+#else
+ stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
+#endif
+ ld r12,_MSR(r1)
rldicl r4,r12,49,63 /* get MSR_EE to LSB */
stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
- b 1f
+ b 3f
.globl fast_exception_return
fast_exception_return:
ld r12,_MSR(r1)
-1: ld r11,_NIP(r1)
+3: ld r11,_NIP(r1)
andi. r3,r12,MSR_RI /* check if RI is set */
beq- unrecov_fer
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
andi. r3,r12,MSR_PR
- beq 2f
+ beq 4f
ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+4:
#endif
ld r3,_CCR(r1)
@@ -1387,11 +1408,24 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
/*
* hash_page couldn't handle it, set soft interrupt enable back
- * to what it was before the trap. Note that .local_irq_restore
+ * to what it was before the trap. Note that .raw_local_irq_restore
* handles any interrupts pending at this point.
*/
ld r3,SOFTE(r1)
- bl .local_irq_restore
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r3,0
+ beq 14f
+ bl .trace_hardirqs_on
+ ld r3,SOFTE(r1)
+14:
+ bl .raw_local_irq_restore
+ cmpdi r3,0
+ bne 15f
+ bl .trace_hardirqs_off
+15:
+#else
+ bl .raw_local_irq_restore
+#endif
b 11f
/* Here we have a page fault that hash_page can't handle. */
--- linux-2.6-git.orig/arch/powerpc/kernel/setup_64.c 2007-07-05 23:01:11.829397556 +0200
+++ linux-2.6-git/arch/powerpc/kernel/setup_64.c 2007-07-05 23:01:18.185397556 +0200
@@ -33,6 +33,7 @@
#include <linux/serial_8250.h>
#include <linux/bootmem.h>
#include <linux/pci.h>
+#include <linux/lockdep.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
@@ -359,6 +360,11 @@ void __init setup_system(void)
&__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
/*
+ * start lockdep
+ */
+ lockdep_init();
+
+ /*
* Unflatten the device-tree passed by prom_init or kexec
*/
unflatten_device_tree();
--- linux-2.6-git.orig/arch/powerpc/kernel/entry_64.S 2007-07-05 23:01:11.864397556 +0200
+++ linux-2.6-git/arch/powerpc/kernel/entry_64.S 2007-07-05 23:01:18.211397556 +0200
@@ -88,6 +88,13 @@ system_call_common:
addi r9,r1,STACK_FRAME_OVERHEAD
ld r11,exception_marker@toc(r2)
std r11,-16(r9) /* "regshere" marker */
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .trace_hardirqs_on
+ REST_GPR(0,r1)
+ REST_4GPRS(3,r1)
+ REST_2GPRS(7,r1)
+ addi r9,r1,STACK_FRAME_OVERHEAD
+#endif
li r10,1
stb r10,PACASOFTIRQEN(r13)
stb r10,PACAHARDIRQEN(r13)
@@ -491,8 +498,20 @@ BEGIN_FW_FTR_SECTION
4:
END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
#endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+ cmpdi r5,0
+ beq 5f
+ bl .trace_hardirqs_on
+ ld r5,SOFTE(r1)
stb r5,PACASOFTIRQEN(r13)
-
+ b 6f
+5:
+ stb r5,PACASOFTIRQEN(r13)
+ bl .trace_hardirqs_off
+6:
+#else
+ stb r5,PACASOFTIRQEN(r13)
+#endif
/* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
@@ -560,6 +579,9 @@ do_work:
bne restore
/* here we are preempting the current task */
1:
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .powerpc_trace_hardirqs_on
+#endif
li r0,1
stb r0,PACASOFTIRQEN(r13)
stb r0,PACAHARDIRQEN(r13)
--- linux-2.6-git.orig/arch/powerpc/kernel/Makefile 2007-07-05 23:01:18.002397556 +0200
+++ linux-2.6-git/arch/powerpc/kernel/Makefile 2007-07-05 23:01:18.212397556 +0200
@@ -62,6 +62,7 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_TRACE_IRQFLAGS) += irqtrace.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-git/arch/powerpc/kernel/irqtrace.S 2007-07-06 02:11:15.110814034 +0200
@@ -0,0 +1,82 @@
+/*
+ * helpers for irq-trace
+ *
+ * We invoke the hardirq trace functions from various inconvenient
+ * places; these helpers save all callee-saved registers.
+ *
+ * Author: Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#ifdef CONFIG_PPC64
+#define ST std
+#define STU stdu
+#define L ld
+#define WSZ 8
+#define FREE 32
+#else
+#error double-check please
+#define ST stw
+#define STU stwu
+#define L lwz
+#define WSZ 4
+#define FREE 16
+#endif
+
+#define STACKSPACE (FREE + 16*WSZ)
+#define SAVE(n) (FREE + n*WSZ)
+
+_GLOBAL(powerpc_trace_hardirqs_on)
+ ST r3, (SAVE(2)-STACKSPACE)(r1)
+ LOAD_REG_IMMEDIATE(r3, .trace_hardirqs_on)
+ b powerpc_trace_hardirqs
+
+_GLOBAL(powerpc_trace_hardirqs_off)
+ ST r3, (SAVE(2)-STACKSPACE)(r1)
+ LOAD_REG_IMMEDIATE(r3, .trace_hardirqs_off)
+
+powerpc_trace_hardirqs:
+ ST r0, (SAVE(0)-STACKSPACE)(r1)
+ mflr r0
+ ST r0, LRSAVE(r1)
+ STU r1, -STACKSPACE(r1)
+ mfctr r0
+ ST r0, SAVE(14)(r1)
+ mtctr r3
+ ST r2, SAVE(1)(r1)
+ ST r4, SAVE(3)(r1)
+ ST r5, SAVE(4)(r1)
+ ST r6, SAVE(5)(r1)
+ ST r7, SAVE(6)(r1)
+ ST r8, SAVE(7)(r1)
+ ST r9, SAVE(8)(r1)
+ ST r10, SAVE(9)(r1)
+ ST r11, SAVE(10)(r1)
+ ST r12, SAVE(11)(r1)
+ ST r13, SAVE(12)(r1)
+ mfcr r0
+ ST r0, SAVE(13)(r1)
+ bctrl
+ L r2, SAVE(1)(r1)
+ L r3, SAVE(2)(r1)
+ L r4, SAVE(3)(r1)
+ L r5, SAVE(4)(r1)
+ L r6, SAVE(5)(r1)
+ L r7, SAVE(6)(r1)
+ L r8, SAVE(7)(r1)
+ L r9, SAVE(8)(r1)
+ L r10, SAVE(9)(r1)
+ L r11, SAVE(10)(r1)
+ L r12, SAVE(11)(r1)
+ L r13, SAVE(12)(r1)
+ L r0, SAVE(13)(r1)
+ mtcr r0
+ L r0, SAVE(14)(r1)
+ mtctr r0
+ L r1, 0(r1)
+ L r0, LRSAVE(r1)
+ mtlr r0
+ L r0, (SAVE(0)-STACKSPACE)(r1)
+ blr
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-07-06 9:23 ` Johannes Berg
@ 2007-07-06 9:54 ` Johannes Berg
0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2007-07-06 9:54 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1464 bytes --]
*sigh* I really shouldn't have mailed this out in the first place. Every
time I look at it I find new bugs despite the fact that it actually
works on my machine.
> ld r3,SOFTE(r1)
> - bl .local_irq_restore
> +#ifdef CONFIG_TRACE_IRQFLAGS
> + cmpdi r3,0
> + beq 14f
> + bl .trace_hardirqs_on
> + ld r3,SOFTE(r1)
> +14:
> + bl .raw_local_irq_restore
> + cmpdi r3,0
This should reload r3 before the second compare as raw_local_irq_restore
returns nothing (void). And why does it need a second compare anyway?
Just rewrite as
ld r3, SOFTE(r1)
#ifdef CONFIG_TRACE_IRQFLAGS
cmpdi r3, 0
bne 14f
bl .raw_local_irq_restore
bl .trace_hardirqs_off
b 15f
14:
bl .trace_hardirqs_on
li r3, 1
#endif
bl .raw_local_irq_restore
15:
which has the advantage of having only one conditional branch and less
preprocessor foo.
> +#ifdef CONFIG_TRACE_IRQFLAGS
> + cmpdi r5,0
> + beq 5f
> + bl .trace_hardirqs_on
> + ld r5,SOFTE(r1)
> stb r5,PACASOFTIRQEN(r13)
> -
> + b 6f
> +5:
> + stb r5,PACASOFTIRQEN(r13)
> + bl .trace_hardirqs_off
> +6:
> +#else
> + stb r5,PACASOFTIRQEN(r13)
> +#endif
Similarly, that could be rewritten as
#ifdef CONFIG_TRACE_IRQFLAGS
cmpdi r5, 0
bne 5f
stb r5, PACASOFTIRQEN(r13)
bl .trace_hardirqs_off
b 6f
5:
bl .trace_hardirqs_on
li r5, 1
#endif
stb r5, PACASOFTIRQEN(r13)
6:
I can't test these modifications over the weekend but they should be
fine.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: powerpc stacktrace and lockdep support
2007-07-05 19:26 ` Sergei Shtylyov
@ 2007-07-06 10:59 ` Johannes Berg
0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2007-07-06 10:59 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: linuxppc-dev, Christoph Hellwig
[-- Attachment #1: Type: text/plain, Size: 1654 bytes --]
Sergei, Thanks for your review!
> I suggest to also remove these 3 lines from the heading comment in this
> file -- they're not true anyway:
>
> * This file gets included from lowlevel asm headers too, to provide
> * wrapped versions of the local_irq_*() APIs, based on the
> * raw_local_irq_*() macros from the lowlevel headers.
Good point.
> > +#ifdef CONFIG_TRACE_IRQFLAGS
> > +#define TRACE_DISABLE_INTS bl .powerpc_trace_hardirqs_off
> > +#else
> > +#define TRACE_DISABLE_INTS
> > +#endif
> > +
>
> Erm, weren't those supposed to be in <asm-powerpc/irqflags.h>?
I guess they could be there. I was mucking my way through ;)
> The following code seemed over-engineered:
Yeah, perfectly correct. See my last mail to this thread from this
morning.
> Again, could have been more compact... unless trace_hardirqs_*() calls
> need to be in certain order WRT writes to PACASOFTIRQEN -- if so, in the 1st
> case that I've pointed out the order was not identical (probably wrong?)...
Yeah, there is an ordering requirement and it was wrong in that version
of the patch.
> > +/*
> > + * crappy helper for irq-trace
> > + */
> > +
> > +#include <asm/ppc_asm.h>
> > +#include <asm/asm-offsets.h>
> > +
> > +#define STACKSPACE GPR0 + 16*8
>
> I guess this should be 16*4 for PPC32.
> Didn't you forget to add GPR0 to the offsets here?
> You certainly did. I bet you're clobbering GPR11/12 (if I didn't miscount)...
All correct. That might even be why it didn't work on 32-bit for me and
then I gave up. In any case, I completely rewrote this file.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-07-06 10:58 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-08 13:54 powerpc stacktrace and lockdep support Christoph Hellwig
2007-06-26 22:47 ` Johannes Berg
2007-06-27 19:00 ` Johannes Berg
2007-06-28 16:20 ` Johannes Berg
2007-06-30 8:58 ` Christoph Hellwig
2007-07-04 22:40 ` Johannes Berg
2007-07-06 9:23 ` Johannes Berg
2007-07-06 9:54 ` Johannes Berg
2007-07-05 19:26 ` Sergei Shtylyov
2007-07-06 10:59 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).