Merge tools/for-next

This commit is contained in:
Steven Rostedt (Google) 2025-01-08 14:51:26 -05:00
commit 6492781961
20 changed files with 418 additions and 362 deletions

View File

@ -25,30 +25,9 @@ menuconfig RV
For further information, see: For further information, see:
Documentation/trace/rv/runtime-verification.rst Documentation/trace/rv/runtime-verification.rst
config RV_MON_WIP source "kernel/trace/rv/monitors/wip/Kconfig"
depends on RV source "kernel/trace/rv/monitors/wwnr/Kconfig"
depends on PREEMPT_TRACER # Add new monitors here
select DA_MON_EVENTS_IMPLICIT
bool "wip monitor"
help
Enable wip (wakeup in preemptive) sample monitor that illustrates
the usage of per-cpu monitors, and one limitation of the
preempt_disable/enable events.
For further information, see:
Documentation/trace/rv/monitor_wip.rst
config RV_MON_WWNR
depends on RV
select DA_MON_EVENTS_ID
bool "wwnr monitor"
help
Enable wwnr (wakeup while not running) sample monitor, this is a
sample monitor that illustrates the usage of per-task monitor.
The model is borken on purpose: it serves to test reactors.
For further information, see:
Documentation/trace/rv/monitor_wwnr.rst
config RV_REACTORS config RV_REACTORS
bool "Runtime verification reactors" bool "Runtime verification reactors"

View File

@ -1,8 +1,11 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
ccflags-y += -I $(src) # needed for trace events
obj-$(CONFIG_RV) += rv.o obj-$(CONFIG_RV) += rv.o
obj-$(CONFIG_RV_MON_WIP) += monitors/wip/wip.o obj-$(CONFIG_RV_MON_WIP) += monitors/wip/wip.o
obj-$(CONFIG_RV_MON_WWNR) += monitors/wwnr/wwnr.o obj-$(CONFIG_RV_MON_WWNR) += monitors/wwnr/wwnr.o
# Add new monitors here
obj-$(CONFIG_RV_REACTORS) += rv_reactors.o obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o
obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o

View File

@ -0,0 +1,12 @@
config RV_MON_WIP
depends on RV
depends on PREEMPT_TRACER
select DA_MON_EVENTS_IMPLICIT
bool "wip monitor"
help
Enable wip (wakeup in preemptive) sample monitor that illustrates
the usage of per-cpu monitors, and one limitation of the
preempt_disable/enable events.
For further information, see:
Documentation/trace/rv/monitor_wip.rst

View File

@ -10,7 +10,7 @@
#define MODULE_NAME "wip" #define MODULE_NAME "wip"
#include <trace/events/rv.h> #include <rv_trace.h>
#include <trace/events/sched.h> #include <trace/events/sched.h>
#include <trace/events/preemptirq.h> #include <trace/events/preemptirq.h>

View File

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Snippet to be included in rv_trace.h
*/
#ifdef CONFIG_RV_MON_WIP
DEFINE_EVENT(event_da_monitor, event_wip,
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_wip,
TP_PROTO(char *state, char *event),
TP_ARGS(state, event));
#endif /* CONFIG_RV_MON_WIP */

View File

@ -0,0 +1,11 @@
config RV_MON_WWNR
depends on RV
select DA_MON_EVENTS_ID
bool "wwnr monitor"
help
Enable wwnr (wakeup while not running) sample monitor, this is a
sample monitor that illustrates the usage of per-task monitor.
The model is borken on purpose: it serves to test reactors.
For further information, see:
Documentation/trace/rv/monitor_wwnr.rst

View File

@ -10,7 +10,7 @@
#define MODULE_NAME "wwnr" #define MODULE_NAME "wwnr"
#include <trace/events/rv.h> #include <rv_trace.h>
#include <trace/events/sched.h> #include <trace/events/sched.h>
#include "wwnr.h" #include "wwnr.h"

View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Snippet to be included in rv_trace.h
*/
#ifdef CONFIG_RV_MON_WWNR
/* id is the pid of the task */
DEFINE_EVENT(event_da_monitor_id, event_wwnr,
TP_PROTO(int id, char *state, char *event, char *next_state, bool final_state),
TP_ARGS(id, state, event, next_state, final_state));
DEFINE_EVENT(error_da_monitor_id, error_wwnr,
TP_PROTO(int id, char *state, char *event),
TP_ARGS(id, state, event));
#endif /* CONFIG_RV_MON_WWNR */

View File

@ -145,7 +145,7 @@
#ifdef CONFIG_DA_MON_EVENTS #ifdef CONFIG_DA_MON_EVENTS
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/rv.h> #include <rv_trace.h>
#endif #endif
#include "rv.h" #include "rv.h"

View File

@ -57,15 +57,9 @@ DECLARE_EVENT_CLASS(error_da_monitor,
__entry->state) __entry->state)
); );
#ifdef CONFIG_RV_MON_WIP #include <monitors/wip/wip_trace.h>
DEFINE_EVENT(event_da_monitor, event_wip, // Add new monitors based on CONFIG_DA_MON_EVENTS_IMPLICIT here
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_wip,
TP_PROTO(char *state, char *event),
TP_ARGS(state, event));
#endif /* CONFIG_RV_MON_WIP */
#endif /* CONFIG_DA_MON_EVENTS_IMPLICIT */ #endif /* CONFIG_DA_MON_EVENTS_IMPLICIT */
#ifdef CONFIG_DA_MON_EVENTS_ID #ifdef CONFIG_DA_MON_EVENTS_ID
@ -123,20 +117,14 @@ DECLARE_EVENT_CLASS(error_da_monitor_id,
__entry->state) __entry->state)
); );
#ifdef CONFIG_RV_MON_WWNR #include <monitors/wwnr/wwnr_trace.h>
/* id is the pid of the task */ // Add new monitors based on CONFIG_DA_MON_EVENTS_ID here
DEFINE_EVENT(event_da_monitor_id, event_wwnr,
TP_PROTO(int id, char *state, char *event, char *next_state, bool final_state),
TP_ARGS(id, state, event, next_state, final_state));
DEFINE_EVENT(error_da_monitor_id, error_wwnr,
TP_PROTO(int id, char *state, char *event),
TP_ARGS(id, state, event));
#endif /* CONFIG_RV_MON_WWNR */
#endif /* CONFIG_DA_MON_EVENTS_ID */ #endif /* CONFIG_DA_MON_EVENTS_ID */
#endif /* _TRACE_RV_H */ #endif /* _TRACE_RV_H */
/* This part ust be outside protection */ /* This part ust be outside protection */
#undef TRACE_INCLUDE_PATH #undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE rv_trace
#include <trace/define_trace.h> #include <trace/define_trace.h>

View File

@ -19,13 +19,14 @@ class Automata:
invalid_state_str = "INVALID_STATE" invalid_state_str = "INVALID_STATE"
def __init__(self, file_path): def __init__(self, file_path, model_name=None):
self.__dot_path = file_path self.__dot_path = file_path
self.name = self.__get_model_name() self.name = model_name or self.__get_model_name()
self.__dot_lines = self.__open_dot() self.__dot_lines = self.__open_dot()
self.states, self.initial_state, self.final_states = self.__get_state_variables() self.states, self.initial_state, self.final_states = self.__get_state_variables()
self.events = self.__get_event_variables() self.events = self.__get_event_variables()
self.function = self.__create_matrix() self.function = self.__create_matrix()
self.events_start, self.events_start_run = self.__store_init_events()
def __get_model_name(self): def __get_model_name(self):
basename = ntpath.basename(self.__dot_path) basename = ntpath.basename(self.__dot_path)
@ -172,3 +173,34 @@ class Automata:
cursor += 1 cursor += 1
return matrix return matrix
def __store_init_events(self):
events_start = [False] * len(self.events)
events_start_run = [False] * len(self.events)
for i, _ in enumerate(self.events):
curr_event_will_init = 0
curr_event_from_init = False
curr_event_used = 0
for j, _ in enumerate(self.states):
if self.function[j][i] != self.invalid_state_str:
curr_event_used += 1
if self.function[j][i] == self.initial_state:
curr_event_will_init += 1
if self.function[0][i] != self.invalid_state_str:
curr_event_from_init = True
# this event always leads to init
if curr_event_will_init and curr_event_used == curr_event_will_init:
events_start[i] = True
# this event is only called from init
if curr_event_from_init and curr_event_used == 1:
events_start_run[i] = True
return events_start, events_start_run
def is_start_event(self, event):
return self.events_start[self.events.index(event)]
def is_start_run_event(self, event):
# prefer handle_start_event if there
if any(self.events_start):
return False
return self.events_start_run[self.events.index(event)]

View File

@ -22,8 +22,8 @@ class Dot2c(Automata):
struct_automaton_def = "automaton" struct_automaton_def = "automaton"
var_automaton_def = "aut" var_automaton_def = "aut"
def __init__(self, file_path): def __init__(self, file_path, model_name=None):
super().__init__(file_path) super().__init__(file_path, model_name)
self.line_length = 100 self.line_length = 100
def __buff_to_string(self, buff): def __buff_to_string(self, buff):

View File

@ -21,25 +21,24 @@ if __name__ == '__main__':
parser.add_argument('-t', "--monitor_type", dest="monitor_type", required=True) parser.add_argument('-t', "--monitor_type", dest="monitor_type", required=True)
parser.add_argument('-n', "--model_name", dest="model_name", required=False) parser.add_argument('-n', "--model_name", dest="model_name", required=False)
parser.add_argument("-D", "--description", dest="description", required=False) parser.add_argument("-D", "--description", dest="description", required=False)
parser.add_argument("-a", "--auto_patch", dest="auto_patch",
action="store_true", required=False,
help="Patch the kernel in place")
params = parser.parse_args() params = parser.parse_args()
print("Opening and parsing the dot file %s" % params.dot_file) print("Opening and parsing the dot file %s" % params.dot_file)
try: try:
monitor=dot2k(params.dot_file, params.monitor_type) monitor=dot2k(params.dot_file, params.monitor_type, vars(params))
except Exception as e: except Exception as e:
print('Error: '+ str(e)) print('Error: '+ str(e))
print("Sorry : :-(") print("Sorry : :-(")
sys.exit(1) sys.exit(1)
# easier than using argparse action.
if params.model_name != None:
print(params.model_name)
print("Writing the monitor into the directory %s" % monitor.name) print("Writing the monitor into the directory %s" % monitor.name)
monitor.print_files() monitor.print_files()
print("Almost done, checklist") print("Almost done, checklist")
print(" - Edit the %s/%s.c to add the instrumentation" % (monitor.name, monitor.name)) print(" - Edit the %s/%s.c to add the instrumentation" % (monitor.name, monitor.name))
print(" - Edit include/trace/events/rv.h to add the tracepoint entry") print(monitor.fill_tracepoint_tooltip())
print(" - Move it to the kernel's monitor directory") print(monitor.fill_makefile_tooltip())
print(" - Edit kernel/trace/rv/Makefile") print(monitor.fill_kconfig_tooltip())
print(" - Edit kernel/trace/rv/Kconfig") print(monitor.fill_monitor_tooltip())

View File

@ -14,50 +14,83 @@ import os
class dot2k(Dot2c): class dot2k(Dot2c):
monitor_types = { "global" : 1, "per_cpu" : 2, "per_task" : 3 } monitor_types = { "global" : 1, "per_cpu" : 2, "per_task" : 3 }
monitor_templates_dir = "dot2k/rv_templates/" monitor_templates_dir = "dot2/dot2k_templates/"
rv_dir = "kernel/trace/rv"
monitor_type = "per_cpu" monitor_type = "per_cpu"
def __init__(self, file_path, MonitorType): def __init__(self, file_path, MonitorType, extra_params={}):
super().__init__(file_path) super().__init__(file_path, extra_params.get("model_name"))
self.monitor_type = self.monitor_types.get(MonitorType) self.monitor_type = self.monitor_types.get(MonitorType)
if self.monitor_type == None: if self.monitor_type is None:
raise Exception("Unknown monitor type: %s" % MonitorType) raise ValueError("Unknown monitor type: %s" % MonitorType)
self.monitor_type = MonitorType self.monitor_type = MonitorType
self.__fill_rv_templates_dir() self.__fill_rv_templates_dir()
self.main_c = self.__open_file(self.monitor_templates_dir + "main_" + MonitorType + ".c") self.main_c = self.__read_file(self.monitor_templates_dir + "main.c")
self.trace_h = self.__read_file(self.monitor_templates_dir + "trace.h")
self.kconfig = self.__read_file(self.monitor_templates_dir + "Kconfig")
self.enum_suffix = "_%s" % self.name self.enum_suffix = "_%s" % self.name
self.description = extra_params.get("description", self.name) or "auto-generated"
self.auto_patch = extra_params.get("auto_patch")
if self.auto_patch:
self.__fill_rv_kernel_dir()
def __fill_rv_templates_dir(self): def __fill_rv_templates_dir(self):
if os.path.exists(self.monitor_templates_dir) == True: if os.path.exists(self.monitor_templates_dir):
return return
if platform.system() != "Linux": if platform.system() != "Linux":
raise Exception("I can only run on Linux.") raise OSError("I can only run on Linux.")
kernel_path = "/lib/modules/%s/build/tools/verification/dot2/dot2k_templates/" % (platform.release()) kernel_path = "/lib/modules/%s/build/tools/verification/dot2/dot2k_templates/" % (platform.release())
if os.path.exists(kernel_path) == True: if os.path.exists(kernel_path):
self.monitor_templates_dir = kernel_path self.monitor_templates_dir = kernel_path
return return
if os.path.exists("/usr/share/dot2/dot2k_templates/") == True: if os.path.exists("/usr/share/dot2/dot2k_templates/"):
self.monitor_templates_dir = "/usr/share/dot2/dot2k_templates/" self.monitor_templates_dir = "/usr/share/dot2/dot2k_templates/"
return return
raise Exception("Could not find the template directory, do you have the kernel source installed?") raise FileNotFoundError("Could not find the template directory, do you have the kernel source installed?")
def __fill_rv_kernel_dir(self):
def __open_file(self, path): # first try if we are running in the kernel tree root
if os.path.exists(self.rv_dir):
return
# offset if we are running inside the kernel tree from verification/dot2
kernel_path = os.path.join("../..", self.rv_dir)
if os.path.exists(kernel_path):
self.rv_dir = kernel_path
return
if platform.system() != "Linux":
raise OSError("I can only run on Linux.")
kernel_path = os.path.join("/lib/modules/%s/build" % platform.release(), self.rv_dir)
# if the current kernel is from a distro this may not be a full kernel tree
# verify that one of the files we are going to modify is available
if os.path.exists(os.path.join(kernel_path, "rv_trace.h")):
self.rv_dir = kernel_path
return
raise FileNotFoundError("Could not find the rv directory, do you have the kernel source installed?")
def __read_file(self, path):
try: try:
fd = open(path) fd = open(path, 'r')
except OSError: except OSError:
raise Exception("Cannot open the file: %s" % path) raise Exception("Cannot open the file: %s" % path)
content = fd.read() content = fd.read()
fd.close()
return content return content
def __buff_to_string(self, buff): def __buff_to_string(self, buff):
@ -69,16 +102,26 @@ class dot2k(Dot2c):
# cut off the last \n # cut off the last \n
return string[:-1] return string[:-1]
def fill_monitor_type(self):
return self.monitor_type.upper()
def fill_tracepoint_handlers_skel(self): def fill_tracepoint_handlers_skel(self):
buff = [] buff = []
for event in self.events: for event in self.events:
buff.append("static void handle_%s(void *data, /* XXX: fill header */)" % event) buff.append("static void handle_%s(void *data, /* XXX: fill header */)" % event)
buff.append("{") buff.append("{")
handle = "handle_event"
if self.is_start_event(event):
buff.append("\t/* XXX: validate that this event always leads to the initial state */")
handle = "handle_start_event"
elif self.is_start_run_event(event):
buff.append("\t/* XXX: validate that this event is only valid in the initial state */")
handle = "handle_start_run_event"
if self.monitor_type == "per_task": if self.monitor_type == "per_task":
buff.append("\tstruct task_struct *p = /* XXX: how do I get p? */;"); buff.append("\tstruct task_struct *p = /* XXX: how do I get p? */;");
buff.append("\tda_handle_event_%s(p, %s%s);" % (self.name, event, self.enum_suffix)); buff.append("\tda_%s_%s(p, %s%s);" % (handle, self.name, event, self.enum_suffix));
else: else:
buff.append("\tda_handle_event_%s(%s%s);" % (self.name, event, self.enum_suffix)); buff.append("\tda_%s_%s(%s%s);" % (handle, self.name, event, self.enum_suffix));
buff.append("}") buff.append("}")
buff.append("") buff.append("")
return self.__buff_to_string(buff) return self.__buff_to_string(buff)
@ -97,18 +140,21 @@ class dot2k(Dot2c):
def fill_main_c(self): def fill_main_c(self):
main_c = self.main_c main_c = self.main_c
monitor_type = self.fill_monitor_type()
min_type = self.get_minimun_type() min_type = self.get_minimun_type()
nr_events = self.events.__len__() nr_events = len(self.events)
tracepoint_handlers = self.fill_tracepoint_handlers_skel() tracepoint_handlers = self.fill_tracepoint_handlers_skel()
tracepoint_attach = self.fill_tracepoint_attach_probe() tracepoint_attach = self.fill_tracepoint_attach_probe()
tracepoint_detach = self.fill_tracepoint_detach_helper() tracepoint_detach = self.fill_tracepoint_detach_helper()
main_c = main_c.replace("MIN_TYPE", min_type) main_c = main_c.replace("%%MONITOR_TYPE%%", monitor_type)
main_c = main_c.replace("MODEL_NAME", self.name) main_c = main_c.replace("%%MIN_TYPE%%", min_type)
main_c = main_c.replace("NR_EVENTS", str(nr_events)) main_c = main_c.replace("%%MODEL_NAME%%", self.name)
main_c = main_c.replace("TRACEPOINT_HANDLERS_SKEL", tracepoint_handlers) main_c = main_c.replace("%%NR_EVENTS%%", str(nr_events))
main_c = main_c.replace("TRACEPOINT_ATTACH", tracepoint_attach) main_c = main_c.replace("%%TRACEPOINT_HANDLERS_SKEL%%", tracepoint_handlers)
main_c = main_c.replace("TRACEPOINT_DETACH", tracepoint_detach) main_c = main_c.replace("%%TRACEPOINT_ATTACH%%", tracepoint_attach)
main_c = main_c.replace("%%TRACEPOINT_DETACH%%", tracepoint_detach)
main_c = main_c.replace("%%DESCRIPTION%%", self.description)
return main_c return main_c
@ -137,31 +183,142 @@ class dot2k(Dot2c):
return self.__buff_to_string(buff) return self.__buff_to_string(buff)
def fill_monitor_class_type(self):
if self.monitor_type == "per_task":
return "DA_MON_EVENTS_ID"
return "DA_MON_EVENTS_IMPLICIT"
def fill_monitor_class(self):
if self.monitor_type == "per_task":
return "da_monitor_id"
return "da_monitor"
def fill_tracepoint_args_skel(self, tp_type):
buff = []
tp_args_event = [
("char *", "state"),
("char *", "event"),
("char *", "next_state"),
("bool ", "final_state"),
]
tp_args_error = [
("char *", "state"),
("char *", "event"),
]
tp_args_id = ("int ", "id")
tp_args = tp_args_event if tp_type == "event" else tp_args_error
if self.monitor_type == "per_task":
tp_args.insert(0, tp_args_id)
tp_proto_c = ", ".join([a+b for a,b in tp_args])
tp_args_c = ", ".join([b for a,b in tp_args])
buff.append(" TP_PROTO(%s)," % tp_proto_c)
buff.append(" TP_ARGS(%s)" % tp_args_c)
return self.__buff_to_string(buff)
def fill_trace_h(self):
trace_h = self.trace_h
monitor_class = self.fill_monitor_class()
monitor_class_type = self.fill_monitor_class_type()
tracepoint_args_skel_event = self.fill_tracepoint_args_skel("event")
tracepoint_args_skel_error = self.fill_tracepoint_args_skel("error")
trace_h = trace_h.replace("%%MODEL_NAME%%", self.name)
trace_h = trace_h.replace("%%MODEL_NAME_UP%%", self.name.upper())
trace_h = trace_h.replace("%%MONITOR_CLASS%%", monitor_class)
trace_h = trace_h.replace("%%MONITOR_CLASS_TYPE%%", monitor_class_type)
trace_h = trace_h.replace("%%TRACEPOINT_ARGS_SKEL_EVENT%%", tracepoint_args_skel_event)
trace_h = trace_h.replace("%%TRACEPOINT_ARGS_SKEL_ERROR%%", tracepoint_args_skel_error)
return trace_h
def fill_kconfig(self):
kconfig = self.kconfig
monitor_class_type = self.fill_monitor_class_type()
kconfig = kconfig.replace("%%MODEL_NAME%%", self.name)
kconfig = kconfig.replace("%%MODEL_NAME_UP%%", self.name.upper())
kconfig = kconfig.replace("%%MONITOR_CLASS_TYPE%%", monitor_class_type)
kconfig = kconfig.replace("%%DESCRIPTION%%", self.description)
return kconfig
def __patch_file(self, file, marker, line):
file_to_patch = os.path.join(self.rv_dir, file)
content = self.__read_file(file_to_patch)
content = content.replace(marker, line + "\n" + marker)
self.__write_file(file_to_patch, content)
def fill_tracepoint_tooltip(self):
monitor_class_type = self.fill_monitor_class_type()
if self.auto_patch:
self.__patch_file("rv_trace.h",
"// Add new monitors based on CONFIG_%s here" % monitor_class_type,
"#include <monitors/%s/%s_trace.h>" % (self.name, self.name))
return " - Patching %s/rv_trace.h, double check the result" % self.rv_dir
return """ - Edit %s/rv_trace.h:
Add this line where other tracepoints are included and %s is defined:
#include <monitors/%s/%s_trace.h>
""" % (self.rv_dir, monitor_class_type, self.name, self.name)
def fill_kconfig_tooltip(self):
if self.auto_patch:
self.__patch_file("Kconfig",
"# Add new monitors here",
"source \"kernel/trace/rv/monitors/%s/Kconfig\"" % (self.name))
return " - Patching %s/Kconfig, double check the result" % self.rv_dir
return """ - Edit %s/Kconfig:
Add this line where other monitors are included:
source \"kernel/trace/rv/monitors/%s/Kconfig\"
""" % (self.rv_dir, self.name)
def fill_makefile_tooltip(self):
name = self.name
name_up = name.upper()
if self.auto_patch:
self.__patch_file("Makefile",
"# Add new monitors here",
"obj-$(CONFIG_RV_MON_%s) += monitors/%s/%s.o" % (name_up, name, name))
return " - Patching %s/Makefile, double check the result" % self.rv_dir
return """ - Edit %s/Makefile:
Add this line where other monitors are included:
obj-$(CONFIG_RV_MON_%s) += monitors/%s/%s.o
""" % (self.rv_dir, name_up, name, name)
def fill_monitor_tooltip(self):
if self.auto_patch:
return " - Monitor created in %s/monitors/%s" % (self.rv_dir, self. name)
return " - Move %s/ to the kernel's monitor directory (%s/monitors)" % (self.name, self.rv_dir)
def __create_directory(self): def __create_directory(self):
path = self.name
if self.auto_patch:
path = os.path.join(self.rv_dir, "monitors", path)
try: try:
os.mkdir(self.name) os.mkdir(path)
except FileExistsError: except FileExistsError:
return return
except: except:
print("Fail creating the output dir: %s" % self.name) print("Fail creating the output dir: %s" % self.name)
def __create_file(self, file_name, content): def __write_file(self, file_name, content):
path = "%s/%s" % (self.name, file_name)
try: try:
file = open(path, 'w') file = open(file_name, 'w')
except FileExistsError:
return
except: except:
print("Fail creating file: %s" % path) print("Fail writing to file: %s" % file_name)
file.write(content) file.write(content)
file.close() file.close()
def __create_file(self, file_name, content):
path = "%s/%s" % (self.name, file_name)
if self.auto_patch:
path = os.path.join(self.rv_dir, "monitors", path)
self.__write_file(path, content)
def __get_main_name(self): def __get_main_name(self):
path = "%s/%s" % (self.name, "main.c") path = "%s/%s" % (self.name, "main.c")
if os.path.exists(path) == False: if not os.path.exists(path):
return "main.c" return "main.c"
return "__main.c" return "__main.c"
def print_files(self): def print_files(self):
@ -175,3 +332,10 @@ class dot2k(Dot2c):
path = "%s.h" % self.name path = "%s.h" % self.name
self.__create_file(path, model_h) self.__create_file(path, model_h)
trace_h = self.fill_trace_h()
path = "%s_trace.h" % self.name
self.__create_file(path, trace_h)
kconfig = self.fill_kconfig()
self.__create_file("Kconfig", kconfig)

View File

@ -0,0 +1,6 @@
config RV_MON_%%MODEL_NAME_UP%%
depends on RV
select %%MONITOR_CLASS_TYPE%%
bool "%%MODEL_NAME%% monitor"
help
%%DESCRIPTION%%

View File

@ -0,0 +1,91 @@
// 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 "%%MODEL_NAME%%"
/*
* XXX: include required tracepoint headers, e.g.,
* #include <trace/events/sched.h>
*/
#include <rv_trace.h>
/*
* This is the self-generated part of the monitor. Generally, there is no need
* to touch this section.
*/
#include "%%MODEL_NAME%%.h"
/*
* Declare the deterministic automata monitor.
*
* The rv monitor reference is needed for the monitor declaration.
*/
static struct rv_monitor rv_%%MODEL_NAME%%;
DECLARE_DA_MON_%%MONITOR_TYPE%%(%%MODEL_NAME%%, %%MIN_TYPE%%);
/*
* This is the instrumentation part of the monitor.
*
* This is the section where manual work is required. Here the kernel events
* are translated into model's event.
*
*/
%%TRACEPOINT_HANDLERS_SKEL%%
static int enable_%%MODEL_NAME%%(void)
{
int retval;
retval = da_monitor_init_%%MODEL_NAME%%();
if (retval)
return retval;
%%TRACEPOINT_ATTACH%%
return 0;
}
static void disable_%%MODEL_NAME%%(void)
{
rv_%%MODEL_NAME%%.enabled = 0;
%%TRACEPOINT_DETACH%%
da_monitor_destroy_%%MODEL_NAME%%();
}
/*
* This is the monitor register section.
*/
static struct rv_monitor rv_%%MODEL_NAME%% = {
.name = "%%MODEL_NAME%%",
.description = "%%DESCRIPTION%%",
.enable = enable_%%MODEL_NAME%%,
.disable = disable_%%MODEL_NAME%%,
.reset = da_monitor_reset_all_%%MODEL_NAME%%,
.enabled = 0,
};
static int __init register_%%MODEL_NAME%%(void)
{
rv_register_monitor(&rv_%%MODEL_NAME%%);
return 0;
}
static void __exit unregister_%%MODEL_NAME%%(void)
{
rv_unregister_monitor(&rv_%%MODEL_NAME%%);
}
module_init(register_%%MODEL_NAME%%);
module_exit(unregister_%%MODEL_NAME%%);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dot2k: auto-generated");
MODULE_DESCRIPTION("%%MODEL_NAME%%: %%DESCRIPTION%%");

View File

@ -1,91 +0,0 @@
// 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 "MODEL_NAME"
/*
* XXX: include required tracepoint headers, e.g.,
* #include <trace/events/sched.h>
*/
#include <trace/events/rv.h>
/*
* This is the self-generated part of the monitor. Generally, there is no need
* to touch this section.
*/
#include "MODEL_NAME.h"
/*
* Declare the deterministic automata monitor.
*
* The rv monitor reference is needed for the monitor declaration.
*/
static struct rv_monitor rv_MODEL_NAME;
DECLARE_DA_MON_GLOBAL(MODEL_NAME, MIN_TYPE);
/*
* This is the instrumentation part of the monitor.
*
* This is the section where manual work is required. Here the kernel events
* are translated into model's event.
*
*/
TRACEPOINT_HANDLERS_SKEL
static int enable_MODEL_NAME(void)
{
int retval;
retval = da_monitor_init_MODEL_NAME();
if (retval)
return retval;
TRACEPOINT_ATTACH
return 0;
}
static void disable_MODEL_NAME(void)
{
rv_MODEL_NAME.enabled = 0;
TRACEPOINT_DETACH
da_monitor_destroy_MODEL_NAME();
}
/*
* This is the monitor register section.
*/
static struct rv_monitor rv_MODEL_NAME = {
.name = "MODEL_NAME",
.description = "auto-generated MODEL_NAME",
.enable = enable_MODEL_NAME,
.disable = disable_MODEL_NAME,
.reset = da_monitor_reset_all_MODEL_NAME,
.enabled = 0,
};
static int __init register_MODEL_NAME(void)
{
rv_register_monitor(&rv_MODEL_NAME);
return 0;
}
static void __exit unregister_MODEL_NAME(void)
{
rv_unregister_monitor(&rv_MODEL_NAME);
}
module_init(register_MODEL_NAME);
module_exit(unregister_MODEL_NAME);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dot2k: auto-generated");
MODULE_DESCRIPTION("MODEL_NAME");

View File

@ -1,91 +0,0 @@
// 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 "MODEL_NAME"
/*
* XXX: include required tracepoint headers, e.g.,
* #include <linux/trace/events/sched.h>
*/
#include <trace/events/rv.h>
/*
* This is the self-generated part of the monitor. Generally, there is no need
* to touch this section.
*/
#include "MODEL_NAME.h"
/*
* Declare the deterministic automata monitor.
*
* The rv monitor reference is needed for the monitor declaration.
*/
static struct rv_monitor rv_MODEL_NAME;
DECLARE_DA_MON_PER_CPU(MODEL_NAME, MIN_TYPE);
/*
* This is the instrumentation part of the monitor.
*
* This is the section where manual work is required. Here the kernel events
* are translated into model's event.
*
*/
TRACEPOINT_HANDLERS_SKEL
static int enable_MODEL_NAME(void)
{
int retval;
retval = da_monitor_init_MODEL_NAME();
if (retval)
return retval;
TRACEPOINT_ATTACH
return 0;
}
static void disable_MODEL_NAME(void)
{
rv_MODEL_NAME.enabled = 0;
TRACEPOINT_DETACH
da_monitor_destroy_MODEL_NAME();
}
/*
* This is the monitor register section.
*/
static struct rv_monitor rv_MODEL_NAME = {
.name = "MODEL_NAME",
.description = "auto-generated MODEL_NAME",
.enable = enable_MODEL_NAME,
.disable = disable_MODEL_NAME,
.reset = da_monitor_reset_all_MODEL_NAME,
.enabled = 0,
};
static int __init register_MODEL_NAME(void)
{
rv_register_monitor(&rv_MODEL_NAME);
return 0;
}
static void __exit unregister_MODEL_NAME(void)
{
rv_unregister_monitor(&rv_MODEL_NAME);
}
module_init(register_MODEL_NAME);
module_exit(unregister_MODEL_NAME);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dot2k: auto-generated");
MODULE_DESCRIPTION("MODEL_NAME");

View File

@ -1,91 +0,0 @@
// 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 "MODEL_NAME"
/*
* XXX: include required tracepoint headers, e.g.,
* #include <linux/trace/events/sched.h>
*/
#include <trace/events/rv.h>
/*
* This is the self-generated part of the monitor. Generally, there is no need
* to touch this section.
*/
#include "MODEL_NAME.h"
/*
* Declare the deterministic automata monitor.
*
* The rv monitor reference is needed for the monitor declaration.
*/
static struct rv_monitor rv_MODEL_NAME;
DECLARE_DA_MON_PER_TASK(MODEL_NAME, MIN_TYPE);
/*
* This is the instrumentation part of the monitor.
*
* This is the section where manual work is required. Here the kernel events
* are translated into model's event.
*
*/
TRACEPOINT_HANDLERS_SKEL
static int enable_MODEL_NAME(void)
{
int retval;
retval = da_monitor_init_MODEL_NAME();
if (retval)
return retval;
TRACEPOINT_ATTACH
return 0;
}
static void disable_MODEL_NAME(void)
{
rv_MODEL_NAME.enabled = 0;
TRACEPOINT_DETACH
da_monitor_destroy_MODEL_NAME();
}
/*
* This is the monitor register section.
*/
static struct rv_monitor rv_MODEL_NAME = {
.name = "MODEL_NAME",
.description = "auto-generated MODEL_NAME",
.enable = enable_MODEL_NAME,
.disable = disable_MODEL_NAME,
.reset = da_monitor_reset_all_MODEL_NAME,
.enabled = 0,
};
static int __init register_MODEL_NAME(void)
{
rv_register_monitor(&rv_MODEL_NAME);
return 0;
}
static void __exit unregister_MODEL_NAME(void)
{
rv_unregister_monitor(&rv_MODEL_NAME);
}
module_init(register_MODEL_NAME);
module_exit(unregister_MODEL_NAME);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dot2k: auto-generated");
MODULE_DESCRIPTION("MODEL_NAME");

View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Snippet to be included in rv_trace.h
*/
#ifdef CONFIG_RV_MON_%%MODEL_NAME_UP%%
DEFINE_EVENT(event_%%MONITOR_CLASS%%, event_%%MODEL_NAME%%,
%%TRACEPOINT_ARGS_SKEL_EVENT%%);
DEFINE_EVENT(error_%%MONITOR_CLASS%%, error_%%MODEL_NAME%%,
%%TRACEPOINT_ARGS_SKEL_ERROR%%);
#endif /* CONFIG_RV_MON_%%MODEL_NAME_UP%% */