-
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 scpd, snep and sncid per-cpu monitors
Add 3 per-cpu monitors as part of the sched model: * scpd: schedule called with preemption disabled Monitor to ensure schedule is called with preemption disabled * snep: schedule does not enable preempt Monitor to ensure schedule does not enable preempt * sncid: schedule not called with interrupt disabled Monitor to ensure schedule is not called with interrupt disabled 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-6-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
93bac9c
commit fbe6c09
Showing
18 changed files
with
588 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,15 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
# | ||
config RV_MON_SCPD | ||
depends on RV | ||
depends on PREEMPT_TRACER | ||
depends on RV_MON_SCHED | ||
default y | ||
select DA_MON_EVENTS_IMPLICIT | ||
bool "scpd monitor" | ||
help | ||
Monitor to ensure schedule is called with preemption disabled. | ||
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,96 @@ | ||
// 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 "scpd" | ||
|
||
#include <trace/events/sched.h> | ||
#include <trace/events/preemptirq.h> | ||
#include <rv_trace.h> | ||
#include <monitors/sched/sched.h> | ||
|
||
#include "scpd.h" | ||
|
||
static struct rv_monitor rv_scpd; | ||
DECLARE_DA_MON_PER_CPU(scpd, unsigned char); | ||
|
||
static void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip) | ||
{ | ||
da_handle_event_scpd(preempt_disable_scpd); | ||
} | ||
|
||
static void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip) | ||
{ | ||
da_handle_start_event_scpd(preempt_enable_scpd); | ||
} | ||
|
||
static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) | ||
{ | ||
da_handle_event_scpd(schedule_entry_scpd); | ||
} | ||
|
||
static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) | ||
{ | ||
da_handle_event_scpd(schedule_exit_scpd); | ||
} | ||
|
||
static int enable_scpd(void) | ||
{ | ||
int retval; | ||
|
||
retval = da_monitor_init_scpd(); | ||
if (retval) | ||
return retval; | ||
|
||
rv_attach_trace_probe("scpd", preempt_disable, handle_preempt_disable); | ||
rv_attach_trace_probe("scpd", preempt_enable, handle_preempt_enable); | ||
rv_attach_trace_probe("scpd", sched_entry_tp, handle_schedule_entry); | ||
rv_attach_trace_probe("scpd", sched_exit_tp, handle_schedule_exit); | ||
|
||
return 0; | ||
} | ||
|
||
static void disable_scpd(void) | ||
{ | ||
rv_scpd.enabled = 0; | ||
|
||
rv_detach_trace_probe("scpd", preempt_disable, handle_preempt_disable); | ||
rv_detach_trace_probe("scpd", preempt_enable, handle_preempt_enable); | ||
rv_detach_trace_probe("scpd", sched_entry_tp, handle_schedule_entry); | ||
rv_detach_trace_probe("scpd", sched_exit_tp, handle_schedule_exit); | ||
|
||
da_monitor_destroy_scpd(); | ||
} | ||
|
||
static struct rv_monitor rv_scpd = { | ||
.name = "scpd", | ||
.description = "schedule called with preemption disabled.", | ||
.enable = enable_scpd, | ||
.disable = disable_scpd, | ||
.reset = da_monitor_reset_all_scpd, | ||
.enabled = 0, | ||
}; | ||
|
||
static int __init register_scpd(void) | ||
{ | ||
rv_register_monitor(&rv_scpd, &rv_sched); | ||
return 0; | ||
} | ||
|
||
static void __exit unregister_scpd(void) | ||
{ | ||
rv_unregister_monitor(&rv_scpd); | ||
} | ||
|
||
module_init(register_scpd); | ||
module_exit(unregister_scpd); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); | ||
MODULE_DESCRIPTION("scpd: schedule called with preemption disabled."); |
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,49 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Automatically generated C representation of scpd automaton | ||
* For further information about this format, see kernel documentation: | ||
* Documentation/trace/rv/deterministic_automata.rst | ||
*/ | ||
|
||
enum states_scpd { | ||
cant_sched_scpd = 0, | ||
can_sched_scpd, | ||
state_max_scpd | ||
}; | ||
|
||
#define INVALID_STATE state_max_scpd | ||
|
||
enum events_scpd { | ||
preempt_disable_scpd = 0, | ||
preempt_enable_scpd, | ||
schedule_entry_scpd, | ||
schedule_exit_scpd, | ||
event_max_scpd | ||
}; | ||
|
||
struct automaton_scpd { | ||
char *state_names[state_max_scpd]; | ||
char *event_names[event_max_scpd]; | ||
unsigned char function[state_max_scpd][event_max_scpd]; | ||
unsigned char initial_state; | ||
bool final_states[state_max_scpd]; | ||
}; | ||
|
||
static const struct automaton_scpd automaton_scpd = { | ||
.state_names = { | ||
"cant_sched", | ||
"can_sched" | ||
}, | ||
.event_names = { | ||
"preempt_disable", | ||
"preempt_enable", | ||
"schedule_entry", | ||
"schedule_exit" | ||
}, | ||
.function = { | ||
{ can_sched_scpd, INVALID_STATE, INVALID_STATE, INVALID_STATE }, | ||
{ INVALID_STATE, cant_sched_scpd, can_sched_scpd, can_sched_scpd }, | ||
}, | ||
.initial_state = cant_sched_scpd, | ||
.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_SCPD | ||
DEFINE_EVENT(event_da_monitor, event_scpd, | ||
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_scpd, | ||
TP_PROTO(char *state, char *event), | ||
TP_ARGS(state, event)); | ||
#endif /* CONFIG_RV_MON_SCPD */ |
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-only | ||
# | ||
config RV_MON_SNCID | ||
depends on RV | ||
depends on IRQSOFF_TRACER | ||
depends on RV_MON_SCHED | ||
default y | ||
select DA_MON_EVENTS_IMPLICIT | ||
bool "sncid monitor" | ||
help | ||
Monitor to ensure schedule is not called with interrupt disabled. | ||
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,96 @@ | ||
// 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 "sncid" | ||
|
||
#include <trace/events/sched.h> | ||
#include <trace/events/preemptirq.h> | ||
#include <rv_trace.h> | ||
#include <monitors/sched/sched.h> | ||
|
||
#include "sncid.h" | ||
|
||
static struct rv_monitor rv_sncid; | ||
DECLARE_DA_MON_PER_CPU(sncid, unsigned char); | ||
|
||
static void handle_irq_disable(void *data, unsigned long ip, unsigned long parent_ip) | ||
{ | ||
da_handle_event_sncid(irq_disable_sncid); | ||
} | ||
|
||
static void handle_irq_enable(void *data, unsigned long ip, unsigned long parent_ip) | ||
{ | ||
da_handle_start_event_sncid(irq_enable_sncid); | ||
} | ||
|
||
static void handle_schedule_entry(void *data, bool preempt, unsigned long ip) | ||
{ | ||
da_handle_start_event_sncid(schedule_entry_sncid); | ||
} | ||
|
||
static void handle_schedule_exit(void *data, bool is_switch, unsigned long ip) | ||
{ | ||
da_handle_start_event_sncid(schedule_exit_sncid); | ||
} | ||
|
||
static int enable_sncid(void) | ||
{ | ||
int retval; | ||
|
||
retval = da_monitor_init_sncid(); | ||
if (retval) | ||
return retval; | ||
|
||
rv_attach_trace_probe("sncid", irq_disable, handle_irq_disable); | ||
rv_attach_trace_probe("sncid", irq_enable, handle_irq_enable); | ||
rv_attach_trace_probe("sncid", sched_entry_tp, handle_schedule_entry); | ||
rv_attach_trace_probe("sncid", sched_exit_tp, handle_schedule_exit); | ||
|
||
return 0; | ||
} | ||
|
||
static void disable_sncid(void) | ||
{ | ||
rv_sncid.enabled = 0; | ||
|
||
rv_detach_trace_probe("sncid", irq_disable, handle_irq_disable); | ||
rv_detach_trace_probe("sncid", irq_enable, handle_irq_enable); | ||
rv_detach_trace_probe("sncid", sched_entry_tp, handle_schedule_entry); | ||
rv_detach_trace_probe("sncid", sched_exit_tp, handle_schedule_exit); | ||
|
||
da_monitor_destroy_sncid(); | ||
} | ||
|
||
static struct rv_monitor rv_sncid = { | ||
.name = "sncid", | ||
.description = "schedule not called with interrupt disabled.", | ||
.enable = enable_sncid, | ||
.disable = disable_sncid, | ||
.reset = da_monitor_reset_all_sncid, | ||
.enabled = 0, | ||
}; | ||
|
||
static int __init register_sncid(void) | ||
{ | ||
rv_register_monitor(&rv_sncid, &rv_sched); | ||
return 0; | ||
} | ||
|
||
static void __exit unregister_sncid(void) | ||
{ | ||
rv_unregister_monitor(&rv_sncid); | ||
} | ||
|
||
module_init(register_sncid); | ||
module_exit(unregister_sncid); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); | ||
MODULE_DESCRIPTION("sncid: schedule not called with interrupt disabled."); |
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,49 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Automatically generated C representation of sncid automaton | ||
* For further information about this format, see kernel documentation: | ||
* Documentation/trace/rv/deterministic_automata.rst | ||
*/ | ||
|
||
enum states_sncid { | ||
can_sched_sncid = 0, | ||
cant_sched_sncid, | ||
state_max_sncid | ||
}; | ||
|
||
#define INVALID_STATE state_max_sncid | ||
|
||
enum events_sncid { | ||
irq_disable_sncid = 0, | ||
irq_enable_sncid, | ||
schedule_entry_sncid, | ||
schedule_exit_sncid, | ||
event_max_sncid | ||
}; | ||
|
||
struct automaton_sncid { | ||
char *state_names[state_max_sncid]; | ||
char *event_names[event_max_sncid]; | ||
unsigned char function[state_max_sncid][event_max_sncid]; | ||
unsigned char initial_state; | ||
bool final_states[state_max_sncid]; | ||
}; | ||
|
||
static const struct automaton_sncid automaton_sncid = { | ||
.state_names = { | ||
"can_sched", | ||
"cant_sched" | ||
}, | ||
.event_names = { | ||
"irq_disable", | ||
"irq_enable", | ||
"schedule_entry", | ||
"schedule_exit" | ||
}, | ||
.function = { | ||
{ cant_sched_sncid, INVALID_STATE, can_sched_sncid, can_sched_sncid }, | ||
{ INVALID_STATE, can_sched_sncid, INVALID_STATE, INVALID_STATE }, | ||
}, | ||
.initial_state = can_sched_sncid, | ||
.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_SNCID | ||
DEFINE_EVENT(event_da_monitor, event_sncid, | ||
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_sncid, | ||
TP_PROTO(char *state, char *event), | ||
TP_ARGS(state, event)); | ||
#endif /* CONFIG_RV_MON_SNCID */ |
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-only | ||
# | ||
config RV_MON_SNEP | ||
depends on RV | ||
depends on PREEMPT_TRACER | ||
depends on RV_MON_SCHED | ||
default y | ||
select DA_MON_EVENTS_IMPLICIT | ||
bool "snep monitor" | ||
help | ||
Monitor to ensure schedule does not enable preempt. | ||
This monitor is part of the sched monitors collection. | ||
|
||
For further information, see: | ||
Documentation/trace/rv/monitor_sched.rst |
Oops, something went wrong.