Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Remove runqslower tool

runqslower was added in commit 9c01546d26d2 "tools/bpf: Add runqslower
tool to tools/bpf" as a BCC port to showcase early BPF CO-RE + libbpf
workflows. runqslower continues to live in BCC (libbpf-tools), so there
is no need to keep building and maintaining it.

Drop tools/bpf/runqslower and remove all build hooks in tools/bpf and
selftests accordingly.

Signed-off-by: Hoyeon Lee <hoyeon.lee@suse.com>
Link: https://lore.kernel.org/r/20251126093821.373291-1-hoyeon.lee@suse.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Hoyeon Lee and committed by
Alexei Starovoitov
bd5bdd20 a3a60cc1

+4 -413
+3 -10
tools/bpf/Makefile
··· 32 32 FEATURE_DISPLAY = libbfd 33 33 34 34 check_feat := 1 35 - NON_CHECK_FEAT_TARGETS := clean bpftool_clean runqslower_clean resolve_btfids_clean 35 + NON_CHECK_FEAT_TARGETS := clean bpftool_clean resolve_btfids_clean 36 36 ifdef MAKECMDGOALS 37 37 ifeq ($(filter-out $(NON_CHECK_FEAT_TARGETS),$(MAKECMDGOALS)),) 38 38 check_feat := 0 ··· 70 70 71 71 PROGS = $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg $(OUTPUT)bpf_asm 72 72 73 - all: $(PROGS) bpftool runqslower 73 + all: $(PROGS) bpftool 74 74 75 75 $(OUTPUT)bpf_jit_disasm: CFLAGS += -DPACKAGE='bpf_jit_disasm' 76 76 $(OUTPUT)bpf_jit_disasm: $(OUTPUT)bpf_jit_disasm.o ··· 86 86 $(OUTPUT)bpf_exp.yacc.o: $(OUTPUT)bpf_exp.yacc.c 87 87 $(OUTPUT)bpf_exp.lex.o: $(OUTPUT)bpf_exp.lex.c 88 88 89 - clean: bpftool_clean runqslower_clean resolve_btfids_clean 89 + clean: bpftool_clean resolve_btfids_clean 90 90 $(call QUIET_CLEAN, bpf-progs) 91 91 $(Q)$(RM) -r -- $(OUTPUT)*.o $(OUTPUT)bpf_jit_disasm $(OUTPUT)bpf_dbg \ 92 92 $(OUTPUT)bpf_asm $(OUTPUT)bpf_exp.yacc.* $(OUTPUT)bpf_exp.lex.* ··· 112 112 bpftool_clean: 113 113 $(call descend,bpftool,clean) 114 114 115 - runqslower: 116 - $(call descend,runqslower) 117 - 118 - runqslower_clean: 119 - $(call descend,runqslower,clean) 120 - 121 115 resolve_btfids: 122 116 $(call descend,resolve_btfids) 123 117 ··· 119 125 $(call descend,resolve_btfids,clean) 120 126 121 127 .PHONY: all install clean bpftool bpftool_install bpftool_clean \ 122 - runqslower runqslower_clean \ 123 128 resolve_btfids resolve_btfids_clean
-2
tools/bpf/runqslower/.gitignore
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - /.output
-91
tools/bpf/runqslower/Makefile
··· 1 - # SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 - include ../../scripts/Makefile.include 3 - 4 - OUTPUT ?= $(abspath .output)/ 5 - 6 - BPFTOOL_OUTPUT := $(OUTPUT)bpftool/ 7 - DEFAULT_BPFTOOL := $(BPFTOOL_OUTPUT)bootstrap/bpftool 8 - BPFTOOL ?= $(DEFAULT_BPFTOOL) 9 - BPF_TARGET_ENDIAN ?= --target=bpf 10 - LIBBPF_SRC := $(abspath ../../lib/bpf) 11 - BPFOBJ_OUTPUT := $(OUTPUT)libbpf/ 12 - BPFOBJ := $(BPFOBJ_OUTPUT)libbpf.a 13 - BPF_DESTDIR := $(BPFOBJ_OUTPUT) 14 - BPF_INCLUDE := $(BPF_DESTDIR)/include 15 - INCLUDES := -I$(OUTPUT) -I$(BPF_INCLUDE) -I$(abspath ../../include/uapi) 16 - CFLAGS := -g -Wall $(CLANG_CROSS_FLAGS) 17 - CFLAGS += $(EXTRA_CFLAGS) 18 - LDFLAGS += $(EXTRA_LDFLAGS) 19 - LDLIBS += -lelf -lz 20 - 21 - # Try to detect best kernel BTF source 22 - KERNEL_REL := $(shell uname -r) 23 - VMLINUX_BTF_PATHS := $(if $(O),$(O)/vmlinux) \ 24 - $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ 25 - ../../../vmlinux /sys/kernel/btf/vmlinux \ 26 - /boot/vmlinux-$(KERNEL_REL) 27 - VMLINUX_BTF_PATH := $(or $(VMLINUX_BTF),$(firstword \ 28 - $(wildcard $(VMLINUX_BTF_PATHS)))) 29 - 30 - ifneq ($(V),1) 31 - MAKEFLAGS += --no-print-directory 32 - submake_extras := feature_display=0 33 - endif 34 - 35 - .DELETE_ON_ERROR: 36 - 37 - .PHONY: all clean runqslower libbpf_hdrs 38 - all: runqslower 39 - 40 - runqslower: $(OUTPUT)/runqslower 41 - 42 - clean: 43 - $(call QUIET_CLEAN, runqslower) 44 - $(Q)$(RM) -r $(BPFOBJ_OUTPUT) $(BPFTOOL_OUTPUT) 45 - $(Q)$(RM) $(OUTPUT)*.o $(OUTPUT)*.d 46 - $(Q)$(RM) $(OUTPUT)*.skel.h $(OUTPUT)vmlinux.h 47 - $(Q)$(RM) $(OUTPUT)runqslower 48 - $(Q)$(RM) -r .output 49 - 50 - libbpf_hdrs: $(BPFOBJ) 51 - 52 - $(OUTPUT)/runqslower: $(OUTPUT)/runqslower.o $(BPFOBJ) 53 - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ 54 - 55 - $(OUTPUT)/runqslower.o: runqslower.h $(OUTPUT)/runqslower.skel.h \ 56 - $(OUTPUT)/runqslower.bpf.o | libbpf_hdrs 57 - 58 - $(OUTPUT)/runqslower.bpf.o: $(OUTPUT)/vmlinux.h runqslower.h | libbpf_hdrs 59 - 60 - $(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(BPFTOOL) 61 - $(QUIET_GEN)$(BPFTOOL) gen skeleton $< > $@ 62 - 63 - $(OUTPUT)/%.bpf.o: %.bpf.c $(BPFOBJ) | $(OUTPUT) 64 - $(QUIET_GEN)$(CLANG) -g -O2 $(BPF_TARGET_ENDIAN) $(INCLUDES) \ 65 - -c $(filter %.c,$^) -o $@ && \ 66 - $(LLVM_STRIP) -g $@ 67 - 68 - $(OUTPUT)/%.o: %.c | $(OUTPUT) 69 - $(QUIET_CC)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@ 70 - 71 - $(OUTPUT) $(BPFOBJ_OUTPUT) $(BPFTOOL_OUTPUT): 72 - $(QUIET_MKDIR)mkdir -p $@ 73 - 74 - $(OUTPUT)/vmlinux.h: $(VMLINUX_BTF_PATH) | $(OUTPUT) $(BPFTOOL) 75 - ifeq ($(VMLINUX_H),) 76 - $(Q)if [ ! -e "$(VMLINUX_BTF_PATH)" ] ; then \ 77 - echo "Couldn't find kernel BTF; set VMLINUX_BTF to" \ 78 - "specify its location." >&2; \ 79 - exit 1;\ 80 - fi 81 - $(QUIET_GEN)$(BPFTOOL) btf dump file $(VMLINUX_BTF_PATH) format c > $@ 82 - else 83 - $(Q)cp "$(VMLINUX_H)" $@ 84 - endif 85 - 86 - $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(BPFOBJ_OUTPUT) 87 - $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(BPFOBJ_OUTPUT) \ 88 - DESTDIR=$(BPFOBJ_OUTPUT) prefix= $(abspath $@) install_headers 89 - 90 - $(DEFAULT_BPFTOOL): | $(BPFTOOL_OUTPUT) 91 - $(Q)$(MAKE) $(submake_extras) -C ../bpftool OUTPUT=$(BPFTOOL_OUTPUT) bootstrap
-106
tools/bpf/runqslower/runqslower.bpf.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - // Copyright (c) 2019 Facebook 3 - #include "vmlinux.h" 4 - #include <bpf/bpf_helpers.h> 5 - #include "runqslower.h" 6 - 7 - #define TASK_RUNNING 0 8 - #define BPF_F_CURRENT_CPU 0xffffffffULL 9 - 10 - const volatile __u64 min_us = 0; 11 - const volatile pid_t targ_pid = 0; 12 - 13 - struct { 14 - __uint(type, BPF_MAP_TYPE_TASK_STORAGE); 15 - __uint(map_flags, BPF_F_NO_PREALLOC); 16 - __type(key, int); 17 - __type(value, u64); 18 - } start SEC(".maps"); 19 - 20 - struct { 21 - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 22 - __uint(key_size, sizeof(u32)); 23 - __uint(value_size, sizeof(u32)); 24 - } events SEC(".maps"); 25 - 26 - /* record enqueue timestamp */ 27 - __always_inline 28 - static int trace_enqueue(struct task_struct *t) 29 - { 30 - u32 pid = t->pid; 31 - u64 *ptr; 32 - 33 - if (!pid || (targ_pid && targ_pid != pid)) 34 - return 0; 35 - 36 - ptr = bpf_task_storage_get(&start, t, 0, 37 - BPF_LOCAL_STORAGE_GET_F_CREATE); 38 - if (!ptr) 39 - return 0; 40 - 41 - *ptr = bpf_ktime_get_ns(); 42 - return 0; 43 - } 44 - 45 - SEC("tp_btf/sched_wakeup") 46 - int handle__sched_wakeup(u64 *ctx) 47 - { 48 - /* TP_PROTO(struct task_struct *p) */ 49 - struct task_struct *p = (void *)ctx[0]; 50 - 51 - return trace_enqueue(p); 52 - } 53 - 54 - SEC("tp_btf/sched_wakeup_new") 55 - int handle__sched_wakeup_new(u64 *ctx) 56 - { 57 - /* TP_PROTO(struct task_struct *p) */ 58 - struct task_struct *p = (void *)ctx[0]; 59 - 60 - return trace_enqueue(p); 61 - } 62 - 63 - SEC("tp_btf/sched_switch") 64 - int handle__sched_switch(u64 *ctx) 65 - { 66 - /* TP_PROTO(bool preempt, struct task_struct *prev, 67 - * struct task_struct *next) 68 - */ 69 - struct task_struct *prev = (struct task_struct *)ctx[1]; 70 - struct task_struct *next = (struct task_struct *)ctx[2]; 71 - struct runq_event event = {}; 72 - u64 *tsp, delta_us; 73 - u32 pid; 74 - 75 - /* ivcsw: treat like an enqueue event and store timestamp */ 76 - if (prev->__state == TASK_RUNNING) 77 - trace_enqueue(prev); 78 - 79 - pid = next->pid; 80 - 81 - /* For pid mismatch, save a bpf_task_storage_get */ 82 - if (!pid || (targ_pid && targ_pid != pid)) 83 - return 0; 84 - 85 - /* fetch timestamp and calculate delta */ 86 - tsp = bpf_task_storage_get(&start, next, 0, 0); 87 - if (!tsp) 88 - return 0; /* missed enqueue */ 89 - 90 - delta_us = (bpf_ktime_get_ns() - *tsp) / 1000; 91 - if (min_us && delta_us <= min_us) 92 - return 0; 93 - 94 - event.pid = pid; 95 - event.delta_us = delta_us; 96 - bpf_get_current_comm(&event.task, sizeof(event.task)); 97 - 98 - /* output */ 99 - bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, 100 - &event, sizeof(event)); 101 - 102 - bpf_task_storage_delete(&start, next); 103 - return 0; 104 - } 105 - 106 - char LICENSE[] SEC("license") = "GPL";
-171
tools/bpf/runqslower/runqslower.c
··· 1 - // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 - // Copyright (c) 2019 Facebook 3 - #include <argp.h> 4 - #include <stdio.h> 5 - #include <stdlib.h> 6 - #include <string.h> 7 - #include <time.h> 8 - #include <bpf/libbpf.h> 9 - #include <bpf/bpf.h> 10 - #include "runqslower.h" 11 - #include "runqslower.skel.h" 12 - 13 - struct env { 14 - pid_t pid; 15 - __u64 min_us; 16 - bool verbose; 17 - } env = { 18 - .min_us = 10000, 19 - }; 20 - 21 - const char *argp_program_version = "runqslower 0.1"; 22 - const char *argp_program_bug_address = "<bpf@vger.kernel.org>"; 23 - const char argp_program_doc[] = 24 - "runqslower Trace long process scheduling delays.\n" 25 - " For Linux, uses eBPF, BPF CO-RE, libbpf, BTF.\n" 26 - "\n" 27 - "This script traces high scheduling delays between tasks being\n" 28 - "ready to run and them running on CPU after that.\n" 29 - "\n" 30 - "USAGE: runqslower [-p PID] [min_us]\n" 31 - "\n" 32 - "EXAMPLES:\n" 33 - " runqslower # trace run queue latency higher than 10000 us (default)\n" 34 - " runqslower 1000 # trace run queue latency higher than 1000 us\n" 35 - " runqslower -p 123 # trace pid 123 only\n"; 36 - 37 - static const struct argp_option opts[] = { 38 - { "pid", 'p', "PID", 0, "Process PID to trace"}, 39 - { "verbose", 'v', NULL, 0, "Verbose debug output" }, 40 - {}, 41 - }; 42 - 43 - static error_t parse_arg(int key, char *arg, struct argp_state *state) 44 - { 45 - static int pos_args; 46 - int pid; 47 - long long min_us; 48 - 49 - switch (key) { 50 - case 'v': 51 - env.verbose = true; 52 - break; 53 - case 'p': 54 - errno = 0; 55 - pid = strtol(arg, NULL, 10); 56 - if (errno || pid <= 0) { 57 - fprintf(stderr, "Invalid PID: %s\n", arg); 58 - argp_usage(state); 59 - } 60 - env.pid = pid; 61 - break; 62 - case ARGP_KEY_ARG: 63 - if (pos_args++) { 64 - fprintf(stderr, 65 - "Unrecognized positional argument: %s\n", arg); 66 - argp_usage(state); 67 - } 68 - errno = 0; 69 - min_us = strtoll(arg, NULL, 10); 70 - if (errno || min_us <= 0) { 71 - fprintf(stderr, "Invalid delay (in us): %s\n", arg); 72 - argp_usage(state); 73 - } 74 - env.min_us = min_us; 75 - break; 76 - default: 77 - return ARGP_ERR_UNKNOWN; 78 - } 79 - return 0; 80 - } 81 - 82 - int libbpf_print_fn(enum libbpf_print_level level, 83 - const char *format, va_list args) 84 - { 85 - if (level == LIBBPF_DEBUG && !env.verbose) 86 - return 0; 87 - return vfprintf(stderr, format, args); 88 - } 89 - 90 - void handle_event(void *ctx, int cpu, void *data, __u32 data_sz) 91 - { 92 - const struct runq_event *e = data; 93 - struct tm *tm; 94 - char ts[32]; 95 - time_t t; 96 - 97 - time(&t); 98 - tm = localtime(&t); 99 - strftime(ts, sizeof(ts), "%H:%M:%S", tm); 100 - printf("%-8s %-16s %-6d %14llu\n", ts, e->task, e->pid, e->delta_us); 101 - } 102 - 103 - void handle_lost_events(void *ctx, int cpu, __u64 lost_cnt) 104 - { 105 - printf("Lost %llu events on CPU #%d!\n", lost_cnt, cpu); 106 - } 107 - 108 - int main(int argc, char **argv) 109 - { 110 - static const struct argp argp = { 111 - .options = opts, 112 - .parser = parse_arg, 113 - .doc = argp_program_doc, 114 - }; 115 - struct perf_buffer *pb = NULL; 116 - struct runqslower_bpf *obj; 117 - int err; 118 - 119 - err = argp_parse(&argp, argc, argv, 0, NULL, NULL); 120 - if (err) 121 - return err; 122 - 123 - libbpf_set_print(libbpf_print_fn); 124 - 125 - /* Use libbpf 1.0 API mode */ 126 - libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 127 - 128 - obj = runqslower_bpf__open(); 129 - if (!obj) { 130 - fprintf(stderr, "failed to open and/or load BPF object\n"); 131 - return 1; 132 - } 133 - 134 - /* initialize global data (filtering options) */ 135 - obj->rodata->targ_pid = env.pid; 136 - obj->rodata->min_us = env.min_us; 137 - 138 - err = runqslower_bpf__load(obj); 139 - if (err) { 140 - fprintf(stderr, "failed to load BPF object: %d\n", err); 141 - goto cleanup; 142 - } 143 - 144 - err = runqslower_bpf__attach(obj); 145 - if (err) { 146 - fprintf(stderr, "failed to attach BPF programs\n"); 147 - goto cleanup; 148 - } 149 - 150 - printf("Tracing run queue latency higher than %llu us\n", env.min_us); 151 - printf("%-8s %-16s %-6s %14s\n", "TIME", "COMM", "PID", "LAT(us)"); 152 - 153 - pb = perf_buffer__new(bpf_map__fd(obj->maps.events), 64, 154 - handle_event, handle_lost_events, NULL, NULL); 155 - err = libbpf_get_error(pb); 156 - if (err) { 157 - pb = NULL; 158 - fprintf(stderr, "failed to open perf buffer: %d\n", err); 159 - goto cleanup; 160 - } 161 - 162 - while ((err = perf_buffer__poll(pb, 100)) >= 0) 163 - ; 164 - printf("Error polling perf buffer: %d\n", err); 165 - 166 - cleanup: 167 - perf_buffer__free(pb); 168 - runqslower_bpf__destroy(obj); 169 - 170 - return err != 0; 171 - }
-13
tools/bpf/runqslower/runqslower.h
··· 1 - /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ 2 - #ifndef __RUNQSLOWER_H 3 - #define __RUNQSLOWER_H 4 - 5 - #define TASK_COMM_LEN 16 6 - 7 - struct runq_event { 8 - char task[TASK_COMM_LEN]; 9 - __u64 delta_us; 10 - pid_t pid; 11 - }; 12 - 13 - #endif /* __RUNQSLOWER_H */
-1
tools/testing/selftests/bpf/.gitignore
··· 33 33 /cpuv4 34 34 /host-tools 35 35 /tools 36 - /runqslower 37 36 /bench 38 37 /veristat 39 38 /sign-file
+1 -15
tools/testing/selftests/bpf/Makefile
··· 127 127 TEST_GEN_PROGS_EXTENDED = \ 128 128 bench \ 129 129 flow_dissector_load \ 130 - runqslower \ 131 130 test_cpp \ 132 131 test_lirc_mode2_user \ 133 132 veristat \ ··· 208 209 endif 209 210 HOST_BPFOBJ := $(HOST_BUILD_DIR)/libbpf/libbpf.a 210 211 RESOLVE_BTFIDS := $(HOST_BUILD_DIR)/resolve_btfids/resolve_btfids 211 - RUNQSLOWER_OUTPUT := $(BUILD_DIR)/runqslower/ 212 - 213 212 VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ 214 213 $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ 215 214 ../../../../vmlinux \ ··· 229 232 MAKE_DIRS := $(sort $(BUILD_DIR)/libbpf $(HOST_BUILD_DIR)/libbpf \ 230 233 $(BUILD_DIR)/bpftool $(HOST_BUILD_DIR)/bpftool \ 231 234 $(HOST_BUILD_DIR)/resolve_btfids \ 232 - $(RUNQSLOWER_OUTPUT) $(INCLUDE_DIR)) 235 + $(INCLUDE_DIR)) 233 236 $(MAKE_DIRS): 234 237 $(call msg,MKDIR,,$@) 235 238 $(Q)mkdir -p $@ ··· 300 303 TRUNNER_BPFTOOL := $(DEFAULT_BPFTOOL) 301 304 USE_BOOTSTRAP := "bootstrap/" 302 305 endif 303 - 304 - $(OUTPUT)/runqslower: $(BPFOBJ) | $(DEFAULT_BPFTOOL) $(RUNQSLOWER_OUTPUT) 305 - $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/runqslower \ 306 - OUTPUT=$(RUNQSLOWER_OUTPUT) VMLINUX_BTF=$(VMLINUX_BTF) \ 307 - BPFTOOL_OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \ 308 - BPFOBJ_OUTPUT=$(BUILD_DIR)/libbpf/ \ 309 - BPFOBJ=$(BPFOBJ) BPF_INCLUDE=$(INCLUDE_DIR) \ 310 - BPF_TARGET_ENDIAN=$(BPF_TARGET_ENDIAN) \ 311 - EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS) $(EXTRA_CFLAGS)' \ 312 - EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)' && \ 313 - cp $(RUNQSLOWER_OUTPUT)runqslower $@ 314 306 315 307 TEST_GEN_PROGS_EXTENDED += $(TRUNNER_BPFTOOL) 316 308
-4
tools/testing/selftests/bpf/test_bpftool_build.sh
··· 90 90 91 91 if [ -f ".config" ] ; then 92 92 make_and_clean tools/bpf 93 - ## "make tools/bpf" sets $(OUTPUT) to ...tools/bpf/runqslower for 94 - ## runqslower, but the default (used for the "clean" target) is .output. 95 - ## Let's make sure we clean runqslower's directory properly. 96 - make -C tools/bpf/runqslower OUTPUT=${KDIR_ROOT_DIR}/tools/bpf/runqslower/ clean 97 93 98 94 ## $OUTPUT is overwritten in kbuild Makefile, and thus cannot be passed 99 95 ## down from toplevel Makefile to bpftool's Makefile.