Skip to content

Commit

Permalink
Merge tag 'trace-tools-v6.15' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/trace/linux-trace

Pull tracing tooling updates from Steven Rostedt:

 - Allow RTLA to collect data via BPF

   The current implementation of rtla uses libtracefs and libtraceevent
   to pull sample events generated by the timerlat tracer from the trace
   buffer. rtla then processes the sample by updating the histogram and
   summary (current, maximum, minimum, and sum values) as well as checks
   if tracing has been stopped due to threshold overflow.

   In use cases where a large number of samples is being generated, that
   is, with measurements running on many CPUs and with a low interval,
   this sample processing design causes a significant CPU load on the
   rtla side. Furthermore, with >100 CPUs and 100us interval, rtla was
   reported as not being able to keep up with the samples and dropping
   most of them, leading to it being unusable.

   Change the way the timerlat trace processes samples by attaching a
   BPF program to the trace event using the BPF skeleton feature of
   bpftool. Unlike the current implementation, the BPF implementation
   does not check whether tracing is stopped (in BPF mode, tracing is
   always off to improve performance), but waits for a write to a BPF
   ringbuffer instead. This allows rtla to exit immediately when a
   threshold is violated, without waiting for the next iteration of the
   while loop.

   If the requirements for the BPF implementation are not met, either at
   build time or at run time, the current implementation is used as
   fallback. Which implementation is being used can be seen when running
   rtla timerlat with "-D" option. rtla can be forced to run in non-BPF
   mode by setting the RTLA_NO_BPF option to 1, for debugging purposes.

 - Fix LD_FLAGS from being dropped in build

 - Refactor code to remove duplication of save_trace_to_file

 - Always set options and do not rely on default settings

   Do not rely on the default kernel settings of the tracers when
   starting. They could have been changed by the user which gives
   inconsistent results. Always set the options that rtla expects.

 - Add creation of ctags and TAGS for traversing code

* tag 'trace-tools-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  rtla: Add the ability to create ctags and etags
  rtla/tests: Test setting default options
  rtla/tests: Reset osnoise options before check
  rtla: Always set all tracer options
  rtla/osnoise: Set OSNOISE_WORKLOAD to true
  rtla: Unify apply_config between top and hist
  rtla/osnoise: Unify params struct
  rtla: Fix segfault in save_trace_to_file call
  tools/build: Use SYSTEM_BPFTOOL for system bpftool
  rtla: Refactor save_trace_to_file
  tools/rv: Keep user LDFLAGS in build
  rtla/timerlat: Test BPF mode
  rtla/timerlat_top: Use BPF to collect samples
  rtla/timerlat_top: Move divisor to update
  rtla/timerlat_hist: Use BPF to collect samples
  rtla/timerlat: Add BPF skeleton to collect samples
  rtla: Add optional dependency on BPF tooling
  tools/build: Add bpftool-skeletons feature test
  rtla/timerlat: Unify params struct
  • Loading branch information
Linus Torvalds committed Mar 28, 2025
2 parents 744fab2 + 7320326 commit 4fa118e
Show file tree
Hide file tree
Showing 25 changed files with 1,315 additions and 625 deletions.
3 changes: 2 additions & 1 deletion tools/build/Makefile.feature
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ FEATURE_TESTS_EXTRA := \
libbpf-bpf_create_map \
libpfm4 \
libdebuginfod \
clang-bpf-co-re
clang-bpf-co-re \
bpftool-skeletons


FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
Expand Down
3 changes: 3 additions & 0 deletions tools/build/feature/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,9 @@ $(OUTPUT)test-file-handle.bin:
$(OUTPUT)test-libpfm4.bin:
$(BUILD) -lpfm

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

clean:
Expand Down
3 changes: 3 additions & 0 deletions tools/scripts/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ LLVM_CONFIG ?= llvm-config
LLVM_OBJCOPY ?= llvm-objcopy
LLVM_STRIP ?= llvm-strip

# Some tools require bpftool
SYSTEM_BPFTOOL ?= bpftool

ifeq ($(CC_NO_CLANG), 1)
EXTRA_WARNINGS += -Wstrict-aliasing=3

Expand Down
1 change: 1 addition & 0 deletions tools/tracing/rtla/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ rtla-static
fixdep
feature
FEATURE-DUMP
*.skel.h
20 changes: 19 additions & 1 deletion tools/tracing/rtla/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@ DOCSRC := ../../../Documentation/tools/rtla/
FEATURE_TESTS := libtraceevent
FEATURE_TESTS += libtracefs
FEATURE_TESTS += libcpupower
FEATURE_TESTS += libbpf
FEATURE_TESTS += clang-bpf-co-re
FEATURE_TESTS += bpftool-skeletons
FEATURE_DISPLAY := libtraceevent
FEATURE_DISPLAY += libtracefs
FEATURE_DISPLAY += libcpupower
FEATURE_DISPLAY += libbpf
FEATURE_DISPLAY += clang-bpf-co-re
FEATURE_DISPLAY += bpftool-skeletons

all: $(RTLA)

Expand All @@ -61,6 +67,17 @@ CFLAGS += $(INCLUDES) $(LIB_INCLUDES)

export CFLAGS OUTPUT srctree

ifeq ($(BUILD_BPF_SKEL),1)
src/timerlat.bpf.o: src/timerlat.bpf.c
$(QUIET_CLANG)$(CLANG) -g -O2 -target bpf -c $(filter %.c,$^) -o $@

src/timerlat.skel.h: src/timerlat.bpf.o
$(QUIET_GENSKEL)$(SYSTEM_BPFTOOL) gen skeleton $< > $@
else
src/timerlat.skel.h:
$(Q)echo '/* BPF skeleton is disabled */' > src/timerlat.skel.h
endif

$(RTLA): $(RTLA_IN)
$(QUIET_LINK)$(CC) $(LDFLAGS) -o $(RTLA) $(RTLA_IN) $(EXTLIBS)

Expand All @@ -71,14 +88,15 @@ static: $(RTLA_IN)
rtla.%: fixdep FORCE
make -f $(srctree)/tools/build/Makefile.build dir=. $@

$(RTLA_IN): fixdep FORCE
$(RTLA_IN): fixdep FORCE src/timerlat.skel.h
make $(build)=rtla

clean: doc_clean fixdep-clean
$(call QUIET_CLEAN, rtla)
$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
$(Q)rm -rf feature
$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h
check: $(RTLA)
RTLA=$(RTLA) prove -o -f tests/
.PHONY: FORCE clean check
42 changes: 42 additions & 0 deletions tools/tracing/rtla/Makefile.config
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,48 @@ else
$(info Please install libcpupower-dev/kernel-tools-libs-devel)
endif

ifndef BUILD_BPF_SKEL
# BPF skeletons are used to implement improved sample collection, enable
# them by default.
BUILD_BPF_SKEL := 1
endif

ifeq ($(BUILD_BPF_SKEL),0)
$(info BPF skeleton support disabled, building without BPF skeleton support.)
endif

$(call feature_check,libbpf)
ifeq ($(feature-libbpf), 1)
$(call detected,CONFIG_LIBBPF)
else
$(info libbpf is missing, building without BPF skeleton support.)
$(info Please install libbpf-dev/libbpf-devel)
BUILD_BPF_SKEL := 0
endif

$(call feature_check,clang-bpf-co-re)
ifeq ($(feature-clang-bpf-co-re), 1)
$(call detected,CONFIG_CLANG_BPF_CO_RE)
else
$(info clang is missing or does not support BPF CO-RE, building without BPF skeleton support.)
$(info Please install clang)
BUILD_BPF_SKEL := 0
endif

$(call feature_check,bpftool-skeletons)
ifeq ($(feature-bpftool-skeletons), 1)
$(call detected,CONFIG_BPFTOOL_SKELETONS)
else
$(info bpftool is missing or not supporting skeletons, building without BPF skeleton support.)
$(info Please install bpftool)
BUILD_BPF_SKEL := 0
endif

ifeq ($(BUILD_BPF_SKEL),1)
CFLAGS += -DHAVE_BPF_SKEL
EXTLIBS += -lbpf
endif

ifeq ($(STOP_ERROR),1)
$(error Please, check the errors above.)
endif
17 changes: 15 additions & 2 deletions tools/tracing/rtla/Makefile.rtla
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ INSTALL := install
MKDIR := mkdir
STRIP := strip
BINDIR := /usr/bin
CTAGS := ctags
ETAGS := ctags -e

.PHONY: install
install: doc_install
Expand All @@ -47,6 +49,18 @@ install: doc_install
@test ! -f $(DESTDIR)$(BINDIR)/timerlat || $(RM) $(DESTDIR)$(BINDIR)/timerlat
@$(LN) -s rtla $(DESTDIR)$(BINDIR)/timerlat

.PHONY: tags
tags:
$(CTAGS) -R --extras=+f --c-kinds=+p src

.PHONY: TAGS
TAGS:
$(ETAGS) -R --extras=+f --c-kinds=+p src

.PHONY: tags_clean
tags_clean:
$(RM) tags TAGS

.PHONY: doc doc_clean doc_install
doc:
$(MAKE) -C $(DOCSRC)
Expand All @@ -57,8 +71,7 @@ doc_clean:
doc_install:
$(MAKE) -C $(DOCSRC) install

# This section is neesary for the tarball, when the tarball
# support is removed, we can delete these entries.
# This section is necessary to make the rtla tarball
NAME := rtla
DIRS := src
FILES := Makefile README.txt
Expand Down
1 change: 1 addition & 0 deletions tools/tracing/rtla/src/Build
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ rtla-y += timerlat_top.o
rtla-y += timerlat_hist.o
rtla-y += timerlat_u.o
rtla-y += timerlat_aa.o
rtla-y += timerlat_bpf.o
rtla-y += rtla.o
86 changes: 85 additions & 1 deletion tools/tracing/rtla/src/osnoise.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
*/

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
Expand All @@ -12,9 +13,12 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sched.h>

#include "osnoise.h"
#include "utils.h"

#define DEFAULT_SAMPLE_PERIOD 1000000 /* 1s */
#define DEFAULT_SAMPLE_RUNTIME 1000000 /* 1s */

/*
* osnoise_get_cpus - return the original "osnoise/cpus" content
Expand Down Expand Up @@ -1115,6 +1119,86 @@ osnoise_report_missed_events(struct osnoise_tool *tool)
}
}

/*
* osnoise_apply_config - apply common configs to the initialized tool
*/
int
osnoise_apply_config(struct osnoise_tool *tool, struct osnoise_params *params)
{
int retval;

if (!params->sleep_time)
params->sleep_time = 1;

retval = osnoise_set_cpus(tool->context, params->cpus ? params->cpus : "all");
if (retval) {
err_msg("Failed to apply CPUs config\n");
goto out_err;
}

if (params->runtime || params->period) {
retval = osnoise_set_runtime_period(tool->context,
params->runtime,
params->period);
} else {
retval = osnoise_set_runtime_period(tool->context,
DEFAULT_SAMPLE_PERIOD,
DEFAULT_SAMPLE_RUNTIME);
}

if (retval) {
err_msg("Failed to set runtime and/or period\n");
goto out_err;
}

retval = osnoise_set_stop_us(tool->context, params->stop_us);
if (retval) {
err_msg("Failed to set stop us\n");
goto out_err;
}

retval = osnoise_set_stop_total_us(tool->context, params->stop_total_us);
if (retval) {
err_msg("Failed to set stop total us\n");
goto out_err;
}

retval = osnoise_set_tracing_thresh(tool->context, params->threshold);
if (retval) {
err_msg("Failed to set tracing_thresh\n");
goto out_err;
}

if (params->hk_cpus) {
retval = sched_setaffinity(getpid(), sizeof(params->hk_cpu_set),
&params->hk_cpu_set);
if (retval == -1) {
err_msg("Failed to set rtla to the house keeping CPUs\n");
goto out_err;
}
} else if (params->cpus) {
/*
* Even if the user do not set a house-keeping CPU, try to
* move rtla to a CPU set different to the one where the user
* set the workload to run.
*
* No need to check results as this is an automatic attempt.
*/
auto_house_keeping(&params->monitored_cpus);
}

retval = osnoise_set_workload(tool->context, true);
if (retval < -1) {
err_msg("Failed to set OSNOISE_WORKLOAD option\n");
goto out_err;
}

return 0;

out_err:
return -1;
}

static void osnoise_usage(int err)
{
int i;
Expand Down
50 changes: 50 additions & 0 deletions tools/tracing/rtla/src/osnoise.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,55 @@
// SPDX-License-Identifier: GPL-2.0
#pragma once

#include "utils.h"
#include "trace.h"

enum osnoise_mode {
MODE_OSNOISE = 0,
MODE_HWNOISE
};

struct osnoise_params {
/* Common params */
char *cpus;
cpu_set_t monitored_cpus;
char *trace_output;
char *cgroup_name;
unsigned long long runtime;
unsigned long long period;
long long threshold;
long long stop_us;
long long stop_total_us;
int sleep_time;
int duration;
int set_sched;
int cgroup;
int hk_cpus;
cpu_set_t hk_cpu_set;
struct sched_attr sched_param;
struct trace_events *events;
int warmup;
int buffer_size;
union {
struct {
/* top only */
int quiet;
int pretty_output;
enum osnoise_mode mode;
};
struct {
/* hist only */
int output_divisor;
char no_header;
char no_summary;
char no_index;
char with_zeros;
int bucket_size;
int entries;
};
};
};

/*
* osnoise_context - read, store, write, restore osnoise configs.
*/
Expand Down Expand Up @@ -106,6 +155,7 @@ struct osnoise_tool *osnoise_init_tool(char *tool_name);
struct osnoise_tool *osnoise_init_trace_tool(char *tracer);
void osnoise_report_missed_events(struct osnoise_tool *tool);
bool osnoise_trace_is_off(struct osnoise_tool *tool, struct osnoise_tool *record);
int osnoise_apply_config(struct osnoise_tool *tool, struct osnoise_params *params);

int osnoise_hist_main(int argc, char *argv[]);
int osnoise_top_main(int argc, char **argv);
Expand Down
Loading

0 comments on commit 4fa118e

Please sign in to comment.