Skip to content

Commit 26f8068

Browse files
glemcorostedt
authored andcommitted
sched: Add sched tracepoints for RV task model
Add the following tracepoints: * sched_entry(bool preempt, ip) Called while entering __schedule * sched_exit(bool is_switch, ip) Called while exiting __schedule * sched_set_state(task, curr_state, state) Called when a task changes its state (to and from running) These tracepoints are useful to describe the Linux task model and are adapted from the patches by Daniel Bristot de Oliveira (https://bristot.me/linux-task-model/). Cc: Ingo Molnar <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Juri Lelli <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Gabriele Monaco <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 41a4d2d commit 26f8068

File tree

5 files changed

+53
-3
lines changed

5 files changed

+53
-3
lines changed

include/linux/rv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#ifndef _LINUX_RV_H
88
#define _LINUX_RV_H
99

10-
#define MAX_DA_NAME_LEN 24
10+
#define MAX_DA_NAME_LEN 32
1111

1212
#ifdef CONFIG_RV
1313
/*

include/linux/sched.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <linux/rv.h>
4747
#include <linux/livepatch_sched.h>
4848
#include <linux/uidgid_types.h>
49+
#include <linux/tracepoint-defs.h>
4950
#include <asm/kmap_size.h>
5051

5152
/* task_struct member predeclarations (sorted alphabetically): */
@@ -186,6 +187,12 @@ struct user_event_mm;
186187
# define debug_rtlock_wait_restore_state() do { } while (0)
187188
#endif
188189

190+
#define trace_set_current_state(state_value) \
191+
do { \
192+
if (tracepoint_enabled(sched_set_state_tp)) \
193+
__trace_set_current_state(state_value); \
194+
} while (0)
195+
189196
/*
190197
* set_current_state() includes a barrier so that the write of current->__state
191198
* is correctly serialised wrt the caller's subsequent test of whether to
@@ -226,12 +233,14 @@ struct user_event_mm;
226233
#define __set_current_state(state_value) \
227234
do { \
228235
debug_normal_state_change((state_value)); \
236+
trace_set_current_state(state_value); \
229237
WRITE_ONCE(current->__state, (state_value)); \
230238
} while (0)
231239

232240
#define set_current_state(state_value) \
233241
do { \
234242
debug_normal_state_change((state_value)); \
243+
trace_set_current_state(state_value); \
235244
smp_store_mb(current->__state, (state_value)); \
236245
} while (0)
237246

@@ -247,6 +256,7 @@ struct user_event_mm;
247256
\
248257
raw_spin_lock_irqsave(&current->pi_lock, flags); \
249258
debug_special_state_change((state_value)); \
259+
trace_set_current_state(state_value); \
250260
WRITE_ONCE(current->__state, (state_value)); \
251261
raw_spin_unlock_irqrestore(&current->pi_lock, flags); \
252262
} while (0)
@@ -282,6 +292,7 @@ struct user_event_mm;
282292
raw_spin_lock(&current->pi_lock); \
283293
current->saved_state = current->__state; \
284294
debug_rtlock_wait_set_state(); \
295+
trace_set_current_state(TASK_RTLOCK_WAIT); \
285296
WRITE_ONCE(current->__state, TASK_RTLOCK_WAIT); \
286297
raw_spin_unlock(&current->pi_lock); \
287298
} while (0);
@@ -291,6 +302,7 @@ struct user_event_mm;
291302
lockdep_assert_irqs_disabled(); \
292303
raw_spin_lock(&current->pi_lock); \
293304
debug_rtlock_wait_restore_state(); \
305+
trace_set_current_state(current->saved_state); \
294306
WRITE_ONCE(current->__state, current->saved_state); \
295307
current->saved_state = TASK_RUNNING; \
296308
raw_spin_unlock(&current->pi_lock); \
@@ -327,6 +339,10 @@ extern void io_schedule_finish(int token);
327339
extern long io_schedule_timeout(long timeout);
328340
extern void io_schedule(void);
329341

342+
/* wrapper function to trace from this header file */
343+
DECLARE_TRACEPOINT(sched_set_state_tp);
344+
extern void __trace_set_current_state(int state_value);
345+
330346
/**
331347
* struct prev_cputime - snapshot of system and user cputime
332348
* @utime: time spent in user mode

include/trace/events/sched.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,19 @@ DECLARE_TRACE(sched_compute_energy_tp,
824824
unsigned long max_util, unsigned long busy_time),
825825
TP_ARGS(p, dst_cpu, energy, max_util, busy_time));
826826

827+
DECLARE_TRACE(sched_entry_tp,
828+
TP_PROTO(bool preempt, unsigned long ip),
829+
TP_ARGS(preempt, ip));
830+
831+
DECLARE_TRACE(sched_exit_tp,
832+
TP_PROTO(bool is_switch, unsigned long ip),
833+
TP_ARGS(is_switch, ip));
834+
835+
DECLARE_TRACE_CONDITION(sched_set_state_tp,
836+
TP_PROTO(struct task_struct *tsk, int state),
837+
TP_ARGS(tsk, state),
838+
TP_CONDITION(!!(tsk->__state) != !!state));
839+
827840
#endif /* _TRACE_SCHED_H */
828841

829842
/* This part must be outside protection */

kernel/sched/core.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,16 @@ sched_core_dequeue(struct rq *rq, struct task_struct *p, int flags) { }
491491

492492
#endif /* CONFIG_SCHED_CORE */
493493

494+
/* need a wrapper since we may need to trace from modules */
495+
EXPORT_TRACEPOINT_SYMBOL(sched_set_state_tp);
496+
497+
/* Call via the helper macro trace_set_current_state. */
498+
void __trace_set_current_state(int state_value)
499+
{
500+
trace_sched_set_state_tp(current, state_value);
501+
}
502+
EXPORT_SYMBOL(__trace_set_current_state);
503+
494504
/*
495505
* Serialization rules:
496506
*
@@ -5307,6 +5317,12 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev)
53075317
*/
53085318

53095319
finish_task_switch(prev);
5320+
/*
5321+
* This is a special case: the newly created task has just
5322+
* switched the context for the first time. It is returning from
5323+
* schedule for the first time in this path.
5324+
*/
5325+
trace_sched_exit_tp(true, CALLER_ADDR0);
53105326
preempt_enable();
53115327

53125328
if (current->set_child_tid)
@@ -6650,12 +6666,15 @@ static void __sched notrace __schedule(int sched_mode)
66506666
* as a preemption by schedule_debug() and RCU.
66516667
*/
66526668
bool preempt = sched_mode > SM_NONE;
6669+
bool is_switch = false;
66536670
unsigned long *switch_count;
66546671
unsigned long prev_state;
66556672
struct rq_flags rf;
66566673
struct rq *rq;
66576674
int cpu;
66586675

6676+
trace_sched_entry_tp(preempt, CALLER_ADDR0);
6677+
66596678
cpu = smp_processor_id();
66606679
rq = cpu_rq(cpu);
66616680
prev = rq->curr;
@@ -6723,7 +6742,8 @@ static void __sched notrace __schedule(int sched_mode)
67236742
rq->last_seen_need_resched_ns = 0;
67246743
#endif
67256744

6726-
if (likely(prev != next)) {
6745+
is_switch = prev != next;
6746+
if (likely(is_switch)) {
67276747
rq->nr_switches++;
67286748
/*
67296749
* RCU users of rcu_dereference(rq->curr) may not see
@@ -6768,6 +6788,7 @@ static void __sched notrace __schedule(int sched_mode)
67686788
__balance_callbacks(rq);
67696789
raw_spin_rq_unlock_irq(rq);
67706790
}
6791+
trace_sched_exit_tp(is_switch, CALLER_ADDR0);
67716792
}
67726793

67736794
void __noreturn do_task_dead(void)

tools/verification/rv/include/rv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
#define MAX_DESCRIPTION 1024
4-
#define MAX_DA_NAME_LEN 24
4+
#define MAX_DA_NAME_LEN 32
55

66
struct monitor {
77
char name[MAX_DA_NAME_LEN];

0 commit comments

Comments
 (0)