-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rv: Add sco and tss per-cpu monitors
Add 2 per-cpu monitors as part of the sched model: * sco: scheduling context operations Monitor to ensure sched_set_state happens only in thread context * tss: task switch while scheduling Monitor to ensure sched_switch happens only in scheduling context To: Ingo Molnar <mingo@redhat.com> To: Peter Zijlstra <peterz@infradead.org> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: John Kacur <jkacur@redhat.com> Cc: Clark Williams <williams@redhat.com> Link: https://lore.kernel.org/20250305140406.350227-4-gmonaco@redhat.com Signed-off-by: Gabriele Monaco <gmonaco@redhat.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
- Loading branch information
Gabriele Monaco
authored and
Steven Rostedt (Google)
committed
Mar 24, 2025
1 parent
cb85c66
commit 9fd420a
Showing
13 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
# | ||
config RV_MON_SCO | ||
depends on RV | ||
depends on RV_MON_SCHED | ||
default y | ||
select DA_MON_EVENTS_IMPLICIT | ||
bool "sco monitor" | ||
help | ||
Monitor to ensure sched_set_state happens only in thread context. | ||
This monitor is part of the sched monitors collection. | ||
|
||
For further information, see: | ||
Documentation/trace/rv/monitor_sched.rst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <linux/ftrace.h> | ||
#include <linux/tracepoint.h> | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <linux/rv.h> | ||
#include <rv/instrumentation.h> | ||
#include <rv/da_monitor.h> | ||
|
||
#define MODULE_NAME "sco" | ||
|
||
#include <trace/events/sched.h> | ||
#include <rv_trace.h> | ||
#include <monitors/sched/sched.h> | ||
|
||
#include "sco.h" | ||
|
||
static struct rv_monitor rv_sco; | ||
DECLARE_DA_MON_PER_CPU(sco, unsigned char); | ||
|
||
static void handle_sched_set_state(void *data, struct task_struct *tsk, int state) | ||
{ | ||
da_handle_start_event_sco(sched_set_state_sco); | ||
} | ||
|
||
static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) | ||
{ | ||
da_handle_event_sco(schedule_entry_sco); | ||
} | ||
|
||
static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) | ||
{ | ||
da_handle_start_event_sco(schedule_exit_sco); | ||
} | ||
|
||
static int enable_sco(void) | ||
{ | ||
int retval; | ||
|
||
retval = da_monitor_init_sco(); | ||
if (retval) | ||
return retval; | ||
|
||
rv_attach_trace_probe("sco", sched_set_state_tp, handle_sched_set_state); | ||
rv_attach_trace_probe("sco", sched_entry_tp, handle_schedule_entry); | ||
rv_attach_trace_probe("sco", sched_exit_tp, handle_schedule_exit); | ||
|
||
return 0; | ||
} | ||
|
||
static void disable_sco(void) | ||
{ | ||
rv_sco.enabled = 0; | ||
|
||
rv_detach_trace_probe("sco", sched_set_state_tp, handle_sched_set_state); | ||
rv_detach_trace_probe("sco", sched_entry_tp, handle_schedule_entry); | ||
rv_detach_trace_probe("sco", sched_exit_tp, handle_schedule_exit); | ||
|
||
da_monitor_destroy_sco(); | ||
} | ||
|
||
static struct rv_monitor rv_sco = { | ||
.name = "sco", | ||
.description = "scheduling context operations.", | ||
.enable = enable_sco, | ||
.disable = disable_sco, | ||
.reset = da_monitor_reset_all_sco, | ||
.enabled = 0, | ||
}; | ||
|
||
static int __init register_sco(void) | ||
{ | ||
rv_register_monitor(&rv_sco, &rv_sched); | ||
return 0; | ||
} | ||
|
||
static void __exit unregister_sco(void) | ||
{ | ||
rv_unregister_monitor(&rv_sco); | ||
} | ||
|
||
module_init(register_sco); | ||
module_exit(unregister_sco); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); | ||
MODULE_DESCRIPTION("sco: scheduling context operations."); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Automatically generated C representation of sco automaton | ||
* For further information about this format, see kernel documentation: | ||
* Documentation/trace/rv/deterministic_automata.rst | ||
*/ | ||
|
||
enum states_sco { | ||
thread_context_sco = 0, | ||
scheduling_context_sco, | ||
state_max_sco | ||
}; | ||
|
||
#define INVALID_STATE state_max_sco | ||
|
||
enum events_sco { | ||
sched_set_state_sco = 0, | ||
schedule_entry_sco, | ||
schedule_exit_sco, | ||
event_max_sco | ||
}; | ||
|
||
struct automaton_sco { | ||
char *state_names[state_max_sco]; | ||
char *event_names[event_max_sco]; | ||
unsigned char function[state_max_sco][event_max_sco]; | ||
unsigned char initial_state; | ||
bool final_states[state_max_sco]; | ||
}; | ||
|
||
static const struct automaton_sco automaton_sco = { | ||
.state_names = { | ||
"thread_context", | ||
"scheduling_context" | ||
}, | ||
.event_names = { | ||
"sched_set_state", | ||
"schedule_entry", | ||
"schedule_exit" | ||
}, | ||
.function = { | ||
{ thread_context_sco, scheduling_context_sco, INVALID_STATE }, | ||
{ INVALID_STATE, INVALID_STATE, thread_context_sco }, | ||
}, | ||
.initial_state = thread_context_sco, | ||
.final_states = { 1, 0 }, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
|
||
/* | ||
* Snippet to be included in rv_trace.h | ||
*/ | ||
|
||
#ifdef CONFIG_RV_MON_SCO | ||
DEFINE_EVENT(event_da_monitor, event_sco, | ||
TP_PROTO(char *state, char *event, char *next_state, bool final_state), | ||
TP_ARGS(state, event, next_state, final_state)); | ||
|
||
DEFINE_EVENT(error_da_monitor, error_sco, | ||
TP_PROTO(char *state, char *event), | ||
TP_ARGS(state, event)); | ||
#endif /* CONFIG_RV_MON_SCO */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
# | ||
config RV_MON_TSS | ||
depends on RV | ||
depends on RV_MON_SCHED | ||
default y | ||
select DA_MON_EVENTS_IMPLICIT | ||
bool "tss monitor" | ||
help | ||
Monitor to ensure sched_switch happens only in scheduling context. | ||
This monitor is part of the sched monitors collection. | ||
|
||
For further information, see: | ||
Documentation/trace/rv/monitor_sched.rst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <linux/ftrace.h> | ||
#include <linux/tracepoint.h> | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <linux/rv.h> | ||
#include <rv/instrumentation.h> | ||
#include <rv/da_monitor.h> | ||
|
||
#define MODULE_NAME "tss" | ||
|
||
#include <trace/events/sched.h> | ||
#include <rv_trace.h> | ||
#include <monitors/sched/sched.h> | ||
|
||
#include "tss.h" | ||
|
||
static struct rv_monitor rv_tss; | ||
DECLARE_DA_MON_PER_CPU(tss, unsigned char); | ||
|
||
static void handle_sched_switch(void *data, bool preempt, | ||
struct task_struct *prev, | ||
struct task_struct *next, | ||
unsigned int prev_state) | ||
{ | ||
da_handle_event_tss(sched_switch_tss); | ||
} | ||
|
||
static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) | ||
{ | ||
da_handle_event_tss(schedule_entry_tss); | ||
} | ||
|
||
static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) | ||
{ | ||
da_handle_start_event_tss(schedule_exit_tss); | ||
} | ||
|
||
static int enable_tss(void) | ||
{ | ||
int retval; | ||
|
||
retval = da_monitor_init_tss(); | ||
if (retval) | ||
return retval; | ||
|
||
rv_attach_trace_probe("tss", sched_switch, handle_sched_switch); | ||
rv_attach_trace_probe("tss", sched_entry_tp, handle_schedule_entry); | ||
rv_attach_trace_probe("tss", sched_exit_tp, handle_schedule_exit); | ||
|
||
return 0; | ||
} | ||
|
||
static void disable_tss(void) | ||
{ | ||
rv_tss.enabled = 0; | ||
|
||
rv_detach_trace_probe("tss", sched_switch, handle_sched_switch); | ||
rv_detach_trace_probe("tss", sched_entry_tp, handle_schedule_entry); | ||
rv_detach_trace_probe("tss", sched_exit_tp, handle_schedule_exit); | ||
|
||
da_monitor_destroy_tss(); | ||
} | ||
|
||
static struct rv_monitor rv_tss = { | ||
.name = "tss", | ||
.description = "task switch while scheduling.", | ||
.enable = enable_tss, | ||
.disable = disable_tss, | ||
.reset = da_monitor_reset_all_tss, | ||
.enabled = 0, | ||
}; | ||
|
||
static int __init register_tss(void) | ||
{ | ||
rv_register_monitor(&rv_tss, &rv_sched); | ||
return 0; | ||
} | ||
|
||
static void __exit unregister_tss(void) | ||
{ | ||
rv_unregister_monitor(&rv_tss); | ||
} | ||
|
||
module_init(register_tss); | ||
module_exit(unregister_tss); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); | ||
MODULE_DESCRIPTION("tss: task switch while scheduling."); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Automatically generated C representation of tss automaton | ||
* For further information about this format, see kernel documentation: | ||
* Documentation/trace/rv/deterministic_automata.rst | ||
*/ | ||
|
||
enum states_tss { | ||
thread_tss = 0, | ||
sched_tss, | ||
state_max_tss | ||
}; | ||
|
||
#define INVALID_STATE state_max_tss | ||
|
||
enum events_tss { | ||
sched_switch_tss = 0, | ||
schedule_entry_tss, | ||
schedule_exit_tss, | ||
event_max_tss | ||
}; | ||
|
||
struct automaton_tss { | ||
char *state_names[state_max_tss]; | ||
char *event_names[event_max_tss]; | ||
unsigned char function[state_max_tss][event_max_tss]; | ||
unsigned char initial_state; | ||
bool final_states[state_max_tss]; | ||
}; | ||
|
||
static const struct automaton_tss automaton_tss = { | ||
.state_names = { | ||
"thread", | ||
"sched" | ||
}, | ||
.event_names = { | ||
"sched_switch", | ||
"schedule_entry", | ||
"schedule_exit" | ||
}, | ||
.function = { | ||
{ INVALID_STATE, sched_tss, INVALID_STATE }, | ||
{ sched_tss, INVALID_STATE, thread_tss }, | ||
}, | ||
.initial_state = thread_tss, | ||
.final_states = { 1, 0 }, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
|
||
/* | ||
* Snippet to be included in rv_trace.h | ||
*/ | ||
|
||
#ifdef CONFIG_RV_MON_TSS | ||
DEFINE_EVENT(event_da_monitor, event_tss, | ||
TP_PROTO(char *state, char *event, char *next_state, bool final_state), | ||
TP_ARGS(state, event, next_state, final_state)); | ||
|
||
DEFINE_EVENT(error_da_monitor, error_tss, | ||
TP_PROTO(char *state, char *event), | ||
TP_ARGS(state, event)); | ||
#endif /* CONFIG_RV_MON_TSS */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
digraph state_automaton { | ||
center = true; | ||
size = "7,11"; | ||
{node [shape = plaintext] "scheduling_context"}; | ||
{node [shape = plaintext, style=invis, label=""] "__init_thread_context"}; | ||
{node [shape = ellipse] "thread_context"}; | ||
{node [shape = plaintext] "thread_context"}; | ||
"__init_thread_context" -> "thread_context"; | ||
"scheduling_context" [label = "scheduling_context"]; | ||
"scheduling_context" -> "thread_context" [ label = "schedule_exit" ]; | ||
"thread_context" [label = "thread_context", color = green3]; | ||
"thread_context" -> "scheduling_context" [ label = "schedule_entry" ]; | ||
"thread_context" -> "thread_context" [ label = "sched_set_state" ]; | ||
{ rank = min ; | ||
"__init_thread_context"; | ||
"thread_context"; | ||
} | ||
} |
Oops, something went wrong.