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

Configure Feed

Select the types of activity you want to include in your feed.

perf test workload: Add code_with_type test workload

The purpose of the workload is to gather samples of rust runtime. To
achieve that it has a dummy rust library linked with it.

Per recommendations for such scenarios [1], the rust library is
statically linked.

An example:

$ perf record perf test -w code_with_type
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.160 MB perf.data (4074 samples) ]

$ perf report --stdio --dso perf -s srcfile,srcline
45.16% ub_checks.rs ub_checks.rs:72
6.72% code_with_type.rs code_with_type.rs:15
6.64% range.rs range.rs:767
4.26% code_with_type.rs code_with_type.rs:21
4.23% range.rs range.rs:0
3.99% code_with_type.rs code_with_type.rs:16
[...]

[1]: https://doc.rust-lang.org/reference/linkage.html#mixed-rust-and-foreign-codebases

Signed-off-by: Dmitrii Dolgov <9erthalion6@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Dmitrii Dolgov and committed by
Arnaldo Carvalho de Melo
2e05bb52 6a32fa5c

+99 -1
+14
tools/build/Makefile.build
··· 76 76 cmd_host_ld_multi = $(if $(strip $(obj-y)),\ 77 77 $(HOSTLD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@) 78 78 79 + rust_common_cmd = \ 80 + $(RUSTC) $(rust_flags) \ 81 + --crate-type staticlib -L $(objtree)/rust/ \ 82 + --emit=dep-info=$(depfile),link 83 + 84 + quiet_cmd_rustc_a_rs = $(RUSTC) $(quiet_modtag) $@ 85 + cmd_rustc_a_rs = $(rust_common_cmd) -o $@ -g $< $(cmd_objtool) 86 + 79 87 ifneq ($(filter $(obj),$(hostprogs)),) 80 88 host = host_ 81 89 endif ··· 112 104 $(OUTPUT)%.s: %.c FORCE 113 105 $(call rule_mkdir) 114 106 $(call if_changed_dep,cc_s_c) 107 + 108 + # it's recommended to build a static rust library, when a foreight (to rust) 109 + # linker is used. 110 + $(OUTPUT)%.a: %.rs FORCE 111 + $(call rule_mkdir) 112 + $(call if_changed_dep,rustc_a_rs) 115 113 116 114 # bison and flex files are generated in the OUTPUT directory 117 115 # so it needs a separate rule to depend on them properly
+1 -1
tools/perf/Makefile.perf
··· 271 271 PYLINT := $(shell which pylint 2> /dev/null) 272 272 endif 273 273 274 - export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK 274 + export srctree OUTPUT RM CC CXX RUSTC LD AR CFLAGS CXXFLAGS V BISON FLEX AWK 275 275 export HOSTCC HOSTLD HOSTAR HOSTCFLAGS SHELLCHECK MYPY PYLINT 276 276 277 277 include $(srctree)/tools/build/Makefile.include
+4
tools/perf/tests/builtin-test.c
··· 154 154 &workload__landlock, 155 155 &workload__traploop, 156 156 &workload__inlineloop, 157 + 158 + #ifdef HAVE_RUST_SUPPORT 159 + &workload__code_with_type, 160 + #endif 157 161 }; 158 162 159 163 #define workloads__for_each(workload) \
+4
tools/perf/tests/tests.h
··· 242 242 DECLARE_WORKLOAD(traploop); 243 243 DECLARE_WORKLOAD(inlineloop); 244 244 245 + #ifdef HAVE_RUST_SUPPORT 246 + DECLARE_WORKLOAD(code_with_type); 247 + #endif 248 + 245 249 extern const char *dso_to_test; 246 250 extern const char *test_objdump_path; 247 251
+5
tools/perf/tests/workloads/Build
··· 10 10 perf-test-y += traploop.o 11 11 perf-test-y += inlineloop.o 12 12 13 + ifeq ($(CONFIG_RUST_SUPPORT),y) 14 + perf-test-y += code_with_type.o 15 + perf-test-y += code_with_type.a 16 + endif 17 + 13 18 CFLAGS_sqrtloop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE 14 19 CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE 15 20 CFLAGS_brstack.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE
+46
tools/perf/tests/workloads/code_with_type.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <pthread.h> 3 + #include <stdlib.h> 4 + #include <signal.h> 5 + #include <unistd.h> 6 + #include <linux/compiler.h> 7 + #include "../tests.h" 8 + 9 + extern void test_rs(uint count); 10 + 11 + static volatile sig_atomic_t done; 12 + 13 + static void sighandler(int sig __maybe_unused) 14 + { 15 + done = 1; 16 + } 17 + 18 + static int code_with_type(int argc, const char **argv) 19 + { 20 + int sec = 1, num_loops = 100; 21 + 22 + pthread_setname_np(pthread_self(), "perf-code-with-type"); 23 + if (argc > 0) 24 + sec = atoi(argv[0]); 25 + 26 + if (argc > 1) 27 + num_loops = atoi(argv[1]); 28 + 29 + signal(SIGINT, sighandler); 30 + signal(SIGALRM, sighandler); 31 + alarm(sec); 32 + 33 + /* 34 + * Rust doesn't have signal management in the standard library. To 35 + * not deal with any external crates, offload signal handling to the 36 + * outside code. 37 + */ 38 + while (!done) { 39 + test_rs(num_loops); 40 + continue; 41 + } 42 + 43 + return 0; 44 + } 45 + 46 + DEFINE_WORKLOAD(code_with_type);
+23
tools/perf/tests/workloads/code_with_type.rs
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // We're going to look for this structure in the data type profiling report 4 + #[allow(dead_code)] 5 + struct Buf { 6 + data1: u64, 7 + data2: String, 8 + data3: u64, 9 + } 10 + 11 + #[no_mangle] 12 + pub extern "C" fn test_rs(count: u32) { 13 + let mut b = Buf { data1: 0, data2: String::from("data"), data3: 0}; 14 + 15 + for _ in 1..count { 16 + b.data1 += 1; 17 + if b.data1 == 123 { 18 + b.data1 += 1; 19 + } 20 + 21 + b.data3 += b.data1; 22 + } 23 + }
+2
tools/scripts/Makefile.include
··· 94 94 # Some tools require bpftool 95 95 SYSTEM_BPFTOOL ?= bpftool 96 96 97 + RUSTC ?= rustc 98 + 97 99 ifeq ($(CC_NO_CLANG), 1) 98 100 EXTRA_WARNINGS += -Wstrict-aliasing=3 99 101