linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] [POWERPC] lockdep support for ppc64
@ 2008-04-02  7:52 Benjamin Herrenschmidt
  2008-04-02  7:52 ` [PATCH 1/4] [POWERPC] Initialize paca->current earlier Benjamin Herrenschmidt
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2008-04-02  7:52 UTC (permalink / raw)
  To: linuxppc-dev

[Not to merge just yet ... almost]

This serie of patches adds lockdep support for 64 bits
powerpc. Dale's patch for 32 bits still need me to review
and test it which I'll try to do asap.

It needs the iSeries hardirq enable fix that I posted
earlier (which is probably 2.6.25 material).

Note that we can already see potential problems exposed
by it. So far on my list:

 - something wrong with iseries veth. Haven't got to figure
out what yet, could be a false positive

 - possible deadlock with the device-tree rwlock. The one that
I caught with lockdep here is pSeries rtas_set_rtc_time() calls
rtas_token() from softirq, which does on of_find_property(),
which takes the read lock. Other things can call prom_add_propety()
which can take the write lock, while softirqs are enabled -> boom.
Maybe we should forbid OF device-tree access from IRQs and thus
things that need to use rtas_token() will have to cache the token.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] [POWERPC] Initialize paca->current earlier
  2008-04-02  7:52 [PATCH 0/4] [POWERPC] lockdep support for ppc64 Benjamin Herrenschmidt
@ 2008-04-02  7:52 ` Benjamin Herrenschmidt
  2008-04-02 12:30   ` Stephen Rothwell
  2008-04-02  7:52 ` [PATCH 2/4] [POWERPC] lockdep stacktrace support Benjamin Herrenschmidt
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2008-04-02  7:52 UTC (permalink / raw)
  To: linuxppc-dev

Currently, we initialize the "current" pointer in the PACA (which
is used by the "current" macro in the kernel) before calling
setup_system(). That means that early_setup() is called with
current still "NULL" which is -not- a good idea. It happens to
work so far but breaks with lockdep when early code calls printk.

This changes it so that all PACAs are statically initialized with
__current pointing to the init task. For non-0 CPUs, this is fixed
up before use.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/head_64.S |    4 ----
 arch/powerpc/kernel/paca.c    |    3 ++-
 2 files changed, 2 insertions(+), 5 deletions(-)

--- linux-work.orig/arch/powerpc/kernel/head_64.S	2008-04-02 18:20:53.000000000 +1100
+++ linux-work/arch/powerpc/kernel/head_64.S	2008-04-02 18:24:45.000000000 +1100
@@ -1505,10 +1505,6 @@ _INIT_GLOBAL(start_here_common)
 	li	r0,0
 	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
 
-	/* ptr to current */
-	LOAD_REG_IMMEDIATE(r4, init_task)
-	std	r4,PACACURRENT(r13)
-
 	/* Load the TOC */
 	ld	r2,PACATOC(r13)
 	std	r1,PACAKSAVE(r13)
Index: linux-work/arch/powerpc/kernel/paca.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/paca.c	2008-04-02 18:28:07.000000000 +1100
+++ linux-work/arch/powerpc/kernel/paca.c	2008-04-02 18:28:22.000000000 +1100
@@ -72,7 +72,8 @@ struct slb_shadow slb_shadow[] __cacheli
 	.paca_index = (number),		/* Paca Index */		    \
 	.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL,		    \
 	.hw_cpu_id = 0xffff,						    \
-	.slb_shadow_ptr = &slb_shadow[number],
+	.slb_shadow_ptr = &slb_shadow[number],				    \
+	.__current = &init_task,
 
 #ifdef CONFIG_PPC_ISERIES
 #define PACA_INIT_ISERIES(number)					    \

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/4] [POWERPC] lockdep stacktrace support
  2008-04-02  7:52 [PATCH 0/4] [POWERPC] lockdep support for ppc64 Benjamin Herrenschmidt
  2008-04-02  7:52 ` [PATCH 1/4] [POWERPC] Initialize paca->current earlier Benjamin Herrenschmidt
@ 2008-04-02  7:52 ` Benjamin Herrenschmidt
  2008-04-02 12:29   ` Stephen Rothwell
  2008-04-02  7:52 ` [PATCH 3/4] [POWERPC] Fixup softirq preempt count Benjamin Herrenschmidt
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2008-04-02  7:52 UTC (permalink / raw)
  To: linuxppc-dev

From: Christoph Hellwig <hch@lst.de>

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:

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---
 arch/powerpc/Kconfig             |    4 +++
 arch/powerpc/kernel/Makefile     |    1 
 arch/powerpc/kernel/stacktrace.c |   52 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+)

--- linux-work.orig/arch/powerpc/Kconfig	2008-04-02 15:46:07.000000000 +1100
+++ linux-work/arch/powerpc/Kconfig	2008-04-02 16:47:46.000000000 +1100
@@ -49,6 +49,10 @@ config IRQ_PER_CPU
 	bool
 	default y
 
+config STACKTRACE_SUPPORT
+	bool
+	default y
+
 config RWSEM_GENERIC_SPINLOCK
 	bool
 
Index: linux-work/arch/powerpc/kernel/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/kernel/Makefile	2008-04-02 15:46:07.000000000 +1100
+++ linux-work/arch/powerpc/kernel/Makefile	2008-04-02 16:46:07.000000000 +1100
@@ -67,6 +67,7 @@ obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 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
 
 pci64-$(CONFIG_PPC64)		+= pci_dn.o isa-bridge.o
 obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
Index: linux-work/arch/powerpc/kernel/stacktrace.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/kernel/stacktrace.c	2008-04-02 16:46:07.000000000 +1100
@@ -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

* [PATCH 3/4] [POWERPC] Fixup softirq preempt count
  2008-04-02  7:52 [PATCH 0/4] [POWERPC] lockdep support for ppc64 Benjamin Herrenschmidt
  2008-04-02  7:52 ` [PATCH 1/4] [POWERPC] Initialize paca->current earlier Benjamin Herrenschmidt
  2008-04-02  7:52 ` [PATCH 2/4] [POWERPC] lockdep stacktrace support Benjamin Herrenschmidt
@ 2008-04-02  7:52 ` Benjamin Herrenschmidt
  2008-04-02  7:52 ` [PATCH 4/4] [POWERPC] irqtrace support to 64-bit powerpc Benjamin Herrenschmidt
  2008-04-02  9:50 ` [PATCH 0/4] [POWERPC] lockdep support for ppc64 Johannes Berg
  4 siblings, 0 replies; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2008-04-02  7:52 UTC (permalink / raw)
  To: linuxppc-dev

This fixes the handling of the preempt count when switching
interrupt stacks so that HW interrupt properly get the softirq
mask copied over from the previous stack.

It also initializes the softirq stack preempt_count to 0 instead
of SOFTIRQ_OFFSET, like x86, as __do_softirq() does the increment,
and we hit some lockdep checks if we have it twice.

That means we do run for a little while off the softirq stack
with the preempt-count set to 0, which could be deadly if we
try to take a softirq at that point, however we do so with
interrupts disabled, so I think we are ok.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/irq.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

--- linux-work.orig/arch/powerpc/kernel/irq.c	2008-04-02 16:48:58.000000000 +1100
+++ linux-work/arch/powerpc/kernel/irq.c	2008-04-02 16:49:36.000000000 +1100
@@ -310,8 +310,21 @@ void do_IRQ(struct pt_regs *regs)
 				handler = &__do_IRQ;
 			irqtp->task = curtp->task;
 			irqtp->flags = 0;
+
+			/* Copy the softirq bits in preempt_count so that the
+			 * softirq checks work in the hardirq context.
+			 */
+			irqtp->preempt_count =
+				(irqtp->preempt_count & ~SOFTIRQ_MASK) |
+				(curtp->preempt_count & SOFTIRQ_MASK);
+
 			call_handle_irq(irq, desc, irqtp, handler);
 			irqtp->task = NULL;
+
+
+			/* Set any flag that may have been set on the
+			 * alternate stack
+			 */
 			if (irqtp->flags)
 				set_bits(irqtp->flags, &curtp->flags);
 		} else
@@ -357,7 +370,7 @@ void irq_ctx_init(void)
 		memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
 		tp = softirq_ctx[i];
 		tp->cpu = i;
-		tp->preempt_count = SOFTIRQ_OFFSET;
+		tp->preempt_count = 0;
 
 		memset((void *)hardirq_ctx[i], 0, THREAD_SIZE);
 		tp = hardirq_ctx[i];

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 4/4] [POWERPC] irqtrace support to 64-bit powerpc
  2008-04-02  7:52 [PATCH 0/4] [POWERPC] lockdep support for ppc64 Benjamin Herrenschmidt
                   ` (2 preceding siblings ...)
  2008-04-02  7:52 ` [PATCH 3/4] [POWERPC] Fixup softirq preempt count Benjamin Herrenschmidt
@ 2008-04-02  7:52 ` Benjamin Herrenschmidt
  2008-04-02  9:50 ` [PATCH 0/4] [POWERPC] lockdep support for ppc64 Johannes Berg
  4 siblings, 0 replies; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2008-04-02  7:52 UTC (permalink / raw)
  To: linuxppc-dev

This adds the low level irq tracing hooks to the powerpc architecture
needed to enable full lockdep functionality

Partly based on Johannes Berg's initial version, removing the asm
trampoline that isn't needed (thus improving perfs) and all sorts
of bits and pieces, reworking most of the assembly, etc...

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---

 arch/powerpc/Kconfig            |    9 +++++++
 arch/powerpc/kernel/entry_64.S  |   27 +++++++++++++++++++++-
 arch/powerpc/kernel/head_64.S   |   47 +++++++++++++++++++++++++++-------------
 arch/powerpc/kernel/irq.c       |    3 +-
 arch/powerpc/kernel/ppc_ksyms.c |    4 ---
 arch/powerpc/kernel/setup_64.c  |    4 +++
 include/asm-powerpc/exception.h |    6 ++---
 include/asm-powerpc/hw_irq.h    |   13 +++++------
 include/asm-powerpc/irqflags.h  |   37 +++++++++++++++++++++----------
 include/asm-powerpc/rwsem.h     |   35 ++++++++++++++++++++++-------
 include/asm-powerpc/spinlock.h  |    1 
 11 files changed, 134 insertions(+), 52 deletions(-)

--- linux-work.orig/arch/powerpc/Kconfig	2008-04-02 18:30:18.000000000 +1100
+++ linux-work/arch/powerpc/Kconfig	2008-04-02 18:30:21.000000000 +1100
@@ -53,6 +53,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
 
Index: linux-work/arch/powerpc/kernel/irq.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/irq.c	2008-04-02 18:30:20.000000000 +1100
+++ linux-work/arch/powerpc/kernel/irq.c	2008-04-02 18:30:21.000000000 +1100
@@ -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;
@@ -174,6 +174,7 @@ void local_irq_restore(unsigned long en)
 
 	__hard_irq_enable();
 }
+EXPORT_SYMBOL(raw_local_irq_restore);
 #endif /* CONFIG_PPC64 */
 
 int show_interrupts(struct seq_file *p, void *v)
Index: linux-work/arch/powerpc/kernel/ppc_ksyms.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/ppc_ksyms.c	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/arch/powerpc/kernel/ppc_ksyms.c	2008-04-02 18:30:21.000000000 +1100
@@ -45,10 +45,6 @@
 #include <asm/signal.h>
 #include <asm/dcr.h>
 
-#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(local_irq_restore);
-#endif
-
 #ifdef CONFIG_PPC32
 extern void transfer_to_handler(void);
 extern void do_IRQ(struct pt_regs *regs);
Index: linux-work/include/asm-powerpc/hw_irq.h
===================================================================
--- linux-work.orig/include/asm-powerpc/hw_irq.h	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/include/asm-powerpc/hw_irq.h	2008-04-02 18:30:21.000000000 +1100
@@ -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)
Index: linux-work/include/asm-powerpc/irqflags.h
===================================================================
--- linux-work.orig/include/asm-powerpc/irqflags.h	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/include/asm-powerpc/irqflags.h	2008-04-02 18:30:21.000000000 +1100
@@ -2,30 +2,43 @@
  * include/asm-powerpc/irqflags.h
  *
  * IRQ flags handling
- *
- * 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.
  */
 #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>
 
+#else
+#ifdef CONFIG_TRACE_IRQFLAGS
 /*
- * Do the CPU's IRQ-state tracing from assembly code. We call a
- * C function, so save all the C-clobbered registers:
+ * Most of the CPU's IRQ-state tracing is done from assembly code; we
+ * have to call a C function so call a wrapper that saves all the
+ * C-clobbered registers.
  */
-#ifdef CONFIG_TRACE_IRQFLAGS
-
-#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
-
+#define TRACE_ENABLE_INTS	bl .trace_hardirqs_on
+#define TRACE_DISABLE_INTS	bl .trace_hardirqs_off
+#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip)	\
+	cmpdi	en, 0;				\
+	bne	95f;				\
+	stb	en,PACASOFTIRQEN(r13);		\
+	bl	.trace_hardirqs_off;		\
+	b	skip;				\
+95:	bl	.trace_hardirqs_on;		\
+	li	en,1;
+#define TRACE_AND_RESTORE_IRQ(en)		\
+	TRACE_AND_RESTORE_IRQ_PARTIAL(en,96f);	\
+96:	stb	en,PACASOFTIRQEN(r13)
 #else
-# define TRACE_IRQS_ON
-# define TRACE_IRQS_OFF
+#define TRACE_ENABLE_INTS
+#define TRACE_DISABLE_INTS
+#define TRACE_AND_RESTORE_IRQ_PARTIAL(en,skip)
+#define TRACE_AND_RESTORE_IRQ(en)		\
+	stb	en,PACASOFTIRQEN(r13)
+#endif
 #endif
 
 #endif
Index: linux-work/include/asm-powerpc/rwsem.h
===================================================================
--- linux-work.orig/include/asm-powerpc/rwsem.h	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/include/asm-powerpc/rwsem.h	2008-04-02 18:30:21.000000000 +1100
@@ -32,11 +32,20 @@ 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) }
+	{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
+	  LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
 
 #define DECLARE_RWSEM(name)		\
 	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@@ -46,12 +55,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
@@ -78,7 +90,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;
 
@@ -88,6 +100,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;
Index: linux-work/include/asm-powerpc/spinlock.h
===================================================================
--- linux-work.orig/include/asm-powerpc/spinlock.h	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/include/asm-powerpc/spinlock.h	2008-04-02 18:30:21.000000000 +1100
@@ -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>
Index: linux-work/include/asm-powerpc/exception.h
===================================================================
--- linux-work.orig/include/asm-powerpc/exception.h	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/include/asm-powerpc/exception.h	2008-04-02 18:30:21.000000000 +1100
@@ -228,18 +228,18 @@ label##_pSeries:							\
 BEGIN_FW_FTR_SECTION;				\
 	stb	r11,PACAHARDIRQEN(r13);		\
 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);	\
+	TRACE_DISABLE_INTS;			\
 BEGIN_FW_FTR_SECTION;				\
 	mfmsr	r10;				\
 	ori	r10,r10,MSR_EE;			\
 	mtmsrd	r10,1;				\
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-
 #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				\
Index: linux-work/arch/powerpc/kernel/head_64.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_64.S	2008-04-02 18:24:45.000000000 +1100
+++ linux-work/arch/powerpc/kernel/head_64.S	2008-04-02 18:30:21.000000000 +1100
@@ -36,8 +36,7 @@
 #include <asm/firmware.h>
 #include <asm/page_64.h>
 #include <asm/exception.h>
-
-#define DO_SOFT_DISABLE
+#include <asm/irqflags.h>
 
 /*
  * We layout physical memory as follows:
@@ -450,8 +449,8 @@ bad_stack:
  */
 fast_exc_return_irq:			/* restores irq state too */
 	ld	r3,SOFTE(r1)
+	TRACE_AND_RESTORE_IRQ(r3);
 	ld	r12,_MSR(r1)
-	stb	r3,PACASOFTIRQEN(r13)	/* restore paca->soft_enabled */
 	rldicl	r4,r12,49,63		/* get MSR_EE to LSB */
 	stb	r4,PACAHARDIRQEN(r13)	/* restore paca->hard_enabled */
 	b	1f
@@ -808,7 +807,7 @@ _STATIC(load_up_altivec)
  * Hash table stuff
  */
 	.align	7
-_GLOBAL(do_hash_page)
+_STATIC(do_hash_page)
 	std	r3,_DAR(r1)
 	std	r4,_DSISR(r1)
 
@@ -820,6 +819,27 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 
 	/*
+	 * On iSeries, we soft-disable interrupts here, then
+	 * hard-enable interrupts so that the hash_page code can spin on
+	 * the hash_table_lock without problems on a shared processor.
+	 */
+	DISABLE_INTS
+
+	/*
+	 * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
+	 * and will clobber volatile registers when irq tracing is enabled
+	 * so we need to reload them. It may be possible to be smarter here
+	 * and move the irq tracing elsewhere but let's keep it simple for
+	 * now
+	 */
+#ifdef CONFIG_TRACE_IRQFLAGS
+	ld	r3,_DAR(r1)
+	ld	r4,_DSISR(r1)
+	ld	r5,_TRAP(r1)
+	ld	r12,_MSR(r1)
+	clrrdi	r5,r5,4
+#endif /* CONFIG_TRACE_IRQFLAGS */
+	/*
 	 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
 	 * accessing a userspace segment (even from the kernel). We assume
 	 * kernel addresses always have the high bit set.
@@ -832,13 +852,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 	rlwimi	r4,r5,22+2,31-2,31-2	/* Set _PAGE_EXEC if trap is 0x400 */
 
 	/*
-	 * On iSeries, we soft-disable interrupts here, then
-	 * hard-enable interrupts so that the hash_page code can spin on
-	 * the hash_table_lock without problems on a shared processor.
-	 */
-	DISABLE_INTS
-
-	/*
 	 * r3 contains the faulting address
 	 * r4 contains the required access permissions
 	 * r5 contains the trap number
@@ -848,7 +861,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 	bl	.hash_page		/* build HPTE if possible */
 	cmpdi	r3,0			/* see if hash_page succeeded */
 
-#ifdef DO_SOFT_DISABLE
 BEGIN_FW_FTR_SECTION
 	/*
 	 * If we had interrupts soft-enabled at the point where the
@@ -860,7 +872,7 @@ BEGIN_FW_FTR_SECTION
 	 */
 	beq	13f
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif
+
 BEGIN_FW_FTR_SECTION
 	/*
 	 * Here we have interrupts hard-disabled, so it is sufficient
@@ -874,11 +886,12 @@ 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
+	TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
+	bl	.raw_local_irq_restore
 	b	11f
 
 /* Here we have a page fault that hash_page can't handle. */
@@ -1477,6 +1490,10 @@ _INIT_STATIC(start_here_multiplatform)
 	addi	r2,r2,0x4000
 	add	r2,r2,r26
 
+	/* Set initial ptr to current */
+	LOAD_REG_IMMEDIATE(r4, init_task)
+	std	r4,PACACURRENT(r13)
+
 	/* Do very early kernel initializations, including initial hash table,
 	 * stab and slb setup before we turn on relocation.	*/
 
Index: linux-work/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/setup_64.c	2008-04-02 18:28:32.000000000 +1100
+++ linux-work/arch/powerpc/kernel/setup_64.c	2008-04-02 18:30:21.000000000 +1100
@@ -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>
@@ -178,6 +179,9 @@ void __init early_setup(unsigned long dt
 	/* Enable early debugging if any specified (see udbg.h) */
 	udbg_early_init();
 
+	/* Initialize lockdep early or else spinlocks will blow */
+	lockdep_init();
+
  	DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
 
 	/*
Index: linux-work/arch/powerpc/kernel/entry_64.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/entry_64.S	2008-04-02 18:11:56.000000000 +1100
+++ linux-work/arch/powerpc/kernel/entry_64.S	2008-04-02 18:30:21.000000000 +1100
@@ -29,6 +29,7 @@
 #include <asm/cputable.h>
 #include <asm/firmware.h>
 #include <asm/bug.h>
+#include <asm/irqflags.h>
 
 /*
  * System calls.
@@ -88,6 +89,14 @@ 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
+	ld	r12,_MSR(r1)
+#endif /* CONFIG_TRACE_IRQFLAGS */
 	li	r10,1
 	stb	r10,PACASOFTIRQEN(r13)
 	stb	r10,PACAHARDIRQEN(r13)
@@ -102,7 +111,7 @@ BEGIN_FW_FTR_SECTION
 	b	hardware_interrupt_entry
 2:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif
+#endif /* CONFIG_PPC_ISERIES */
 	mfmsr	r11
 	ori	r11,r11,MSR_EE
 	mtmsrd	r11,1
@@ -504,6 +513,10 @@ BEGIN_FW_FTR_SECTION
 
 	li	r3,0
 	stb	r3,PACASOFTIRQEN(r13)	/* ensure we are soft-disabled */
+#ifdef CONFIG_TRACE_IRQFLAGS
+	bl	.trace_hardirqs_off
+	mfmsr	r10
+#endif
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10			/* hard-enable again */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -512,7 +525,7 @@ BEGIN_FW_FTR_SECTION
 4:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
-	stb	r5,PACASOFTIRQEN(r13)
+	TRACE_AND_RESTORE_IRQ(r5);
 
 	/* extract EE bit and use it to restore paca->hard_enabled */
 	ld	r3,_MSR(r1)
@@ -580,6 +593,16 @@ do_work:
 	bne	restore
 	/* here we are preempting the current task */
 1:
+#ifdef CONFIG_TRACE_IRQFLAGS
+	bl	.trace_hardirqs_on
+	/* Note: we just clobbered r10 which used to contain the previous
+	 * MSR before the hard-disabling done by the caller of do_work.
+	 * We don't have that value anymore, but it doesn't matter as
+	 * we will hard-enable unconditionally, we can just reload the
+	 * current MSR into r10
+	 */
+	mfmsr	r10
+#endif /* CONFIG_TRACE_IRQFLAGS */
 	li	r0,1
 	stb	r0,PACASOFTIRQEN(r13)
 	stb	r0,PACAHARDIRQEN(r13)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/4] [POWERPC] lockdep support for ppc64
  2008-04-02  7:52 [PATCH 0/4] [POWERPC] lockdep support for ppc64 Benjamin Herrenschmidt
                   ` (3 preceding siblings ...)
  2008-04-02  7:52 ` [PATCH 4/4] [POWERPC] irqtrace support to 64-bit powerpc Benjamin Herrenschmidt
@ 2008-04-02  9:50 ` Johannes Berg
  2008-04-02 11:02   ` Benjamin Herrenschmidt
  4 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2008-04-02  9:50 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 230 bytes --]


> This serie of patches adds lockdep support for 64 bits
> powerpc. Dale's patch for 32 bits still need me to review
> and test it which I'll try to do asap.

Yay. I'll give it another try later today.

Thanks,
johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/4] [POWERPC] lockdep support for ppc64
  2008-04-02  9:50 ` [PATCH 0/4] [POWERPC] lockdep support for ppc64 Johannes Berg
@ 2008-04-02 11:02   ` Benjamin Herrenschmidt
  2008-04-02 13:20     ` Johannes Berg
  0 siblings, 1 reply; 10+ messages in thread
From: Benjamin Herrenschmidt @ 2008-04-02 11:02 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev


On Wed, 2008-04-02 at 11:50 +0200, Johannes Berg wrote:
> > This serie of patches adds lockdep support for 64 bits
> > powerpc. Dale's patch for 32 bits still need me to review
> > and test it which I'll try to do asap.
> 
> Yay. I'll give it another try later today.

Haven't tested this version on G5 yet btw :-) (though I had a previous
one working internally). I tested on POWER6 pSeries and old iSeries
(spent a while fixing the later).

I'll run more tests tomorrow hopefully and add a few patch fixing
some of the issues that lockdep already starting showing.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/4] [POWERPC] lockdep stacktrace support
  2008-04-02  7:52 ` [PATCH 2/4] [POWERPC] lockdep stacktrace support Benjamin Herrenschmidt
@ 2008-04-02 12:29   ` Stephen Rothwell
  0 siblings, 0 replies; 10+ messages in thread
From: Stephen Rothwell @ 2008-04-02 12:29 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1019 bytes --]

On Wed, 02 Apr 2008 18:52:10 +1100 Benjamin Herrenschmidt <benh@ozlabs.org> wrote:
>
> +++ linux-work/arch/powerpc/kernel/stacktrace.c	2008-04-02 16:46:07.000000000 +1100
> @@ -0,0 +1,52 @@
> +

Copyight and license statement needed.

> +#include <linux/sched.h>
> +#include <linux/stacktrace.h>

You should include <asm/ptrace.h> for STACK_FRAME_OVERHEAD and struct pt_regs.

> +#ifdef CONFIG_PPC64
> +#define MIN_STACK_FRAME 112     /* same as STACK_FRAME_OVERHEAD, in fact */

So use STACK_FRAME_OVERHEAD?

> +#define FRAME_LR_SAVE   2
> +#define INT_FRAME_SIZE  (sizeof(struct pt_regs) + STACK_FRAME_OVERHEAD + 288)
                                                     ^^^^^^^^^^^^^^^^^^^^
Its used here already ...

> +#define REGS_MARKER     0x7265677368657265ul

Maybe we need to put REGS_MARKER into a header file as it already appears
in two assembly files and two C files.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] [POWERPC] Initialize paca->current earlier
  2008-04-02  7:52 ` [PATCH 1/4] [POWERPC] Initialize paca->current earlier Benjamin Herrenschmidt
@ 2008-04-02 12:30   ` Stephen Rothwell
  0 siblings, 0 replies; 10+ messages in thread
From: Stephen Rothwell @ 2008-04-02 12:30 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 429 bytes --]

On Wed, 02 Apr 2008 18:52:09 +1100 Benjamin Herrenschmidt <benh@ozlabs.org> wrote:
>
> This changes it so that all PACAs are statically initialized with
> __current pointing to the init task. For non-0 CPUs, this is fixed
> up before use.

You might want to see how this impacts on Tony Breed's 1024 way patches.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/4] [POWERPC] lockdep support for ppc64
  2008-04-02 11:02   ` Benjamin Herrenschmidt
@ 2008-04-02 13:20     ` Johannes Berg
  0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2008-04-02 13:20 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 453 bytes --]


> Haven't tested this version on G5 yet btw :-) (though I had a previous
> one working internally). I tested on POWER6 pSeries and old iSeries
> (spent a while fixing the later).
> 
> I'll run more tests tomorrow hopefully and add a few patch fixing
> some of the issues that lockdep already starting showing.

Works fine, and on my box I don't see lockdep showing issues.

Thanks for picking this up from me and rewriting it :)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-04-02 13:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-02  7:52 [PATCH 0/4] [POWERPC] lockdep support for ppc64 Benjamin Herrenschmidt
2008-04-02  7:52 ` [PATCH 1/4] [POWERPC] Initialize paca->current earlier Benjamin Herrenschmidt
2008-04-02 12:30   ` Stephen Rothwell
2008-04-02  7:52 ` [PATCH 2/4] [POWERPC] lockdep stacktrace support Benjamin Herrenschmidt
2008-04-02 12:29   ` Stephen Rothwell
2008-04-02  7:52 ` [PATCH 3/4] [POWERPC] Fixup softirq preempt count Benjamin Herrenschmidt
2008-04-02  7:52 ` [PATCH 4/4] [POWERPC] irqtrace support to 64-bit powerpc Benjamin Herrenschmidt
2008-04-02  9:50 ` [PATCH 0/4] [POWERPC] lockdep support for ppc64 Johannes Berg
2008-04-02 11:02   ` Benjamin Herrenschmidt
2008-04-02 13:20     ` 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).