xref: /linux/kernel/trace/rv/monitors/scpd/scpd.c (revision ca220141fa8ebae09765a242076b2b77338106b0)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ftrace.h>
3 #include <linux/tracepoint.h>
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/init.h>
7 #include <linux/rv.h>
8 #include <rv/instrumentation.h>
9 
10 #define MODULE_NAME "scpd"
11 
12 #include <trace/events/sched.h>
13 #include <trace/events/preemptirq.h>
14 #include <rv_trace.h>
15 #include <monitors/sched/sched.h>
16 
17 #define RV_MON_TYPE RV_MON_PER_CPU
18 #include "scpd.h"
19 #include <rv/da_monitor.h>
20 
21 static void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip)
22 {
23 	da_handle_event(preempt_disable_scpd);
24 }
25 
26 static void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip)
27 {
28 	da_handle_start_event(preempt_enable_scpd);
29 }
30 
31 static void handle_schedule_entry(void *data, bool preempt)
32 {
33 	da_handle_event(schedule_entry_scpd);
34 }
35 
36 static void handle_schedule_exit(void *data, bool is_switch)
37 {
38 	da_handle_event(schedule_exit_scpd);
39 }
40 
41 static int enable_scpd(void)
42 {
43 	int retval;
44 
45 	retval = da_monitor_init();
46 	if (retval)
47 		return retval;
48 
49 	rv_attach_trace_probe("scpd", preempt_disable, handle_preempt_disable);
50 	rv_attach_trace_probe("scpd", preempt_enable, handle_preempt_enable);
51 	rv_attach_trace_probe("scpd", sched_entry_tp, handle_schedule_entry);
52 	rv_attach_trace_probe("scpd", sched_exit_tp, handle_schedule_exit);
53 
54 	return 0;
55 }
56 
57 static void disable_scpd(void)
58 {
59 	rv_this.enabled = 0;
60 
61 	rv_detach_trace_probe("scpd", preempt_disable, handle_preempt_disable);
62 	rv_detach_trace_probe("scpd", preempt_enable, handle_preempt_enable);
63 	rv_detach_trace_probe("scpd", sched_entry_tp, handle_schedule_entry);
64 	rv_detach_trace_probe("scpd", sched_exit_tp, handle_schedule_exit);
65 
66 	da_monitor_destroy();
67 }
68 
69 static struct rv_monitor rv_this = {
70 	.name = "scpd",
71 	.description = "schedule called with preemption disabled.",
72 	.enable = enable_scpd,
73 	.disable = disable_scpd,
74 	.reset = da_monitor_reset_all,
75 	.enabled = 0,
76 };
77 
78 static int __init register_scpd(void)
79 {
80 	return rv_register_monitor(&rv_this, &rv_sched);
81 }
82 
83 static void __exit unregister_scpd(void)
84 {
85 	rv_unregister_monitor(&rv_this);
86 }
87 
88 module_init(register_scpd);
89 module_exit(unregister_scpd);
90 
91 MODULE_LICENSE("GPL");
92 MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>");
93 MODULE_DESCRIPTION("scpd: schedule called with preemption disabled.");
94