Skip to content

Commit 7af08b5

Browse files
committed
Merge tag 'trace-v6.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull more tracing updates from Steven Rostedt: - Add trace flag for NEED_RESCHED_LAZY Now that NEED_RESCHED_LAZY is upstream, add it to the status bits of the common_flags. This will now show when the NEED_RESCHED_LAZY flag is set that is used for debugging latency issues in the kernel via a trace. - Remove leftover "__idx" variable when SRCU was removed from the tracepoint code - Add rcu_tasks_trace guard To add a guard() around the tracepoint code, a rcu_tasks_trace guard needs to be created first. - Remove __DO_TRACE() macro and just call __DO_TRACE_CALL() directly The DO_TRACE() macro has conditional locking depending on what was passed into the macro parameters. As the guts of the macro has been moved to __DO_TRACE_CALL() to handle static call logic, there's no reason to keep the __DO_TRACE() macro around. It is better to just do the locking in place without the conditionals and call __DO_TRACE_CALL() from those locations. The "cond" passed in can also be moved out of that macro. This simplifies the code. - Remove the "cond" from the system call tracepoint macros The "cond" variable was added to allow some tracepoints to check a condition within the static_branch (jump/nop) logic. The system calls do not need this. Removing it simplifies the code. - Replace scoped_guard() with just guard() in the tracepoint logic guard() works just as well as scoped_guard() in the tracepoint logic and the scoped_guard() causes some issues. * tag 'trace-v6.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing: Use guard() rather than scoped_guard() tracing: Remove cond argument from __DECLARE_TRACE_SYSCALL tracing: Remove conditional locking from __DO_TRACE() rcupdate_trace: Define rcu_tasks_trace lock guard tracing: Remove __idx variable from __DO_TRACE tracing: Move it_func[0] comment to the relevant context tracing: Record task flag NEED_RESCHED_LAZY.
2 parents 65ae975 + 2bd9b57 commit 7af08b5

File tree

6 files changed

+55
-53
lines changed

6 files changed

+55
-53
lines changed

Documentation/trace/ftrace.rst

+4
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,13 @@ explains which is which.
10331033
irqs-off: 'd' interrupts are disabled. '.' otherwise.
10341034

10351035
need-resched:
1036+
- 'B' all, TIF_NEED_RESCHED, PREEMPT_NEED_RESCHED and TIF_RESCHED_LAZY is set,
10361037
- 'N' both TIF_NEED_RESCHED and PREEMPT_NEED_RESCHED is set,
10371038
- 'n' only TIF_NEED_RESCHED is set,
10381039
- 'p' only PREEMPT_NEED_RESCHED is set,
1040+
- 'L' both PREEMPT_NEED_RESCHED and TIF_RESCHED_LAZY is set,
1041+
- 'b' both TIF_NEED_RESCHED and TIF_RESCHED_LAZY is set,
1042+
- 'l' only TIF_RESCHED_LAZY is set
10391043
- '.' otherwise.
10401044

10411045
hardirq/softirq:

include/linux/rcupdate_trace.h

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/sched.h>
1212
#include <linux/rcupdate.h>
13+
#include <linux/cleanup.h>
1314

1415
extern struct lockdep_map rcu_trace_lock_map;
1516

@@ -98,4 +99,8 @@ static inline void rcu_read_lock_trace(void) { BUG(); }
9899
static inline void rcu_read_unlock_trace(void) { BUG(); }
99100
#endif /* #ifdef CONFIG_TASKS_TRACE_RCU */
100101

102+
DEFINE_LOCK_GUARD_0(rcu_tasks_trace,
103+
rcu_read_lock_trace(),
104+
rcu_read_unlock_trace())
105+
101106
#endif /* __LINUX_RCUPDATE_TRACE_H */

include/linux/trace_events.h

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status);
184184

185185
enum trace_flag_type {
186186
TRACE_FLAG_IRQS_OFF = 0x01,
187+
TRACE_FLAG_NEED_RESCHED_LAZY = 0x02,
187188
TRACE_FLAG_NEED_RESCHED = 0x04,
188189
TRACE_FLAG_HARDIRQ = 0x08,
189190
TRACE_FLAG_SOFTIRQ = 0x10,

include/linux/tracepoint.h

+30-52
Original file line numberDiff line numberDiff line change
@@ -209,36 +209,6 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
209209
#define __DO_TRACE_CALL(name, args) __traceiter_##name(NULL, args)
210210
#endif /* CONFIG_HAVE_STATIC_CALL */
211211

212-
/*
213-
* it_func[0] is never NULL because there is at least one element in the array
214-
* when the array itself is non NULL.
215-
*
216-
* With @syscall=0, the tracepoint callback array dereference is
217-
* protected by disabling preemption.
218-
* With @syscall=1, the tracepoint callback array dereference is
219-
* protected by Tasks Trace RCU, which allows probes to handle page
220-
* faults.
221-
*/
222-
#define __DO_TRACE(name, args, cond, syscall) \
223-
do { \
224-
int __maybe_unused __idx = 0; \
225-
\
226-
if (!(cond)) \
227-
return; \
228-
\
229-
if (syscall) \
230-
rcu_read_lock_trace(); \
231-
else \
232-
preempt_disable_notrace(); \
233-
\
234-
__DO_TRACE_CALL(name, TP_ARGS(args)); \
235-
\
236-
if (syscall) \
237-
rcu_read_unlock_trace(); \
238-
else \
239-
preempt_enable_notrace(); \
240-
} while (0)
241-
242212
/*
243213
* Declare an exported function that Rust code can call to trigger this
244214
* tracepoint. This function does not include the static branch; that is done
@@ -262,7 +232,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
262232
* site if it is not watching, as it will need to be active when the
263233
* tracepoint is enabled.
264234
*/
265-
#define __DECLARE_TRACE_COMMON(name, proto, args, cond, data_proto) \
235+
#define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \
266236
extern int __traceiter_##name(data_proto); \
267237
DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
268238
extern struct tracepoint __tracepoint_##name; \
@@ -297,41 +267,43 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
297267
}
298268

299269
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
300-
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \
270+
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \
301271
static inline void __rust_do_trace_##name(proto) \
302272
{ \
303-
__DO_TRACE(name, \
304-
TP_ARGS(args), \
305-
TP_CONDITION(cond), 0); \
273+
if (cond) { \
274+
guard(preempt_notrace)(); \
275+
__DO_TRACE_CALL(name, TP_ARGS(args)); \
276+
} \
306277
} \
307278
static inline void trace_##name(proto) \
308279
{ \
309-
if (static_branch_unlikely(&__tracepoint_##name.key)) \
310-
__DO_TRACE(name, \
311-
TP_ARGS(args), \
312-
TP_CONDITION(cond), 0); \
280+
if (static_branch_unlikely(&__tracepoint_##name.key)) { \
281+
if (cond) { \
282+
guard(preempt_notrace)(); \
283+
__DO_TRACE_CALL(name, TP_ARGS(args)); \
284+
} \
285+
} \
313286
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
314287
WARN_ONCE(!rcu_is_watching(), \
315288
"RCU not watching for tracepoint"); \
316289
} \
317290
}
318291

319-
#define __DECLARE_TRACE_SYSCALL(name, proto, args, cond, data_proto) \
320-
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \
292+
#define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \
293+
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \
321294
static inline void __rust_do_trace_##name(proto) \
322295
{ \
323-
__DO_TRACE(name, \
324-
TP_ARGS(args), \
325-
TP_CONDITION(cond), 1); \
296+
guard(rcu_tasks_trace)(); \
297+
__DO_TRACE_CALL(name, TP_ARGS(args)); \
326298
} \
327299
static inline void trace_##name(proto) \
328300
{ \
329301
might_fault(); \
330-
if (static_branch_unlikely(&__tracepoint_##name.key)) \
331-
__DO_TRACE(name, \
332-
TP_ARGS(args), \
333-
TP_CONDITION(cond), 1); \
334-
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
302+
if (static_branch_unlikely(&__tracepoint_##name.key)) { \
303+
guard(rcu_tasks_trace)(); \
304+
__DO_TRACE_CALL(name, TP_ARGS(args)); \
305+
} \
306+
if (IS_ENABLED(CONFIG_LOCKDEP)) { \
335307
WARN_ONCE(!rcu_is_watching(), \
336308
"RCU not watching for tracepoint"); \
337309
} \
@@ -341,6 +313,9 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
341313
* We have no guarantee that gcc and the linker won't up-align the tracepoint
342314
* structures, so we create an array of pointers that will be used for iteration
343315
* on the tracepoints.
316+
*
317+
* it_func[0] is never NULL because there is at least one element in the array
318+
* when the array itself is non NULL.
344319
*/
345320
#define __DEFINE_TRACE_EXT(_name, _ext, proto, args) \
346321
static const char __tpstrtab_##_name[] \
@@ -412,7 +387,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
412387

413388

414389
#else /* !TRACEPOINTS_ENABLED */
415-
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
390+
#define __DECLARE_TRACE_COMMON(name, proto, args, data_proto) \
416391
static inline void trace_##name(proto) \
417392
{ } \
418393
static inline int \
@@ -436,7 +411,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
436411
return false; \
437412
}
438413

439-
#define __DECLARE_TRACE_SYSCALL __DECLARE_TRACE
414+
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
415+
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto))
416+
417+
#define __DECLARE_TRACE_SYSCALL(name, proto, args, data_proto) \
418+
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto))
440419

441420
#define DEFINE_TRACE_FN(name, reg, unreg, proto, args)
442421
#define DEFINE_TRACE_SYSCALL(name, reg, unreg, proto, args)
@@ -502,7 +481,6 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
502481

503482
#define DECLARE_TRACE_SYSCALL(name, proto, args) \
504483
__DECLARE_TRACE_SYSCALL(name, PARAMS(proto), PARAMS(args), \
505-
cpu_online(raw_smp_processor_id()), \
506484
PARAMS(void *__data, proto))
507485

508486
#define TRACE_EVENT_FLAGS(event, flag)

kernel/trace/trace.c

+2
Original file line numberDiff line numberDiff line change
@@ -2552,6 +2552,8 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status)
25522552
trace_flags |= TRACE_FLAG_NEED_RESCHED;
25532553
if (test_preempt_need_resched())
25542554
trace_flags |= TRACE_FLAG_PREEMPT_RESCHED;
2555+
if (IS_ENABLED(CONFIG_ARCH_HAS_PREEMPT_LAZY) && tif_test_bit(TIF_NEED_RESCHED_LAZY))
2556+
trace_flags |= TRACE_FLAG_NEED_RESCHED_LAZY;
25552557
return (trace_flags << 16) | (min_t(unsigned int, pc & 0xff, 0xf)) |
25562558
(min_t(unsigned int, migration_disable_value(), 0xf)) << 4;
25572559
}

kernel/trace/trace_output.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -462,17 +462,29 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
462462
bh_off ? 'b' :
463463
'.';
464464

465-
switch (entry->flags & (TRACE_FLAG_NEED_RESCHED |
465+
switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY |
466466
TRACE_FLAG_PREEMPT_RESCHED)) {
467+
case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED:
468+
need_resched = 'B';
469+
break;
467470
case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED:
468471
need_resched = 'N';
469472
break;
473+
case TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED:
474+
need_resched = 'L';
475+
break;
476+
case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY:
477+
need_resched = 'b';
478+
break;
470479
case TRACE_FLAG_NEED_RESCHED:
471480
need_resched = 'n';
472481
break;
473482
case TRACE_FLAG_PREEMPT_RESCHED:
474483
need_resched = 'p';
475484
break;
485+
case TRACE_FLAG_NEED_RESCHED_LAZY:
486+
need_resched = 'l';
487+
break;
476488
default:
477489
need_resched = '.';
478490
break;

0 commit comments

Comments
 (0)