After commit 5e66a5bdad69 ("ftrace: Fix rcu warn in ftrace_location()"),
lockdep still complain that:
include/linux/rcupdate.h:646 rcu_read_lock() used illegally while idle!
As Xu suggested, lockdep check can be disabled when exectue
ftrace_int3_handler(), refer to mainline commit ba1f2b2eaa2a
("x86/entry: Fix NMI vs IRQ state tracking").
Fixes: 5e66a5bdad69 ("ftrace: Fix rcu warn in ftrace_location()")
Suggested-by: Xu Kuohai <xukuohai(a)huawei.com>
Signed-off-by: Zheng Yejian <zhengyejian1(a)huawei.com>
---
arch/x86/kernel/traps.c | 12 +++++++++---
kernel/trace/ftrace.c | 10 ++--------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index e832a9becc19..343c21fa3fad 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -585,9 +585,15 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
* ftrace must be first, everything else may cause a recursive crash.
* See note by declaration of modifying_ftrace_code in ftrace.c
*/
- if (unlikely(atomic_read(&modifying_ftrace_code)) &&
- ftrace_int3_handler(regs))
- return;
+ if (unlikely(atomic_read(&modifying_ftrace_code))) {
+ int ret;
+
+ lockdep_off();
+ ret = ftrace_int3_handler(regs);
+ lockdep_on();
+ if (ret)
+ return;
+ }
#endif
if (poke_int3_handler(regs))
return;
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index ad4440da5b78..6704150cb655 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1581,12 +1581,7 @@ unsigned long ftrace_location_range(unsigned long start, unsigned long end)
key.ip = start;
key.flags = end; /* overload flags, as it is unsigned long */
- /*
- * It is in atomic context when called from ftrace_int3_handler(),
- * in this case rcu lock is not needed.
- */
- if (!in_atomic())
- rcu_read_lock();
+ rcu_read_lock();
for (pg = ftrace_pages_start; pg; pg = pg->next) {
if (pg->index == 0 ||
end < pg->records[0].ip ||
@@ -1600,8 +1595,7 @@ unsigned long ftrace_location_range(unsigned long start, unsigned long end)
break;
}
}
- if (!in_atomic())
- rcu_read_unlock();
+ rcu_read_unlock();
return ip;
}
--
2.25.1