[RFC PATCH] Add TRACE_IRQFLAGS_SUPPORT, LOCKDEP_SUPPORT then enable ftrace for ia64
From: Luming Yu
Date: Thu Aug 27 2009 - 23:18:33 EST
Hi there,
The following rfc patch is to add lockdep support and IRQ-flags
state tracing support for ia64 architecture based on instructions
described in irqflags-tracing.
The next step is to fix issues. I plan to target it for -32 or -33.
Ps. Bob Picco had done similar things before.
Ps. The patch is enclosed in attachment. The inlined one
is c&p of it for reading.
Thanks,
Luming
Signed-off-by: Bob Picco <bob.picco@xxxxxx>
Signed-off-by: Yu Luming <luming.yu@xxxxxxxxx>
arch/ia64/Kconfig | 7 +++
arch/ia64/Kconfig.debug | 4 +
arch/ia64/include/asm/page.h | 2
arch/ia64/include/asm/rwsem.h | 3 +
arch/ia64/include/asm/system.h | 84 -------------------------------------
arch/ia64/kernel/Makefile | 1
arch/ia64/kernel/ivt.S | 5 ++
arch/ia64/kernel/smpboot.c | 2
arch/ia64/kernel/stacktrace.c | 23 ++++++++++
include/asm-ia64/irqflags.h | 92 +++++++++++++++++++++++++++++++++++++++++
include/asm-ia64/stacktrace.h | 7 +++
include/linux/lockdep.h | 2
lib/Kconfig.debug | 2
13 files changed, 147 insertions(+), 87 deletions(-)
diff -BruN linux-2.6.31-rc6/arch/ia64/include/asm/page.h
linux-2.6.31-rc6-lockdep/arch/ia64/include/asm/page.h
--- linux-2.6.31-rc6/arch/ia64/include/asm/page.h 2009-08-13
15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/include/asm/page.h 2009-08-23
18:59:00.000000000 -0700
@@ -41,7 +41,7 @@
#define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
-#define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */
+#define PERCPU_PAGE_SHIFT 20 /*16 log2() of max. size of per-CPU area */
#define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)
diff -BruN linux-2.6.31-rc6/arch/ia64/include/asm/rwsem.h
linux-2.6.31-rc6-lockdep/arch/ia64/include/asm/rwsem.h
--- linux-2.6.31-rc6/arch/ia64/include/asm/rwsem.h 2009-08-13
15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/include/asm/rwsem.h 2009-08-23
18:59:00.000000000 -0700
@@ -37,6 +37,9 @@
signed long count;
spinlock_t wait_lock;
struct list_head wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
};
#define RWSEM_UNLOCKED_VALUE __IA64_UL_CONST(0x0000000000000000)
diff -BruN linux-2.6.31-rc6/arch/ia64/include/asm/system.h
linux-2.6.31-rc6-lockdep/arch/ia64/include/asm/system.h
--- linux-2.6.31-rc6/arch/ia64/include/asm/system.h 2009-08-13
15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/include/asm/system.h 2009-08-23
18:59:00.000000000 -0700
@@ -107,88 +107,6 @@
*/
#define set_mb(var, value) do { (var) = (value); mb(); } while (0)
-#define safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */
-
-/*
- * The group barrier in front of the rsm & ssm are necessary to ensure
- * that none of the previous instructions in the same group are
- * affected by the rsm/ssm.
- */
-/* For spinlocks etc */
-
-/*
- * - clearing psr.i is implicitly serialized (visible by next insn)
- * - setting psr.i requires data serialization
- * - we need a stop-bit before reading PSR because we sometimes
- * write a floating-point register right before reading the PSR
- * and that writes to PSR.mfl
- */
-#ifdef CONFIG_PARAVIRT
-#define __local_save_flags() ia64_get_psr_i()
-#else
-#define __local_save_flags() ia64_getreg(_IA64_REG_PSR)
-#endif
-
-#define __local_irq_save(x) \
-do { \
- ia64_stop(); \
- (x) = __local_save_flags(); \
- ia64_stop(); \
- ia64_rsm(IA64_PSR_I); \
-} while (0)
-
-#define __local_irq_disable() \
-do { \
- ia64_stop(); \
- ia64_rsm(IA64_PSR_I); \
-} while (0)
-
-#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I)
-
-#ifdef CONFIG_IA64_DEBUG_IRQ
-
- extern unsigned long last_cli_ip;
-
-# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP)
-
-# define local_irq_save(x) \
-do { \
- unsigned long __psr; \
- \
- __local_irq_save(__psr); \
- if (__psr & IA64_PSR_I) \
- __save_ip(); \
- (x) = __psr; \
-} while (0)
-
-# define local_irq_disable() do { unsigned long __x;
local_irq_save(__x); } while (0)
-
-# define local_irq_restore(x) \
-do { \
- unsigned long __old_psr, __psr = (x); \
- \
- local_save_flags(__old_psr); \
- __local_irq_restore(__psr); \
- if ((__old_psr & IA64_PSR_I) && !(__psr & IA64_PSR_I)) \
- __save_ip(); \
-} while (0)
-
-#else /* !CONFIG_IA64_DEBUG_IRQ */
-# define local_irq_save(x) __local_irq_save(x)
-# define local_irq_disable() __local_irq_disable()
-# define local_irq_restore(x) __local_irq_restore(x)
-#endif /* !CONFIG_IA64_DEBUG_IRQ */
-
-#define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I);
ia64_srlz_d(); })
-#define local_save_flags(flags) ({ ia64_stop(); (flags) =
__local_save_flags(); })
-
-#define irqs_disabled() \
-({ \
- unsigned long __ia64_id_flags; \
- local_save_flags(__ia64_id_flags); \
- (__ia64_id_flags & IA64_PSR_I) == 0; \
-})
-
#ifdef __KERNEL__
#ifdef CONFIG_IA32_SUPPORT
@@ -274,7 +192,7 @@
#define __ARCH_WANT_UNLOCKED_CTXSW
#define ARCH_HAS_PREFETCH_SWITCH_STACK
#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
-
+#include <linux/irqflags.h>
void cpu_idle_wait(void);
#define arch_align_stack(x) (x)
diff -BruN linux-2.6.31-rc6/arch/ia64/Kconfig
linux-2.6.31-rc6-lockdep/arch/ia64/Kconfig
--- linux-2.6.31-rc6/arch/ia64/Kconfig 2009-08-13 15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/Kconfig 2009-08-23
18:59:00.000000000 -0700
@@ -143,6 +143,13 @@
endif
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
+config STACKTRACE_SUPPORT
+ bool
+ default y
choice
prompt "System type"
default IA64_GENERIC
diff -BruN linux-2.6.31-rc6/arch/ia64/Kconfig.debug
linux-2.6.31-rc6-lockdep/arch/ia64/Kconfig.debug
--- linux-2.6.31-rc6/arch/ia64/Kconfig.debug 2009-08-13 15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/Kconfig.debug 2009-08-23
18:58:59.000000000 -0700
@@ -2,6 +2,10 @@
source "lib/Kconfig.debug"
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ default y
+
choice
prompt "Physical memory granularity"
default IA64_GRANULE_64MB
diff -BruN linux-2.6.31-rc6/arch/ia64/kernel/ivt.S
linux-2.6.31-rc6-lockdep/arch/ia64/kernel/ivt.S
--- linux-2.6.31-rc6/arch/ia64/kernel/ivt.S 2009-08-13 15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/kernel/ivt.S 2009-08-23
18:58:59.000000000 -0700
@@ -1603,6 +1603,11 @@
SAVE_REST
;;
MCA_RECOVER_RANGE(interrupt)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ ;;
+ br.call.sptk.many rp=trace_hardirqs_off
+ ;;
+#endif
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg
add out1=16,sp // pass pointer to pt_regs as second arg
diff -BruN linux-2.6.31-rc6/arch/ia64/kernel/Makefile
linux-2.6.31-rc6-lockdep/arch/ia64/kernel/Makefile
--- linux-2.6.31-rc6/arch/ia64/kernel/Makefile 2009-08-13
15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/kernel/Makefile 2009-08-23
18:58:59.000000000 -0700
@@ -40,6 +40,7 @@
obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o \
paravirt_patch.o
diff -BruN linux-2.6.31-rc6/arch/ia64/kernel/smpboot.c
linux-2.6.31-rc6-lockdep/arch/ia64/kernel/smpboot.c
--- linux-2.6.31-rc6/arch/ia64/kernel/smpboot.c 2009-08-13
15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/arch/ia64/kernel/smpboot.c 2009-08-23
18:58:59.000000000 -0700
@@ -504,7 +504,7 @@
struct create_idle c_idle = {
.work = __WORK_INITIALIZER(c_idle.work, do_fork_idle),
.cpu = cpu,
- .done = COMPLETION_INITIALIZER(c_idle.done),
+ .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
};
c_idle.idle = get_idle_for_cpu(cpu);
diff -BruN linux-2.6.31-rc6/arch/ia64/kernel/stacktrace.c
linux-2.6.31-rc6-lockdep/arch/ia64/kernel/stacktrace.c
--- linux-2.6.31-rc6/arch/ia64/kernel/stacktrace.c 1969-12-31
16:00:00.000000000 -0800
+++ linux-2.6.31-rc6-lockdep/arch/ia64/kernel/stacktrace.c 2009-08-23
18:58:59.000000000 -0700
@@ -0,0 +1,23 @@
+/*
+ * arch/x86_64/kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@xxxxxxxxxx>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/module.h>
+#include <asm/stacktrace.h>
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+}
+EXPORT_SYMBOL(save_stack_trace);
+void __ia64_save_stack_nonlocal(struct stack_trace *trace)
+{
+}
+EXPORT_SYMBOL(__ia64_save_stack_nonlocal);
diff -BruN linux-2.6.31-rc6/include/asm-ia64/irqflags.h
linux-2.6.31-rc6-lockdep/include/asm-ia64/irqflags.h
--- linux-2.6.31-rc6/include/asm-ia64/irqflags.h 1969-12-31
16:00:00.000000000 -0800
+++ linux-2.6.31-rc6-lockdep/include/asm-ia64/irqflags.h 2009-08-23
18:59:14.000000000 -0700
@@ -0,0 +1,92 @@
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+#include <asm/kregs.h>
+#include <asm/pal.h>
+/*
+ * The group barrier in front of the rsm & ssm are necessary to ensure
+ * that none of the previous instructions in the same group are
+ * affected by the rsm/ssm.
+ */
+/* For spinlocks etc */
+
+/*
+ * - clearing psr.i is implicitly serialized (visible by next insn)
+ * - setting psr.i requires data serialization
+ * - we need a stop-bit before reading PSR because we sometimes
+ * write a floating-point register right before reading the PSR
+ * and that writes to PSR.mfl
+ */
+#define __local_irq_save(x) \
+do { \
+ ia64_stop(); \
+ (x) = ia64_getreg(_IA64_REG_PSR); \
+ ia64_stop(); \
+ ia64_rsm(IA64_PSR_I); \
+} while (0)
+
+#define __local_irq_disable() \
+do { \
+ ia64_stop(); \
+ ia64_rsm(IA64_PSR_I); \
+} while (0)
+
+#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I)
+
+#ifdef CONFIG_IA64_DEBUG_IRQ
+
+ extern unsigned long last_cli_ip;
+
+# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP)
+
+# define raw_local_irq_save(x) \
+do { \
+ unsigned long psr; \
+ \
+ __local_irq_save(psr); \
+ if (psr & IA64_PSR_I) \
+ __save_ip(); \
+ (x) = psr; \
+} while (0)
+
+# define raw_local_irq_disable() do { unsigned long x;
raw_local_irq_save(x); } while (0)
+
+# define raw_local_irq_restore(x) \
+do { \
+ unsigned long old_psr, psr = (x); \
+ \
+ local_save_flags(old_psr); \
+ __local_irq_restore(psr); \
+ if ((old_psr & IA64_PSR_I) && !(psr & IA64_PSR_I)) \
+ __save_ip(); \
+} while (0)
+
+#else /* !CONFIG_IA64_DEBUG_IRQ */
+# define raw_local_irq_save(x) __local_irq_save(x)
+# define raw_local_irq_disable() __local_irq_disable()
+# define raw_local_irq_restore(x) __local_irq_restore(x)
+#endif /* !CONFIG_IA64_DEBUG_IRQ */
+
+#define raw_local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I);
ia64_srlz_d(); })
+#define raw_local_save_flags(flags) ({ ia64_stop(); (flags) =
ia64_getreg(_IA64_REG_PSR); })
+
+#define raw_irqs_disabled() \
+({ \
+ unsigned long __ia64_id_flags; \
+ raw_local_save_flags(__ia64_id_flags); \
+ (__ia64_id_flags & IA64_PSR_I) == 0; \
+})
+
+#define raw_safe_halt() ia64_pal_halt_light() /* PAL_HALT_LIGHT */
+#define raw_irqs_disabled_flags(flags) \
+({ \
+ (int)((flags) & IA64_PSR_I) == 0; \
+})
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+#define TRACE_IRQS_ON br.call.sptk.many b0=trace_hardirqs_on
+#define TRACE_IRQS_OFF br.call.sptk.many b0=trace_hardirqs_off
+#else
+#define TRACE_IRQS_ON
+#define TRACE_IRQS_OFF
+#endif
+#endif
diff -BruN linux-2.6.31-rc6/include/asm-ia64/stacktrace.h
linux-2.6.31-rc6-lockdep/include/asm-ia64/stacktrace.h
--- linux-2.6.31-rc6/include/asm-ia64/stacktrace.h 1969-12-31
16:00:00.000000000 -0800
+++ linux-2.6.31-rc6-lockdep/include/asm-ia64/stacktrace.h 2009-08-23
18:59:14.000000000 -0700
@@ -0,0 +1,7 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H 1
+
+/* Generic stack tracer with callbacks */
+
+
+#endif
diff -BruN linux-2.6.31-rc6/include/linux/lockdep.h
linux-2.6.31-rc6-lockdep/include/linux/lockdep.h
--- linux-2.6.31-rc6/include/linux/lockdep.h 2009-08-13 15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/include/linux/lockdep.h 2009-08-23
18:59:20.000000000 -0700
@@ -162,7 +162,7 @@
u64 chain_key;
};
-#define MAX_LOCKDEP_KEYS_BITS 13
+#define MAX_LOCKDEP_KEYS_BITS 10
/*
* Subtract one because we offset hlock->class_idx by 1 in order
* to make 0 mean no class. This avoids overflowing the class_idx
diff -BruN linux-2.6.31-rc6/lib/Kconfig.debug
linux-2.6.31-rc6-lockdep/lib/Kconfig.debug
--- linux-2.6.31-rc6/lib/Kconfig.debug 2009-08-13 15:43:34.000000000 -0700
+++ linux-2.6.31-rc6-lockdep/lib/Kconfig.debug 2009-08-23
18:59:06.000000000 -0700
@@ -504,7 +504,7 @@
config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
- depends on DEBUG_KERNEL && LOCKDEP
+ depends on DEBUG_KERNEL && LOCKDEP && !IA64
help
If you say Y here, the lock dependency engine will do
additional runtime checks to debug itself, at the price
Attachment:
ia64-lockdep-linux-2.6.31-rc6.patch
Description: Binary data