Commit 42c2a756 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull trace tool updates from Steven Rostedt:
 "Tracing:

   - Update makefiles for latency-collector and RTLA, using tools/build/
     makefiles like perf does, inheriting its benefits. For example,
     having a proper way to handle library dependencies.

   - The timerlat tracer has an interface for any tool to use. rtla
     timerlat tool uses this interface dispatching its own threads as
     workload. But, rtla timerlat could also be used for any other
     process. So, add 'rtla timerlat -U' option, allowing the timerlat
     tool to measure the latency of any task using the timerlat tracer
     interface.

  Verification:

   - Update makefiles for verification/rv, using tools/build/ makefiles
     like perf does, inheriting its benefits. For example, having a
     proper way to handle dependencies"

* tag 'trace-tools-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tools/rtla: Add -U/--user-load option to timerlat
  tools/verification: Use tools/build makefiles on rv
  tools/rtla: Use tools/build makefiles to build rtla
  tools/tracing: Use tools/build makefiles on latency-collector
parents dba89d1b a23c05fd
...@@ -33,3 +33,9 @@ ...@@ -33,3 +33,9 @@
to wait on the timerlat_fd. Once the workload is awakes, it goes to sleep again to wait on the timerlat_fd. Once the workload is awakes, it goes to sleep again
adding so the measurement for the kernel-to-user and user-to-kernel to the tracer adding so the measurement for the kernel-to-user and user-to-kernel to the tracer
output. output.
**-U**, **--user-load**
Set timerlat to run without workload, waiting for the user to dispatch a per-cpu
task that waits for a new period on the tracing/osnoise/per_cpu/cpu$ID/timerlat_fd.
See linux/tools/rtla/sample/timerlat_load.py for an example of user-load code.
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0-only
latency-collector latency-collector
fixdep
feature
FEATURE-DUMP
latency-collector-y += latency-collector.o
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0-only
# Makefile for vm tools
#
VAR_CFLAGS := $(shell pkg-config --cflags libtracefs 2>/dev/null)
VAR_LDLIBS := $(shell pkg-config --libs libtracefs 2>/dev/null)
TARGETS = latency-collector ifeq ($(srctree),)
CFLAGS = -Wall -Wextra -g -O2 $(VAR_CFLAGS) srctree := $(patsubst %/,%,$(dir $(CURDIR)))
LDFLAGS = -lpthread $(VAR_LDLIBS) srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
all: $(TARGETS) include $(srctree)/tools/scripts/Makefile.include
%: %.c # O is an alias for OUTPUT
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) OUTPUT := $(O)
clean: ifeq ($(OUTPUT),)
$(RM) latency-collector OUTPUT := $(CURDIR)
else
# subdir is used by the ../Makefile in $(call descend,)
ifneq ($(subdir),)
OUTPUT := $(OUTPUT)/$(subdir)
endif
endif
ifneq ($(patsubst %/,,$(lastword $(OUTPUT))),)
OUTPUT := $(OUTPUT)/
endif
LATENCY-COLLECTOR := $(OUTPUT)latency-collector
LATENCY-COLLECTOR_IN := $(LATENCY-COLLECTOR)-in.o
export CC := gcc
export LD := ld
export AR := ar
export PKG_CONFIG := pkg-config
FEATURE_TESTS := libtraceevent
FEATURE_TESTS += libtracefs
FEATURE_DISPLAY := libtraceevent
FEATURE_DISPLAY += libtracefs
ifeq ($(V),1)
Q =
else
Q = @
endif
all: $(LATENCY-COLLECTOR)
include $(srctree)/tools/build/Makefile.include
# check for dependencies only on required targets
NON_CONFIG_TARGETS := clean install
prefix ?= /usr/local config := 1
sbindir ?= ${prefix}/sbin ifdef MAKECMDGOALS
ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
config := 0
endif
endif
install: all ifeq ($(config),1)
install -d $(DESTDIR)$(sbindir) include $(srctree)/tools/build/Makefile.feature
install -m 755 -p $(TARGETS) $(DESTDIR)$(sbindir) include Makefile.config
endif
CFLAGS += $(INCLUDES) $(LIB_INCLUDES)
export CFLAGS OUTPUT srctree
$(LATENCY-COLLECTOR): $(LATENCY-COLLECTOR_IN)
$(QUIET_LINK)$(CC) $(LDFLAGS) -o $(LATENCY-COLLECTOR) $(LATENCY-COLLECTOR_IN) $(EXTLIBS)
latency-collector.%: fixdep FORCE
make -f $(srctree)/tools/build/Makefile.build dir=. $@
$(LATENCY-COLLECTOR_IN): fixdep FORCE
make $(build)=latency-collector
INSTALL := install
MKDIR := mkdir
STRIP := strip
BINDIR := /usr/bin
install:
@$(MKDIR) -p $(DESTDIR)$(BINDIR)
$(call QUIET_INSTALL,latency-collector)$(INSTALL) $(LATENCY-COLLECTOR) -m 755 $(DESTDIR)$(BINDIR)
@$(STRIP) $(DESTDIR)$(BINDIR)/latency-collector
clean:
$(call QUIET_CLEAN, latency-collector)
$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
$(Q)@rm -f latency-collector fixdep FEATURE-DUMP
$(Q)rm -rf feature
.PHONY: FORCE clean install
# SPDX-License-Identifier: GPL-2.0-only
STOP_ERROR :=
define lib_setup
$(eval EXTLIBS += -l$(1))
$(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)"))
endef
$(call feature_check,libtraceevent)
ifeq ($(feature-libtraceevent), 1)
$(call detected,CONFIG_LIBTRACEEVENT)
$(call lib_setup,traceevent)
else
STOP_ERROR := 1
$(info libtraceevent is missing. Please install libtraceevent-dev/libtraceevent-devel)
endif
$(call feature_check,libtracefs)
ifeq ($(feature-libtracefs), 1)
$(call detected,CONFIG_LIBTRACEFS)
$(call lib_setup,tracefs)
else
STOP_ERROR := 1
$(info libtracefs is missing. Please install libtracefs-dev/libtracefs-devel)
endif
ifeq ($(STOP_ERROR),1)
$(error Please, check the errors above.)
endif
/rtla # SPDX-License-Identifier: GPL-2.0-only
rtla
rtla-static
fixdep
feature
FEATURE-DUMP
NAME := rtla # SPDX-License-Identifier: GPL-2.0-only
# Follow the kernel version
VERSION := $(shell cat VERSION 2> /dev/null || make -sC ../../.. kernelversion | grep -v make) ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
# From libtracefs: srctree := $(patsubst %/,%,$(dir $(srctree)))
# Makefiles suck: This macro sets a default value of $(2) for the srctree := $(patsubst %/,%,$(dir $(srctree)))
# variable named by $(1), unless the variable has been set by
# environment or command line. This is necessary for CC and AR
# because make sets default values, so the simpler ?= approach
# won't work as expected.
define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef
# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
$(call allow-override,AR,$(CROSS_COMPILE)ar)
$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
$(call allow-override,PKG_CONFIG,pkg-config)
$(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/)
$(call allow-override,LDCONFIG,ldconfig)
INSTALL = install
MKDIR = mkdir
FOPTS := -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \
-fasynchronous-unwind-tables -fstack-clash-protection
WOPTS := -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized
ifeq ($(CC),clang)
FOPTS := $(filter-out -ffat-lto-objects, $(FOPTS))
WOPTS := $(filter-out -Wno-maybe-uninitialized, $(WOPTS))
endif endif
TRACEFS_HEADERS := $$($(PKG_CONFIG) --cflags libtracefs) include $(srctree)/tools/scripts/Makefile.include
CFLAGS := -O -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS) $(EXTRA_CFLAGS) # O is an alias for OUTPUT
LDFLAGS := -flto=auto -ggdb $(EXTRA_LDFLAGS) OUTPUT := $(O)
LIBS := $$($(PKG_CONFIG) --libs libtracefs)
ifeq ($(OUTPUT),)
SRC := $(wildcard src/*.c) OUTPUT := $(CURDIR)
HDR := $(wildcard src/*.h)
OBJ := $(SRC:.c=.o)
DIRS := src
FILES := Makefile README.txt
CEXT := bz2
TARBALL := $(NAME)-$(VERSION).tar.$(CEXT)
TAROPTS := -cvjf $(TARBALL)
BINDIR := /usr/bin
DATADIR := /usr/share
DOCDIR := $(DATADIR)/doc
MANDIR := $(DATADIR)/man
LICDIR := $(DATADIR)/licenses
SRCTREE := $(or $(BUILD_SRC),$(CURDIR))
# If running from the tarball, man pages are stored in the Documentation
# dir. If running from the kernel source, man pages are stored in
# Documentation/tools/rtla/.
ifneq ($(wildcard Documentation/.*),)
DOCSRC = Documentation/
else else
DOCSRC = $(SRCTREE)/../../../Documentation/tools/rtla/ # subdir is used by the ../Makefile in $(call descend,)
ifneq ($(subdir),)
OUTPUT := $(OUTPUT)/$(subdir)
endif
endif
ifneq ($(patsubst %/,,$(lastword $(OUTPUT))),)
OUTPUT := $(OUTPUT)/
endif endif
LIBTRACEEVENT_MIN_VERSION = 1.5 RTLA := $(OUTPUT)rtla
LIBTRACEFS_MIN_VERSION = 1.3 RTLA_IN := $(RTLA)-in.o
.PHONY: all warnings show_warnings VERSION := $(shell sh -c "make -sC ../../.. kernelversion | grep -v make")
all: warnings rtla DOCSRC := ../../../Documentation/tools/rtla/
TEST_LIBTRACEEVENT = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 || echo n") FEATURE_TESTS := libtraceevent
ifeq ("$(TEST_LIBTRACEEVENT)", "n") FEATURE_TESTS += libtracefs
WARNINGS = show_warnings FEATURE_DISPLAY := libtraceevent
MISSING_LIBS += echo "** libtraceevent version $(LIBTRACEEVENT_MIN_VERSION) or higher"; FEATURE_DISPLAY += libtracefs
MISSING_PACKAGES += "libtraceevent-devel"
MISSING_SOURCE += echo "** https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ "; ifeq ($(V),1)
Q =
else
Q = @
endif endif
TEST_LIBTRACEFS = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEFS_MIN_VERSION) libtracefs > /dev/null 2>&1 || echo n") all: $(RTLA)
ifeq ("$(TEST_LIBTRACEFS)", "n")
WARNINGS = show_warnings include $(srctree)/tools/build/Makefile.include
MISSING_LIBS += echo "** libtracefs version $(LIBTRACEFS_MIN_VERSION) or higher"; include Makefile.rtla
MISSING_PACKAGES += "libtracefs-devel"
MISSING_SOURCE += echo "** https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ "; # check for dependencies only on required targets
NON_CONFIG_TARGETS := clean install tarball doc doc_clean doc_install
config := 1
ifdef MAKECMDGOALS
ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
config := 0
endif
endif endif
define show_dependencies ifeq ($(config),1)
@echo "********************************************"; \ include $(srctree)/tools/build/Makefile.feature
echo "** NOTICE: Failed build dependencies"; \ include Makefile.config
echo "**"; \
echo "** Required Libraries:"; \
$(MISSING_LIBS) \
echo "**"; \
echo "** Consider installing the latest libtracefs from your"; \
echo "** distribution, e.g., 'dnf install $(MISSING_PACKAGES)' on Fedora,"; \
echo "** or from source:"; \
echo "**"; \
$(MISSING_SOURCE) \
echo "**"; \
echo "********************************************"
endef
show_warnings:
$(call show_dependencies);
ifneq ("$(WARNINGS)", "")
ERROR_OUT = $(error Please add the necessary dependencies)
warnings: $(WARNINGS)
$(ERROR_OUT)
endif endif
rtla: $(OBJ) CFLAGS += $(INCLUDES) $(LIB_INCLUDES)
$(CC) -o rtla $(LDFLAGS) $(OBJ) $(LIBS)
export CFLAGS OUTPUT srctree
static: $(OBJ)
$(CC) -o rtla-static $(LDFLAGS) --static $(OBJ) $(LIBS) -lpthread -ldl $(RTLA): $(RTLA_IN)
$(QUIET_LINK)$(CC) $(LDFLAGS) -o $(RTLA) $(RTLA_IN) $(EXTLIBS)
.PHONY: install
install: doc_install static: $(RTLA_IN)
$(MKDIR) -p $(DESTDIR)$(BINDIR) $(eval LDFLAGS += -static)
$(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR) $(QUIET_LINK)$(CC) -static $(LDFLAGS) -o $(RTLA)-static $(RTLA_IN) $(EXTLIBS)
$(STRIP) $(DESTDIR)$(BINDIR)/rtla
@test ! -f $(DESTDIR)$(BINDIR)/osnoise || rm $(DESTDIR)$(BINDIR)/osnoise rtla.%: fixdep FORCE
ln -s rtla $(DESTDIR)$(BINDIR)/osnoise make -f $(srctree)/tools/build/Makefile.build dir=. $@
@test ! -f $(DESTDIR)$(BINDIR)/hwnoise || rm $(DESTDIR)$(BINDIR)/hwnoise
ln -s rtla $(DESTDIR)$(BINDIR)/hwnoise $(RTLA_IN): fixdep FORCE
@test ! -f $(DESTDIR)$(BINDIR)/timerlat || rm $(DESTDIR)$(BINDIR)/timerlat make $(build)=rtla
ln -s rtla $(DESTDIR)$(BINDIR)/timerlat
clean: doc_clean fixdep-clean
.PHONY: clean tarball $(call QUIET_CLEAN, rtla)
clean: doc_clean $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
@test ! -f rtla || rm rtla $(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
@test ! -f rtla-static || rm rtla-static $(Q)rm -rf feature
@test ! -f src/rtla.o || rm src/rtla.o .PHONY: FORCE clean
@test ! -f $(TARBALL) || rm -f $(TARBALL)
@rm -rf *~ $(OBJ) *.tar.$(CEXT)
tarball: clean
rm -rf $(NAME)-$(VERSION) && mkdir $(NAME)-$(VERSION)
echo $(VERSION) > $(NAME)-$(VERSION)/VERSION
cp -r $(DIRS) $(FILES) $(NAME)-$(VERSION)
mkdir $(NAME)-$(VERSION)/Documentation/
cp -rp $(SRCTREE)/../../../Documentation/tools/rtla/* $(NAME)-$(VERSION)/Documentation/
tar $(TAROPTS) --exclude='*~' $(NAME)-$(VERSION)
rm -rf $(NAME)-$(VERSION)
.PHONY: doc doc_clean doc_install
doc:
$(MAKE) -C $(DOCSRC)
doc_clean:
$(MAKE) -C $(DOCSRC) clean
doc_install:
$(MAKE) -C $(DOCSRC) install
# SPDX-License-Identifier: GPL-2.0-only
STOP_ERROR :=
LIBTRACEEVENT_MIN_VERSION = 1.5
LIBTRACEFS_MIN_VERSION = 1.3
define lib_setup
$(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)"))
$(eval EXTLIBS += -l$(1))
endef
$(call feature_check,libtraceevent)
ifeq ($(feature-libtraceevent), 1)
$(call detected,CONFIG_LIBTRACEEVENT)
TEST = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 && echo y || echo n")
ifeq ($(TEST),n)
$(info libtraceevent version is too low, it must be at least $(LIBTRACEEVENT_MIN_VERSION))
STOP_ERROR := 1
endif
$(call lib_setup,traceevent)
else
STOP_ERROR := 1
$(info libtraceevent is missing. Please install libtraceevent-dev/libtraceevent-devel)
endif
$(call feature_check,libtracefs)
ifeq ($(feature-libtracefs), 1)
$(call detected,CONFIG_LIBTRACEFS)
TEST = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEFS_MIN_VERSION) libtracefs > /dev/null 2>&1 && echo y || echo n")
ifeq ($(TEST),n)
$(info libtracefs version is too low, it must be at least $(LIBTRACEFS_MIN_VERSION))
STOP_ERROR := 1
endif
$(call lib_setup,tracefs)
else
STOP_ERROR := 1
$(info libtracefs is missing. Please install libtracefs-dev/libtracefs-devel)
endif
ifeq ($(STOP_ERROR),1)
$(error Please, check the errors above.)
endif
# SPDX-License-Identifier: GPL-2.0-only
define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef
# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
$(call allow-override,AR,$(CROSS_COMPILE)ar)
$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
$(call allow-override,PKG_CONFIG,pkg-config)
$(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/)
$(call allow-override,LDCONFIG,ldconfig)
export CC AR STRIP PKG_CONFIG LD_SO_CONF_PATH LDCONFIG
FOPTS := -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \
-fasynchronous-unwind-tables -fstack-clash-protection
WOPTS := -O -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 \
-Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized
ifeq ($(CC),clang)
FOPTS := $(filter-out -flto=auto -ffat-lto-objects, $(FOPTS))
WOPTS := $(filter-out -Wno-maybe-uninitialized, $(WOPTS))
endif
CFLAGS := -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(WOPTS) $(CFLAGS)
LDFLAGS := -ggdb $(LDFLAGS)
RM := rm -rf
LN := ln -s
INSTALL := install
MKDIR := mkdir
STRIP := strip
BINDIR := /usr/bin
.PHONY: install
install: doc_install
@$(MKDIR) -p $(DESTDIR)$(BINDIR)
$(call QUIET_INSTALL,rtla)$(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR)
@$(STRIP) $(DESTDIR)$(BINDIR)/rtla
@test ! -f $(DESTDIR)$(BINDIR)/osnoise || $(RM) $(DESTDIR)$(BINDIR)/osnoise
@$(LN) rtla $(DESTDIR)$(BINDIR)/osnoise
@test ! -f $(DESTDIR)$(BINDIR)/hwnoise || $(RM) $(DESTDIR)$(BINDIR)/hwnoise
@$(LN) -s rtla $(DESTDIR)$(BINDIR)/hwnoise
@test ! -f $(DESTDIR)$(BINDIR)/timerlat || $(RM) $(DESTDIR)$(BINDIR)/timerlat
@$(LN) -s rtla $(DESTDIR)$(BINDIR)/timerlat
.PHONY: doc doc_clean doc_install
doc:
$(MAKE) -C $(DOCSRC)
doc_clean:
$(MAKE) -C $(DOCSRC) 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.
NAME := rtla
DIRS := src
FILES := Makefile README.txt
CEXT := bz2
TARBALL := $(NAME)-$(VERSION).tar.$(CEXT)
TAROPTS := -cvjf $(TARBALL)
SRCTREE := $(or $(BUILD_SRC),$(CURDIR))
tarball: clean
$(RM) $(NAME)-$(VERSION) && $(MKDIR) $(NAME)-$(VERSION)
echo $(VERSION) > $(NAME)-$(VERSION)/VERSION
cp -r $(DIRS) $(FILES) $(NAME)-$(VERSION)
$(MKDIR) $(NAME)-$(VERSION)/Documentation/
cp -rp $(SRCTREE)/../../../Documentation/tools/$(NAME)/* $(NAME)-$(VERSION)/Documentation/
cp Makefile.standalone $(NAME)-$(VERSION)/Makefile
cp Makefile.$(NAME) $(NAME)-$(VERSION)/
tar $(TAROPTS) --exclude='*~' $(NAME)-$(VERSION)
$(RM) $(NAME)-$(VERSION)
.PHONY: tarball
# SPDX-License-Identifier: GPL-2.0-only
VERSION := $(shell cat VERSION)
CFLAGS += $$($(PKG_CONFIG) --cflags libtracefs)
EXTLIBS += $$($(PKG_CONFIG) --libs libtracefs)
rtla:
include Makefile.rtla
SRC := $(wildcard src/*.c)
HDR := $(wildcard src/*.h)
OBJ := $(SRC:.c=.o)
DOCSRC := Documentation/
rtla: $(OBJ)
$(CC) -o rtla $(LDFLAGS) $(OBJ) $(LIBS) $(EXTLIBS)
$(info This is a deprecated method to compile RTLA, please compile from Linux kernel source)
.PHONY: clean tarball
clean: doc_clean
@test ! -f rtla || rm rtla
@test ! -f rtla-static || rm rtla-static
@test ! -f src/rtla.o || rm src/rtla.o
@test ! -f $(TARBALL) || rm -f $(TARBALL)
@rm -rf *~ $(OBJ) *.tar.$(CEXT)
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2024 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
#
# This is a sample code about how to use timerlat's timer by any workload
# so rtla can measure and provide auto-analysis for the overall latency (IOW
# the response time) for a task.
#
# Before running it, you need to dispatch timerlat with -U option in a terminal.
# Then # run this script pinned to a CPU on another terminal. For example:
#
# timerlat_load.py 1 -p 95
#
# The "Timerlat IRQ" is the IRQ latency, The thread latency is the latency
# for the python process to get the CPU. The Ret from user Timer Latency is
# the overall latency. In other words, it is the response time for that
# activation.
#
# This is just an example, the load is reading 20MB of data from /dev/full
# It is in python because it is easy to read :-)
import argparse
import sys
import os
parser = argparse.ArgumentParser(description='user-space timerlat thread in Python')
parser.add_argument("cpu", help='CPU to run timerlat thread')
parser.add_argument("-p", "--prio", help='FIFO priority')
args = parser.parse_args()
try:
affinity_mask = { int(args.cpu) }
except:
print("Invalid cpu: " + args.cpu)
exit(1)
try:
os.sched_setaffinity(0, affinity_mask);
except:
print("Error setting affinity")
exit(1)
if (args.prio):
try:
param = os.sched_param(int(args.prio))
os.sched_setscheduler(0, os.SCHED_FIFO, param)
except:
print("Error setting priority")
exit(1)
try:
timerlat_path = "/sys/kernel/tracing/osnoise/per_cpu/cpu" + args.cpu + "/timerlat_fd"
timerlat_fd = open(timerlat_path, 'r')
except:
print("Error opening timerlat fd, did you run timerlat -U?")
exit(1)
try:
data_fd = open("/dev/full", 'r');
except:
print("Error opening data fd")
while True:
try:
timerlat_fd.read(1)
data_fd.read(20*1024*1024)
except:
print("Leaving")
break
timerlat_fd.close()
data_fd.close()
rtla-y += trace.o
rtla-y += utils.o
rtla-y += osnoise.o
rtla-y += osnoise_top.o
rtla-y += osnoise_hist.o
rtla-y += timerlat.o
rtla-y += timerlat_top.o
rtla-y += timerlat_hist.o
rtla-y += timerlat_u.o
rtla-y += timerlat_aa.o
rtla-y += rtla.o
...@@ -39,6 +39,7 @@ struct timerlat_hist_params { ...@@ -39,6 +39,7 @@ struct timerlat_hist_params {
int hk_cpus; int hk_cpus;
int no_aa; int no_aa;
int dump_tasks; int dump_tasks;
int user_workload;
int user_hist; int user_hist;
cpu_set_t hk_cpu_set; cpu_set_t hk_cpu_set;
struct sched_attr sched_param; struct sched_attr sched_param;
...@@ -534,6 +535,7 @@ static void timerlat_hist_usage(char *usage) ...@@ -534,6 +535,7 @@ static void timerlat_hist_usage(char *usage)
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period", " d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period",
" in nanoseconds", " in nanoseconds",
" -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads", " -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads",
" -U/--user-load: enable timerlat for user-defined user-space workload",
NULL, NULL,
}; };
...@@ -595,6 +597,7 @@ static struct timerlat_hist_params ...@@ -595,6 +597,7 @@ static struct timerlat_hist_params
{"thread", required_argument, 0, 'T'}, {"thread", required_argument, 0, 'T'},
{"trace", optional_argument, 0, 't'}, {"trace", optional_argument, 0, 't'},
{"user-threads", no_argument, 0, 'u'}, {"user-threads", no_argument, 0, 'u'},
{"user-load", no_argument, 0, 'U'},
{"event", required_argument, 0, 'e'}, {"event", required_argument, 0, 'e'},
{"no-irq", no_argument, 0, '0'}, {"no-irq", no_argument, 0, '0'},
{"no-thread", no_argument, 0, '1'}, {"no-thread", no_argument, 0, '1'},
...@@ -613,7 +616,7 @@ static struct timerlat_hist_params ...@@ -613,7 +616,7 @@ static struct timerlat_hist_params
/* getopt_long stores the option index here. */ /* getopt_long stores the option index here. */
int option_index = 0; int option_index = 0;
c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:np:P:s:t::T:u0123456:7:8:9\1", c = getopt_long(argc, argv, "a:c:C::b:d:e:E:DhH:i:np:P:s:t::T:uU0123456:7:8:9\1",
long_options, &option_index); long_options, &option_index);
/* detect the end of the options. */ /* detect the end of the options. */
...@@ -724,6 +727,9 @@ static struct timerlat_hist_params ...@@ -724,6 +727,9 @@ static struct timerlat_hist_params
params->trace_output = "timerlat_trace.txt"; params->trace_output = "timerlat_trace.txt";
break; break;
case 'u': case 'u':
params->user_workload = 1;
/* fallback: -u implies in -U */
case 'U':
params->user_hist = 1; params->user_hist = 1;
break; break;
case '0': /* no irq */ case '0': /* no irq */
...@@ -985,7 +991,7 @@ int timerlat_hist_main(int argc, char *argv[]) ...@@ -985,7 +991,7 @@ int timerlat_hist_main(int argc, char *argv[])
} }
} }
if (params->cgroup && !params->user_hist) { if (params->cgroup && !params->user_workload) {
retval = set_comm_cgroup("timerlat/", params->cgroup_name); retval = set_comm_cgroup("timerlat/", params->cgroup_name);
if (!retval) { if (!retval) {
err_msg("Failed to move threads to cgroup\n"); err_msg("Failed to move threads to cgroup\n");
...@@ -1049,7 +1055,7 @@ int timerlat_hist_main(int argc, char *argv[]) ...@@ -1049,7 +1055,7 @@ int timerlat_hist_main(int argc, char *argv[])
tool->start_time = time(NULL); tool->start_time = time(NULL);
timerlat_hist_set_signals(params); timerlat_hist_set_signals(params);
if (params->user_hist) { if (params->user_workload) {
/* rtla asked to stop */ /* rtla asked to stop */
params_u.should_run = 1; params_u.should_run = 1;
/* all threads left */ /* all threads left */
...@@ -1086,14 +1092,14 @@ int timerlat_hist_main(int argc, char *argv[]) ...@@ -1086,14 +1092,14 @@ int timerlat_hist_main(int argc, char *argv[])
break; break;
/* is there still any user-threads ? */ /* is there still any user-threads ? */
if (params->user_hist) { if (params->user_workload) {
if (params_u.stopped_running) { if (params_u.stopped_running) {
debug_msg("timerlat user-space threads stopped!\n"); debug_msg("timerlat user-space threads stopped!\n");
break; break;
} }
} }
} }
if (params->user_hist && !params_u.stopped_running) { if (params->user_workload && !params_u.stopped_running) {
params_u.should_run = 0; params_u.should_run = 0;
sleep(1); sleep(1);
} }
......
...@@ -43,6 +43,7 @@ struct timerlat_top_params { ...@@ -43,6 +43,7 @@ struct timerlat_top_params {
int cgroup; int cgroup;
int hk_cpus; int hk_cpus;
int user_top; int user_top;
int user_workload;
cpu_set_t hk_cpu_set; cpu_set_t hk_cpu_set;
struct sched_attr sched_param; struct sched_attr sched_param;
struct trace_events *events; struct trace_events *events;
...@@ -364,6 +365,7 @@ static void timerlat_top_usage(char *usage) ...@@ -364,6 +365,7 @@ static void timerlat_top_usage(char *usage)
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period", " d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period",
" in nanoseconds", " in nanoseconds",
" -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads", " -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads",
" -U/--user-load: enable timerlat for user-defined user-space workload",
NULL, NULL,
}; };
...@@ -423,6 +425,7 @@ static struct timerlat_top_params ...@@ -423,6 +425,7 @@ static struct timerlat_top_params
{"thread", required_argument, 0, 'T'}, {"thread", required_argument, 0, 'T'},
{"trace", optional_argument, 0, 't'}, {"trace", optional_argument, 0, 't'},
{"user-threads", no_argument, 0, 'u'}, {"user-threads", no_argument, 0, 'u'},
{"user-load", no_argument, 0, 'U'},
{"trigger", required_argument, 0, '0'}, {"trigger", required_argument, 0, '0'},
{"filter", required_argument, 0, '1'}, {"filter", required_argument, 0, '1'},
{"dma-latency", required_argument, 0, '2'}, {"dma-latency", required_argument, 0, '2'},
...@@ -435,7 +438,7 @@ static struct timerlat_top_params ...@@ -435,7 +438,7 @@ static struct timerlat_top_params
/* getopt_long stores the option index here. */ /* getopt_long stores the option index here. */
int option_index = 0; int option_index = 0;
c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:np:P:qs:t::T:u0:1:2:345:", c = getopt_long(argc, argv, "a:c:C::d:De:hH:i:np:P:qs:t::T:uU0:1:2:345:",
long_options, &option_index); long_options, &option_index);
/* detect the end of the options. */ /* detect the end of the options. */
...@@ -552,6 +555,9 @@ static struct timerlat_top_params ...@@ -552,6 +555,9 @@ static struct timerlat_top_params
break; break;
case 'u': case 'u':
params->user_workload = true;
/* fallback: -u implies -U */
case 'U':
params->user_top = true; params->user_top = true;
break; break;
case '0': /* trigger */ case '0': /* trigger */
...@@ -869,7 +875,7 @@ int timerlat_top_main(int argc, char *argv[]) ...@@ -869,7 +875,7 @@ int timerlat_top_main(int argc, char *argv[])
top->start_time = time(NULL); top->start_time = time(NULL);
timerlat_top_set_signals(params); timerlat_top_set_signals(params);
if (params->user_top) { if (params->user_workload) {
/* rtla asked to stop */ /* rtla asked to stop */
params_u.should_run = 1; params_u.should_run = 1;
/* all threads left */ /* all threads left */
...@@ -912,7 +918,7 @@ int timerlat_top_main(int argc, char *argv[]) ...@@ -912,7 +918,7 @@ int timerlat_top_main(int argc, char *argv[])
break; break;
/* is there still any user-threads ? */ /* is there still any user-threads ? */
if (params->user_top) { if (params->user_workload) {
if (params_u.stopped_running) { if (params_u.stopped_running) {
debug_msg("timerlat user space threads stopped!\n"); debug_msg("timerlat user space threads stopped!\n");
break; break;
...@@ -920,7 +926,7 @@ int timerlat_top_main(int argc, char *argv[]) ...@@ -920,7 +926,7 @@ int timerlat_top_main(int argc, char *argv[])
} }
} }
if (params->user_top && !params_u.stopped_running) { if (params->user_workload && !params_u.stopped_running) {
params_u.should_run = 0; params_u.should_run = 0;
sleep(1); sleep(1);
} }
......
# SPDX-License-Identifier: GPL-2.0-only
rv
rv-static
fixdep
feature
FEATURE-DUMP
NAME := rv # SPDX-License-Identifier: GPL-2.0-only
# Follow the kernel version
VERSION := $(shell cat VERSION 2> /dev/null || make -sC ../../.. kernelversion | grep -v make) ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
# From libtracefs: srctree := $(patsubst %/,%,$(dir $(srctree)))
# Makefiles suck: This macro sets a default value of $(2) for the srctree := $(patsubst %/,%,$(dir $(srctree)))
# variable named by $(1), unless the variable has been set by
# environment or command line. This is necessary for CC and AR
# because make sets default values, so the simpler ?= approach
# won't work as expected.
define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef
# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
$(call allow-override,AR,$(CROSS_COMPILE)ar)
$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
$(call allow-override,PKG_CONFIG,pkg-config)
$(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/)
$(call allow-override,LDCONFIG,ldconfig)
INSTALL = install
MKDIR = mkdir
FOPTS := -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \
-fasynchronous-unwind-tables -fstack-clash-protection
WOPTS := -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized
ifeq ($(CC),clang)
FOPTS := $(filter-out -ffat-lto-objects, $(FOPTS))
WOPTS := $(filter-out -Wno-maybe-uninitialized, $(WOPTS))
endif endif
TRACEFS_HEADERS := $$($(PKG_CONFIG) --cflags libtracefs) include $(srctree)/tools/scripts/Makefile.include
CFLAGS := -O -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS) $(EXTRA_CFLAGS) -I include # O is an alias for OUTPUT
LDFLAGS := -flto=auto -ggdb $(EXTRA_LDFLAGS) OUTPUT := $(O)
LIBS := $$($(PKG_CONFIG) --libs libtracefs)
ifeq ($(OUTPUT),)
SRC := $(wildcard src/*.c) OUTPUT := $(CURDIR)/
HDR := $(wildcard src/*.h)
OBJ := $(SRC:.c=.o)
DIRS := src
FILES := Makefile README.txt
CEXT := bz2
TARBALL := $(NAME)-$(VERSION).tar.$(CEXT)
TAROPTS := -cvjf $(TARBALL)
BINDIR := /usr/bin
DATADIR := /usr/share
DOCDIR := $(DATADIR)/doc
MANDIR := $(DATADIR)/man
LICDIR := $(DATADIR)/licenses
SRCTREE := $(or $(BUILD_SRC),$(CURDIR))
# If running from the tarball, man pages are stored in the Documentation
# dir. If running from the kernel source, man pages are stored in
# Documentation/tools/rv/.
ifneq ($(wildcard Documentation/.*),)
DOCSRC = Documentation/
else else
DOCSRC = $(SRCTREE)/../../../Documentation/tools/rv/ # subdir is used by the ../Makefile in $(call descend,)
ifneq ($(subdir),)
OUTPUT := $(OUTPUT)/$(subdir)
endif
endif
ifneq ($(patsubst %/,,$(lastword $(OUTPUT))),)
OUTPUT := $(OUTPUT)/
endif endif
LIBTRACEEVENT_MIN_VERSION = 1.5 RV := $(OUTPUT)rv
LIBTRACEFS_MIN_VERSION = 1.3 RV_IN := $(RV)-in.o
.PHONY: all warnings show_warnings VERSION := $(shell sh -c "make -sC ../../.. kernelversion | grep -v make")
all: warnings rv DOCSRC := ../../../Documentation/tools/rv/
TEST_LIBTRACEEVENT = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 || echo n") FEATURE_TESTS := libtraceevent
ifeq ("$(TEST_LIBTRACEEVENT)", "n") FEATURE_TESTS += libtracefs
WARNINGS = show_warnings FEATURE_DISPLAY := libtraceevent
MISSING_LIBS += echo "** libtraceevent version $(LIBTRACEEVENT_MIN_VERSION) or higher"; FEATURE_DISPLAY += libtracefs
MISSING_PACKAGES += "libtraceevent-devel"
MISSING_SOURCE += echo "** https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ "; ifeq ($(V),1)
Q =
else
Q = @
endif endif
TEST_LIBTRACEFS = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEFS_MIN_VERSION) libtracefs > /dev/null 2>&1 || echo n") all: $(RV)
ifeq ("$(TEST_LIBTRACEFS)", "n")
WARNINGS = show_warnings include $(srctree)/tools/build/Makefile.include
MISSING_LIBS += echo "** libtracefs version $(LIBTRACEFS_MIN_VERSION) or higher"; include Makefile.rv
MISSING_PACKAGES += "libtracefs-devel"
MISSING_SOURCE += echo "** https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ "; # check for dependencies only on required targets
NON_CONFIG_TARGETS := clean install doc doc_clean doc_install
config := 1
ifdef MAKECMDGOALS
ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
config := 0
endif
endif endif
define show_dependencies ifeq ($(config),1)
@echo "********************************************"; \ include $(srctree)/tools/build/Makefile.feature
echo "** NOTICE: Failed build dependencies"; \ include Makefile.config
echo "**"; \
echo "** Required Libraries:"; \
$(MISSING_LIBS) \
echo "**"; \
echo "** Consider installing the latest libtracefs from your"; \
echo "** distribution, e.g., 'dnf install $(MISSING_PACKAGES)' on Fedora,"; \
echo "** or from source:"; \
echo "**"; \
$(MISSING_SOURCE) \
echo "**"; \
echo "********************************************"
endef
show_warnings:
$(call show_dependencies);
ifneq ("$(WARNINGS)", "")
ERROR_OUT = $(error Please add the necessary dependencies)
warnings: $(WARNINGS)
$(ERROR_OUT)
endif endif
rv: $(OBJ) CFLAGS += $(INCLUDES) $(LIB_INCLUDES)
$(CC) -o rv $(LDFLAGS) $(OBJ) $(LIBS)
export CFLAGS OUTPUT srctree
.PHONY: install
install: doc_install $(RV): $(RV_IN)
$(MKDIR) -p $(DESTDIR)$(BINDIR) $(QUIET_LINK)$(CC) $(LDFLAGS) -o $(RV) $(RV_IN) $(EXTLIBS)
$(INSTALL) rv -m 755 $(DESTDIR)$(BINDIR)
$(STRIP) $(DESTDIR)$(BINDIR)/rv static: $(RV_IN)
$(eval LDFLAGS += -static)
.PHONY: clean tarball $(QUIET_LINK)$(CC) $(LDFLAGS) -o $(RV)-static $(RV_IN) $(EXTLIBS)
clean: doc_clean
@test ! -f rv || rm rv rv.%: fixdep FORCE
@test ! -f $(TARBALL) || rm -f $(TARBALL) make -f $(srctree)/tools/build/Makefile.build dir=. $@
@rm -rf *~ $(OBJ) *.tar.$(CEXT)
$(RV_IN): fixdep FORCE
tarball: clean make $(build)=rv
rm -rf $(NAME)-$(VERSION) && mkdir $(NAME)-$(VERSION)
echo $(VERSION) > $(NAME)-$(VERSION)/VERSION clean: doc_clean fixdep-clean
cp -r $(DIRS) $(FILES) $(NAME)-$(VERSION) $(call QUIET_CLEAN, rv)
mkdir $(NAME)-$(VERSION)/Documentation/ $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
cp -rp $(SRCTREE)/../../../Documentation/tools/rv/* $(NAME)-$(VERSION)/Documentation/ $(Q)rm -f rv rv-static fixdep FEATURE-DUMP rv-*
tar $(TAROPTS) --exclude='*~' $(NAME)-$(VERSION) $(Q)rm -rf feature
rm -rf $(NAME)-$(VERSION)
.PHONY: FORCE clean
.PHONY: doc doc_clean doc_install
doc:
$(MAKE) -C $(DOCSRC)
doc_clean:
$(MAKE) -C $(DOCSRC) clean
doc_install:
$(MAKE) -C $(DOCSRC) install
# SPDX-License-Identifier: GPL-2.0-only
STOP_ERROR :=
LIBTRACEEVENT_MIN_VERSION = 1.5
LIBTRACEFS_MIN_VERSION = 1.3
define lib_setup
$(eval LIB_INCLUDES += $(shell sh -c "$(PKG_CONFIG) --cflags lib$(1)"))
$(eval EXTLIBS += -l$(1))
endef
$(call feature_check,libtraceevent)
ifeq ($(feature-libtraceevent), 1)
$(call detected,CONFIG_LIBTRACEEVENT)
TEST = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEEVENT_MIN_VERSION) libtraceevent > /dev/null 2>&1 && echo y || echo n")
ifeq ($(TEST),n)
$(info libtraceevent version is too low, it must be at least $(LIBTRACEEVENT_MIN_VERSION))
STOP_ERROR := 1
endif
$(call lib_setup,traceevent)
else
STOP_ERROR := 1
$(info libtraceevent is missing. Please install libtraceevent-dev/libtraceevent-devel)
endif
$(call feature_check,libtracefs)
ifeq ($(feature-libtracefs), 1)
$(call detected,CONFIG_LIBTRACEFS)
TEST = $(shell sh -c "$(PKG_CONFIG) --atleast-version $(LIBTRACEFS_MIN_VERSION) libtracefs > /dev/null 2>&1 && echo y || echo n")
ifeq ($(TEST),n)
$(info libtracefs version is too low, it must be at least $(LIBTRACEFS_MIN_VERSION))
STOP_ERROR := 1
endif
$(call lib_setup,tracefs)
else
STOP_ERROR := 1
$(info libtracefs is missing. Please install libtracefs-dev/libtracefs-devel)
endif
ifeq ($(STOP_ERROR),1)
$(error Please, check the errors above.)
endif
# SPDX-License-Identifier: GPL-2.0-only
define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef
# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
$(call allow-override,AR,$(CROSS_COMPILE)ar)
$(call allow-override,STRIP,$(CROSS_COMPILE)strip)
$(call allow-override,PKG_CONFIG,pkg-config)
$(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/)
$(call allow-override,LDCONFIG,ldconfig)
export CC AR STRIP PKG_CONFIG LD_SO_CONF_PATH LDCONFIG
FOPTS :=-flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \
-fasynchronous-unwind-tables -fstack-clash-protection
WOPTS := -O -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 \
-Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized
ifeq ($(CC),clang)
FOPTS := $(filter-out -flto=auto -ffat-lto-objects, $(FOPTS))
WOPTS := $(filter-out -Wno-maybe-uninitialized, $(WOPTS))
endif
INCLUDE := -Iinclude/
CFLAGS := -g -DVERSION=\"$(VERSION)\" $(FOPTS) $(WOPTS) $(EXTRA_CFLAGS) $(INCLUDE)
LDFLAGS := -ggdb $(EXTRA_LDFLAGS)
INSTALL := install
MKDIR := mkdir
STRIP := strip
BINDIR := /usr/bin
.PHONY: install
install: doc_install
$(Q)$(MKDIR) -p $(DESTDIR)$(BINDIR)
$(call QUIET_INSTALL,rv)$(INSTALL) $(OUTPUT)rv -m 755 $(DESTDIR)$(BINDIR)
$(Q)@$(STRIP) $(DESTDIR)$(BINDIR)/rv
.PHONY: doc doc_clean doc_install
doc:
$(MAKE) -C $(DOCSRC)
doc_clean:
$(MAKE) -C $(DOCSRC) clean
doc_install:
$(MAKE) -C $(DOCSRC) install
rv-y += trace.o
rv-y += utils.o
rv-y += in_kernel.o
rv-y += rv.o
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment