Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sched: Adapt sched tracepoints for RV task model

Add the following tracepoint:
* sched_set_need_resched(tsk, cpu, tif)
Called when a task is set the need resched [lazy] flag

Remove the unused ip parameter from sched_entry and sched_exit and alter
sched_entry to have a value of preempt consistent with the one used in
sched_switch.

Also adapt all monitors using sched_{entry,exit} to avoid breaking build.

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 <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Nam Cao <namcao@linutronix.de>
Cc: Tomas Glozar <tglozar@redhat.com>
Cc: Juri Lelli <jlelli@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Cc: John Kacur <jkacur@redhat.com>
Link: https://lore.kernel.org/20250728135022.255578-7-gmonaco@redhat.com
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Gabriele Monaco and committed by
Steven Rostedt (Google)
adcc3bfa 9d475d80

+34 -18
+6 -1
include/linux/sched.h
··· 339 339 extern long io_schedule_timeout(long timeout); 340 340 extern void io_schedule(void); 341 341 342 - /* wrapper function to trace from this header file */ 342 + /* wrapper functions to trace from this header file */ 343 343 DECLARE_TRACEPOINT(sched_set_state_tp); 344 344 extern void __trace_set_current_state(int state_value); 345 + DECLARE_TRACEPOINT(sched_set_need_resched_tp); 346 + extern void __trace_set_need_resched(struct task_struct *curr, int tif); 345 347 346 348 /** 347 349 * struct prev_cputime - snapshot of system and user cputime ··· 2065 2063 2066 2064 static inline void set_tsk_need_resched(struct task_struct *tsk) 2067 2065 { 2066 + if (tracepoint_enabled(sched_set_need_resched_tp) && 2067 + !test_tsk_thread_flag(tsk, TIF_NEED_RESCHED)) 2068 + __trace_set_need_resched(tsk, TIF_NEED_RESCHED); 2068 2069 set_tsk_thread_flag(tsk,TIF_NEED_RESCHED); 2069 2070 } 2070 2071
+8 -4
include/trace/events/sched.h
··· 882 882 TP_ARGS(p, dst_cpu, energy, max_util, busy_time)); 883 883 884 884 DECLARE_TRACE(sched_entry, 885 - TP_PROTO(bool preempt, unsigned long ip), 886 - TP_ARGS(preempt, ip)); 885 + TP_PROTO(bool preempt), 886 + TP_ARGS(preempt)); 887 887 888 888 DECLARE_TRACE(sched_exit, 889 - TP_PROTO(bool is_switch, unsigned long ip), 890 - TP_ARGS(is_switch, ip)); 889 + TP_PROTO(bool is_switch), 890 + TP_ARGS(is_switch)); 891 891 892 892 DECLARE_TRACE_CONDITION(sched_set_state, 893 893 TP_PROTO(struct task_struct *tsk, int state), 894 894 TP_ARGS(tsk, state), 895 895 TP_CONDITION(!!(tsk->__state) != !!state)); 896 + 897 + DECLARE_TRACE(sched_set_need_resched, 898 + TP_PROTO(struct task_struct *tsk, int cpu, int tif), 899 + TP_ARGS(tsk, cpu, tif)); 896 900 897 901 #endif /* _TRACE_SCHED_H */ 898 902
+10 -3
kernel/sched/core.c
··· 1110 1110 1111 1111 cpu = cpu_of(rq); 1112 1112 1113 + trace_sched_set_need_resched_tp(curr, cpu, tif); 1113 1114 if (cpu == smp_processor_id()) { 1114 1115 set_ti_thread_flag(cti, tif); 1115 1116 if (tif == TIF_NEED_RESCHED) ··· 1124 1123 } else { 1125 1124 trace_sched_wake_idle_without_ipi(cpu); 1126 1125 } 1126 + } 1127 + 1128 + void __trace_set_need_resched(struct task_struct *curr, int tif) 1129 + { 1130 + trace_sched_set_need_resched_tp(curr, smp_processor_id(), tif); 1127 1131 } 1128 1132 1129 1133 void resched_curr(struct rq *rq) ··· 5335 5329 * switched the context for the first time. It is returning from 5336 5330 * schedule for the first time in this path. 5337 5331 */ 5338 - trace_sched_exit_tp(true, CALLER_ADDR0); 5332 + trace_sched_exit_tp(true); 5339 5333 preempt_enable(); 5340 5334 5341 5335 if (current->set_child_tid) ··· 6684 6678 struct rq *rq; 6685 6679 int cpu; 6686 6680 6687 - trace_sched_entry_tp(preempt, CALLER_ADDR0); 6681 + /* Trace preemptions consistently with task switches */ 6682 + trace_sched_entry_tp(sched_mode == SM_PREEMPT); 6688 6683 6689 6684 cpu = smp_processor_id(); 6690 6685 rq = cpu_rq(cpu); ··· 6800 6793 __balance_callbacks(rq); 6801 6794 raw_spin_rq_unlock_irq(rq); 6802 6795 } 6803 - trace_sched_exit_tp(is_switch, CALLER_ADDR0); 6796 + trace_sched_exit_tp(is_switch); 6804 6797 } 6805 6798 6806 6799 void __noreturn do_task_dead(void)
+2 -2
kernel/trace/rv/monitors/sco/sco.c
··· 24 24 da_handle_start_event_sco(sched_set_state_sco); 25 25 } 26 26 27 - static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) 27 + static void handle_schedule_entry(void *data, bool preempt) 28 28 { 29 29 da_handle_event_sco(schedule_entry_sco); 30 30 } 31 31 32 - static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) 32 + static void handle_schedule_exit(void *data, bool is_switch) 33 33 { 34 34 da_handle_start_event_sco(schedule_exit_sco); 35 35 }
+2 -2
kernel/trace/rv/monitors/scpd/scpd.c
··· 30 30 da_handle_start_event_scpd(preempt_enable_scpd); 31 31 } 32 32 33 - static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) 33 + static void handle_schedule_entry(void *data, bool preempt) 34 34 { 35 35 da_handle_event_scpd(schedule_entry_scpd); 36 36 } 37 37 38 - static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) 38 + static void handle_schedule_exit(void *data, bool is_switch) 39 39 { 40 40 da_handle_event_scpd(schedule_exit_scpd); 41 41 }
+2 -2
kernel/trace/rv/monitors/sncid/sncid.c
··· 30 30 da_handle_start_event_sncid(irq_enable_sncid); 31 31 } 32 32 33 - static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) 33 + static void handle_schedule_entry(void *data, bool preempt) 34 34 { 35 35 da_handle_start_event_sncid(schedule_entry_sncid); 36 36 } 37 37 38 - static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) 38 + static void handle_schedule_exit(void *data, bool is_switch) 39 39 { 40 40 da_handle_start_event_sncid(schedule_exit_sncid); 41 41 }
+2 -2
kernel/trace/rv/monitors/snep/snep.c
··· 30 30 da_handle_start_event_snep(preempt_enable_snep); 31 31 } 32 32 33 - static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) 33 + static void handle_schedule_entry(void *data, bool preempt) 34 34 { 35 35 da_handle_event_snep(schedule_entry_snep); 36 36 } 37 37 38 - static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) 38 + static void handle_schedule_exit(void *data, bool is_switch) 39 39 { 40 40 da_handle_start_event_snep(schedule_exit_snep); 41 41 }
+2 -2
kernel/trace/rv/monitors/tss/tss.c
··· 27 27 da_handle_event_tss(sched_switch_tss); 28 28 } 29 29 30 - static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) 30 + static void handle_schedule_entry(void *data, bool preempt) 31 31 { 32 32 da_handle_event_tss(schedule_entry_tss); 33 33 } 34 34 35 - static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) 35 + static void handle_schedule_exit(void *data, bool is_switch) 36 36 { 37 37 da_handle_start_event_tss(schedule_exit_tss); 38 38 }