Skip to content

Commit 6b20bce

Browse files
committed
Merge: rtla: backport fixes and enhancements
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/5009 JIRA: https://issues.redhat.com/browse/RHEL-50869 List of upstream commits backported: ``` 2201aea rtla: Make doc build optional 6127383 Documentation: Add tools/rtla timerlat -u option documentation a23c05f tools/rtla: Add -U/--user-load option to timerlat 5f07693 rtla/timerlat: Simplify "no value" printing on top a40e5e4 rtla/auto-analysis: Replace \t with spaces f5c0cda rtla/timerlat: Use pretty formatting only on interactive tty 285dcb7 rtla/timerlat: Add a summary for top mode 1462501 rtla/timerlat: Add a summary for hist mode cdbf719 rtla: Add the --warm-up option 01b05fc rtla/timerlat: Fix histogram report when a cpu count is 0 842fc5b rtla: Fix -t\--trace[=file] 59237b0 rtla/osnoise: Use pretty formatting only on interactive tty 587f05a rtla/osnoise: Better report when histogram is empty c40583e rtla/osnoise: set the default threshold to 1us ``` Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com> Approved-by: Tomáš Glozar <tglozar@redhat.com> Approved-by: Joe Lawrence <joe.lawrence@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Approved-by: Eder Zulian <ezulian@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents f5d1dcf + c171ce3 commit 6b20bce

File tree

11 files changed

+660
-159
lines changed

11 files changed

+660
-159
lines changed

Documentation/tools/rtla/common_options.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050

5151
Set a *cgroup* to the tracer's threads. If the **-C** option is passed without arguments, the tracer's thread will inherit **rtla**'s *cgroup*. Otherwise, the threads will be placed on the *cgroup* passed to the option.
5252

53+
**--warm-up** *s*
54+
55+
After starting the workload, let it run for *s* seconds before starting collecting the data, allowing the system to warm-up. Statistical data generated during warm-up is discarded.
56+
5357
**-h**, **--help**
5458

5559
Print help menu.

Documentation/tools/rtla/common_timerlat_options.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,16 @@
2626
Set the /dev/cpu_dma_latency to *us*, aiming to bound exit from idle latencies.
2727
*cyclictest* sets this value to *0* by default, use **--dma-latency** *0* to have
2828
similar results.
29+
30+
**-u**, **--user-threads**
31+
32+
Set timerlat to run without a workload, and then dispatches user-space workloads
33+
to wait on the timerlat_fd. Once the workload is awakes, it goes to sleep again
34+
adding so the measurement for the kernel-to-user and user-to-kernel to the tracer
35+
output.
36+
37+
**-U**, **--user-load**
38+
39+
Set timerlat to run without workload, waiting for the user to dispatch a per-cpu
40+
task that waits for a new period on the tracing/osnoise/per_cpu/cpu$ID/timerlat_fd.
41+
See linux/tools/rtla/sample/timerlat_load.py for an example of user-load code.

Documentation/trace/osnoise-tracer.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ The tracer has a set of options inside the osnoise directory, they are:
108108
option.
109109
- tracing_threshold: the minimum delta between two time() reads to be
110110
considered as noise, in us. When set to 0, the default value will
111-
will be used, which is currently 5 us.
111+
be used, which is currently 1 us.
112112

113113
Additional Tracing
114114
------------------

kernel/trace/trace_osnoise.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,9 +1444,9 @@ static int run_osnoise(void)
14441444
save_osn_sample_stats(osn_var, &s);
14451445

14461446
/*
1447-
* if threshold is 0, use the default value of 5 us.
1447+
* if threshold is 0, use the default value of 1 us.
14481448
*/
1449-
threshold = tracing_thresh ? : 5000;
1449+
threshold = tracing_thresh ? : 1000;
14501450

14511451
/*
14521452
* Apply PREEMPT and IRQ disabled options.

tools/tracing/rtla/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ warnings: $(WARNINGS)
111111
$(ERROR_OUT)
112112
endif
113113

114-
rtla: $(OBJ) doc
114+
rtla: $(OBJ)
115115
$(CC) -o rtla $(LDFLAGS) $(OBJ) $(LIBS)
116116

117117
static: $(OBJ)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: GPL-2.0-only
3+
#
4+
# Copyright (C) 2024 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
5+
#
6+
# This is a sample code about how to use timerlat's timer by any workload
7+
# so rtla can measure and provide auto-analysis for the overall latency (IOW
8+
# the response time) for a task.
9+
#
10+
# Before running it, you need to dispatch timerlat with -U option in a terminal.
11+
# Then # run this script pinned to a CPU on another terminal. For example:
12+
#
13+
# timerlat_load.py 1 -p 95
14+
#
15+
# The "Timerlat IRQ" is the IRQ latency, The thread latency is the latency
16+
# for the python process to get the CPU. The Ret from user Timer Latency is
17+
# the overall latency. In other words, it is the response time for that
18+
# activation.
19+
#
20+
# This is just an example, the load is reading 20MB of data from /dev/full
21+
# It is in python because it is easy to read :-)
22+
23+
import argparse
24+
import sys
25+
import os
26+
27+
parser = argparse.ArgumentParser(description='user-space timerlat thread in Python')
28+
parser.add_argument("cpu", help='CPU to run timerlat thread')
29+
parser.add_argument("-p", "--prio", help='FIFO priority')
30+
31+
args = parser.parse_args()
32+
33+
try:
34+
affinity_mask = { int(args.cpu) }
35+
except:
36+
print("Invalid cpu: " + args.cpu)
37+
exit(1)
38+
39+
try:
40+
os.sched_setaffinity(0, affinity_mask);
41+
except:
42+
print("Error setting affinity")
43+
exit(1)
44+
45+
if (args.prio):
46+
try:
47+
param = os.sched_param(int(args.prio))
48+
os.sched_setscheduler(0, os.SCHED_FIFO, param)
49+
except:
50+
print("Error setting priority")
51+
exit(1)
52+
53+
try:
54+
timerlat_path = "/sys/kernel/tracing/osnoise/per_cpu/cpu" + args.cpu + "/timerlat_fd"
55+
timerlat_fd = open(timerlat_path, 'r')
56+
except:
57+
print("Error opening timerlat fd, did you run timerlat -U?")
58+
exit(1)
59+
60+
try:
61+
data_fd = open("/dev/full", 'r');
62+
except:
63+
print("Error opening data fd")
64+
65+
while True:
66+
try:
67+
timerlat_fd.read(1)
68+
data_fd.read(20*1024*1024)
69+
except:
70+
print("Leaving")
71+
break
72+
73+
timerlat_fd.close()
74+
data_fd.close()

tools/tracing/rtla/src/osnoise_hist.c

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ struct osnoise_hist_params {
3636
cpu_set_t hk_cpu_set;
3737
struct sched_attr sched_param;
3838
struct trace_events *events;
39-
4039
char no_header;
4140
char no_summary;
4241
char no_index;
4342
char with_zeros;
4443
int bucket_size;
4544
int entries;
45+
int warmup;
4646
};
4747

4848
struct osnoise_hist_cpu {
@@ -373,6 +373,7 @@ osnoise_print_stats(struct osnoise_hist_params *params, struct osnoise_tool *too
373373
{
374374
struct osnoise_hist_data *data = tool->data;
375375
struct trace_instance *trace = &tool->trace;
376+
int has_samples = 0;
376377
int bucket, cpu;
377378
int total;
378379

@@ -401,11 +402,25 @@ osnoise_print_stats(struct osnoise_hist_params *params, struct osnoise_tool *too
401402
continue;
402403
}
403404

405+
/* There are samples above the threshold */
406+
has_samples = 1;
404407
trace_seq_printf(trace->seq, "\n");
405408
trace_seq_do_printf(trace->seq);
406409
trace_seq_reset(trace->seq);
407410
}
408411

412+
/*
413+
* If no samples were recorded, skip calculations, print zeroed statistics
414+
* and return.
415+
*/
416+
if (!has_samples) {
417+
trace_seq_reset(trace->seq);
418+
trace_seq_printf(trace->seq, "over: 0\ncount: 0\nmin: 0\navg: 0\nmax: 0\n");
419+
trace_seq_do_printf(trace->seq);
420+
trace_seq_reset(trace->seq);
421+
return;
422+
}
423+
409424
if (!params->no_index)
410425
trace_seq_printf(trace->seq, "over: ");
411426

@@ -436,9 +451,9 @@ static void osnoise_hist_usage(char *usage)
436451
static const char * const msg[] = {
437452
"",
438453
" usage: rtla osnoise hist [-h] [-D] [-d s] [-a us] [-p us] [-r us] [-s us] [-S us] \\",
439-
" [-T us] [-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
454+
" [-T us] [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] \\",
440455
" [-c cpu-list] [-H cpu-list] [-P priority] [-b N] [-E N] [--no-header] [--no-summary] \\",
441-
" [--no-index] [--with-zeros] [-C[=cgroup_name]]",
456+
" [--no-index] [--with-zeros] [-C[=cgroup_name]] [--warm-up]",
442457
"",
443458
" -h/--help: print this menu",
444459
" -a/--auto: set automatic trace mode, stopping the session if argument in us sample is hit",
@@ -452,7 +467,7 @@ static void osnoise_hist_usage(char *usage)
452467
" -C/--cgroup[=cgroup_name]: set cgroup, if no cgroup_name is passed, the rtla's cgroup will be inherited",
453468
" -d/--duration time[s|m|h|d]: duration of the session",
454469
" -D/--debug: print debug info",
455-
" -t/--trace[=file]: save the stopped trace to [file|osnoise_trace.txt]",
470+
" -t/--trace[file]: save the stopped trace to [file|osnoise_trace.txt]",
456471
" -e/--event <sys:event>: enable the <sys:event> in the trace instance, multiple -e are allowed",
457472
" --filter <filter>: enable a trace event filter to the previous -e event",
458473
" --trigger <trigger>: enable a trace event trigger to the previous -e event",
@@ -468,6 +483,7 @@ static void osnoise_hist_usage(char *usage)
468483
" f:prio - use SCHED_FIFO with prio",
469484
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period",
470485
" in nanoseconds",
486+
" --warm-up: let the workload run for s seconds before collecting data",
471487
NULL,
472488
};
473489

@@ -531,13 +547,14 @@ static struct osnoise_hist_params
531547
{"with-zeros", no_argument, 0, '3'},
532548
{"trigger", required_argument, 0, '4'},
533549
{"filter", required_argument, 0, '5'},
550+
{"warm-up", required_argument, 0, '6'},
534551
{0, 0, 0, 0}
535552
};
536553

537554
/* getopt_long stores the option index here. */
538555
int option_index = 0;
539556

540-
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:",
557+
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:p:P:r:s:S:t::T:01234:5:6:",
541558
long_options, &option_index);
542559

543560
/* detect the end of the options. */
@@ -640,9 +657,13 @@ static struct osnoise_hist_params
640657
params->threshold = get_llong_from_str(optarg);
641658
break;
642659
case 't':
643-
if (optarg)
644-
/* skip = */
645-
params->trace_output = &optarg[1];
660+
if (optarg) {
661+
if (optarg[0] == '=')
662+
params->trace_output = &optarg[1];
663+
else
664+
params->trace_output = &optarg[0];
665+
} else if (optind < argc && argv[optind][0] != '0')
666+
params->trace_output = argv[optind];
646667
else
647668
params->trace_output = "osnoise_trace.txt";
648669
break;
@@ -680,6 +701,9 @@ static struct osnoise_hist_params
680701
osnoise_hist_usage("--filter requires a previous -e\n");
681702
}
682703
break;
704+
case '6':
705+
params->warmup = get_llong_from_str(optarg);
706+
break;
683707
default:
684708
osnoise_hist_usage("Invalid option");
685709
}
@@ -899,6 +923,25 @@ int osnoise_hist_main(int argc, char *argv[])
899923
trace_instance_start(&record->trace);
900924
trace_instance_start(trace);
901925

926+
if (params->warmup > 0) {
927+
debug_msg("Warming up for %d seconds\n", params->warmup);
928+
sleep(params->warmup);
929+
if (stop_tracing)
930+
goto out_hist;
931+
932+
/*
933+
* Clean up the buffer. The osnoise workload do not run
934+
* with tracing off to avoid creating a performance penalty
935+
* when not needed.
936+
*/
937+
retval = tracefs_instance_file_write(trace->inst, "trace", "");
938+
if (retval < 0) {
939+
debug_msg("Error cleaning up the buffer");
940+
goto out_hist;
941+
}
942+
943+
}
944+
902945
tool->start_time = time(NULL);
903946
osnoise_hist_set_signals(params);
904947

0 commit comments

Comments
 (0)