Hi,
These patches improve the design of preemptirq tracepoints, clean up
several of the ifdeffery and overall makes the feature configuration
cleaner and less confusing. It also uses the tracepoints infra for
the lockdep hooks for irqs on/off thus making a central point for all
users of the event (kernel/trace/trace_preemptirq.c).
Patches based on v4.16-rc5.
Changes since RFC [1]:
- handle case where lockdep warnings occur in tracepoint code (2/2)
- protect tracepoint probe registration in lockdep init by ifdef.
Joel Fernandes (2):
tracing: Improve design of preemptirq tracepoints and its users
tracepoint: Prevent false-positive lockdep warnings
include/linux/ftrace.h | 11 +-
include/linux/irqflags.h | 11 +-
include/linux/lockdep.h | 6 +-
include/linux/preempt.h | 2 +-
include/linux/tracepoint.h | 23 +++-
include/trace/events/preemptirq.h | 23 ++--
init/main.c | 2 +-
kernel/locking/lockdep.c | 31 ++---
kernel/sched/core.c | 2 +-
kernel/trace/Kconfig | 19 ++-
kernel/trace/Makefile | 2 +-
kernel/trace/trace_irqsoff.c | 206 +++++++-----------------------
kernel/trace/trace_preemptirq.c | 70 ++++++++++
13 files changed, 191 insertions(+), 217 deletions(-)
create mode 100644 kernel/trace/trace_preemptirq.c
[1] https://patchwork.kernel.org/patch/10202163/
Cc: Steven Rostedt <[email protected]>
Cc: Peter Zilstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Mathieu Desnoyers <[email protected]>
Cc: Tom Zanussi <[email protected]>
Cc: Namhyung Kim <[email protected]>
Signed-off-by: Joel Fernandes <[email protected]>
--
2.16.2.660.g709887971b-goog
Since the last patch, lockdep hooks for irqs on/off will use the
tracepoint infrastructure. This can however cause false lockdep
warnings triggered by RCU code that does lockdep asserts.
There are 2 cases:
1) trace_hardirqs_off calls the lockdep_hardirqs_off hook, however
this call happens only after rcu_irq_enter_irqsoff. Due to this,
the lockdep assert that happens in the RCU path will think that
IRQs are kept on and will print a warning.
[ 0.001000] ------------[ cut here ]------------
[ 0.001000] IRQs not disabled as expected
[ 0.001000] WARNING: CPU: 0 PID: 0 at kernel/rcu/tree.c:1039
rcu_irq_enter+0x56/0x5d
[ 0.001000] Call Trace:
[ 0.001000] rcu_irq_enter_irqson+0x21/0x47
[ 0.001000] trace_hardirqs_off+0x53/0xcc
[ 0.001000] __down_trylock_console_sem+0x27/0x9d
[ 0.001000] console_trylock+0x10/0x50
[ 0.001000] vprintk_emit+0x2a8/0x400
[ 0.001000] printk+0x43/0x4b
[ 0.001000] lockdep_init+0x38/0xe3
[ 0.001000] start_kernel+0x326/0x446
[ 0.001000] secondary_startup_64+0xa5/0xb0
2) trace_hardirqs_on calls the lockdep_hardirqs_on hook, however
interrupts are enabled only after trace_hardirqs_on. In the meanwhile
lockdep falsely sets its state to hardirqs are enabled. For this reason,
rcu_irq_enter_irqson prints the following false warning claiming IRQs
are not disabled:
[ 0.001000] ------------[ cut here ]------------
[ 0.001000] IRQs not disabled as expected
[ 0.001000] WARNING: CPU: 0 PID: 0 at kernel/rcu/tree.c:886
rcu_irq_exit+0x56/0x5d
[ 0.001000] Call Trace:
[ 0.001000] rcu_irq_exit_irqson+0x21/0x47
[ 0.001000] trace_hardirqs_on+0xb9/0xd7
[ 0.001000] vprintk_emit+0x287/0x400
[ 0.001000] printk+0x43/0x4b
[ 0.001000] lockdep_init+0x38/0xe3
[ 0.001000] start_kernel+0x326/0x446
[ 0.001000] secondary_startup_64+0xa5/0xb0
To fix it, just disable lockdep checks before and enable it after
rcu_irq_exit_irqson.
Cc: Steven Rostedt <[email protected]>
Cc: Peter Zilstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Mathieu Desnoyers <[email protected]>
Cc: Tom Zanussi <[email protected]>
Cc: Namhyung Kim <[email protected]>
Signed-off-by: Joel Fernandes <[email protected]>
---
include/linux/tracepoint.h | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index c94f466d57ef..81eac3562787 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -137,8 +137,17 @@ extern void syscall_unregfunc(void);
\
if (!(cond)) \
return; \
- if (rcucheck) \
+ \
+ /* \
+ * lockdep hook for irqsoff may run only after \
+ * rcu_irq_enter_irqson so in the meanwhile don't do \
+ * lockdep checks to prevent false lockdep warnings \
+ */ \
+ if (rcucheck) { \
+ lockdep_off(); \
rcu_irq_enter_irqson(); \
+ lockdep_on(); \
+ } \
rcu_read_lock_sched_notrace(); \
it_func_ptr = rcu_dereference_sched((tp)->funcs); \
if (it_func_ptr) { \
@@ -149,8 +158,18 @@ extern void syscall_unregfunc(void);
} while ((++it_func_ptr)->func); \
} \
rcu_read_unlock_sched_notrace(); \
- if (rcucheck) \
+ \
+ /* \
+ * Turn off lockdep before calling rcu_irq_exit_irqson \
+ * since the lockdep irqson hook may have just run \
+ * but irqs are only after trace_hardirqs_off returns. \
+ * This can cause false lockdep warnings. \
+ */ \
+ if (rcucheck) { \
+ lockdep_off(); \
rcu_irq_exit_irqson(); \
+ lockdep_on(); \
+ } \
} while (0)
#ifndef MODULE
--
2.16.2.660.g709887971b-goog
This patch detaches the preemptirq tracepoints from the tracers and
keeps it separate. With this, several ifdefs are cleaner, and lockdep
and other users can use the preemptirq tracepoints by registering probes
onto them. This makes it much cleaner by getting rid of all the horrific
ifdeferry around PROVE_LOCKING. It also makes configuration of the
different users of the tracepoints more easy and understandable.
In the patch we introduce a new CONFIG option PREEMPTIRQ_TRACEPOINTS
as a single point for registering probes onto the tracepoints. With this,
the web of config options for preempt/irq toggle tracepoints and its
users becomes:
PREEMPT_TRACER PREEMPTIRQ_EVENTS IRQSOFF_TRACER PROVE_LOCKING
| | \ | |
\ (selects) / \ \ (selects) /
TRACE_PREEMPT_TOGGLE ----> TRACE_IRQFLAGS
\ /
\ (depends on) /
PREEMPTIRQ_TRACEPOINTS
Three user's of the tracepoints exist after this: lockdep, the
preemptirq tracers and preemptirq trace events. I did sanity testing on
all of these to see expected results.
Cc: Steven Rostedt <[email protected]>
Cc: Peter Zilstra <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Mathieu Desnoyers <[email protected]>
Cc: Tom Zanussi <[email protected]>
Cc: Namhyung Kim <[email protected]>
Signed-off-by: Joel Fernandes <[email protected]>
---
include/linux/ftrace.h | 11 +-
include/linux/irqflags.h | 11 +-
include/linux/lockdep.h | 6 +-
include/linux/preempt.h | 2 +-
include/trace/events/preemptirq.h | 23 ++--
init/main.c | 2 +-
kernel/locking/lockdep.c | 31 ++---
kernel/sched/core.c | 2 +-
kernel/trace/Kconfig | 19 ++-
kernel/trace/Makefile | 2 +-
kernel/trace/trace_irqsoff.c | 206 +++++++-----------------------
kernel/trace/trace_preemptirq.c | 70 ++++++++++
12 files changed, 170 insertions(+), 215 deletions(-)
create mode 100644 kernel/trace/trace_preemptirq.c
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 9c3c9a319e48..5191030af0c0 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -709,16 +709,7 @@ static inline unsigned long get_lock_parent_ip(void)
return CALLER_ADDR2;
}
-#ifdef CONFIG_IRQSOFF_TRACER
- extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
- extern void time_hardirqs_off(unsigned long a0, unsigned long a1);
-#else
- static inline void time_hardirqs_on(unsigned long a0, unsigned long a1) { }
- static inline void time_hardirqs_off(unsigned long a0, unsigned long a1) { }
-#endif
-
-#if defined(CONFIG_PREEMPT_TRACER) || \
- (defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_PREEMPTIRQ_EVENTS))
+#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
extern void trace_preempt_on(unsigned long a0, unsigned long a1);
extern void trace_preempt_off(unsigned long a0, unsigned long a1);
#else
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 9700f00bbc04..50edb9cbbd26 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -15,9 +15,16 @@
#include <linux/typecheck.h>
#include <asm/irqflags.h>
-#ifdef CONFIG_TRACE_IRQFLAGS
+/* Currently trace_softirqs_on/off is used only by lockdep */
+#ifdef CONFIG_PROVE_LOCKING
extern void trace_softirqs_on(unsigned long ip);
extern void trace_softirqs_off(unsigned long ip);
+#else
+# define trace_softirqs_on(ip) do { } while (0)
+# define trace_softirqs_off(ip) do { } while (0)
+#endif
+
+#ifdef CONFIG_TRACE_IRQFLAGS
extern void trace_hardirqs_on(void);
extern void trace_hardirqs_off(void);
# define trace_hardirq_context(p) ((p)->hardirq_context)
@@ -43,8 +50,6 @@ do { \
#else
# define trace_hardirqs_on() do { } while (0)
# define trace_hardirqs_off() do { } while (0)
-# define trace_softirqs_on(ip) do { } while (0)
-# define trace_softirqs_off(ip) do { } while (0)
# define trace_hardirq_context(p) 0
# define trace_softirq_context(p) 0
# define trace_hardirqs_enabled(p) 0
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 6fc77d4dbdcd..b0d0b51c4d85 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -266,7 +266,7 @@ struct held_lock {
/*
* Initialization, self-test and debugging-output methods:
*/
-extern void lockdep_info(void);
+extern void lockdep_init(void);
extern void lockdep_reset(void);
extern void lockdep_reset_lock(struct lockdep_map *lock);
extern void lockdep_free_key_range(void *start, unsigned long size);
@@ -406,7 +406,7 @@ static inline void lockdep_on(void)
# define lock_downgrade(l, i) do { } while (0)
# define lock_set_class(l, n, k, s, i) do { } while (0)
# define lock_set_subclass(l, s, i) do { } while (0)
-# define lockdep_info() do { } while (0)
+# define lockdep_init() do { } while (0)
# define lockdep_init_map(lock, name, key, sub) \
do { (void)(name); (void)(key); } while (0)
# define lockdep_set_class(lock, key) do { (void)(key); } while (0)
@@ -532,7 +532,7 @@ do { \
#endif /* CONFIG_LOCKDEP */
-#ifdef CONFIG_TRACE_IRQFLAGS
+#ifdef CONFIG_PROVE_LOCKING
extern void print_irqtrace_events(struct task_struct *curr);
#else
static inline void print_irqtrace_events(struct task_struct *curr)
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 5bd3f151da78..c01813c3fbe9 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -150,7 +150,7 @@
*/
#define in_atomic_preempt_off() (preempt_count() != PREEMPT_DISABLE_OFFSET)
-#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_PREEMPT_TRACER)
+#if defined(CONFIG_DEBUG_PREEMPT) || defined(CONFIG_TRACE_PREEMPT_TOGGLE)
extern void preempt_count_add(int val);
extern void preempt_count_sub(int val);
#define preempt_count_dec_and_test() \
diff --git a/include/trace/events/preemptirq.h b/include/trace/events/preemptirq.h
index 9c4eb33c5a1d..9a0d4ceeb166 100644
--- a/include/trace/events/preemptirq.h
+++ b/include/trace/events/preemptirq.h
@@ -1,4 +1,4 @@
-#ifdef CONFIG_PREEMPTIRQ_EVENTS
+#ifdef CONFIG_PREEMPTIRQ_TRACEPOINTS
#undef TRACE_SYSTEM
#define TRACE_SYSTEM preemptirq
@@ -32,7 +32,7 @@ DECLARE_EVENT_CLASS(preemptirq_template,
(void *)((unsigned long)(_stext) + __entry->parent_offs))
);
-#ifndef CONFIG_PROVE_LOCKING
+#ifdef CONFIG_TRACE_IRQFLAGS
DEFINE_EVENT(preemptirq_template, irq_disable,
TP_PROTO(unsigned long ip, unsigned long parent_ip),
TP_ARGS(ip, parent_ip));
@@ -40,9 +40,14 @@ DEFINE_EVENT(preemptirq_template, irq_disable,
DEFINE_EVENT(preemptirq_template, irq_enable,
TP_PROTO(unsigned long ip, unsigned long parent_ip),
TP_ARGS(ip, parent_ip));
+#else
+#define trace_irq_enable(...)
+#define trace_irq_disable(...)
+#define trace_irq_enable_rcuidle(...)
+#define trace_irq_disable_rcuidle(...)
#endif
-#ifdef CONFIG_DEBUG_PREEMPT
+#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
DEFINE_EVENT(preemptirq_template, preempt_disable,
TP_PROTO(unsigned long ip, unsigned long parent_ip),
TP_ARGS(ip, parent_ip));
@@ -50,22 +55,22 @@ DEFINE_EVENT(preemptirq_template, preempt_disable,
DEFINE_EVENT(preemptirq_template, preempt_enable,
TP_PROTO(unsigned long ip, unsigned long parent_ip),
TP_ARGS(ip, parent_ip));
+#else
+#define trace_preempt_enable(...)
+#define trace_preempt_disable(...)
+#define trace_preempt_enable_rcuidle(...)
+#define trace_preempt_disable_rcuidle(...)
#endif
#endif /* _TRACE_PREEMPTIRQ_H */
#include <trace/define_trace.h>
-#endif /* !CONFIG_PREEMPTIRQ_EVENTS */
-
-#if !defined(CONFIG_PREEMPTIRQ_EVENTS) || defined(CONFIG_PROVE_LOCKING)
+#else /* !CONFIG_PREEMPTIRQ_TRACEPOINTS */
#define trace_irq_enable(...)
#define trace_irq_disable(...)
#define trace_irq_enable_rcuidle(...)
#define trace_irq_disable_rcuidle(...)
-#endif
-
-#if !defined(CONFIG_PREEMPTIRQ_EVENTS) || !defined(CONFIG_DEBUG_PREEMPT)
#define trace_preempt_enable(...)
#define trace_preempt_disable(...)
#define trace_preempt_enable_rcuidle(...)
diff --git a/init/main.c b/init/main.c
index 969eaf140ef0..5991de14c196 100644
--- a/init/main.c
+++ b/init/main.c
@@ -644,7 +644,7 @@ asmlinkage __visible void __init start_kernel(void)
panic("Too many boot %s vars at `%s'", panic_later,
panic_param);
- lockdep_info();
+ lockdep_init();
/*
* Need to run this when irqs are enabled, because it wants
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 89b5f83f1969..b62b0b54404e 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -55,6 +55,7 @@
#include "lockdep_internals.h"
+#include <trace/events/preemptirq.h>
#define CREATE_TRACE_POINTS
#include <trace/events/lock.h>
@@ -2841,10 +2842,9 @@ static void __trace_hardirqs_on_caller(unsigned long ip)
debug_atomic_inc(hardirqs_on_events);
}
-__visible void trace_hardirqs_on_caller(unsigned long ip)
+static void lockdep_hardirqs_on(void *none, unsigned long ignore,
+ unsigned long ip)
{
- time_hardirqs_on(CALLER_ADDR0, ip);
-
if (unlikely(!debug_locks || current->lockdep_recursion))
return;
@@ -2883,23 +2883,15 @@ __visible void trace_hardirqs_on_caller(unsigned long ip)
__trace_hardirqs_on_caller(ip);
current->lockdep_recursion = 0;
}
-EXPORT_SYMBOL(trace_hardirqs_on_caller);
-
-void trace_hardirqs_on(void)
-{
- trace_hardirqs_on_caller(CALLER_ADDR0);
-}
-EXPORT_SYMBOL(trace_hardirqs_on);
/*
* Hardirqs were disabled:
*/
-__visible void trace_hardirqs_off_caller(unsigned long ip)
+static void lockdep_hardirqs_off(void *none, unsigned long ignore,
+ unsigned long ip)
{
struct task_struct *curr = current;
- time_hardirqs_off(CALLER_ADDR0, ip);
-
if (unlikely(!debug_locks || current->lockdep_recursion))
return;
@@ -2921,13 +2913,6 @@ __visible void trace_hardirqs_off_caller(unsigned long ip)
} else
debug_atomic_inc(redundant_hardirqs_off);
}
-EXPORT_SYMBOL(trace_hardirqs_off_caller);
-
-void trace_hardirqs_off(void)
-{
- trace_hardirqs_off_caller(CALLER_ADDR0);
-}
-EXPORT_SYMBOL(trace_hardirqs_off);
/*
* Softirqs will be enabled:
@@ -4334,8 +4319,12 @@ void lockdep_reset_lock(struct lockdep_map *lock)
raw_local_irq_restore(flags);
}
-void __init lockdep_info(void)
+void __init lockdep_init(void)
{
+#ifdef CONFIG_PROVE_LOCKING
+ register_trace_irq_disable(lockdep_hardirqs_off, NULL);
+ register_trace_irq_enable(lockdep_hardirqs_on, NULL);
+#endif
printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
printk("... MAX_LOCKDEP_SUBCLASSES: %lu\n", MAX_LOCKDEP_SUBCLASSES);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e7c535eee0a6..32e8b8534ecc 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3128,7 +3128,7 @@ u64 scheduler_tick_max_deferment(void)
#endif
#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
- defined(CONFIG_PREEMPT_TRACER))
+ defined(CONFIG_TRACE_PREEMPT_TOGGLE))
/*
* If the value passed in is equal to the current preempt count
* then we just disabled preemption. Start timing the latency.
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 0b249e2f0c3c..348d775b63eb 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -159,18 +159,28 @@ config FUNCTION_GRAPH_TRACER
the return value. This is done by setting the current return
address on the current task structure into a stack of calls.
+config TRACE_PREEMPT_TOGGLE
+ bool
+ help
+ Enables hooks which will be called when preemption is first disabled,
+ and last enabled.
+
+config PREEMPTIRQ_TRACEPOINTS
+ bool
+ depends on TRACE_PREEMPT_TOGGLE || TRACE_IRQFLAGS
+ default y
+ help
+ Create preempt/irq toggle tracepoints if needed, so that other parts
+ of the kernel can use them to generate or add hooks to them.
config PREEMPTIRQ_EVENTS
bool "Enable trace events for preempt and irq disable/enable"
select TRACE_IRQFLAGS
- depends on DEBUG_PREEMPT || !PROVE_LOCKING
+ select TRACE_PREEMPT_TOGGLE if PREEMPT
depends on TRACING
default n
help
Enable tracing of disable and enable events for preemption and irqs.
- For tracing preempt disable/enable events, DEBUG_PREEMPT must be
- enabled. For tracing irq disable/enable events, PROVE_LOCKING must
- be disabled.
config IRQSOFF_TRACER
bool "Interrupts-off Latency Tracer"
@@ -207,6 +217,7 @@ config PREEMPT_TRACER
select RING_BUFFER_ALLOW_SWAP
select TRACER_SNAPSHOT
select TRACER_SNAPSHOT_PER_CPU_SWAP
+ select TRACE_PREEMPT_TOGGLE
help
This option measures the time spent in preemption-off critical
sections, with microsecond accuracy.
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index e2538c7638d4..84a0cb222f20 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_TRACING) += trace_printk.o
obj-$(CONFIG_TRACING_MAP) += tracing_map.o
obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
-obj-$(CONFIG_PREEMPTIRQ_EVENTS) += trace_irqsoff.o
+obj-$(CONFIG_PREEMPTIRQ_TRACEPOINTS) += trace_preemptirq.o
obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 03ecb4465ee4..e3cec13dd935 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -16,7 +16,6 @@
#include "trace.h"
-#define CREATE_TRACE_POINTS
#include <trace/events/preemptirq.h>
#if defined(CONFIG_IRQSOFF_TRACER) || defined(CONFIG_PREEMPT_TRACER)
@@ -450,66 +449,6 @@ void stop_critical_timings(void)
}
EXPORT_SYMBOL_GPL(stop_critical_timings);
-#ifdef CONFIG_IRQSOFF_TRACER
-#ifdef CONFIG_PROVE_LOCKING
-void time_hardirqs_on(unsigned long a0, unsigned long a1)
-{
- if (!preempt_trace() && irq_trace())
- stop_critical_timing(a0, a1);
-}
-
-void time_hardirqs_off(unsigned long a0, unsigned long a1)
-{
- if (!preempt_trace() && irq_trace())
- start_critical_timing(a0, a1);
-}
-
-#else /* !CONFIG_PROVE_LOCKING */
-
-/*
- * We are only interested in hardirq on/off events:
- */
-static inline void tracer_hardirqs_on(void)
-{
- if (!preempt_trace() && irq_trace())
- stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
-}
-
-static inline void tracer_hardirqs_off(void)
-{
- if (!preempt_trace() && irq_trace())
- start_critical_timing(CALLER_ADDR0, CALLER_ADDR1);
-}
-
-static inline void tracer_hardirqs_on_caller(unsigned long caller_addr)
-{
- if (!preempt_trace() && irq_trace())
- stop_critical_timing(CALLER_ADDR0, caller_addr);
-}
-
-static inline void tracer_hardirqs_off_caller(unsigned long caller_addr)
-{
- if (!preempt_trace() && irq_trace())
- start_critical_timing(CALLER_ADDR0, caller_addr);
-}
-
-#endif /* CONFIG_PROVE_LOCKING */
-#endif /* CONFIG_IRQSOFF_TRACER */
-
-#ifdef CONFIG_PREEMPT_TRACER
-static inline void tracer_preempt_on(unsigned long a0, unsigned long a1)
-{
- if (preempt_trace() && !irq_trace())
- stop_critical_timing(a0, a1);
-}
-
-static inline void tracer_preempt_off(unsigned long a0, unsigned long a1)
-{
- if (preempt_trace() && !irq_trace())
- start_critical_timing(a0, a1);
-}
-#endif /* CONFIG_PREEMPT_TRACER */
-
#ifdef CONFIG_FUNCTION_TRACER
static bool function_enabled;
@@ -659,10 +598,28 @@ static void irqsoff_tracer_stop(struct trace_array *tr)
}
#ifdef CONFIG_IRQSOFF_TRACER
+/*
+ * We are only interested in hardirq on/off events:
+ */
+static void tracer_hardirqs_on(void *none, unsigned long a0, unsigned long a1)
+{
+ if (!preempt_trace() && irq_trace())
+ stop_critical_timing(a0, a1);
+}
+
+static void tracer_hardirqs_off(void *none, unsigned long a0, unsigned long a1)
+{
+ if (!preempt_trace() && irq_trace())
+ start_critical_timing(a0, a1);
+}
+
static int irqsoff_tracer_init(struct trace_array *tr)
{
trace_type = TRACER_IRQS_OFF;
+ register_trace_irq_disable(tracer_hardirqs_off, NULL);
+ register_trace_irq_enable(tracer_hardirqs_on, NULL);
+
return __irqsoff_tracer_init(tr);
}
static struct tracer irqsoff_tracer __read_mostly =
@@ -686,14 +643,31 @@ static struct tracer irqsoff_tracer __read_mostly =
};
# define register_irqsoff(trace) register_tracer(&trace)
#else
+static inline void tracer_hardirqs_on(unsigned long a0, unsigned long a1) { }
+static inline void tracer_hardirqs_off(unsigned long a0, unsigned long a1) { }
# define register_irqsoff(trace) do { } while (0)
-#endif
+#endif /* CONFIG_IRQSOFF_TRACER */
#ifdef CONFIG_PREEMPT_TRACER
+static void tracer_preempt_on(void *none, unsigned long a0, unsigned long a1)
+{
+ if (preempt_trace() && !irq_trace())
+ stop_critical_timing(a0, a1);
+}
+
+static void tracer_preempt_off(void *none, unsigned long a0, unsigned long a1)
+{
+ if (preempt_trace() && !irq_trace())
+ start_critical_timing(a0, a1);
+}
+
static int preemptoff_tracer_init(struct trace_array *tr)
{
trace_type = TRACER_PREEMPT_OFF;
+ register_trace_preempt_disable(tracer_preempt_off, NULL);
+ register_trace_preempt_enable(tracer_preempt_on, NULL);
+
return __irqsoff_tracer_init(tr);
}
@@ -718,16 +692,22 @@ static struct tracer preemptoff_tracer __read_mostly =
};
# define register_preemptoff(trace) register_tracer(&trace)
#else
+static inline void tracer_preempt_on(unsigned long a0, unsigned long a1) { }
+static inline void tracer_preempt_off(unsigned long a0, unsigned long a1) { }
# define register_preemptoff(trace) do { } while (0)
-#endif
+#endif /* CONFIG_PREEMPT_TRACER */
-#if defined(CONFIG_IRQSOFF_TRACER) && \
- defined(CONFIG_PREEMPT_TRACER)
+#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
static int preemptirqsoff_tracer_init(struct trace_array *tr)
{
trace_type = TRACER_IRQS_OFF | TRACER_PREEMPT_OFF;
+ register_trace_irq_disable(tracer_hardirqs_off, NULL);
+ register_trace_irq_enable(tracer_hardirqs_on, NULL);
+ register_trace_preempt_disable(tracer_preempt_off, NULL);
+ register_trace_preempt_enable(tracer_preempt_on, NULL);
+
return __irqsoff_tracer_init(tr);
}
@@ -766,99 +746,3 @@ __init static int init_irqsoff_tracer(void)
}
core_initcall(init_irqsoff_tracer);
#endif /* IRQSOFF_TRACER || PREEMPTOFF_TRACER */
-
-#ifndef CONFIG_IRQSOFF_TRACER
-static inline void tracer_hardirqs_on(void) { }
-static inline void tracer_hardirqs_off(void) { }
-static inline void tracer_hardirqs_on_caller(unsigned long caller_addr) { }
-static inline void tracer_hardirqs_off_caller(unsigned long caller_addr) { }
-#endif
-
-#ifndef CONFIG_PREEMPT_TRACER
-static inline void tracer_preempt_on(unsigned long a0, unsigned long a1) { }
-static inline void tracer_preempt_off(unsigned long a0, unsigned long a1) { }
-#endif
-
-#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PROVE_LOCKING)
-/* Per-cpu variable to prevent redundant calls when IRQs already off */
-static DEFINE_PER_CPU(int, tracing_irq_cpu);
-
-void trace_hardirqs_on(void)
-{
- if (!this_cpu_read(tracing_irq_cpu))
- return;
-
- trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
- tracer_hardirqs_on();
-
- this_cpu_write(tracing_irq_cpu, 0);
-}
-EXPORT_SYMBOL(trace_hardirqs_on);
-
-void trace_hardirqs_off(void)
-{
- if (this_cpu_read(tracing_irq_cpu))
- return;
-
- this_cpu_write(tracing_irq_cpu, 1);
-
- trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
- tracer_hardirqs_off();
-}
-EXPORT_SYMBOL(trace_hardirqs_off);
-
-__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
-{
- if (!this_cpu_read(tracing_irq_cpu))
- return;
-
- trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
- tracer_hardirqs_on_caller(caller_addr);
-
- this_cpu_write(tracing_irq_cpu, 0);
-}
-EXPORT_SYMBOL(trace_hardirqs_on_caller);
-
-__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
-{
- if (this_cpu_read(tracing_irq_cpu))
- return;
-
- this_cpu_write(tracing_irq_cpu, 1);
-
- trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
- tracer_hardirqs_off_caller(caller_addr);
-}
-EXPORT_SYMBOL(trace_hardirqs_off_caller);
-
-/*
- * Stubs:
- */
-
-void trace_softirqs_on(unsigned long ip)
-{
-}
-
-void trace_softirqs_off(unsigned long ip)
-{
-}
-
-inline void print_irqtrace_events(struct task_struct *curr)
-{
-}
-#endif
-
-#if defined(CONFIG_PREEMPT_TRACER) || \
- (defined(CONFIG_DEBUG_PREEMPT) && defined(CONFIG_PREEMPTIRQ_EVENTS))
-void trace_preempt_on(unsigned long a0, unsigned long a1)
-{
- trace_preempt_enable_rcuidle(a0, a1);
- tracer_preempt_on(a0, a1);
-}
-
-void trace_preempt_off(unsigned long a0, unsigned long a1)
-{
- trace_preempt_disable_rcuidle(a0, a1);
- tracer_preempt_off(a0, a1);
-}
-#endif
diff --git a/kernel/trace/trace_preemptirq.c b/kernel/trace/trace_preemptirq.c
new file mode 100644
index 000000000000..bec9926acb00
--- /dev/null
+++ b/kernel/trace/trace_preemptirq.c
@@ -0,0 +1,70 @@
+/*
+ * preemptoff and irqoff tracepoints
+ *
+ * Copyright (C) 2017 Joel Fernandes <[email protected]>
+ */
+
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/ftrace.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/preemptirq.h>
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+/* Per-cpu variable to prevent redundant calls when IRQs already off */
+static DEFINE_PER_CPU(int, tracing_irq_cpu);
+
+void trace_hardirqs_on(void)
+{
+ if (!this_cpu_read(tracing_irq_cpu))
+ return;
+
+ trace_irq_enable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+ this_cpu_write(tracing_irq_cpu, 0);
+}
+EXPORT_SYMBOL(trace_hardirqs_on);
+
+void trace_hardirqs_off(void)
+{
+ if (this_cpu_read(tracing_irq_cpu))
+ return;
+
+ this_cpu_write(tracing_irq_cpu, 1);
+ trace_irq_disable_rcuidle(CALLER_ADDR0, CALLER_ADDR1);
+}
+EXPORT_SYMBOL(trace_hardirqs_off);
+
+__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
+{
+ if (!this_cpu_read(tracing_irq_cpu))
+ return;
+
+ trace_irq_enable_rcuidle(CALLER_ADDR0, caller_addr);
+ this_cpu_write(tracing_irq_cpu, 0);
+}
+EXPORT_SYMBOL(trace_hardirqs_on_caller);
+
+__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
+{
+ if (this_cpu_read(tracing_irq_cpu))
+ return;
+
+ this_cpu_write(tracing_irq_cpu, 1);
+ trace_irq_disable_rcuidle(CALLER_ADDR0, caller_addr);
+}
+EXPORT_SYMBOL(trace_hardirqs_off_caller);
+#endif /* CONFIG_TRACE_IRQFLAGS */
+
+#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
+void trace_preempt_on(unsigned long a0, unsigned long a1)
+{
+ trace_preempt_enable_rcuidle(a0, a1);
+}
+
+void trace_preempt_off(unsigned long a0, unsigned long a1)
+{
+ trace_preempt_disable_rcuidle(a0, a1);
+}
+#endif
--
2.16.2.660.g709887971b-goog
Hi Joel,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.16-rc5 next-20180315]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/tracing-Improve-design-of-preemptirq-tracepoints-and-its-users/20180316-012211
config: i386-randconfig-x006-201810 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
kernel//locking/lockdep.c: In function 'lockdep_init':
>> kernel//locking/lockdep.c:4325:2: error: implicit declaration of function 'register_trace_irq_disable'; did you mean 'trace_irq_disable'? [-Werror=implicit-function-declaration]
register_trace_irq_disable(lockdep_hardirqs_off, NULL);
^~~~~~~~~~~~~~~~~~~~~~~~~~
trace_irq_disable
>> kernel//locking/lockdep.c:4326:2: error: implicit declaration of function 'register_trace_irq_enable'; did you mean 'register_trace_lock_release'? [-Werror=implicit-function-declaration]
register_trace_irq_enable(lockdep_hardirqs_on, NULL);
^~~~~~~~~~~~~~~~~~~~~~~~~
register_trace_lock_release
cc1: some warnings being treated as errors
vim +4325 kernel//locking/lockdep.c
4321
4322 void __init lockdep_init(void)
4323 {
4324 #ifdef CONFIG_PROVE_LOCKING
> 4325 register_trace_irq_disable(lockdep_hardirqs_off, NULL);
> 4326 register_trace_irq_enable(lockdep_hardirqs_on, NULL);
4327 #endif
4328 printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
4329
4330 printk("... MAX_LOCKDEP_SUBCLASSES: %lu\n", MAX_LOCKDEP_SUBCLASSES);
4331 printk("... MAX_LOCK_DEPTH: %lu\n", MAX_LOCK_DEPTH);
4332 printk("... MAX_LOCKDEP_KEYS: %lu\n", MAX_LOCKDEP_KEYS);
4333 printk("... CLASSHASH_SIZE: %lu\n", CLASSHASH_SIZE);
4334 printk("... MAX_LOCKDEP_ENTRIES: %lu\n", MAX_LOCKDEP_ENTRIES);
4335 printk("... MAX_LOCKDEP_CHAINS: %lu\n", MAX_LOCKDEP_CHAINS);
4336 printk("... CHAINHASH_SIZE: %lu\n", CHAINHASH_SIZE);
4337
4338 printk(" memory used by lock dependency info: %lu kB\n",
4339 (sizeof(struct lock_class) * MAX_LOCKDEP_KEYS +
4340 sizeof(struct list_head) * CLASSHASH_SIZE +
4341 sizeof(struct lock_list) * MAX_LOCKDEP_ENTRIES +
4342 sizeof(struct lock_chain) * MAX_LOCKDEP_CHAINS +
4343 sizeof(struct list_head) * CHAINHASH_SIZE
4344 #ifdef CONFIG_PROVE_LOCKING
4345 + sizeof(struct circular_queue)
4346 #endif
4347 ) / 1024
4348 );
4349
4350 printk(" per task-struct memory footprint: %lu bytes\n",
4351 sizeof(struct held_lock) * MAX_LOCK_DEPTH);
4352 }
4353
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hello,
On Thu, Mar 15, 2018 at 12:51 PM, kbuild test robot <[email protected]> wrote:
>
> Hi Joel,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.16-rc5 next-20180315]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/tracing-Improve-design-of-preemptirq-tracepoints-and-its-users/20180316-012211
> config: i386-randconfig-x006-201810 (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
> kernel//locking/lockdep.c: In function 'lockdep_init':
> >> kernel//locking/lockdep.c:4325:2: error: implicit declaration of function 'register_trace_irq_disable'; did you mean 'trace_irq_disable'? [-Werror=implicit-function-declaration]
> register_trace_irq_disable(lockdep_hardirqs_off, NULL);
> ^~~~~~~~~~~~~~~~~~~~~~~~~~
The reason for this is PREEMPTIRQ_TRACEPOINTS depends on FTRACE which
is turned off in the config. Its a combination I hadn't tested in my
matrix. It causes build errors in in lockdep code that tries to
register the lockdep hooks. I'll fix it in the next rev. Thanks.
- Joel
Hi Joel,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.16-rc5 next-20180314]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/tracing-Improve-design-of-preemptirq-tracepoints-and-its-users/20180316-012211
config: i386-randconfig-a1-201810 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
kernel/locking/lockdep.c: In function 'lockdep_init':
>> kernel/locking/lockdep.c:4325:2: error: implicit declaration of function 'register_trace_irq_disable' [-Werror=implicit-function-declaration]
register_trace_irq_disable(lockdep_hardirqs_off, NULL);
^
>> kernel/locking/lockdep.c:4326:2: error: implicit declaration of function 'register_trace_irq_enable' [-Werror=implicit-function-declaration]
register_trace_irq_enable(lockdep_hardirqs_on, NULL);
^
cc1: some warnings being treated as errors
vim +/register_trace_irq_disable +4325 kernel/locking/lockdep.c
4321
4322 void __init lockdep_init(void)
4323 {
4324 #ifdef CONFIG_PROVE_LOCKING
> 4325 register_trace_irq_disable(lockdep_hardirqs_off, NULL);
> 4326 register_trace_irq_enable(lockdep_hardirqs_on, NULL);
4327 #endif
4328 printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
4329
4330 printk("... MAX_LOCKDEP_SUBCLASSES: %lu\n", MAX_LOCKDEP_SUBCLASSES);
4331 printk("... MAX_LOCK_DEPTH: %lu\n", MAX_LOCK_DEPTH);
4332 printk("... MAX_LOCKDEP_KEYS: %lu\n", MAX_LOCKDEP_KEYS);
4333 printk("... CLASSHASH_SIZE: %lu\n", CLASSHASH_SIZE);
4334 printk("... MAX_LOCKDEP_ENTRIES: %lu\n", MAX_LOCKDEP_ENTRIES);
4335 printk("... MAX_LOCKDEP_CHAINS: %lu\n", MAX_LOCKDEP_CHAINS);
4336 printk("... CHAINHASH_SIZE: %lu\n", CHAINHASH_SIZE);
4337
4338 printk(" memory used by lock dependency info: %lu kB\n",
4339 (sizeof(struct lock_class) * MAX_LOCKDEP_KEYS +
4340 sizeof(struct list_head) * CLASSHASH_SIZE +
4341 sizeof(struct lock_list) * MAX_LOCKDEP_ENTRIES +
4342 sizeof(struct lock_chain) * MAX_LOCKDEP_CHAINS +
4343 sizeof(struct list_head) * CHAINHASH_SIZE
4344 #ifdef CONFIG_PROVE_LOCKING
4345 + sizeof(struct circular_queue)
4346 #endif
4347 ) / 1024
4348 );
4349
4350 printk(" per task-struct memory footprint: %lu bytes\n",
4351 sizeof(struct held_lock) * MAX_LOCK_DEPTH);
4352 }
4353
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Thu, Mar 15, 2018 at 8:13 PM, kbuild test robot <[email protected]> wrote:
> Hi Joel,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.16-rc5 next-20180314]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/tracing-Improve-design-of-preemptirq-tracepoints-and-its-users/20180316-012211
> config: i386-randconfig-a1-201810 (attached as .config)
> compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
> kernel/locking/lockdep.c: In function 'lockdep_init':
>>> kernel/locking/lockdep.c:4325:2: error: implicit declaration of function 'register_trace_irq_disable' [-Werror=implicit-function-declaration]
> register_trace_irq_disable(lockdep_hardirqs_off, NULL);
> ^
>>> kernel/locking/lockdep.c:4326:2: error: implicit declaration of function 'register_trace_irq_enable' [-Werror=implicit-function-declaration]
> register_trace_irq_enable(lockdep_hardirqs_on, NULL);
> ^
> cc1: some warnings being treated as errors
>
> vim +/register_trace_irq_disable +4325 kernel/locking/lockdep.c
Can't reproduce this. Kbuild bot might be testing old patches. With
the latest patches and the config kbuild shared, I don't get any
errors.
thanks,
- Joel
FYI, we noticed the following commit (built with gcc-7):
commit: b648360016fd691bcb1128a6b7fa2473b3a53ed3 ("tracing: Improve design of preemptirq tracepoints and its users")
url: https://github.com/0day-ci/linux/commits/Joel-Fernandes/tracing-Improve-design-of-preemptirq-tracepoints-and-its-users/20180316-012211
in testcase: boot
on test machine: qemu-system-i386 -enable-kvm -m 256M
caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace):
+--------------------------------------------------+------------+------------+
| | 3266b5bd97 | b648360016 |
+--------------------------------------------------+------------+------------+
| boot_successes | 8 | 0 |
| boot_failures | 0 | 8 |
| WARNING:at_kernel/locking/lockdep.c:#check_flags | 0 | 8 |
| EIP:check_flags | 0 | 8 |
+--------------------------------------------------+------------+------------+
[ 0.004000] WARNING: CPU: 0 PID: 0 at kernel/locking/lockdep.c:3826 check_flags+0x8f/0x13e
[ 0.004000] WARNING: CPU: 0 PID: 0 at kernel/locking/lockdep.c:3826 check_flags+0x8f/0x13e
[ 0.004000] Modules linked in:
[ 0.004000] Modules linked in:
[ 0.004000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.16.0-rc4-00340-gb648360 #1
[ 0.004000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.16.0-rc4-00340-gb648360 #1
[ 0.004000] EIP: check_flags+0x8f/0x13e
[ 0.004000] EIP: check_flags+0x8f/0x13e
[ 0.004000] EFLAGS: 00210012 CPU: 0
[ 0.004000] EFLAGS: 00210012 CPU: 0
[ 0.004000] EAX: 0000002f EBX: 4c4e78c0 ECX: 00000000 EDX: 00000000
[ 0.004000] EAX: 0000002f EBX: 4c4e78c0 ECX: 00000000 EDX: 00000000
[ 0.004000] ESI: 4c4fbbd0 EDI: 00000000 EBP: 4c4e1f08 ESP: 4c4e1f00
[ 0.004000] ESI: 4c4fbbd0 EDI: 00000000 EBP: 4c4e1f08 ESP: 4c4e1f00
[ 0.004000] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[ 0.004000] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[ 0.004000] CR0: 80050033 CR2: ffffffff CR3: 0ca02000 CR4: 00000690
[ 0.004000] CR0: 80050033 CR2: ffffffff CR3: 0ca02000 CR4: 00000690
[ 0.004000] Call Trace:
[ 0.004000] Call Trace:
[ 0.004000] ? lock_acquire+0x54/0x1b6
[ 0.004000] ? lock_acquire+0x54/0x1b6
[ 0.004000] ? console_lock+0x35/0x6e
[ 0.004000] ? console_lock+0x35/0x6e
[ 0.004000] ? register_console+0x3ce/0x6b9
[ 0.004000] ? register_console+0x3ce/0x6b9
[ 0.004000] ? register_console+0x3ce/0x6b9
[ 0.004000] ? register_console+0x3ce/0x6b9
[ 0.004000] ? native_irq_disable+0x6/0x6
[ 0.004000] ? native_irq_disable+0x6/0x6
[ 0.004000] ? univ8250_console_init+0x32/0x3c
[ 0.004000] ? univ8250_console_init+0x32/0x3c
[ 0.004000] ? console_init+0x17/0x22
[ 0.004000] ? console_init+0x17/0x22
[ 0.004000] ? start_kernel+0x481/0x5e4
[ 0.004000] ? start_kernel+0x481/0x5e4
[ 0.004000] ? i386_start_kernel+0xaa/0xae
[ 0.004000] ? i386_start_kernel+0xaa/0xae
[ 0.004000] ? startup_32_smp+0x164/0x168
[ 0.004000] ? startup_32_smp+0x164/0x168
[ 0.004000] Code: 4c 83 b8 a8 04 00 00 00 75 30 e8 0e b1 56 00 85 c0 74 1c 83 3d 00 bd 21 4d 00 75 13 68 2a 4a 3c 4c 68 ad 21 3b 4c e8 0e f6 f8 ff <0f> 0b 58 5a 68 45 4a 3c 4c e8 65 2c 01 00 59 64 8b 15 4c d7 9e
[ 0.004000] Code: 4c 83 b8 a8 04 00 00 00 75 30 e8 0e b1 56 00 85 c0 74 1c 83 3d 00 bd 21 4d 00 75 13 68 2a 4a 3c 4c 68 ad 21 3b 4c e8 0e f6 f8 ff <0f> 0b 58 5a 68 45 4a 3c 4c e8 65 2c 01 00 59 64 8b 15 4c d7 9e
[ 0.004000] ---[ end trace 49e3ccf384119f2e ]---
To reproduce:
git clone https://github.com/intel/lkp-tests.git
cd lkp-tests
bin/lkp qemu -k <bzImage> job-script # job-script is attached in this email
Thanks,
lkp