Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb42e2d9 authored by Satya Durga Srinivasu Prabhala's avatar Satya Durga Srinivasu Prabhala
Browse files

tracing: irqsoff: Prevent false-positive lockdep warning



Below warning is observed during boot when lockdep is enabled
due to per-cpu irqsoff_store access. As rcu_read_lock/unlock
can not be called from idle CPU, fix the warning by disabling
lockdep checks before call and enable it after.

[    0.125185] =============================
[    0.129317] WARNING: suspicious RCU usage
[    0.133452] 4.19.12+ #31 Not tainted
[    0.137130] -----------------------------
[    0.141263] include/trace/events/preemptirq.h:91 \
			suspicious rcu_dereference_check() usage!
[    0.153137]
[    0.153137] other info that might help us debug this:
[    0.153137]
[    0.161364]
[    0.161364] RCU used illegally from idle CPU!
[    0.161364] rcu_scheduler_active = 1, debug_locks = 1
[    0.172518] RCU used illegally from extended quiescent state!
[    0.178428] no locks held by swapper/0/0.
[    0.182560]
[    0.196994] Call trace:
[    0.199534]  dump_backtrace+0x0/0x190
[    0.203311]  show_stack+0x20/0x30
[    0.206728]  dump_stack+0xe8/0x13c
[    0.210240]  lockdep_rcu_suspicious+0x128/0x150
[    0.214905]  tracer_hardirqs_on+0x1a0/0x458
[    0.219209]  trace_hardirqs_on+0x148/0x1b8
[    0.223428]  arch_cpu_idle+0xf8/0x200
[    0.227208]  do_idle+0xcc/0x2a8
[    0.230446]  cpu_startup_entry+0x24/0x28
[    0.234485]  rest_init+0x1f0/0x200
[    0.237998]  start_kernel+0x434/0x4bc.

Change-Id: I4ae8f57ba965d9263d90030ee938c39479d409ea
Signed-off-by: default avatarSatya Durga Srinivasu Prabhala <satyap@codeaurora.org>
parent b3583cea
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -629,13 +629,17 @@ void tracer_hardirqs_on(unsigned long a0, unsigned long a1)
{
	unsigned int pc = preempt_count();
#ifdef CONFIG_PREEMPTIRQ_EVENTS
	struct irqsoff_store *is = &per_cpu(the_irqsoff,
						raw_smp_processor_id());
	u64 delta = sched_clock() - is->ts;
	struct irqsoff_store *is;
	u64 delta;

	lockdep_off();
	is = &per_cpu(the_irqsoff, raw_smp_processor_id());
	delta = sched_clock() - is->ts;

	if (delta > sysctl_irqsoff_tracing_threshold_ns)
		trace_irqs_disable(delta, is->caddr[0], is->caddr[1],
						is->caddr[2], is->caddr[3]);
	lockdep_on();
#endif /* CONFIG_PREEMPTIRQ_EVENTS */

	if (!preempt_trace(pc) && irq_trace())
@@ -646,14 +650,16 @@ void tracer_hardirqs_off(unsigned long a0, unsigned long a1)
{
	unsigned int pc = preempt_count();
#ifdef CONFIG_PREEMPTIRQ_EVENTS
	struct irqsoff_store *is = &per_cpu(the_irqsoff,
						raw_smp_processor_id());
	struct irqsoff_store *is;

	lockdep_off();
	is = &per_cpu(the_irqsoff, raw_smp_processor_id());
	is->ts = sched_clock();
	is->caddr[0] = CALLER_ADDR0;
	is->caddr[1] = CALLER_ADDR1;
	is->caddr[2] = CALLER_ADDR2;
	is->caddr[3] = CALLER_ADDR3;
	lockdep_on();
#endif /* CONFIG_PREEMPTIRQ_EVENTS */

	if (!preempt_trace(pc) && irq_trace())