// SPDX-License-Identifier: GPL-2.0 #include #include #include #include #include #include #include #define MODULE_NAME "scpd" #include #include #include #include #define RV_MON_TYPE RV_MON_PER_CPU #include "scpd.h" #include static void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip) { da_handle_event(preempt_disable_scpd); } static void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip) { da_handle_start_event(preempt_enable_scpd); } static void handle_schedule_entry(void *data, bool preempt) { da_handle_event(schedule_entry_scpd); } static void handle_schedule_exit(void *data, bool is_switch) { da_handle_event(schedule_exit_scpd); } static int enable_scpd(void) { int retval; retval = da_monitor_init(); 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_this.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(); } static struct rv_monitor rv_this = { .name = "scpd", .description = "schedule called with preemption disabled.", .enable = enable_scpd, .disable = disable_scpd, .reset = da_monitor_reset_all, .enabled = 0, }; static int __init register_scpd(void) { return rv_register_monitor(&rv_this, &rv_sched); } static void __exit unregister_scpd(void) { rv_unregister_monitor(&rv_this); } module_init(register_scpd); module_exit(unregister_scpd); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Gabriele Monaco "); MODULE_DESCRIPTION("scpd: schedule called with preemption disabled.");