Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'trace-tools-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull rv and tools/rtla updates from Steven Rostedt:

- Add a test suite to test the tool

Add a small test suite that can be used to test rtla's basic features
to at least have something to test when applying changes.

- Automate manual steps in monitor creation

While creating a new monitor in RV, besides generating code from
dot2k, there are a few manual steps which can be tedious and error
prone, like adding the tracepoints, makefile lines and kconfig, or
selecting events that start the monitor in the initial state.

Updates were made to try and automate as much as possible among those
steps to make creating a new RV monitor much quicker. It is still
requires to select proper tracepoints, this step is harder to
automate in a general way and, in several cases, would still need
user intervention.

- Have rtla timerlat hist and top set OSNOISE_WORKLOAD flag

Have both rtla-timerlat-hist and rtla-timerlat-top set
OSNOISE_WORKLOAD to the proper value ("on" when running with -k,
"off" when running with -u) every time the option is available
instead of setting it only when running with -u.

This prevents rtla timerlat -k from giving no results when
NO_OSNOISE_WORKLOAD is set, either manually or by an abnormally
exited earlier run of rtla timerlat -u.

- Stop rtla timerlat on signal properly when overloaded

There is an issue where if rtla is run on machines with a high number
of CPUs (100+), timerlat can generate more samples than rtla is able
to process via tracefs_iterate_raw_events. This is especially common
when the interval is set to 100us (rteval and cyclictest default) as
opposed to the rtla default of 1000us, but also happens with the rtla
default.

Currently, this leads to rtla hanging and having to be terminated
with SIGTERM. SIGINT setting stop_tracing is not enough, since more
and more events are coming and tracefs_iterate_raw_events never
exits.

To fix this: Stop the timerlat tracer on SIGINT/SIGALRM to ensure no
more events are generated when rtla is supposed to exit.

Also on receiving SIGINT/SIGALRM twice, abort iteration immediately
with tracefs_iterate_stop, making rtla exit right away instead of
waiting for all events to be processed.

- Account for missed events

Due to tracefs buffer overflow, it can happen that rtla misses
events, making the tracing results inaccurate.

Count both the number of missed events and the total number of
processed events, and display missed events as well as their
percentage. The numbers are displayed for both osnoise and timerlat,
even though for the earlier, missed events are generally not
expected.

For hist, the number is displayed at the end of the run; for top, it
is displayed on each printing of the top table.

- Changes to make osnoise more robust

There was a dependency in the code that the first field of the
osnoise_tool structure was the trace field. If that that ever
changed, then the code work break. Change the code to encapsulate
this dependency where the code that uses the structure does not have
this dependency.

* tag 'trace-tools-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: (22 commits)
rtla: Report missed event count
rtla: Add function to report missed events
rtla: Count all processed events
rtla: Count missed trace events
tools/rtla: Add osnoise_trace_is_off()
rtla/timerlat_top: Set OSNOISE_WORKLOAD for kernel threads
rtla/timerlat_hist: Set OSNOISE_WORKLOAD for kernel threads
rtla/osnoise: Distinguish missing workload option
rtla/timerlat_top: Abort event processing on second signal
rtla/timerlat_hist: Abort event processing on second signal
rtla/timerlat_top: Stop timerlat tracer on signal
rtla/timerlat_hist: Stop timerlat tracer on signal
rtla: Add trace_instance_stop
tools/rtla: Add basic test suite
verification/dot2k: Implement event type detection
verification/dot2k: Auto patch current kernel source
verification/dot2k: Simplify manual steps in monitor creation
rv: Simplify manual steps in monitor creation
verification/dot2k: Add support for name and description options
verification/dot2k: More robust template variables
...

+690 -405
+6 -18
include/trace/events/rv.h kernel/trace/rv/rv_trace.h
··· 57 57 __entry->state) 58 58 ); 59 59 60 - #ifdef CONFIG_RV_MON_WIP 61 - DEFINE_EVENT(event_da_monitor, event_wip, 62 - TP_PROTO(char *state, char *event, char *next_state, bool final_state), 63 - TP_ARGS(state, event, next_state, final_state)); 60 + #include <monitors/wip/wip_trace.h> 61 + // Add new monitors based on CONFIG_DA_MON_EVENTS_IMPLICIT here 64 62 65 - DEFINE_EVENT(error_da_monitor, error_wip, 66 - TP_PROTO(char *state, char *event), 67 - TP_ARGS(state, event)); 68 - #endif /* CONFIG_RV_MON_WIP */ 69 63 #endif /* CONFIG_DA_MON_EVENTS_IMPLICIT */ 70 64 71 65 #ifdef CONFIG_DA_MON_EVENTS_ID ··· 117 123 __entry->state) 118 124 ); 119 125 120 - #ifdef CONFIG_RV_MON_WWNR 121 - /* id is the pid of the task */ 122 - DEFINE_EVENT(event_da_monitor_id, event_wwnr, 123 - TP_PROTO(int id, char *state, char *event, char *next_state, bool final_state), 124 - TP_ARGS(id, state, event, next_state, final_state)); 125 - 126 - DEFINE_EVENT(error_da_monitor_id, error_wwnr, 127 - TP_PROTO(int id, char *state, char *event), 128 - TP_ARGS(id, state, event)); 129 - #endif /* CONFIG_RV_MON_WWNR */ 126 + #include <monitors/wwnr/wwnr_trace.h> 127 + // Add new monitors based on CONFIG_DA_MON_EVENTS_ID here 130 128 131 129 #endif /* CONFIG_DA_MON_EVENTS_ID */ 132 130 #endif /* _TRACE_RV_H */ 133 131 134 132 /* This part ust be outside protection */ 135 133 #undef TRACE_INCLUDE_PATH 134 + #define TRACE_INCLUDE_PATH . 135 + #define TRACE_INCLUDE_FILE rv_trace 136 136 #include <trace/define_trace.h>
+3 -24
kernel/trace/rv/Kconfig
··· 25 25 For further information, see: 26 26 Documentation/trace/rv/runtime-verification.rst 27 27 28 - config RV_MON_WIP 29 - depends on RV 30 - depends on PREEMPT_TRACER 31 - select DA_MON_EVENTS_IMPLICIT 32 - bool "wip monitor" 33 - help 34 - Enable wip (wakeup in preemptive) sample monitor that illustrates 35 - the usage of per-cpu monitors, and one limitation of the 36 - preempt_disable/enable events. 37 - 38 - For further information, see: 39 - Documentation/trace/rv/monitor_wip.rst 40 - 41 - config RV_MON_WWNR 42 - depends on RV 43 - select DA_MON_EVENTS_ID 44 - bool "wwnr monitor" 45 - help 46 - Enable wwnr (wakeup while not running) sample monitor, this is a 47 - sample monitor that illustrates the usage of per-task monitor. 48 - The model is borken on purpose: it serves to test reactors. 49 - 50 - For further information, see: 51 - Documentation/trace/rv/monitor_wwnr.rst 28 + source "kernel/trace/rv/monitors/wip/Kconfig" 29 + source "kernel/trace/rv/monitors/wwnr/Kconfig" 30 + # Add new monitors here 52 31 53 32 config RV_REACTORS 54 33 bool "Runtime verification reactors"
+3
kernel/trace/rv/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 + ccflags-y += -I $(src) # needed for trace events 4 + 3 5 obj-$(CONFIG_RV) += rv.o 4 6 obj-$(CONFIG_RV_MON_WIP) += monitors/wip/wip.o 5 7 obj-$(CONFIG_RV_MON_WWNR) += monitors/wwnr/wwnr.o 8 + # Add new monitors here 6 9 obj-$(CONFIG_RV_REACTORS) += rv_reactors.o 7 10 obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o 8 11 obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o
+12
kernel/trace/rv/monitors/wip/Kconfig
··· 1 + config RV_MON_WIP 2 + depends on RV 3 + depends on PREEMPT_TRACER 4 + select DA_MON_EVENTS_IMPLICIT 5 + bool "wip monitor" 6 + help 7 + Enable wip (wakeup in preemptive) sample monitor that illustrates 8 + the usage of per-cpu monitors, and one limitation of the 9 + preempt_disable/enable events. 10 + 11 + For further information, see: 12 + Documentation/trace/rv/monitor_wip.rst
+1 -1
kernel/trace/rv/monitors/wip/wip.c
··· 10 10 11 11 #define MODULE_NAME "wip" 12 12 13 - #include <trace/events/rv.h> 13 + #include <rv_trace.h> 14 14 #include <trace/events/sched.h> 15 15 #include <trace/events/preemptirq.h> 16 16
+15
kernel/trace/rv/monitors/wip/wip_trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* 4 + * Snippet to be included in rv_trace.h 5 + */ 6 + 7 + #ifdef CONFIG_RV_MON_WIP 8 + DEFINE_EVENT(event_da_monitor, event_wip, 9 + TP_PROTO(char *state, char *event, char *next_state, bool final_state), 10 + TP_ARGS(state, event, next_state, final_state)); 11 + 12 + DEFINE_EVENT(error_da_monitor, error_wip, 13 + TP_PROTO(char *state, char *event), 14 + TP_ARGS(state, event)); 15 + #endif /* CONFIG_RV_MON_WIP */
+11
kernel/trace/rv/monitors/wwnr/Kconfig
··· 1 + config RV_MON_WWNR 2 + depends on RV 3 + select DA_MON_EVENTS_ID 4 + bool "wwnr monitor" 5 + help 6 + Enable wwnr (wakeup while not running) sample monitor, this is a 7 + sample monitor that illustrates the usage of per-task monitor. 8 + The model is borken on purpose: it serves to test reactors. 9 + 10 + For further information, see: 11 + Documentation/trace/rv/monitor_wwnr.rst
+1 -1
kernel/trace/rv/monitors/wwnr/wwnr.c
··· 10 10 11 11 #define MODULE_NAME "wwnr" 12 12 13 - #include <trace/events/rv.h> 13 + #include <rv_trace.h> 14 14 #include <trace/events/sched.h> 15 15 16 16 #include "wwnr.h"
+16
kernel/trace/rv/monitors/wwnr/wwnr_trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* 4 + * Snippet to be included in rv_trace.h 5 + */ 6 + 7 + #ifdef CONFIG_RV_MON_WWNR 8 + /* id is the pid of the task */ 9 + DEFINE_EVENT(event_da_monitor_id, event_wwnr, 10 + TP_PROTO(int id, char *state, char *event, char *next_state, bool final_state), 11 + TP_ARGS(id, state, event, next_state, final_state)); 12 + 13 + DEFINE_EVENT(error_da_monitor_id, error_wwnr, 14 + TP_PROTO(int id, char *state, char *event), 15 + TP_ARGS(id, state, event)); 16 + #endif /* CONFIG_RV_MON_WWNR */
+1 -1
kernel/trace/rv/rv.c
··· 145 145 146 146 #ifdef CONFIG_DA_MON_EVENTS 147 147 #define CREATE_TRACE_POINTS 148 - #include <trace/events/rv.h> 148 + #include <rv_trace.h> 149 149 #endif 150 150 151 151 #include "rv.h"
+3 -1
tools/tracing/rtla/Makefile
··· 85 85 $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 86 86 $(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-* 87 87 $(Q)rm -rf feature 88 - .PHONY: FORCE clean 88 + check: $(RTLA) 89 + RTLA=$(RTLA) prove -o -f tests/ 90 + .PHONY: FORCE clean check
+37 -1
tools/tracing/rtla/src/osnoise.c
··· 867 867 868 868 retval = osnoise_options_set_option("OSNOISE_WORKLOAD", onoff); 869 869 if (retval < 0) 870 - return -1; 870 + return -2; 871 871 872 872 context->opt_workload = onoff; 873 873 ··· 1077 1077 out_err: 1078 1078 osnoise_destroy_tool(trace); 1079 1079 return NULL; 1080 + } 1081 + 1082 + bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record) 1083 + { 1084 + /* 1085 + * The tool instance is always present, it is the one used to collect 1086 + * data. 1087 + */ 1088 + if (!tracefs_trace_is_on(tool->trace.inst)) 1089 + return true; 1090 + 1091 + /* 1092 + * The trace record instance is only enabled when -t is set. IOW, when the system 1093 + * is tracing. 1094 + */ 1095 + return record && !tracefs_trace_is_on(record->trace.inst); 1096 + } 1097 + 1098 + /* 1099 + * osnoise_report_missed_events - report number of events dropped by trace 1100 + * buffer 1101 + */ 1102 + void 1103 + osnoise_report_missed_events(struct osnoise_tool *tool) 1104 + { 1105 + unsigned long long total_events; 1106 + 1107 + if (tool->trace.missed_events == UINT64_MAX) 1108 + printf("unknown number of events missed, results might not be accurate\n"); 1109 + else if (tool->trace.missed_events > 0) { 1110 + total_events = tool->trace.processed_events + tool->trace.missed_events; 1111 + 1112 + printf("%lld (%.2f%%) events missed, results might not be accurate\n", 1113 + tool->trace.missed_events, 1114 + (double) tool->trace.missed_events / total_events * 100.0); 1115 + } 1080 1116 } 1081 1117 1082 1118 static void osnoise_usage(int err)
+2
tools/tracing/rtla/src/osnoise.h
··· 104 104 void osnoise_destroy_tool(struct osnoise_tool *top); 105 105 struct osnoise_tool *osnoise_init_tool(char *tool_name); 106 106 struct osnoise_tool *osnoise_init_trace_tool(char *tracer); 107 + void osnoise_report_missed_events(struct osnoise_tool *tool); 108 + bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record); 107 109 108 110 int osnoise_hist_main(int argc, char *argv[]); 109 111 int osnoise_top_main(int argc, char **argv);
+3 -2
tools/tracing/rtla/src/osnoise_hist.c
··· 440 440 trace_seq_reset(trace->seq); 441 441 442 442 osnoise_print_summary(params, trace, data); 443 + osnoise_report_missed_events(tool); 443 444 } 444 445 445 446 /* ··· 971 970 goto out_hist; 972 971 } 973 972 974 - if (trace_is_off(&tool->trace, &record->trace)) 973 + if (osnoise_trace_is_off(tool, record)) 975 974 break; 976 975 } 977 976 ··· 981 980 982 981 return_value = 0; 983 982 984 - if (trace_is_off(&tool->trace, &record->trace)) { 983 + if (osnoise_trace_is_off(tool, record)) { 985 984 printf("rtla osnoise hit stop tracing\n"); 986 985 if (params->trace_output) { 987 986 printf(" Saving trace to %s\n", params->trace_output);
+3 -2
tools/tracing/rtla/src/osnoise_top.c
··· 280 280 281 281 trace_seq_do_printf(trace->seq); 282 282 trace_seq_reset(trace->seq); 283 + osnoise_report_missed_events(top); 283 284 } 284 285 285 286 /* ··· 802 801 if (!params->quiet) 803 802 osnoise_print_stats(params, tool); 804 803 805 - if (trace_is_off(&tool->trace, &record->trace)) 804 + if (osnoise_trace_is_off(tool, record)) 806 805 break; 807 806 808 807 } ··· 811 810 812 811 return_value = 0; 813 812 814 - if (trace_is_off(&tool->trace, &record->trace)) { 813 + if (osnoise_trace_is_off(tool, record)) { 815 814 printf("osnoise hit stop tracing\n"); 816 815 if (params->trace_output) { 817 816 printf(" Saving trace to %s\n", params->trace_output);
+29 -8
tools/tracing/rtla/src/timerlat_hist.c
··· 656 656 657 657 timerlat_print_summary(params, trace, data); 658 658 timerlat_print_stats_all(params, trace, data); 659 + osnoise_report_missed_events(tool); 659 660 } 660 661 661 662 /* ··· 1101 1100 } 1102 1101 } 1103 1102 1104 - if (params->user_hist) { 1105 - retval = osnoise_set_workload(tool->context, 0); 1106 - if (retval) { 1107 - err_msg("Failed to set OSNOISE_WORKLOAD option\n"); 1108 - goto out_err; 1109 - } 1103 + /* 1104 + * Set workload according to type of thread if the kernel supports it. 1105 + * On kernels without support, user threads will have already failed 1106 + * on missing timerlat_fd, and kernel threads do not need it. 1107 + */ 1108 + retval = osnoise_set_workload(tool->context, params->kernel_workload); 1109 + if (retval < -1) { 1110 + err_msg("Failed to set OSNOISE_WORKLOAD option\n"); 1111 + goto out_err; 1110 1112 } 1111 1113 1112 1114 return 0; ··· 1150 1146 } 1151 1147 1152 1148 static int stop_tracing; 1149 + static struct trace_instance *hist_inst = NULL; 1153 1150 static void stop_hist(int sig) 1154 1151 { 1152 + if (stop_tracing) { 1153 + /* 1154 + * Stop requested twice in a row; abort event processing and 1155 + * exit immediately 1156 + */ 1157 + tracefs_iterate_stop(hist_inst->inst); 1158 + return; 1159 + } 1155 1160 stop_tracing = 1; 1161 + if (hist_inst) 1162 + trace_instance_stop(hist_inst); 1156 1163 } 1157 1164 1158 1165 /* ··· 1210 1195 } 1211 1196 1212 1197 trace = &tool->trace; 1198 + /* 1199 + * Save trace instance into global variable so that SIGINT can stop 1200 + * the timerlat tracer. 1201 + * Otherwise, rtla could loop indefinitely when overloaded. 1202 + */ 1203 + hist_inst = trace; 1213 1204 1214 1205 retval = enable_timerlat(trace); 1215 1206 if (retval) { ··· 1363 1342 goto out_hist; 1364 1343 } 1365 1344 1366 - if (trace_is_off(&tool->trace, &record->trace)) 1345 + if (osnoise_trace_is_off(tool, record)) 1367 1346 break; 1368 1347 1369 1348 /* is there still any user-threads ? */ ··· 1384 1363 1385 1364 return_value = 0; 1386 1365 1387 - if (trace_is_off(&tool->trace, &record->trace)) { 1366 + if (osnoise_trace_is_off(tool, record) && !stop_tracing) { 1388 1367 printf("rtla timerlat hit stop tracing\n"); 1389 1368 1390 1369 if (!params->no_aa)
+31 -9
tools/tracing/rtla/src/timerlat_top.c
··· 435 435 436 436 trace_seq_do_printf(trace->seq); 437 437 trace_seq_reset(trace->seq); 438 + osnoise_report_missed_events(top); 438 439 } 439 440 440 441 /* ··· 852 851 } 853 852 } 854 853 855 - if (params->user_top) { 856 - retval = osnoise_set_workload(top->context, 0); 857 - if (retval) { 858 - err_msg("Failed to set OSNOISE_WORKLOAD option\n"); 859 - goto out_err; 860 - } 854 + /* 855 + * Set workload according to type of thread if the kernel supports it. 856 + * On kernels without support, user threads will have already failed 857 + * on missing timerlat_fd, and kernel threads do not need it. 858 + */ 859 + retval = osnoise_set_workload(top->context, params->kernel_workload); 860 + if (retval < -1) { 861 + err_msg("Failed to set OSNOISE_WORKLOAD option\n"); 862 + goto out_err; 861 863 } 862 864 863 865 if (isatty(STDOUT_FILENO) && !params->quiet) ··· 904 900 } 905 901 906 902 static int stop_tracing; 903 + static struct trace_instance *top_inst = NULL; 907 904 static void stop_top(int sig) 908 905 { 906 + if (stop_tracing) { 907 + /* 908 + * Stop requested twice in a row; abort event processing and 909 + * exit immediately 910 + */ 911 + tracefs_iterate_stop(top_inst->inst); 912 + return; 913 + } 909 914 stop_tracing = 1; 915 + if (top_inst) 916 + trace_instance_stop(top_inst); 910 917 } 911 918 912 919 /* ··· 965 950 } 966 951 967 952 trace = &top->trace; 953 + /* 954 + * Save trace instance into global variable so that SIGINT can stop 955 + * the timerlat tracer. 956 + * Otherwise, rtla could loop indefinitely when overloaded. 957 + */ 958 + top_inst = trace; 959 + 968 960 969 961 retval = enable_timerlat(trace); 970 962 if (retval) { ··· 1115 1093 while (!stop_tracing) { 1116 1094 sleep(params->sleep_time); 1117 1095 1118 - if (params->aa_only && !trace_is_off(&top->trace, &record->trace)) 1096 + if (params->aa_only && !osnoise_trace_is_off(top, record)) 1119 1097 continue; 1120 1098 1121 1099 retval = tracefs_iterate_raw_events(trace->tep, ··· 1132 1110 if (!params->quiet) 1133 1111 timerlat_print_stats(params, top); 1134 1112 1135 - if (trace_is_off(&top->trace, &record->trace)) 1113 + if (osnoise_trace_is_off(top, record)) 1136 1114 break; 1137 1115 1138 1116 /* is there still any user-threads ? */ ··· 1153 1131 1154 1132 return_value = 0; 1155 1133 1156 - if (trace_is_off(&top->trace, &record->trace)) { 1134 + if (osnoise_trace_is_off(top, record) && !stop_tracing) { 1157 1135 printf("rtla timerlat hit stop tracing\n"); 1158 1136 1159 1137 if (!params->no_aa)
+46 -19
tools/tracing/rtla/src/trace.c
··· 118 118 struct trace_instance *trace = context; 119 119 struct trace_seq *s = trace->seq; 120 120 121 + trace->processed_events++; 122 + 121 123 if (!event->handler) 122 124 return 0; 123 125 124 126 event->handler(s, record, event, context); 127 + 128 + return 0; 129 + } 130 + 131 + /* 132 + * collect_missed_events - record number of missed events 133 + * 134 + * If rtla cannot keep up with events generated by tracer, events are going 135 + * to fall out of the ring buffer. 136 + * Collect how many events were missed so it can be reported to the user. 137 + */ 138 + static int 139 + collect_missed_events(struct tep_event *event, struct tep_record *record, 140 + int cpu, void *context) 141 + { 142 + struct trace_instance *trace = context; 143 + 144 + if (trace->missed_events == UINT64_MAX) 145 + return 0; 146 + 147 + if (record->missed_events > 0) 148 + trace->missed_events += record->missed_events; 149 + else 150 + /* Events missed but no data on how many */ 151 + trace->missed_events = UINT64_MAX; 125 152 126 153 return 0; 127 154 } ··· 208 181 */ 209 182 tracefs_trace_off(trace->inst); 210 183 184 + /* 185 + * Collect the number of events missed due to tracefs buffer 186 + * overflow. 187 + */ 188 + trace->missed_events = 0; 189 + tracefs_follow_missed_events(trace->inst, 190 + collect_missed_events, 191 + trace); 192 + 193 + trace->processed_events = 0; 194 + 211 195 return 0; 212 196 213 197 out_err: ··· 232 194 int trace_instance_start(struct trace_instance *trace) 233 195 { 234 196 return tracefs_trace_on(trace->inst); 197 + } 198 + 199 + /* 200 + * trace_instance_stop - stop tracing a given rtla instance 201 + */ 202 + int trace_instance_stop(struct trace_instance *trace) 203 + { 204 + return tracefs_trace_off(trace->inst); 235 205 } 236 206 237 207 /* ··· 566 520 567 521 trace_events_disable(instance, events); 568 522 trace_events_free(events); 569 - } 570 - 571 - int trace_is_off(struct trace_instance *tool, struct trace_instance *trace) 572 - { 573 - /* 574 - * The tool instance is always present, it is the one used to collect 575 - * data. 576 - */ 577 - if (!tracefs_trace_is_on(tool->inst)) 578 - return 1; 579 - 580 - /* 581 - * The trace instance is only enabled when -t is set. IOW, when the system 582 - * is tracing. 583 - */ 584 - if (trace && !tracefs_trace_is_on(trace->inst)) 585 - return 1; 586 - 587 - return 0; 588 523 } 589 524 590 525 /*
+3 -1
tools/tracing/rtla/src/trace.h
··· 17 17 struct tracefs_instance *inst; 18 18 struct tep_handle *tep; 19 19 struct trace_seq *seq; 20 + unsigned long long missed_events; 21 + unsigned long long processed_events; 20 22 }; 21 23 22 24 int trace_instance_init(struct trace_instance *trace, char *tool_name); 23 25 int trace_instance_start(struct trace_instance *trace); 26 + int trace_instance_stop(struct trace_instance *trace); 24 27 void trace_instance_destroy(struct trace_instance *trace); 25 28 26 29 struct trace_seq *get_trace_seq(void); ··· 50 47 51 48 int trace_event_add_filter(struct trace_events *event, char *filter); 52 49 int trace_event_add_trigger(struct trace_events *event, char *trigger); 53 - int trace_is_off(struct trace_instance *tool, struct trace_instance *trace); 54 50 int trace_set_buffer_size(struct trace_instance *trace, int size);
+48
tools/tracing/rtla/tests/engine.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + test_begin() { 4 + # Count tests to allow the test harness to double-check if all were 5 + # included correctly. 6 + ctr=0 7 + [ -z "$RTLA" ] && RTLA="./rtla" 8 + [ -n "$TEST_COUNT" ] && echo "1..$TEST_COUNT" 9 + } 10 + 11 + check() { 12 + # Simple check: run rtla with given arguments and test exit code. 13 + # If TEST_COUNT is set, run the test. Otherwise, just count. 14 + ctr=$(($ctr + 1)) 15 + if [ -n "$TEST_COUNT" ] 16 + then 17 + # Run rtla; in case of failure, include its output as comment 18 + # in the test results. 19 + result=$(stdbuf -oL $TIMEOUT "$RTLA" $2 2>&1); exitcode=$? 20 + if [ $exitcode -eq 0 ] 21 + then 22 + echo "ok $ctr - $1" 23 + else 24 + echo "not ok $ctr - $1" 25 + # Add rtla output and exit code as comments in case of failure 26 + echo "$result" | col -b | while read line; do echo "# $line"; done 27 + printf "#\n# exit code %s\n" $exitcode 28 + fi 29 + fi 30 + } 31 + 32 + set_timeout() { 33 + TIMEOUT="timeout -v -k 15s $1" 34 + } 35 + 36 + unset_timeout() { 37 + unset TIMEOUT 38 + } 39 + 40 + test_end() { 41 + # If running without TEST_COUNT, tests are not actually run, just 42 + # counted. In that case, re-run the test with the correct count. 43 + [ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash $0 || true 44 + } 45 + 46 + # Avoid any environmental discrepancies 47 + export LC_ALL=C 48 + unset_timeout
+21
tools/tracing/rtla/tests/hwnoise.t
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + source tests/engine.sh 4 + test_begin 5 + 6 + set_timeout 2m 7 + 8 + check "verify help page" \ 9 + "hwnoise --help" 10 + check "detect noise higher than one microsecond" \ 11 + "hwnoise -c 0 -T 1 -d 5s -q" 12 + check "set the automatic trace mode" \ 13 + "hwnoise -a 5 -d 30s" 14 + check "set scheduling param to the osnoise tracer threads" \ 15 + "hwnoise -P F:1 -c 0 -r 900000 -d 1M -q" 16 + check "stop the trace if a single sample is higher than 1 us" \ 17 + "hwnoise -s 1 -T 1 -t -d 30s" 18 + check "enable a trace event trigger" \ 19 + "hwnoise -t -e osnoise:irq_noise trigger=\"hist:key=desc,duration:sort=desc,duration:vals=hitcount\" -d 1m" 20 + 21 + test_end
+19
tools/tracing/rtla/tests/osnoise.t
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + source tests/engine.sh 4 + test_begin 5 + 6 + set_timeout 2m 7 + 8 + check "verify help page" \ 9 + "osnoise --help" 10 + check "verify the --priority/-P param" \ 11 + "osnoise top -P F:1 -c 0 -r 900000 -d 1M -q" 12 + check "verify the --stop/-s param" \ 13 + "osnoise top -s 30 -T 1 -t" 14 + check "verify the --trace param" \ 15 + "osnoise hist -s 30 -T 1 -t" 16 + check "verify the --entries/-E param" \ 17 + "osnoise hist -P F:1 -c 0 -r 900000 -d 1M -b 10 -E 25" 18 + 19 + test_end
+27
tools/tracing/rtla/tests/timerlat.t
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + source tests/engine.sh 4 + test_begin 5 + 6 + set_timeout 2m 7 + 8 + check "verify help page" \ 9 + "timerlat --help" 10 + check "verify -s/--stack" \ 11 + "timerlat top -s 3 -T 10 -t" 12 + check "verify -P/--priority" \ 13 + "timerlat top -P F:1 -c 0 -d 1M -q" 14 + check "test in nanoseconds" \ 15 + "timerlat top -i 2 -c 0 -n -d 30s" 16 + check "set the automatic trace mode" \ 17 + "timerlat top -a 5 --dump-tasks" 18 + check "print the auto-analysis if hits the stop tracing condition" \ 19 + "timerlat top --aa-only 5" 20 + check "disable auto-analysis" \ 21 + "timerlat top -s 3 -T 10 -t --no-aa" 22 + check "verify -c/--cpus" \ 23 + "timerlat hist -c 0 -d 30s" 24 + check "hist test in nanoseconds" \ 25 + "timerlat hist -i 2 -c 0 -n -d 30s" 26 + 27 + test_end
+34 -2
tools/verification/dot2/automata.py
··· 19 19 20 20 invalid_state_str = "INVALID_STATE" 21 21 22 - def __init__(self, file_path): 22 + def __init__(self, file_path, model_name=None): 23 23 self.__dot_path = file_path 24 - self.name = self.__get_model_name() 24 + self.name = model_name or self.__get_model_name() 25 25 self.__dot_lines = self.__open_dot() 26 26 self.states, self.initial_state, self.final_states = self.__get_state_variables() 27 27 self.events = self.__get_event_variables() 28 28 self.function = self.__create_matrix() 29 + self.events_start, self.events_start_run = self.__store_init_events() 29 30 30 31 def __get_model_name(self): 31 32 basename = ntpath.basename(self.__dot_path) ··· 173 172 cursor += 1 174 173 175 174 return matrix 175 + 176 + def __store_init_events(self): 177 + events_start = [False] * len(self.events) 178 + events_start_run = [False] * len(self.events) 179 + for i, _ in enumerate(self.events): 180 + curr_event_will_init = 0 181 + curr_event_from_init = False 182 + curr_event_used = 0 183 + for j, _ in enumerate(self.states): 184 + if self.function[j][i] != self.invalid_state_str: 185 + curr_event_used += 1 186 + if self.function[j][i] == self.initial_state: 187 + curr_event_will_init += 1 188 + if self.function[0][i] != self.invalid_state_str: 189 + curr_event_from_init = True 190 + # this event always leads to init 191 + if curr_event_will_init and curr_event_used == curr_event_will_init: 192 + events_start[i] = True 193 + # this event is only called from init 194 + if curr_event_from_init and curr_event_used == 1: 195 + events_start_run[i] = True 196 + return events_start, events_start_run 197 + 198 + def is_start_event(self, event): 199 + return self.events_start[self.events.index(event)] 200 + 201 + def is_start_run_event(self, event): 202 + # prefer handle_start_event if there 203 + if any(self.events_start): 204 + return False 205 + return self.events_start_run[self.events.index(event)]
+2 -2
tools/verification/dot2/dot2c.py
··· 22 22 struct_automaton_def = "automaton" 23 23 var_automaton_def = "aut" 24 24 25 - def __init__(self, file_path): 26 - super().__init__(file_path) 25 + def __init__(self, file_path, model_name=None): 26 + super().__init__(file_path, model_name) 27 27 self.line_length = 100 28 28 29 29 def __buff_to_string(self, buff):
+8 -9
tools/verification/dot2/dot2k
··· 21 21 parser.add_argument('-t', "--monitor_type", dest="monitor_type", required=True) 22 22 parser.add_argument('-n', "--model_name", dest="model_name", required=False) 23 23 parser.add_argument("-D", "--description", dest="description", required=False) 24 + parser.add_argument("-a", "--auto_patch", dest="auto_patch", 25 + action="store_true", required=False, 26 + help="Patch the kernel in place") 24 27 params = parser.parse_args() 25 28 26 29 print("Opening and parsing the dot file %s" % params.dot_file) 27 30 try: 28 - monitor=dot2k(params.dot_file, params.monitor_type) 31 + monitor=dot2k(params.dot_file, params.monitor_type, vars(params)) 29 32 except Exception as e: 30 33 print('Error: '+ str(e)) 31 34 print("Sorry : :-(") 32 35 sys.exit(1) 33 36 34 - # easier than using argparse action. 35 - if params.model_name != None: 36 - print(params.model_name) 37 - 38 37 print("Writing the monitor into the directory %s" % monitor.name) 39 38 monitor.print_files() 40 39 print("Almost done, checklist") 41 40 print(" - Edit the %s/%s.c to add the instrumentation" % (monitor.name, monitor.name)) 42 - print(" - Edit include/trace/events/rv.h to add the tracepoint entry") 43 - print(" - Move it to the kernel's monitor directory") 44 - print(" - Edit kernel/trace/rv/Makefile") 45 - print(" - Edit kernel/trace/rv/Kconfig") 41 + print(monitor.fill_tracepoint_tooltip()) 42 + print(monitor.fill_makefile_tooltip()) 43 + print(monitor.fill_kconfig_tooltip()) 44 + print(monitor.fill_monitor_tooltip())
+195 -31
tools/verification/dot2/dot2k.py
··· 14 14 15 15 class dot2k(Dot2c): 16 16 monitor_types = { "global" : 1, "per_cpu" : 2, "per_task" : 3 } 17 - monitor_templates_dir = "dot2k/rv_templates/" 17 + monitor_templates_dir = "dot2/dot2k_templates/" 18 + rv_dir = "kernel/trace/rv" 18 19 monitor_type = "per_cpu" 19 20 20 - def __init__(self, file_path, MonitorType): 21 - super().__init__(file_path) 21 + def __init__(self, file_path, MonitorType, extra_params={}): 22 + super().__init__(file_path, extra_params.get("model_name")) 22 23 23 24 self.monitor_type = self.monitor_types.get(MonitorType) 24 - if self.monitor_type == None: 25 - raise Exception("Unknown monitor type: %s" % MonitorType) 25 + if self.monitor_type is None: 26 + raise ValueError("Unknown monitor type: %s" % MonitorType) 26 27 27 28 self.monitor_type = MonitorType 28 29 self.__fill_rv_templates_dir() 29 - self.main_c = self.__open_file(self.monitor_templates_dir + "main_" + MonitorType + ".c") 30 + self.main_c = self.__read_file(self.monitor_templates_dir + "main.c") 31 + self.trace_h = self.__read_file(self.monitor_templates_dir + "trace.h") 32 + self.kconfig = self.__read_file(self.monitor_templates_dir + "Kconfig") 30 33 self.enum_suffix = "_%s" % self.name 34 + self.description = extra_params.get("description", self.name) or "auto-generated" 35 + self.auto_patch = extra_params.get("auto_patch") 36 + if self.auto_patch: 37 + self.__fill_rv_kernel_dir() 31 38 32 39 def __fill_rv_templates_dir(self): 33 40 34 - if os.path.exists(self.monitor_templates_dir) == True: 41 + if os.path.exists(self.monitor_templates_dir): 35 42 return 36 43 37 44 if platform.system() != "Linux": 38 - raise Exception("I can only run on Linux.") 45 + raise OSError("I can only run on Linux.") 39 46 40 47 kernel_path = "/lib/modules/%s/build/tools/verification/dot2/dot2k_templates/" % (platform.release()) 41 48 42 - if os.path.exists(kernel_path) == True: 49 + if os.path.exists(kernel_path): 43 50 self.monitor_templates_dir = kernel_path 44 51 return 45 52 46 - if os.path.exists("/usr/share/dot2/dot2k_templates/") == True: 53 + if os.path.exists("/usr/share/dot2/dot2k_templates/"): 47 54 self.monitor_templates_dir = "/usr/share/dot2/dot2k_templates/" 48 55 return 49 56 50 - raise Exception("Could not find the template directory, do you have the kernel source installed?") 57 + raise FileNotFoundError("Could not find the template directory, do you have the kernel source installed?") 51 58 59 + def __fill_rv_kernel_dir(self): 52 60 53 - def __open_file(self, path): 61 + # first try if we are running in the kernel tree root 62 + if os.path.exists(self.rv_dir): 63 + return 64 + 65 + # offset if we are running inside the kernel tree from verification/dot2 66 + kernel_path = os.path.join("../..", self.rv_dir) 67 + 68 + if os.path.exists(kernel_path): 69 + self.rv_dir = kernel_path 70 + return 71 + 72 + if platform.system() != "Linux": 73 + raise OSError("I can only run on Linux.") 74 + 75 + kernel_path = os.path.join("/lib/modules/%s/build" % platform.release(), self.rv_dir) 76 + 77 + # if the current kernel is from a distro this may not be a full kernel tree 78 + # verify that one of the files we are going to modify is available 79 + if os.path.exists(os.path.join(kernel_path, "rv_trace.h")): 80 + self.rv_dir = kernel_path 81 + return 82 + 83 + raise FileNotFoundError("Could not find the rv directory, do you have the kernel source installed?") 84 + 85 + def __read_file(self, path): 54 86 try: 55 - fd = open(path) 87 + fd = open(path, 'r') 56 88 except OSError: 57 89 raise Exception("Cannot open the file: %s" % path) 58 90 59 91 content = fd.read() 60 92 93 + fd.close() 61 94 return content 62 95 63 96 def __buff_to_string(self, buff): ··· 102 69 # cut off the last \n 103 70 return string[:-1] 104 71 72 + def fill_monitor_type(self): 73 + return self.monitor_type.upper() 74 + 105 75 def fill_tracepoint_handlers_skel(self): 106 76 buff = [] 107 77 for event in self.events: 108 78 buff.append("static void handle_%s(void *data, /* XXX: fill header */)" % event) 109 79 buff.append("{") 80 + handle = "handle_event" 81 + if self.is_start_event(event): 82 + buff.append("\t/* XXX: validate that this event always leads to the initial state */") 83 + handle = "handle_start_event" 84 + elif self.is_start_run_event(event): 85 + buff.append("\t/* XXX: validate that this event is only valid in the initial state */") 86 + handle = "handle_start_run_event" 110 87 if self.monitor_type == "per_task": 111 88 buff.append("\tstruct task_struct *p = /* XXX: how do I get p? */;"); 112 - buff.append("\tda_handle_event_%s(p, %s%s);" % (self.name, event, self.enum_suffix)); 89 + buff.append("\tda_%s_%s(p, %s%s);" % (handle, self.name, event, self.enum_suffix)); 113 90 else: 114 - buff.append("\tda_handle_event_%s(%s%s);" % (self.name, event, self.enum_suffix)); 91 + buff.append("\tda_%s_%s(%s%s);" % (handle, self.name, event, self.enum_suffix)); 115 92 buff.append("}") 116 93 buff.append("") 117 94 return self.__buff_to_string(buff) ··· 140 97 141 98 def fill_main_c(self): 142 99 main_c = self.main_c 100 + monitor_type = self.fill_monitor_type() 143 101 min_type = self.get_minimun_type() 144 - nr_events = self.events.__len__() 102 + nr_events = len(self.events) 145 103 tracepoint_handlers = self.fill_tracepoint_handlers_skel() 146 104 tracepoint_attach = self.fill_tracepoint_attach_probe() 147 105 tracepoint_detach = self.fill_tracepoint_detach_helper() 148 106 149 - main_c = main_c.replace("MIN_TYPE", min_type) 150 - main_c = main_c.replace("MODEL_NAME", self.name) 151 - main_c = main_c.replace("NR_EVENTS", str(nr_events)) 152 - main_c = main_c.replace("TRACEPOINT_HANDLERS_SKEL", tracepoint_handlers) 153 - main_c = main_c.replace("TRACEPOINT_ATTACH", tracepoint_attach) 154 - main_c = main_c.replace("TRACEPOINT_DETACH", tracepoint_detach) 107 + main_c = main_c.replace("%%MONITOR_TYPE%%", monitor_type) 108 + main_c = main_c.replace("%%MIN_TYPE%%", min_type) 109 + main_c = main_c.replace("%%MODEL_NAME%%", self.name) 110 + main_c = main_c.replace("%%NR_EVENTS%%", str(nr_events)) 111 + main_c = main_c.replace("%%TRACEPOINT_HANDLERS_SKEL%%", tracepoint_handlers) 112 + main_c = main_c.replace("%%TRACEPOINT_ATTACH%%", tracepoint_attach) 113 + main_c = main_c.replace("%%TRACEPOINT_DETACH%%", tracepoint_detach) 114 + main_c = main_c.replace("%%DESCRIPTION%%", self.description) 155 115 156 116 return main_c 157 117 ··· 183 137 184 138 return self.__buff_to_string(buff) 185 139 140 + def fill_monitor_class_type(self): 141 + if self.monitor_type == "per_task": 142 + return "DA_MON_EVENTS_ID" 143 + return "DA_MON_EVENTS_IMPLICIT" 144 + 145 + def fill_monitor_class(self): 146 + if self.monitor_type == "per_task": 147 + return "da_monitor_id" 148 + return "da_monitor" 149 + 150 + def fill_tracepoint_args_skel(self, tp_type): 151 + buff = [] 152 + tp_args_event = [ 153 + ("char *", "state"), 154 + ("char *", "event"), 155 + ("char *", "next_state"), 156 + ("bool ", "final_state"), 157 + ] 158 + tp_args_error = [ 159 + ("char *", "state"), 160 + ("char *", "event"), 161 + ] 162 + tp_args_id = ("int ", "id") 163 + tp_args = tp_args_event if tp_type == "event" else tp_args_error 164 + if self.monitor_type == "per_task": 165 + tp_args.insert(0, tp_args_id) 166 + tp_proto_c = ", ".join([a+b for a,b in tp_args]) 167 + tp_args_c = ", ".join([b for a,b in tp_args]) 168 + buff.append(" TP_PROTO(%s)," % tp_proto_c) 169 + buff.append(" TP_ARGS(%s)" % tp_args_c) 170 + return self.__buff_to_string(buff) 171 + 172 + def fill_trace_h(self): 173 + trace_h = self.trace_h 174 + monitor_class = self.fill_monitor_class() 175 + monitor_class_type = self.fill_monitor_class_type() 176 + tracepoint_args_skel_event = self.fill_tracepoint_args_skel("event") 177 + tracepoint_args_skel_error = self.fill_tracepoint_args_skel("error") 178 + trace_h = trace_h.replace("%%MODEL_NAME%%", self.name) 179 + trace_h = trace_h.replace("%%MODEL_NAME_UP%%", self.name.upper()) 180 + trace_h = trace_h.replace("%%MONITOR_CLASS%%", monitor_class) 181 + trace_h = trace_h.replace("%%MONITOR_CLASS_TYPE%%", monitor_class_type) 182 + trace_h = trace_h.replace("%%TRACEPOINT_ARGS_SKEL_EVENT%%", tracepoint_args_skel_event) 183 + trace_h = trace_h.replace("%%TRACEPOINT_ARGS_SKEL_ERROR%%", tracepoint_args_skel_error) 184 + return trace_h 185 + 186 + def fill_kconfig(self): 187 + kconfig = self.kconfig 188 + monitor_class_type = self.fill_monitor_class_type() 189 + kconfig = kconfig.replace("%%MODEL_NAME%%", self.name) 190 + kconfig = kconfig.replace("%%MODEL_NAME_UP%%", self.name.upper()) 191 + kconfig = kconfig.replace("%%MONITOR_CLASS_TYPE%%", monitor_class_type) 192 + kconfig = kconfig.replace("%%DESCRIPTION%%", self.description) 193 + return kconfig 194 + 195 + def __patch_file(self, file, marker, line): 196 + file_to_patch = os.path.join(self.rv_dir, file) 197 + content = self.__read_file(file_to_patch) 198 + content = content.replace(marker, line + "\n" + marker) 199 + self.__write_file(file_to_patch, content) 200 + 201 + def fill_tracepoint_tooltip(self): 202 + monitor_class_type = self.fill_monitor_class_type() 203 + if self.auto_patch: 204 + self.__patch_file("rv_trace.h", 205 + "// Add new monitors based on CONFIG_%s here" % monitor_class_type, 206 + "#include <monitors/%s/%s_trace.h>" % (self.name, self.name)) 207 + return " - Patching %s/rv_trace.h, double check the result" % self.rv_dir 208 + 209 + return """ - Edit %s/rv_trace.h: 210 + Add this line where other tracepoints are included and %s is defined: 211 + #include <monitors/%s/%s_trace.h> 212 + """ % (self.rv_dir, monitor_class_type, self.name, self.name) 213 + 214 + def fill_kconfig_tooltip(self): 215 + if self.auto_patch: 216 + self.__patch_file("Kconfig", 217 + "# Add new monitors here", 218 + "source \"kernel/trace/rv/monitors/%s/Kconfig\"" % (self.name)) 219 + return " - Patching %s/Kconfig, double check the result" % self.rv_dir 220 + 221 + return """ - Edit %s/Kconfig: 222 + Add this line where other monitors are included: 223 + source \"kernel/trace/rv/monitors/%s/Kconfig\" 224 + """ % (self.rv_dir, self.name) 225 + 226 + def fill_makefile_tooltip(self): 227 + name = self.name 228 + name_up = name.upper() 229 + if self.auto_patch: 230 + self.__patch_file("Makefile", 231 + "# Add new monitors here", 232 + "obj-$(CONFIG_RV_MON_%s) += monitors/%s/%s.o" % (name_up, name, name)) 233 + return " - Patching %s/Makefile, double check the result" % self.rv_dir 234 + 235 + return """ - Edit %s/Makefile: 236 + Add this line where other monitors are included: 237 + obj-$(CONFIG_RV_MON_%s) += monitors/%s/%s.o 238 + """ % (self.rv_dir, name_up, name, name) 239 + 240 + def fill_monitor_tooltip(self): 241 + if self.auto_patch: 242 + return " - Monitor created in %s/monitors/%s" % (self.rv_dir, self. name) 243 + return " - Move %s/ to the kernel's monitor directory (%s/monitors)" % (self.name, self.rv_dir) 244 + 186 245 def __create_directory(self): 246 + path = self.name 247 + if self.auto_patch: 248 + path = os.path.join(self.rv_dir, "monitors", path) 187 249 try: 188 - os.mkdir(self.name) 250 + os.mkdir(path) 189 251 except FileExistsError: 190 252 return 191 253 except: 192 254 print("Fail creating the output dir: %s" % self.name) 193 255 194 - def __create_file(self, file_name, content): 195 - path = "%s/%s" % (self.name, file_name) 256 + def __write_file(self, file_name, content): 196 257 try: 197 - file = open(path, 'w') 198 - except FileExistsError: 199 - return 258 + file = open(file_name, 'w') 200 259 except: 201 - print("Fail creating file: %s" % path) 260 + print("Fail writing to file: %s" % file_name) 202 261 203 262 file.write(content) 204 263 205 264 file.close() 206 265 266 + def __create_file(self, file_name, content): 267 + path = "%s/%s" % (self.name, file_name) 268 + if self.auto_patch: 269 + path = os.path.join(self.rv_dir, "monitors", path) 270 + self.__write_file(path, content) 271 + 207 272 def __get_main_name(self): 208 273 path = "%s/%s" % (self.name, "main.c") 209 - if os.path.exists(path) == False: 210 - return "main.c" 274 + if not os.path.exists(path): 275 + return "main.c" 211 276 return "__main.c" 212 277 213 278 def print_files(self): ··· 332 175 333 176 path = "%s.h" % self.name 334 177 self.__create_file(path, model_h) 178 + 179 + trace_h = self.fill_trace_h() 180 + path = "%s_trace.h" % self.name 181 + self.__create_file(path, trace_h) 182 + 183 + kconfig = self.fill_kconfig() 184 + self.__create_file("Kconfig", kconfig)
+6
tools/verification/dot2/dot2k_templates/Kconfig
··· 1 + config RV_MON_%%MODEL_NAME_UP%% 2 + depends on RV 3 + select %%MONITOR_CLASS_TYPE%% 4 + bool "%%MODEL_NAME%% monitor" 5 + help 6 + %%DESCRIPTION%%
+91
tools/verification/dot2/dot2k_templates/main.c
··· 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 + #include <rv/da_monitor.h> 10 + 11 + #define MODULE_NAME "%%MODEL_NAME%%" 12 + 13 + /* 14 + * XXX: include required tracepoint headers, e.g., 15 + * #include <trace/events/sched.h> 16 + */ 17 + #include <rv_trace.h> 18 + 19 + /* 20 + * This is the self-generated part of the monitor. Generally, there is no need 21 + * to touch this section. 22 + */ 23 + #include "%%MODEL_NAME%%.h" 24 + 25 + /* 26 + * Declare the deterministic automata monitor. 27 + * 28 + * The rv monitor reference is needed for the monitor declaration. 29 + */ 30 + static struct rv_monitor rv_%%MODEL_NAME%%; 31 + DECLARE_DA_MON_%%MONITOR_TYPE%%(%%MODEL_NAME%%, %%MIN_TYPE%%); 32 + 33 + /* 34 + * This is the instrumentation part of the monitor. 35 + * 36 + * This is the section where manual work is required. Here the kernel events 37 + * are translated into model's event. 38 + * 39 + */ 40 + %%TRACEPOINT_HANDLERS_SKEL%% 41 + static int enable_%%MODEL_NAME%%(void) 42 + { 43 + int retval; 44 + 45 + retval = da_monitor_init_%%MODEL_NAME%%(); 46 + if (retval) 47 + return retval; 48 + 49 + %%TRACEPOINT_ATTACH%% 50 + 51 + return 0; 52 + } 53 + 54 + static void disable_%%MODEL_NAME%%(void) 55 + { 56 + rv_%%MODEL_NAME%%.enabled = 0; 57 + 58 + %%TRACEPOINT_DETACH%% 59 + 60 + da_monitor_destroy_%%MODEL_NAME%%(); 61 + } 62 + 63 + /* 64 + * This is the monitor register section. 65 + */ 66 + static struct rv_monitor rv_%%MODEL_NAME%% = { 67 + .name = "%%MODEL_NAME%%", 68 + .description = "%%DESCRIPTION%%", 69 + .enable = enable_%%MODEL_NAME%%, 70 + .disable = disable_%%MODEL_NAME%%, 71 + .reset = da_monitor_reset_all_%%MODEL_NAME%%, 72 + .enabled = 0, 73 + }; 74 + 75 + static int __init register_%%MODEL_NAME%%(void) 76 + { 77 + rv_register_monitor(&rv_%%MODEL_NAME%%); 78 + return 0; 79 + } 80 + 81 + static void __exit unregister_%%MODEL_NAME%%(void) 82 + { 83 + rv_unregister_monitor(&rv_%%MODEL_NAME%%); 84 + } 85 + 86 + module_init(register_%%MODEL_NAME%%); 87 + module_exit(unregister_%%MODEL_NAME%%); 88 + 89 + MODULE_LICENSE("GPL"); 90 + MODULE_AUTHOR("dot2k: auto-generated"); 91 + MODULE_DESCRIPTION("%%MODEL_NAME%%: %%DESCRIPTION%%");
-91
tools/verification/dot2/dot2k_templates/main_global.c
··· 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 - #include <rv/da_monitor.h> 10 - 11 - #define MODULE_NAME "MODEL_NAME" 12 - 13 - /* 14 - * XXX: include required tracepoint headers, e.g., 15 - * #include <trace/events/sched.h> 16 - */ 17 - #include <trace/events/rv.h> 18 - 19 - /* 20 - * This is the self-generated part of the monitor. Generally, there is no need 21 - * to touch this section. 22 - */ 23 - #include "MODEL_NAME.h" 24 - 25 - /* 26 - * Declare the deterministic automata monitor. 27 - * 28 - * The rv monitor reference is needed for the monitor declaration. 29 - */ 30 - static struct rv_monitor rv_MODEL_NAME; 31 - DECLARE_DA_MON_GLOBAL(MODEL_NAME, MIN_TYPE); 32 - 33 - /* 34 - * This is the instrumentation part of the monitor. 35 - * 36 - * This is the section where manual work is required. Here the kernel events 37 - * are translated into model's event. 38 - * 39 - */ 40 - TRACEPOINT_HANDLERS_SKEL 41 - static int enable_MODEL_NAME(void) 42 - { 43 - int retval; 44 - 45 - retval = da_monitor_init_MODEL_NAME(); 46 - if (retval) 47 - return retval; 48 - 49 - TRACEPOINT_ATTACH 50 - 51 - return 0; 52 - } 53 - 54 - static void disable_MODEL_NAME(void) 55 - { 56 - rv_MODEL_NAME.enabled = 0; 57 - 58 - TRACEPOINT_DETACH 59 - 60 - da_monitor_destroy_MODEL_NAME(); 61 - } 62 - 63 - /* 64 - * This is the monitor register section. 65 - */ 66 - static struct rv_monitor rv_MODEL_NAME = { 67 - .name = "MODEL_NAME", 68 - .description = "auto-generated MODEL_NAME", 69 - .enable = enable_MODEL_NAME, 70 - .disable = disable_MODEL_NAME, 71 - .reset = da_monitor_reset_all_MODEL_NAME, 72 - .enabled = 0, 73 - }; 74 - 75 - static int __init register_MODEL_NAME(void) 76 - { 77 - rv_register_monitor(&rv_MODEL_NAME); 78 - return 0; 79 - } 80 - 81 - static void __exit unregister_MODEL_NAME(void) 82 - { 83 - rv_unregister_monitor(&rv_MODEL_NAME); 84 - } 85 - 86 - module_init(register_MODEL_NAME); 87 - module_exit(unregister_MODEL_NAME); 88 - 89 - MODULE_LICENSE("GPL"); 90 - MODULE_AUTHOR("dot2k: auto-generated"); 91 - MODULE_DESCRIPTION("MODEL_NAME");
-91
tools/verification/dot2/dot2k_templates/main_per_cpu.c
··· 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 - #include <rv/da_monitor.h> 10 - 11 - #define MODULE_NAME "MODEL_NAME" 12 - 13 - /* 14 - * XXX: include required tracepoint headers, e.g., 15 - * #include <linux/trace/events/sched.h> 16 - */ 17 - #include <trace/events/rv.h> 18 - 19 - /* 20 - * This is the self-generated part of the monitor. Generally, there is no need 21 - * to touch this section. 22 - */ 23 - #include "MODEL_NAME.h" 24 - 25 - /* 26 - * Declare the deterministic automata monitor. 27 - * 28 - * The rv monitor reference is needed for the monitor declaration. 29 - */ 30 - static struct rv_monitor rv_MODEL_NAME; 31 - DECLARE_DA_MON_PER_CPU(MODEL_NAME, MIN_TYPE); 32 - 33 - /* 34 - * This is the instrumentation part of the monitor. 35 - * 36 - * This is the section where manual work is required. Here the kernel events 37 - * are translated into model's event. 38 - * 39 - */ 40 - TRACEPOINT_HANDLERS_SKEL 41 - static int enable_MODEL_NAME(void) 42 - { 43 - int retval; 44 - 45 - retval = da_monitor_init_MODEL_NAME(); 46 - if (retval) 47 - return retval; 48 - 49 - TRACEPOINT_ATTACH 50 - 51 - return 0; 52 - } 53 - 54 - static void disable_MODEL_NAME(void) 55 - { 56 - rv_MODEL_NAME.enabled = 0; 57 - 58 - TRACEPOINT_DETACH 59 - 60 - da_monitor_destroy_MODEL_NAME(); 61 - } 62 - 63 - /* 64 - * This is the monitor register section. 65 - */ 66 - static struct rv_monitor rv_MODEL_NAME = { 67 - .name = "MODEL_NAME", 68 - .description = "auto-generated MODEL_NAME", 69 - .enable = enable_MODEL_NAME, 70 - .disable = disable_MODEL_NAME, 71 - .reset = da_monitor_reset_all_MODEL_NAME, 72 - .enabled = 0, 73 - }; 74 - 75 - static int __init register_MODEL_NAME(void) 76 - { 77 - rv_register_monitor(&rv_MODEL_NAME); 78 - return 0; 79 - } 80 - 81 - static void __exit unregister_MODEL_NAME(void) 82 - { 83 - rv_unregister_monitor(&rv_MODEL_NAME); 84 - } 85 - 86 - module_init(register_MODEL_NAME); 87 - module_exit(unregister_MODEL_NAME); 88 - 89 - MODULE_LICENSE("GPL"); 90 - MODULE_AUTHOR("dot2k: auto-generated"); 91 - MODULE_DESCRIPTION("MODEL_NAME");
-91
tools/verification/dot2/dot2k_templates/main_per_task.c
··· 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 - #include <rv/da_monitor.h> 10 - 11 - #define MODULE_NAME "MODEL_NAME" 12 - 13 - /* 14 - * XXX: include required tracepoint headers, e.g., 15 - * #include <linux/trace/events/sched.h> 16 - */ 17 - #include <trace/events/rv.h> 18 - 19 - /* 20 - * This is the self-generated part of the monitor. Generally, there is no need 21 - * to touch this section. 22 - */ 23 - #include "MODEL_NAME.h" 24 - 25 - /* 26 - * Declare the deterministic automata monitor. 27 - * 28 - * The rv monitor reference is needed for the monitor declaration. 29 - */ 30 - static struct rv_monitor rv_MODEL_NAME; 31 - DECLARE_DA_MON_PER_TASK(MODEL_NAME, MIN_TYPE); 32 - 33 - /* 34 - * This is the instrumentation part of the monitor. 35 - * 36 - * This is the section where manual work is required. Here the kernel events 37 - * are translated into model's event. 38 - * 39 - */ 40 - TRACEPOINT_HANDLERS_SKEL 41 - static int enable_MODEL_NAME(void) 42 - { 43 - int retval; 44 - 45 - retval = da_monitor_init_MODEL_NAME(); 46 - if (retval) 47 - return retval; 48 - 49 - TRACEPOINT_ATTACH 50 - 51 - return 0; 52 - } 53 - 54 - static void disable_MODEL_NAME(void) 55 - { 56 - rv_MODEL_NAME.enabled = 0; 57 - 58 - TRACEPOINT_DETACH 59 - 60 - da_monitor_destroy_MODEL_NAME(); 61 - } 62 - 63 - /* 64 - * This is the monitor register section. 65 - */ 66 - static struct rv_monitor rv_MODEL_NAME = { 67 - .name = "MODEL_NAME", 68 - .description = "auto-generated MODEL_NAME", 69 - .enable = enable_MODEL_NAME, 70 - .disable = disable_MODEL_NAME, 71 - .reset = da_monitor_reset_all_MODEL_NAME, 72 - .enabled = 0, 73 - }; 74 - 75 - static int __init register_MODEL_NAME(void) 76 - { 77 - rv_register_monitor(&rv_MODEL_NAME); 78 - return 0; 79 - } 80 - 81 - static void __exit unregister_MODEL_NAME(void) 82 - { 83 - rv_unregister_monitor(&rv_MODEL_NAME); 84 - } 85 - 86 - module_init(register_MODEL_NAME); 87 - module_exit(unregister_MODEL_NAME); 88 - 89 - MODULE_LICENSE("GPL"); 90 - MODULE_AUTHOR("dot2k: auto-generated"); 91 - MODULE_DESCRIPTION("MODEL_NAME");
+13
tools/verification/dot2/dot2k_templates/trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* 4 + * Snippet to be included in rv_trace.h 5 + */ 6 + 7 + #ifdef CONFIG_RV_MON_%%MODEL_NAME_UP%% 8 + DEFINE_EVENT(event_%%MONITOR_CLASS%%, event_%%MODEL_NAME%%, 9 + %%TRACEPOINT_ARGS_SKEL_EVENT%%); 10 + 11 + DEFINE_EVENT(error_%%MONITOR_CLASS%%, error_%%MODEL_NAME%%, 12 + %%TRACEPOINT_ARGS_SKEL_ERROR%%); 13 + #endif /* CONFIG_RV_MON_%%MODEL_NAME_UP%% */