Skip to content

Commit b65573c

Browse files
committed
Merge: rtla: Add timerlat BPF sample collection, Set all tracer options by default [rhel-9]
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6686 # Merge Request Required Information JIRA: https://issues.redhat.com/browse/RHEL-77358 JIRA: https://issues.redhat.com/browse/RHEL-86051 ## Summary of Changes Two upstream patchsets are contained in this merge request: * Collect timerlat samples using a BPF program instead of pulling them through a tracefs pipe. This helps with both performance and CPU usage, and fixes an issue where on systems with \>100 CPUs, rtla cannot keep up with timerlat samples and drops most of them, making it useless. * Always set default values of all tracer options (osnoise or timerlat) if not specified otherwise, as they might be set to unexpected values either by another user of the tracers or by a previous abnormally exited run of rtla. Those are combined into a single MR, because the latter depends on a refactoring done in the former. A dependency (rtla test suite) is also pulled. ## Approved Development Ticket(s) All submissions to CentOS Stream must reference a ticket in [Red Hat Jira](https://issues.redhat.com/). <details><summary>Click for formatting instructions</summary> Please follow the CentOS Stream [contribution documentation](https://docs.centos.org/en-US/stream-contrib/quickstart/) for how to file this ticket and have it approved. Signed-off-by: Tomas Glozar <tglozar@redhat.com> List tickets each on their own line of this description using the format "Resolves: RHEL-76229", "Related: RHEL-76229" or "Reverts: RHEL-76229", as appropriate. </details> Approved-by: Wander Lairson Costa <wander@redhat.com> Approved-by: John Kacur <jkacur@redhat.com> Approved-by: Gabriele Monaco <gmonaco@redhat.com> Approved-by: Derek Barbosa <debarbos@redhat.com> Approved-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 8e8b3ae + 145392e commit b65573c

26 files changed

+1521
-646
lines changed

include/trace/events/osnoise.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,105 @@
33
#define TRACE_SYSTEM osnoise
44

55
#if !defined(_OSNOISE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
6+
7+
#ifndef _OSNOISE_TRACE_H
68
#define _OSNOISE_TRACE_H
9+
/*
10+
* osnoise sample structure definition. Used to store the statistics of a
11+
* sample run.
12+
*/
13+
struct osnoise_sample {
14+
u64 runtime; /* runtime */
15+
u64 noise; /* noise */
16+
u64 max_sample; /* max single noise sample */
17+
int hw_count; /* # HW (incl. hypervisor) interference */
18+
int nmi_count; /* # NMIs during this sample */
19+
int irq_count; /* # IRQs during this sample */
20+
int softirq_count; /* # softirqs during this sample */
21+
int thread_count; /* # threads during this sample */
22+
};
23+
24+
#ifdef CONFIG_TIMERLAT_TRACER
25+
/*
26+
* timerlat sample structure definition. Used to store the statistics of
27+
* a sample run.
28+
*/
29+
struct timerlat_sample {
30+
u64 timer_latency; /* timer_latency */
31+
unsigned int seqnum; /* unique sequence */
32+
int context; /* timer context */
33+
};
34+
#endif // CONFIG_TIMERLAT_TRACER
35+
#endif // _OSNOISE_TRACE_H
736

837
#include <linux/tracepoint.h>
38+
TRACE_EVENT(osnoise_sample,
39+
40+
TP_PROTO(struct osnoise_sample *s),
41+
42+
TP_ARGS(s),
43+
44+
TP_STRUCT__entry(
45+
__field( u64, runtime )
46+
__field( u64, noise )
47+
__field( u64, max_sample )
48+
__field( int, hw_count )
49+
__field( int, irq_count )
50+
__field( int, nmi_count )
51+
__field( int, softirq_count )
52+
__field( int, thread_count )
53+
),
54+
55+
TP_fast_assign(
56+
__entry->runtime = s->runtime;
57+
__entry->noise = s->noise;
58+
__entry->max_sample = s->max_sample;
59+
__entry->hw_count = s->hw_count;
60+
__entry->irq_count = s->irq_count;
61+
__entry->nmi_count = s->nmi_count;
62+
__entry->softirq_count = s->softirq_count;
63+
__entry->thread_count = s->thread_count;
64+
),
65+
66+
TP_printk("runtime=%llu noise=%llu max_sample=%llu hw_count=%d"
67+
" irq_count=%d nmi_count=%d softirq_count=%d"
68+
" thread_count=%d",
69+
__entry->runtime,
70+
__entry->noise,
71+
__entry->max_sample,
72+
__entry->hw_count,
73+
__entry->irq_count,
74+
__entry->nmi_count,
75+
__entry->softirq_count,
76+
__entry->thread_count)
77+
);
78+
79+
#ifdef CONFIG_TIMERLAT_TRACER
80+
TRACE_EVENT(timerlat_sample,
81+
82+
TP_PROTO(struct timerlat_sample *s),
83+
84+
TP_ARGS(s),
85+
86+
TP_STRUCT__entry(
87+
__field( u64, timer_latency )
88+
__field( unsigned int, seqnum )
89+
__field( int, context )
90+
),
91+
92+
TP_fast_assign(
93+
__entry->timer_latency = s->timer_latency;
94+
__entry->seqnum = s->seqnum;
95+
__entry->context = s->context;
96+
),
97+
98+
TP_printk("timer_latency=%llu seqnum=%u context=%d",
99+
__entry->timer_latency,
100+
__entry->seqnum,
101+
__entry->context)
102+
);
103+
#endif // CONFIG_TIMERLAT_TRACER
104+
9105
TRACE_EVENT(thread_noise,
10106

11107
TP_PROTO(struct task_struct *t, u64 start, u64 duration),

kernel/trace/trace_osnoise.c

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -315,33 +315,6 @@ static inline void osn_var_reset_all(void)
315315
*/
316316
bool trace_osnoise_callback_enabled;
317317

318-
/*
319-
* osnoise sample structure definition. Used to store the statistics of a
320-
* sample run.
321-
*/
322-
struct osnoise_sample {
323-
u64 runtime; /* runtime */
324-
u64 noise; /* noise */
325-
u64 max_sample; /* max single noise sample */
326-
int hw_count; /* # HW (incl. hypervisor) interference */
327-
int nmi_count; /* # NMIs during this sample */
328-
int irq_count; /* # IRQs during this sample */
329-
int softirq_count; /* # softirqs during this sample */
330-
int thread_count; /* # threads during this sample */
331-
};
332-
333-
#ifdef CONFIG_TIMERLAT_TRACER
334-
/*
335-
* timerlat sample structure definition. Used to store the statistics of
336-
* a sample run.
337-
*/
338-
struct timerlat_sample {
339-
u64 timer_latency; /* timer_latency */
340-
unsigned int seqnum; /* unique sequence */
341-
int context; /* timer context */
342-
};
343-
#endif
344-
345318
/*
346319
* Tracer data.
347320
*/
@@ -497,7 +470,7 @@ static void print_osnoise_headers(struct seq_file *s)
497470
* Record an osnoise_sample into the tracer buffer.
498471
*/
499472
static void
500-
__trace_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buffer)
473+
__record_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buffer)
501474
{
502475
struct trace_event_call *call = &event_osnoise;
503476
struct ring_buffer_event *event;
@@ -522,17 +495,19 @@ __trace_osnoise_sample(struct osnoise_sample *sample, struct trace_buffer *buffe
522495
}
523496

524497
/*
525-
* Record an osnoise_sample on all osnoise instances.
498+
* Record an osnoise_sample on all osnoise instances and fire trace event.
526499
*/
527-
static void trace_osnoise_sample(struct osnoise_sample *sample)
500+
static void record_osnoise_sample(struct osnoise_sample *sample)
528501
{
529502
struct osnoise_instance *inst;
530503
struct trace_buffer *buffer;
531504

505+
trace_osnoise_sample(sample);
506+
532507
rcu_read_lock();
533508
list_for_each_entry_rcu(inst, &osnoise_instances, list) {
534509
buffer = inst->tr->array_buffer.buffer;
535-
__trace_osnoise_sample(sample, buffer);
510+
__record_osnoise_sample(sample, buffer);
536511
}
537512
rcu_read_unlock();
538513
}
@@ -576,7 +551,7 @@ static void print_timerlat_headers(struct seq_file *s)
576551
#endif /* CONFIG_PREEMPT_RT */
577552

578553
static void
579-
__trace_timerlat_sample(struct timerlat_sample *sample, struct trace_buffer *buffer)
554+
__record_timerlat_sample(struct timerlat_sample *sample, struct trace_buffer *buffer)
580555
{
581556
struct trace_event_call *call = &event_osnoise;
582557
struct ring_buffer_event *event;
@@ -598,15 +573,17 @@ __trace_timerlat_sample(struct timerlat_sample *sample, struct trace_buffer *buf
598573
/*
599574
* Record an timerlat_sample into the tracer buffer.
600575
*/
601-
static void trace_timerlat_sample(struct timerlat_sample *sample)
576+
static void record_timerlat_sample(struct timerlat_sample *sample)
602577
{
603578
struct osnoise_instance *inst;
604579
struct trace_buffer *buffer;
605580

581+
trace_timerlat_sample(sample);
582+
606583
rcu_read_lock();
607584
list_for_each_entry_rcu(inst, &osnoise_instances, list) {
608585
buffer = inst->tr->array_buffer.buffer;
609-
__trace_timerlat_sample(sample, buffer);
586+
__record_timerlat_sample(sample, buffer);
610587
}
611588
rcu_read_unlock();
612589
}
@@ -1603,7 +1580,7 @@ static int run_osnoise(void)
16031580
/* Save interference stats info */
16041581
diff_osn_sample_stats(osn_var, &s);
16051582

1606-
trace_osnoise_sample(&s);
1583+
record_osnoise_sample(&s);
16071584

16081585
notify_new_max_latency(max_noise);
16091586

@@ -1798,7 +1775,7 @@ static enum hrtimer_restart timerlat_irq(struct hrtimer *timer)
17981775
s.timer_latency = diff;
17991776
s.context = IRQ_CONTEXT;
18001777

1801-
trace_timerlat_sample(&s);
1778+
record_timerlat_sample(&s);
18021779

18031780
if (osnoise_data.stop_tracing) {
18041781
if (time_to_us(diff) >= osnoise_data.stop_tracing) {
@@ -1918,7 +1895,7 @@ static int timerlat_main(void *data)
19181895
s.timer_latency = diff;
19191896
s.context = THREAD_CONTEXT;
19201897

1921-
trace_timerlat_sample(&s);
1898+
record_timerlat_sample(&s);
19221899

19231900
notify_new_max_latency(diff);
19241901

@@ -2538,7 +2515,7 @@ timerlat_fd_read(struct file *file, char __user *ubuf, size_t count,
25382515
s.timer_latency = diff;
25392516
s.context = THREAD_URET;
25402517

2541-
trace_timerlat_sample(&s);
2518+
record_timerlat_sample(&s);
25422519

25432520
notify_new_max_latency(diff);
25442521

@@ -2573,7 +2550,7 @@ timerlat_fd_read(struct file *file, char __user *ubuf, size_t count,
25732550
s.timer_latency = diff;
25742551
s.context = THREAD_CONTEXT;
25752552

2576-
trace_timerlat_sample(&s);
2553+
record_timerlat_sample(&s);
25772554

25782555
if (osnoise_data.stop_tracing_total) {
25792556
if (time_to_us(diff) >= osnoise_data.stop_tracing_total) {

redhat/kernel.spec.template

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,9 @@ BuildRequires: libcap-devel libcap-ng-devel
682682
BuildRequires: python3-docutils
683683
BuildRequires: libtraceevent-devel
684684
BuildRequires: libtracefs-devel
685+
BuildRequires: libbpf-devel
686+
BuildRequires: bpftool
687+
BuildRequires: clang
685688

686689
%ifnarch s390x
687690
BuildRequires: pciutils-devel
@@ -1161,6 +1164,7 @@ This package provides debug information for package kernel-tools.
11611164
Summary: Real-Time Linux Analysis tools
11621165
Requires: libtraceevent
11631166
Requires: libtracefs
1167+
Requires: libbpf
11641168
%ifarch %{cpupowerarchs}
11651169
Requires: kernel-tools-libs = %{version}-%{release}
11661170
%endif

tools/build/Makefile.feature

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ FEATURE_TESTS_EXTRA := \
110110
libbpf-bpf_create_map \
111111
libpfm4 \
112112
libdebuginfod \
113-
clang-bpf-co-re
113+
clang-bpf-co-re \
114+
bpftool-skeletons
114115

115116

116117
FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)

tools/build/feature/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ $(OUTPUT)test-file-handle.bin:
422422
$(OUTPUT)test-libpfm4.bin:
423423
$(BUILD) -lpfm
424424

425+
$(OUTPUT)test-bpftool-skeletons.bin:
426+
$(SYSTEM_BPFTOOL) version | grep '^features:.*skeletons' \
427+
> $(@:.bin=.make.output) 2>&1
425428
###############################
426429

427430
clean:

tools/scripts/Makefile.include

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ LLVM_CONFIG ?= llvm-config
8585
LLVM_OBJCOPY ?= llvm-objcopy
8686
LLVM_STRIP ?= llvm-strip
8787

88+
# Some tools require bpftool
89+
SYSTEM_BPFTOOL ?= bpftool
90+
8891
ifeq ($(CC_NO_CLANG), 1)
8992
EXTRA_WARNINGS += -Wstrict-aliasing=3
9093

tools/tracing/rtla/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ rtla-static
44
fixdep
55
feature
66
FEATURE-DUMP
7+
*.skel.h

tools/tracing/rtla/Makefile

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ DOCSRC := ../../../Documentation/tools/rtla/
3333
FEATURE_TESTS := libtraceevent
3434
FEATURE_TESTS += libtracefs
3535
FEATURE_TESTS += libcpupower
36+
FEATURE_TESTS += libbpf
37+
FEATURE_TESTS += clang-bpf-co-re
38+
FEATURE_TESTS += bpftool-skeletons
3639
FEATURE_DISPLAY := libtraceevent
3740
FEATURE_DISPLAY += libtracefs
3841
FEATURE_DISPLAY += libcpupower
42+
FEATURE_DISPLAY += libbpf
43+
FEATURE_DISPLAY += clang-bpf-co-re
44+
FEATURE_DISPLAY += bpftool-skeletons
3945

4046
ifeq ($(V),1)
4147
Q =
@@ -67,6 +73,17 @@ CFLAGS += $(INCLUDES) $(LIB_INCLUDES)
6773

6874
export CFLAGS OUTPUT srctree
6975

76+
ifeq ($(BUILD_BPF_SKEL),1)
77+
src/timerlat.bpf.o: src/timerlat.bpf.c
78+
$(QUIET_CLANG)$(CLANG) -g -O2 -target bpf -c $(filter %.c,$^) -o $@
79+
80+
src/timerlat.skel.h: src/timerlat.bpf.o
81+
$(QUIET_GENSKEL)$(SYSTEM_BPFTOOL) gen skeleton $< > $@
82+
else
83+
src/timerlat.skel.h:
84+
$(Q)echo '/* BPF skeleton is disabled */' > src/timerlat.skel.h
85+
endif
86+
7087
$(RTLA): $(RTLA_IN)
7188
$(QUIET_LINK)$(CC) $(LDFLAGS) -o $(RTLA) $(RTLA_IN) $(EXTLIBS)
7289

@@ -77,12 +94,15 @@ static: $(RTLA_IN)
7794
rtla.%: fixdep FORCE
7895
make -f $(srctree)/tools/build/Makefile.build dir=. $@
7996

80-
$(RTLA_IN): fixdep FORCE
97+
$(RTLA_IN): fixdep FORCE src/timerlat.skel.h
8198
make $(build)=rtla
8299

83100
clean: doc_clean fixdep-clean
84101
$(call QUIET_CLEAN, rtla)
85102
$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
86103
$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
87104
$(Q)rm -rf feature
88-
.PHONY: FORCE clean
105+
$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h
106+
check: $(RTLA)
107+
RTLA=$(RTLA) prove -o -f tests/
108+
.PHONY: FORCE clean check

tools/tracing/rtla/Makefile.config

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,48 @@ else
5353
$(info Please install libcpupower-dev/kernel-tools-libs-devel)
5454
endif
5555

56+
ifndef BUILD_BPF_SKEL
57+
# BPF skeletons are used to implement improved sample collection, enable
58+
# them by default.
59+
BUILD_BPF_SKEL := 1
60+
endif
61+
62+
ifeq ($(BUILD_BPF_SKEL),0)
63+
$(info BPF skeleton support disabled, building without BPF skeleton support.)
64+
endif
65+
66+
$(call feature_check,libbpf)
67+
ifeq ($(feature-libbpf), 1)
68+
$(call detected,CONFIG_LIBBPF)
69+
else
70+
$(info libbpf is missing, building without BPF skeleton support.)
71+
$(info Please install libbpf-dev/libbpf-devel)
72+
BUILD_BPF_SKEL := 0
73+
endif
74+
75+
$(call feature_check,clang-bpf-co-re)
76+
ifeq ($(feature-clang-bpf-co-re), 1)
77+
$(call detected,CONFIG_CLANG_BPF_CO_RE)
78+
else
79+
$(info clang is missing or does not support BPF CO-RE, building without BPF skeleton support.)
80+
$(info Please install clang)
81+
BUILD_BPF_SKEL := 0
82+
endif
83+
84+
$(call feature_check,bpftool-skeletons)
85+
ifeq ($(feature-bpftool-skeletons), 1)
86+
$(call detected,CONFIG_BPFTOOL_SKELETONS)
87+
else
88+
$(info bpftool is missing or not supporting skeletons, building without BPF skeleton support.)
89+
$(info Please install bpftool)
90+
BUILD_BPF_SKEL := 0
91+
endif
92+
93+
ifeq ($(BUILD_BPF_SKEL),1)
94+
CFLAGS += -DHAVE_BPF_SKEL
95+
EXTLIBS += -lbpf
96+
endif
97+
5698
ifeq ($(STOP_ERROR),1)
5799
$(error Please, check the errors above.)
58100
endif

0 commit comments

Comments
 (0)