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 "wwnr"
11
12 #include <rv_trace.h>
13 #include <trace/events/sched.h>
14
15 #define RV_MON_TYPE RV_MON_PER_TASK
16 #include "wwnr.h"
17 #include <rv/da_monitor.h>
18
handle_switch(void * data,bool preempt,struct task_struct * p,struct task_struct * n,unsigned int prev_state)19 static void handle_switch(void *data, bool preempt, struct task_struct *p,
20 struct task_struct *n, unsigned int prev_state)
21 {
22 /* start monitoring only after the first suspension */
23 if (prev_state == TASK_INTERRUPTIBLE)
24 da_handle_start_event(p, switch_out_wwnr);
25 else
26 da_handle_event(p, switch_out_wwnr);
27
28 da_handle_event(n, switch_in_wwnr);
29 }
30
handle_wakeup(void * data,struct task_struct * p)31 static void handle_wakeup(void *data, struct task_struct *p)
32 {
33 da_handle_event(p, wakeup_wwnr);
34 }
35
enable_wwnr(void)36 static int enable_wwnr(void)
37 {
38 int retval;
39
40 retval = da_monitor_init();
41 if (retval)
42 return retval;
43
44 rv_attach_trace_probe("wwnr", sched_switch, handle_switch);
45 rv_attach_trace_probe("wwnr", sched_wakeup, handle_wakeup);
46
47 return 0;
48 }
49
disable_wwnr(void)50 static void disable_wwnr(void)
51 {
52 rv_this.enabled = 0;
53
54 rv_detach_trace_probe("wwnr", sched_switch, handle_switch);
55 rv_detach_trace_probe("wwnr", sched_wakeup, handle_wakeup);
56
57 da_monitor_destroy();
58 }
59
60 static struct rv_monitor rv_this = {
61 .name = "wwnr",
62 .description = "wakeup while not running per-task testing model.",
63 .enable = enable_wwnr,
64 .disable = disable_wwnr,
65 .reset = da_monitor_reset_all,
66 .enabled = 0,
67 };
68
register_wwnr(void)69 static int __init register_wwnr(void)
70 {
71 return rv_register_monitor(&rv_this, NULL);
72 }
73
unregister_wwnr(void)74 static void __exit unregister_wwnr(void)
75 {
76 rv_unregister_monitor(&rv_this);
77 }
78
79 module_init(register_wwnr);
80 module_exit(unregister_wwnr);
81
82 MODULE_LICENSE("GPL");
83 MODULE_AUTHOR("Daniel Bristot de Oliveira <bristot@kernel.org>");
84 MODULE_DESCRIPTION("wwnr: wakeup while not running monitor");
85