Skip to content

Commit c267925

Browse files
committed
tracing: Make tracepoint lockdep check actually test something
A while ago where the trace events had the following: rcu_read_lock_sched_notrace(); rcu_dereference_sched(...); rcu_read_unlock_sched_notrace(); If the tracepoint is enabled, it could trigger RCU issues if called in the wrong place. And this warning was only triggered if lockdep was enabled. If the tracepoint was never enabled with lockdep, the bug would not be caught. To handle this, the above sequence was done when lockdep was enabled regardless if the tracepoint was enabled or not (although the always enabled code really didn't do anything, it would still trigger a warning). But a lot has changed since that lockdep code was added. One is, that sequence no longer triggers any warning. Another is, the tracepoint when enabled doesn't even do that sequence anymore. The main check we care about today is whether RCU is "watching" or not. So if lockdep is enabled, always check if rcu_is_watching() which will trigger a warning if it is not (tracepoints require RCU to be watching). Note, that old sequence did add a bit of overhead when lockdep was enabled, and with the latest kernel updates, would cause the system to slow down enough to trigger kernel "stalled" warnings. Link: http://lore.kernel.org/lkml/[email protected] Link: http://lore.kernel.org/lkml/[email protected] Link: https://lore.kernel.org/lkml/[email protected]/ Link: https://lore.kernel.org/linux-trace-kernel/[email protected] Cc: [email protected] Cc: Masami Hiramatsu <[email protected]> Cc: Dave Hansen <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Joel Fernandes <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Paul E. McKenney <[email protected]> Fixes: e6753f2 ("tracepoint: Make rcuidle tracepoint callers use SRCU") Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent aa69f81 commit c267925

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

include/linux/tracepoint.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
231231
* not add unwanted padding between the beginning of the section and the
232232
* structure. Force alignment to the same alignment as the section start.
233233
*
234-
* When lockdep is enabled, we make sure to always do the RCU portions of
235-
* the tracepoint code, regardless of whether tracing is on. However,
236-
* don't check if the condition is false, due to interaction with idle
237-
* instrumentation. This lets us find RCU issues triggered with tracepoints
238-
* even when this tracepoint is off. This code has no purpose other than
239-
* poking RCU a bit.
234+
* When lockdep is enabled, we make sure to always test if RCU is
235+
* "watching" regardless if the tracepoint is enabled or not. Tracepoints
236+
* require RCU to be active, and it should always warn at the tracepoint
237+
* site if it is not watching, as it will need to be active when the
238+
* tracepoint is enabled.
240239
*/
241240
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
242241
extern int __traceiter_##name(data_proto); \
@@ -249,9 +248,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
249248
TP_ARGS(args), \
250249
TP_CONDITION(cond), 0); \
251250
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
252-
rcu_read_lock_sched_notrace(); \
253-
rcu_dereference_sched(__tracepoint_##name.funcs);\
254-
rcu_read_unlock_sched_notrace(); \
251+
WARN_ON_ONCE(!rcu_is_watching()); \
255252
} \
256253
} \
257254
__DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \

0 commit comments

Comments
 (0)