1*655d4809SGabriele Monaco // SPDX-License-Identifier: GPL-2.0 2*655d4809SGabriele Monaco #include <linux/ftrace.h> 3*655d4809SGabriele Monaco #include <linux/tracepoint.h> 4*655d4809SGabriele Monaco #include <linux/kernel.h> 5*655d4809SGabriele Monaco #include <linux/module.h> 6*655d4809SGabriele Monaco #include <linux/init.h> 7*655d4809SGabriele Monaco #include <linux/rv.h> 8*655d4809SGabriele Monaco #include <rv/instrumentation.h> 9*655d4809SGabriele Monaco 10*655d4809SGabriele Monaco #define MODULE_NAME "test_ltl" 11*655d4809SGabriele Monaco 12*655d4809SGabriele Monaco /* 13*655d4809SGabriele Monaco * XXX: include required tracepoint headers, e.g., 14*655d4809SGabriele Monaco * #include <trace/events/sched.h> 15*655d4809SGabriele Monaco */ 16*655d4809SGabriele Monaco #include <rv_trace.h> 17*655d4809SGabriele Monaco #include <monitors/ltl_parent/ltl_parent.h> 18*655d4809SGabriele Monaco 19*655d4809SGabriele Monaco 20*655d4809SGabriele Monaco /* 21*655d4809SGabriele Monaco * This is the self-generated part of the monitor. Generally, there is no need 22*655d4809SGabriele Monaco * to touch this section. 23*655d4809SGabriele Monaco */ 24*655d4809SGabriele Monaco #include "test_ltl.h" 25*655d4809SGabriele Monaco #include <rv/ltl_monitor.h> 26*655d4809SGabriele Monaco 27*655d4809SGabriele Monaco static void ltl_atoms_fetch(struct task_struct *task, struct ltl_monitor *mon) 28*655d4809SGabriele Monaco { 29*655d4809SGabriele Monaco /* 30*655d4809SGabriele Monaco * This is called everytime the Buchi automaton is triggered. 31*655d4809SGabriele Monaco * 32*655d4809SGabriele Monaco * This function could be used to fetch the atomic propositions which 33*655d4809SGabriele Monaco * are expensive to trace. It is possible only if the atomic proposition 34*655d4809SGabriele Monaco * does not need to be updated at precise time. 35*655d4809SGabriele Monaco * 36*655d4809SGabriele Monaco * It is recommended to use tracepoints and ltl_atom_update() instead. 37*655d4809SGabriele Monaco */ 38*655d4809SGabriele Monaco } 39*655d4809SGabriele Monaco 40*655d4809SGabriele Monaco static void ltl_atoms_init(struct task_struct *task, struct ltl_monitor *mon, bool task_creation) 41*655d4809SGabriele Monaco { 42*655d4809SGabriele Monaco /* 43*655d4809SGabriele Monaco * This should initialize as many atomic propositions as possible. 44*655d4809SGabriele Monaco * 45*655d4809SGabriele Monaco * @task_creation indicates whether the task is being created. This is 46*655d4809SGabriele Monaco * false if the task is already running before the monitor is enabled. 47*655d4809SGabriele Monaco */ 48*655d4809SGabriele Monaco ltl_atom_set(mon, LTL_EVENT_A, true/false); 49*655d4809SGabriele Monaco ltl_atom_set(mon, LTL_EVENT_B, true/false); 50*655d4809SGabriele Monaco } 51*655d4809SGabriele Monaco 52*655d4809SGabriele Monaco /* 53*655d4809SGabriele Monaco * This is the instrumentation part of the monitor. 54*655d4809SGabriele Monaco * 55*655d4809SGabriele Monaco * This is the section where manual work is required. Here the kernel events 56*655d4809SGabriele Monaco * are translated into model's event. 57*655d4809SGabriele Monaco */ 58*655d4809SGabriele Monaco static void handle_example_event(void *data, /* XXX: fill header */) 59*655d4809SGabriele Monaco { 60*655d4809SGabriele Monaco ltl_atom_update(task, LTL_EVENT_A, true/false); 61*655d4809SGabriele Monaco } 62*655d4809SGabriele Monaco 63*655d4809SGabriele Monaco static int enable_test_ltl(void) 64*655d4809SGabriele Monaco { 65*655d4809SGabriele Monaco int retval; 66*655d4809SGabriele Monaco 67*655d4809SGabriele Monaco retval = ltl_monitor_init(); 68*655d4809SGabriele Monaco if (retval) 69*655d4809SGabriele Monaco return retval; 70*655d4809SGabriele Monaco 71*655d4809SGabriele Monaco rv_attach_trace_probe("test_ltl", /* XXX: tracepoint */, handle_example_event); 72*655d4809SGabriele Monaco 73*655d4809SGabriele Monaco return 0; 74*655d4809SGabriele Monaco } 75*655d4809SGabriele Monaco 76*655d4809SGabriele Monaco static void disable_test_ltl(void) 77*655d4809SGabriele Monaco { 78*655d4809SGabriele Monaco rv_detach_trace_probe("test_ltl", /* XXX: tracepoint */, handle_example_event); 79*655d4809SGabriele Monaco 80*655d4809SGabriele Monaco ltl_monitor_destroy(); 81*655d4809SGabriele Monaco } 82*655d4809SGabriele Monaco 83*655d4809SGabriele Monaco /* 84*655d4809SGabriele Monaco * This is the monitor register section. 85*655d4809SGabriele Monaco */ 86*655d4809SGabriele Monaco static struct rv_monitor rv_this = { 87*655d4809SGabriele Monaco .name = "test_ltl", 88*655d4809SGabriele Monaco .description = "Simple description", 89*655d4809SGabriele Monaco .enable = enable_test_ltl, 90*655d4809SGabriele Monaco .disable = disable_test_ltl, 91*655d4809SGabriele Monaco }; 92*655d4809SGabriele Monaco 93*655d4809SGabriele Monaco static int __init register_test_ltl(void) 94*655d4809SGabriele Monaco { 95*655d4809SGabriele Monaco return rv_register_monitor(&rv_this, &rv_ltl_parent); 96*655d4809SGabriele Monaco } 97*655d4809SGabriele Monaco 98*655d4809SGabriele Monaco static void __exit unregister_test_ltl(void) 99*655d4809SGabriele Monaco { 100*655d4809SGabriele Monaco rv_unregister_monitor(&rv_this); 101*655d4809SGabriele Monaco } 102*655d4809SGabriele Monaco 103*655d4809SGabriele Monaco module_init(register_test_ltl); 104*655d4809SGabriele Monaco module_exit(unregister_test_ltl); 105*655d4809SGabriele Monaco 106*655d4809SGabriele Monaco MODULE_LICENSE("GPL"); 107*655d4809SGabriele Monaco MODULE_AUTHOR("rvgen: auto-generated"); 108*655d4809SGabriele Monaco MODULE_DESCRIPTION("test_ltl: Simple description"); 109