Skip to content

Commit 4787c36

Browse files
Seiji AguchiIngo Molnar
authored andcommitted
x86/tracing: Add irq_enter/exit() in smp_trace_reschedule_interrupt()
Reschedule vector tracepoints may be called in cpu idle state. This causes lockdep check warning below. The tracepoint requires rcu but for accuracy it also requires irq_enter() (tracepoints record the irq context), thus, the tracepoint interrupt handler should be calling irq_enter() and not rcu_irq_enter() (irq_enter() calls rcu_irq_enter()). So, add irq_enter/exit() to smp_trace_reschedule_interrupt() with common pre/post processing functions, smp_entering_irq() and exiting_irq() (exiting_irq() calls just irq_exit() in arch/x86/include/asm/apic.h), because these can be shared among reschedule, call_function, and call_function_single vectors. [ 50.720557] Testing event reschedule_exit: [ 50.721349] [ 50.721502] =============================== [ 50.721835] [ INFO: suspicious RCU usage. ] [ 50.722169] 3.10.0-rc6-00004-gcf910e8 Freescale#190 Not tainted [ 50.722582] ------------------------------- [ 50.722915] /c/kernel-tests/src/linux/arch/x86/include/asm/trace/irq_vectors.h:50 suspicious rcu_dereference_check() usage! [ 50.723770] [ 50.723770] other info that might help us debug this: [ 50.723770] [ 50.724385] [ 50.724385] RCU used illegally from idle CPU! [ 50.724385] rcu_scheduler_active = 1, debug_locks = 0 [ 50.725232] RCU used illegally from extended quiescent state! [ 50.725690] no locks held by swapper/0/0. [ 50.726010] [ 50.726010] stack backtrace: [...] Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com> Reviewed-by: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/51CDCFA3.9080101@hds.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 5236eb9 commit 4787c36

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

arch/x86/kernel/smp.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -265,23 +265,30 @@ void smp_reschedule_interrupt(struct pt_regs *regs)
265265
*/
266266
}
267267

268-
void smp_trace_reschedule_interrupt(struct pt_regs *regs)
268+
static inline void smp_entering_irq(void)
269269
{
270270
ack_APIC_irq();
271+
irq_enter();
272+
}
273+
274+
void smp_trace_reschedule_interrupt(struct pt_regs *regs)
275+
{
276+
/*
277+
* Need to call irq_enter() before calling the trace point.
278+
* __smp_reschedule_interrupt() calls irq_enter/exit() too (in
279+
* scheduler_ipi(). This is OK, since those functions are allowed
280+
* to nest.
281+
*/
282+
smp_entering_irq();
271283
trace_reschedule_entry(RESCHEDULE_VECTOR);
272284
__smp_reschedule_interrupt();
273285
trace_reschedule_exit(RESCHEDULE_VECTOR);
286+
exiting_irq();
274287
/*
275288
* KVM uses this interrupt to force a cpu out of guest mode
276289
*/
277290
}
278291

279-
static inline void call_function_entering_irq(void)
280-
{
281-
ack_APIC_irq();
282-
irq_enter();
283-
}
284-
285292
static inline void __smp_call_function_interrupt(void)
286293
{
287294
generic_smp_call_function_interrupt();
@@ -290,14 +297,14 @@ static inline void __smp_call_function_interrupt(void)
290297

291298
void smp_call_function_interrupt(struct pt_regs *regs)
292299
{
293-
call_function_entering_irq();
300+
smp_entering_irq();
294301
__smp_call_function_interrupt();
295302
exiting_irq();
296303
}
297304

298305
void smp_trace_call_function_interrupt(struct pt_regs *regs)
299306
{
300-
call_function_entering_irq();
307+
smp_entering_irq();
301308
trace_call_function_entry(CALL_FUNCTION_VECTOR);
302309
__smp_call_function_interrupt();
303310
trace_call_function_exit(CALL_FUNCTION_VECTOR);
@@ -312,14 +319,14 @@ static inline void __smp_call_function_single_interrupt(void)
312319

313320
void smp_call_function_single_interrupt(struct pt_regs *regs)
314321
{
315-
call_function_entering_irq();
322+
smp_entering_irq();
316323
__smp_call_function_single_interrupt();
317324
exiting_irq();
318325
}
319326

320327
void smp_trace_call_function_single_interrupt(struct pt_regs *regs)
321328
{
322-
call_function_entering_irq();
329+
smp_entering_irq();
323330
trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR);
324331
__smp_call_function_single_interrupt();
325332
trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR);

0 commit comments

Comments
 (0)