Skip to content

Commit 40648d2

Browse files
committed
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 ...
2 parents 90ab211 + cf18620 commit 40648d2

33 files changed

+691
-406
lines changed

kernel/trace/rv/Kconfig

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,9 @@ menuconfig RV
2525
For further information, see:
2626
Documentation/trace/rv/runtime-verification.rst
2727

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
5231

5332
config RV_REACTORS
5433
bool "Runtime verification reactors"

kernel/trace/rv/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# SPDX-License-Identifier: GPL-2.0
22

3+
ccflags-y += -I $(src) # needed for trace events
4+
35
obj-$(CONFIG_RV) += rv.o
46
obj-$(CONFIG_RV_MON_WIP) += monitors/wip/wip.o
57
obj-$(CONFIG_RV_MON_WWNR) += monitors/wwnr/wwnr.o
8+
# Add new monitors here
69
obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
710
obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o
811
obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o

kernel/trace/rv/monitors/wip/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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

kernel/trace/rv/monitors/wip/wip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#define MODULE_NAME "wip"
1212

13-
#include <trace/events/rv.h>
13+
#include <rv_trace.h>
1414
#include <trace/events/sched.h>
1515
#include <trace/events/preemptirq.h>
1616

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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 */

kernel/trace/rv/monitors/wwnr/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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

kernel/trace/rv/monitors/wwnr/wwnr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#define MODULE_NAME "wwnr"
1212

13-
#include <trace/events/rv.h>
13+
#include <rv_trace.h>
1414
#include <trace/events/sched.h>
1515

1616
#include "wwnr.h"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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 */

kernel/trace/rv/rv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145

146146
#ifdef CONFIG_DA_MON_EVENTS
147147
#define CREATE_TRACE_POINTS
148-
#include <trace/events/rv.h>
148+
#include <rv_trace.h>
149149
#endif
150150

151151
#include "rv.h"

include/trace/events/rv.h renamed to kernel/trace/rv/rv_trace.h

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,9 @@ DECLARE_EVENT_CLASS(error_da_monitor,
5757
__entry->state)
5858
);
5959

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));
64-
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 */
60+
#include <monitors/wip/wip_trace.h>
61+
// Add new monitors based on CONFIG_DA_MON_EVENTS_IMPLICIT here
62+
6963
#endif /* CONFIG_DA_MON_EVENTS_IMPLICIT */
7064

7165
#ifdef CONFIG_DA_MON_EVENTS_ID
@@ -123,20 +117,14 @@ DECLARE_EVENT_CLASS(error_da_monitor_id,
123117
__entry->state)
124118
);
125119

126-
#ifdef CONFIG_RV_MON_WWNR
127-
/* id is the pid of the task */
128-
DEFINE_EVENT(event_da_monitor_id, event_wwnr,
129-
TP_PROTO(int id, char *state, char *event, char *next_state, bool final_state),
130-
TP_ARGS(id, state, event, next_state, final_state));
131-
132-
DEFINE_EVENT(error_da_monitor_id, error_wwnr,
133-
TP_PROTO(int id, char *state, char *event),
134-
TP_ARGS(id, state, event));
135-
#endif /* CONFIG_RV_MON_WWNR */
120+
#include <monitors/wwnr/wwnr_trace.h>
121+
// Add new monitors based on CONFIG_DA_MON_EVENTS_ID here
136122

137123
#endif /* CONFIG_DA_MON_EVENTS_ID */
138124
#endif /* _TRACE_RV_H */
139125

140126
/* This part ust be outside protection */
141127
#undef TRACE_INCLUDE_PATH
128+
#define TRACE_INCLUDE_PATH .
129+
#define TRACE_INCLUDE_FILE rv_trace
142130
#include <trace/define_trace.h>

tools/tracing/rtla/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,6 @@ clean: doc_clean fixdep-clean
8585
$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
8686
$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
8787
$(Q)rm -rf feature
88-
.PHONY: FORCE clean
88+
check: $(RTLA)
89+
RTLA=$(RTLA) prove -o -f tests/
90+
.PHONY: FORCE clean check

tools/tracing/rtla/src/osnoise.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ int osnoise_set_workload(struct osnoise_context *context, bool onoff)
867867

868868
retval = osnoise_options_set_option("OSNOISE_WORKLOAD", onoff);
869869
if (retval < 0)
870-
return -1;
870+
return -2;
871871

872872
context->opt_workload = onoff;
873873

@@ -1079,6 +1079,42 @@ struct osnoise_tool *osnoise_init_trace_tool(char *tracer)
10791079
return NULL;
10801080
}
10811081

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+
}
1116+
}
1117+
10821118
static void osnoise_usage(int err)
10831119
{
10841120
int i;

tools/tracing/rtla/src/osnoise.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ struct osnoise_tool {
104104
void osnoise_destroy_tool(struct osnoise_tool *top);
105105
struct osnoise_tool *osnoise_init_tool(char *tool_name);
106106
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);
107109

108110
int osnoise_hist_main(int argc, char *argv[]);
109111
int osnoise_top_main(int argc, char **argv);

tools/tracing/rtla/src/osnoise_hist.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ osnoise_print_stats(struct osnoise_hist_params *params, struct osnoise_tool *too
440440
trace_seq_reset(trace->seq);
441441

442442
osnoise_print_summary(params, trace, data);
443+
osnoise_report_missed_events(tool);
443444
}
444445

445446
/*
@@ -970,7 +971,7 @@ int osnoise_hist_main(int argc, char *argv[])
970971
goto out_hist;
971972
}
972973

973-
if (trace_is_off(&tool->trace, &record->trace))
974+
if (osnoise_trace_is_off(tool, record))
974975
break;
975976
}
976977

@@ -980,7 +981,7 @@ int osnoise_hist_main(int argc, char *argv[])
980981

981982
return_value = 0;
982983

983-
if (trace_is_off(&tool->trace, &record->trace)) {
984+
if (osnoise_trace_is_off(tool, record)) {
984985
printf("rtla osnoise hit stop tracing\n");
985986
if (params->trace_output) {
986987
printf(" Saving trace to %s\n", params->trace_output);

tools/tracing/rtla/src/osnoise_top.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ osnoise_print_stats(struct osnoise_top_params *params, struct osnoise_tool *top)
280280

281281
trace_seq_do_printf(trace->seq);
282282
trace_seq_reset(trace->seq);
283+
osnoise_report_missed_events(top);
283284
}
284285

285286
/*
@@ -801,7 +802,7 @@ int osnoise_top_main(int argc, char **argv)
801802
if (!params->quiet)
802803
osnoise_print_stats(params, tool);
803804

804-
if (trace_is_off(&tool->trace, &record->trace))
805+
if (osnoise_trace_is_off(tool, record))
805806
break;
806807

807808
}
@@ -810,7 +811,7 @@ int osnoise_top_main(int argc, char **argv)
810811

811812
return_value = 0;
812813

813-
if (trace_is_off(&tool->trace, &record->trace)) {
814+
if (osnoise_trace_is_off(tool, record)) {
814815
printf("osnoise hit stop tracing\n");
815816
if (params->trace_output) {
816817
printf(" Saving trace to %s\n", params->trace_output);

tools/tracing/rtla/src/timerlat_hist.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ timerlat_print_stats(struct timerlat_hist_params *params, struct osnoise_tool *t
656656

657657
timerlat_print_summary(params, trace, data);
658658
timerlat_print_stats_all(params, trace, data);
659+
osnoise_report_missed_events(tool);
659660
}
660661

661662
/*
@@ -1100,12 +1101,15 @@ timerlat_hist_apply_config(struct osnoise_tool *tool, struct timerlat_hist_param
11001101
}
11011102
}
11021103

1103-
if (params->user_hist) {
1104-
retval = osnoise_set_workload(tool->context, 0);
1105-
if (retval) {
1106-
err_msg("Failed to set OSNOISE_WORKLOAD option\n");
1107-
goto out_err;
1108-
}
1104+
/*
1105+
* Set workload according to type of thread if the kernel supports it.
1106+
* On kernels without support, user threads will have already failed
1107+
* on missing timerlat_fd, and kernel threads do not need it.
1108+
*/
1109+
retval = osnoise_set_workload(tool->context, params->kernel_workload);
1110+
if (retval < -1) {
1111+
err_msg("Failed to set OSNOISE_WORKLOAD option\n");
1112+
goto out_err;
11091113
}
11101114

11111115
return 0;
@@ -1146,9 +1150,20 @@ static struct osnoise_tool
11461150
}
11471151

11481152
static int stop_tracing;
1153+
static struct trace_instance *hist_inst = NULL;
11491154
static void stop_hist(int sig)
11501155
{
1156+
if (stop_tracing) {
1157+
/*
1158+
* Stop requested twice in a row; abort event processing and
1159+
* exit immediately
1160+
*/
1161+
tracefs_iterate_stop(hist_inst->inst);
1162+
return;
1163+
}
11511164
stop_tracing = 1;
1165+
if (hist_inst)
1166+
trace_instance_stop(hist_inst);
11521167
}
11531168

11541169
/*
@@ -1195,6 +1210,12 @@ int timerlat_hist_main(int argc, char *argv[])
11951210
}
11961211

11971212
trace = &tool->trace;
1213+
/*
1214+
* Save trace instance into global variable so that SIGINT can stop
1215+
* the timerlat tracer.
1216+
* Otherwise, rtla could loop indefinitely when overloaded.
1217+
*/
1218+
hist_inst = trace;
11981219

11991220
retval = enable_timerlat(trace);
12001221
if (retval) {
@@ -1342,7 +1363,7 @@ int timerlat_hist_main(int argc, char *argv[])
13421363
goto out_hist;
13431364
}
13441365

1345-
if (trace_is_off(&tool->trace, &record->trace))
1366+
if (osnoise_trace_is_off(tool, record))
13461367
break;
13471368

13481369
/* is there still any user-threads ? */
@@ -1363,7 +1384,7 @@ int timerlat_hist_main(int argc, char *argv[])
13631384

13641385
return_value = 0;
13651386

1366-
if (trace_is_off(&tool->trace, &record->trace)) {
1387+
if (osnoise_trace_is_off(tool, record) && !stop_tracing) {
13671388
printf("rtla timerlat hit stop tracing\n");
13681389

13691390
if (!params->no_aa)

0 commit comments

Comments
 (0)