aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2017-05-02 05:02:41 -0400
committerJiri Kosina <jkosina@suse.cz>2017-05-02 05:02:41 -0400
commit4d6ca227c768b50b05cf183974b40abe444e9d0c (patch)
treebf953d8e895281053548b9967a2c4b58d641df00 /tools
parent800f3eef8ebc1264e9c135bfa892c8ae41fa4792 (diff)
parentaf22a610bc38508d5ea760507d31be6b6983dfa8 (diff)
Merge branch 'for-4.12/asus' into for-linus
Diffstat (limited to 'tools')
-rw-r--r--tools/build/Makefile4
-rw-r--r--tools/build/Makefile.include3
-rw-r--r--tools/gpio/.gitignore4
-rw-r--r--tools/gpio/gpio-hammer.c2
-rw-r--r--tools/iio/iio_event_monitor.c2
-rw-r--r--tools/include/asm-generic/bitops/atomic.h3
-rw-r--r--tools/include/asm/bug.h8
-rw-r--r--tools/include/linux/bitmap.h1
-rw-r--r--tools/include/linux/bitops.h1
-rw-r--r--tools/include/linux/compiler.h4
-rw-r--r--tools/include/linux/log2.h13
-rw-r--r--tools/include/linux/spinlock.h5
-rw-r--r--tools/include/uapi/linux/bpf.h23
-rw-r--r--tools/include/uapi/linux/bpf_perf_event.h18
-rw-r--r--tools/lguest/lguest.c2
-rw-r--r--tools/lib/bpf/Makefile2
-rw-r--r--tools/lib/bpf/bpf.c20
-rw-r--r--tools/lib/bpf/bpf.h12
-rw-r--r--tools/lib/find_bit.c2
-rw-r--r--tools/lib/traceevent/Makefile2
-rw-r--r--tools/lib/traceevent/event-parse.c38
-rw-r--r--tools/lib/traceevent/event-parse.h5
-rw-r--r--tools/objtool/arch.h5
-rw-r--r--tools/objtool/arch/x86/decode.c3
-rw-r--r--tools/objtool/builtin-check.c77
-rw-r--r--tools/objtool/elf.c12
-rw-r--r--tools/objtool/elf.h1
-rw-r--r--tools/perf/Documentation/perf-annotate.txt4
-rw-r--r--tools/perf/Documentation/perf-diff.txt4
-rw-r--r--tools/perf/Documentation/perf-record.txt2
-rw-r--r--tools/perf/Documentation/perf-report.txt4
-rw-r--r--tools/perf/Documentation/perf-stat.txt2
-rw-r--r--tools/perf/Documentation/tips.txt2
-rw-r--r--tools/perf/Makefile.config7
-rw-r--r--tools/perf/Makefile.perf4
-rw-r--r--tools/perf/builtin-annotate.c4
-rw-r--r--tools/perf/builtin-diff.c14
-rw-r--r--tools/perf/builtin-mem.c4
-rw-r--r--tools/perf/builtin-record.c8
-rw-r--r--tools/perf/builtin-report.c21
-rw-r--r--tools/perf/builtin-sched.c12
-rw-r--r--tools/perf/builtin-stat.c11
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/builtin-trace.c6
-rw-r--r--tools/perf/pmu-events/json.c2
-rw-r--r--tools/perf/tests/attr.c2
-rw-r--r--tools/perf/tests/builtin-test.c2
-rw-r--r--tools/perf/tests/code-reading.c2
-rw-r--r--tools/perf/tests/fdarray.c2
-rw-r--r--tools/perf/tests/llvm.c2
-rw-r--r--tools/perf/tests/parse-events.c2
-rw-r--r--tools/perf/tests/perf-record.c4
-rw-r--r--tools/perf/tests/python-use.c2
-rw-r--r--tools/perf/tests/thread-map.c6
-rw-r--r--tools/perf/tests/topology.c4
-rw-r--r--tools/perf/tests/vmlinux-kallsyms.c2
-rw-r--r--tools/perf/ui/browsers/map.c6
-rw-r--r--tools/perf/ui/hist.c2
-rw-r--r--tools/perf/util/annotate.c2
-rw-r--r--tools/perf/util/cgroup.c26
-rw-r--r--tools/perf/util/cpumap.c22
-rw-r--r--tools/perf/util/cpumap.h1
-rw-r--r--tools/perf/util/debug.c17
-rw-r--r--tools/perf/util/debug.h1
-rw-r--r--tools/perf/util/dso.c4
-rw-r--r--tools/perf/util/env.c2
-rw-r--r--tools/perf/util/header.c33
-rw-r--r--tools/perf/util/hist.c6
-rw-r--r--tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c2
-rw-r--r--tools/perf/util/parse-events.c71
-rw-r--r--tools/perf/util/parse-events.h2
-rw-r--r--tools/perf/util/parse-events.y14
-rw-r--r--tools/perf/util/pmu.c21
-rw-r--r--tools/perf/util/probe-event.c2
-rw-r--r--tools/perf/util/probe-finder.c4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c1
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c5
-rw-r--r--tools/perf/util/session.c2
-rw-r--r--tools/perf/util/setup.py9
-rw-r--r--tools/perf/util/sort.c8
-rw-r--r--tools/perf/util/sort.h2
-rw-r--r--tools/perf/util/stat.c2
-rw-r--r--tools/perf/util/symbol-elf.c2
-rw-r--r--tools/perf/util/symbol.c2
-rw-r--r--tools/power/cpupower/utils/cpufreq-info.c21
-rw-r--r--tools/power/x86/turbostat/turbostat.8253
-rw-r--r--tools/power/x86/turbostat/turbostat.c1880
-rwxr-xr-xtools/testing/ktest/ktest.pl132
-rw-r--r--tools/testing/nvdimm/test/nfit.c14
-rw-r--r--tools/testing/radix-tree/.gitignore4
-rw-r--r--tools/testing/radix-tree/Makefile53
-rw-r--r--tools/testing/radix-tree/benchmark.c177
-rw-r--r--tools/testing/radix-tree/generated/autoconf.h2
-rw-r--r--tools/testing/radix-tree/idr-test.c516
-rw-r--r--tools/testing/radix-tree/iteration_check.c2
-rw-r--r--tools/testing/radix-tree/linux.c39
-rw-r--r--tools/testing/radix-tree/linux/bitops.h160
-rw-r--r--tools/testing/radix-tree/linux/bitops/__ffs.h43
-rw-r--r--tools/testing/radix-tree/linux/bitops/ffs.h41
-rw-r--r--tools/testing/radix-tree/linux/bitops/ffz.h12
-rw-r--r--tools/testing/radix-tree/linux/bitops/find.h13
-rw-r--r--tools/testing/radix-tree/linux/bitops/fls.h41
-rw-r--r--tools/testing/radix-tree/linux/bitops/fls64.h14
-rw-r--r--tools/testing/radix-tree/linux/bitops/hweight.h11
-rw-r--r--tools/testing/radix-tree/linux/bitops/le.h53
-rw-r--r--tools/testing/radix-tree/linux/bitops/non-atomic.h110
-rw-r--r--tools/testing/radix-tree/linux/export.h2
-rw-r--r--tools/testing/radix-tree/linux/gfp.h10
-rw-r--r--tools/testing/radix-tree/linux/idr.h1
-rw-r--r--tools/testing/radix-tree/linux/init.h2
-rw-r--r--tools/testing/radix-tree/linux/kernel.h55
-rw-r--r--tools/testing/radix-tree/linux/mempool.h16
-rw-r--r--tools/testing/radix-tree/linux/percpu.h5
-rw-r--r--tools/testing/radix-tree/linux/preempt.h10
-rw-r--r--tools/testing/radix-tree/linux/radix-tree.h25
-rw-r--r--tools/testing/radix-tree/linux/types.h23
-rw-r--r--tools/testing/radix-tree/main.c54
-rw-r--r--tools/testing/radix-tree/multiorder.c39
-rw-r--r--tools/testing/radix-tree/regression1.c4
-rw-r--r--tools/testing/radix-tree/regression2.c10
-rw-r--r--tools/testing/radix-tree/regression3.c28
-rw-r--r--tools/testing/radix-tree/tag_check.c51
-rw-r--r--tools/testing/radix-tree/test.c28
-rw-r--r--tools/testing/radix-tree/test.h3
-rw-r--r--tools/testing/selftests/Makefile39
-rw-r--r--tools/testing/selftests/bpf/.gitignore2
-rw-r--r--tools/testing/selftests/bpf/Makefile25
-rw-r--r--tools/testing/selftests/bpf/bpf_sys.h108
-rw-r--r--tools/testing/selftests/bpf/test_lpm_map.c358
-rw-r--r--tools/testing/selftests/bpf/test_lru_map.c138
-rw-r--r--tools/testing/selftests/bpf/test_maps.c162
-rw-r--r--tools/testing/selftests/bpf/test_tag.c203
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c1637
-rw-r--r--tools/testing/selftests/breakpoints/Makefile10
-rw-r--r--tools/testing/selftests/capabilities/Makefile11
-rw-r--r--tools/testing/selftests/cpufreq/Makefile8
-rwxr-xr-xtools/testing/selftests/cpufreq/cpu.sh84
-rwxr-xr-xtools/testing/selftests/cpufreq/cpufreq.sh241
-rwxr-xr-xtools/testing/selftests/cpufreq/governor.sh153
-rwxr-xr-xtools/testing/selftests/cpufreq/main.sh194
-rwxr-xr-xtools/testing/selftests/cpufreq/module.sh243
-rwxr-xr-xtools/testing/selftests/cpufreq/special-tests.sh115
-rwxr-xr-xtools/testing/selftests/drivers/gpu/drm_mm.sh15
-rw-r--r--tools/testing/selftests/efivarfs/Makefile8
-rw-r--r--tools/testing/selftests/exec/Makefile32
-rw-r--r--tools/testing/selftests/firmware/Makefile2
-rwxr-xr-xtools/testing/selftests/firmware/fw_fallback.sh224
-rwxr-xr-xtools/testing/selftests/firmware/fw_filesystem.sh25
-rwxr-xr-xtools/testing/selftests/firmware/fw_userhelper.sh99
-rw-r--r--tools/testing/selftests/ftrace/Makefile6
-rw-r--r--tools/testing/selftests/futex/Makefile21
-rw-r--r--tools/testing/selftests/futex/functional/Makefile17
-rw-r--r--tools/testing/selftests/futex/include/logging.h1
-rw-r--r--tools/testing/selftests/gpio/.gitignore1
-rw-r--r--tools/testing/selftests/intel_pstate/Makefile13
-rw-r--r--tools/testing/selftests/intel_pstate/aperf.c2
-rw-r--r--tools/testing/selftests/ipc/.gitignore1
-rw-r--r--tools/testing/selftests/ipc/Makefile7
-rw-r--r--tools/testing/selftests/kcmp/Makefile6
-rw-r--r--tools/testing/selftests/lib.mk40
-rwxr-xr-xtools/testing/selftests/lib/prime_numbers.sh15
-rw-r--r--tools/testing/selftests/membarrier/Makefile6
-rw-r--r--tools/testing/selftests/memfd/Makefile15
-rw-r--r--tools/testing/selftests/mount/Makefile7
-rw-r--r--tools/testing/selftests/mqueue/Makefile6
-rw-r--r--tools/testing/selftests/net/Makefile15
-rw-r--r--tools/testing/selftests/net/psock_lib.h39
-rw-r--r--tools/testing/selftests/net/psock_tpacket.c97
-rw-r--r--tools/testing/selftests/nsfs/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/Makefile14
-rw-r--r--tools/testing/selftests/powerpc/alignment/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/benchmarks/Makefile17
-rw-r--r--tools/testing/selftests/powerpc/context_switch/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/copyloops/Makefile19
-rw-r--r--tools/testing/selftests/powerpc/dscr/Makefile13
-rw-r--r--tools/testing/selftests/powerpc/harness.c6
-rw-r--r--tools/testing/selftests/powerpc/include/vsx_asm.h48
-rw-r--r--tools/testing/selftests/powerpc/math/Makefile29
-rw-r--r--tools/testing/selftests/powerpc/mm/Makefile18
-rw-r--r--tools/testing/selftests/powerpc/pmu/Makefile26
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/Makefile15
-rw-r--r--tools/testing/selftests/powerpc/primitives/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/stringloops/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/Makefile17
-rw-r--r--tools/testing/selftests/powerpc/syscalls/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile18
-rw-r--r--tools/testing/selftests/powerpc/vphn/Makefile10
-rw-r--r--tools/testing/selftests/pstore/Makefile4
-rw-r--r--tools/testing/selftests/ptrace/Makefile8
-rw-r--r--tools/testing/selftests/seccomp/Makefile6
-rw-r--r--tools/testing/selftests/sigaltstack/Makefile5
-rw-r--r--tools/testing/selftests/sigaltstack/sas.c7
-rw-r--r--tools/testing/selftests/size/Makefile10
-rw-r--r--tools/testing/selftests/splice/Makefile8
-rw-r--r--tools/testing/selftests/splice/default_file_splice_read.c8
-rwxr-xr-xtools/testing/selftests/splice/default_file_splice_read.sh7
-rw-r--r--tools/testing/selftests/timers/Makefile10
-rw-r--r--tools/testing/selftests/vm/Makefile54
-rwxr-xr-xtools/testing/selftests/vm/run_vmtests24
-rw-r--r--tools/testing/selftests/vm/userfaultfd.c484
-rw-r--r--tools/testing/selftests/x86/Makefile19
-rw-r--r--tools/testing/selftests/x86/fsgsbase.c2
-rw-r--r--tools/testing/selftests/x86/ioperm.c170
-rw-r--r--tools/testing/selftests/x86/ldt_gdt.c16
-rw-r--r--tools/testing/selftests/x86/protection_keys.c19
-rw-r--r--tools/testing/selftests/x86/ptrace_syscall.c3
-rw-r--r--tools/testing/selftests/x86/single_step_syscall.c5
-rw-r--r--tools/testing/selftests/zram/Makefile3
-rw-r--r--tools/usb/ffs-test.c52
-rw-r--r--tools/usb/usbip/README57
-rwxr-xr-xtools/usb/usbip/vudc/vudc_server_example.sh107
-rw-r--r--tools/vm/Makefile8
212 files changed, 8075 insertions, 2419 deletions
diff --git a/tools/build/Makefile b/tools/build/Makefile
index aaf7ed329a45..477f00eda591 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -35,8 +35,8 @@ all: $(OUTPUT)fixdep
35 35
36clean: 36clean:
37 $(call QUIET_CLEAN, fixdep) 37 $(call QUIET_CLEAN, fixdep)
38 $(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 38 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
39 $(Q)rm -f fixdep 39 $(Q)rm -f $(OUTPUT)fixdep
40 40
41$(OUTPUT)fixdep-in.o: FORCE 41$(OUTPUT)fixdep-in.o: FORCE
42 $(Q)$(MAKE) $(build)=fixdep 42 $(Q)$(MAKE) $(build)=fixdep
diff --git a/tools/build/Makefile.include b/tools/build/Makefile.include
index ad22e4e7bc59..d360f39a445b 100644
--- a/tools/build/Makefile.include
+++ b/tools/build/Makefile.include
@@ -3,4 +3,7 @@ build := -f $(srctree)/tools/build/Makefile.build dir=. obj
3fixdep: 3fixdep:
4 $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep 4 $(Q)$(MAKE) -C $(srctree)/tools/build CFLAGS= LDFLAGS= $(OUTPUT)fixdep
5 5
6fixdep-clean:
7 $(Q)$(MAKE) -C $(srctree)/tools/build clean
8
6.PHONY: fixdep 9.PHONY: fixdep
diff --git a/tools/gpio/.gitignore b/tools/gpio/.gitignore
new file mode 100644
index 000000000000..9e9dd4b681b2
--- /dev/null
+++ b/tools/gpio/.gitignore
@@ -0,0 +1,4 @@
1gpio-event-mon
2gpio-hammer
3lsgpio
4
diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c
index f1eab587dfea..4bcb234c0fca 100644
--- a/tools/gpio/gpio-hammer.c
+++ b/tools/gpio/gpio-hammer.c
@@ -38,7 +38,7 @@ int hammer_device(const char *device_name, unsigned int *lines, int nlines,
38 memset(&data.values, 0, sizeof(data.values)); 38 memset(&data.values, 0, sizeof(data.values));
39 ret = gpiotools_request_linehandle(device_name, lines, nlines, 39 ret = gpiotools_request_linehandle(device_name, lines, nlines,
40 GPIOHANDLE_REQUEST_OUTPUT, &data, 40 GPIOHANDLE_REQUEST_OUTPUT, &data,
41 "gpio-hammler"); 41 "gpio-hammer");
42 if (ret < 0) 42 if (ret < 0)
43 goto exit_error; 43 goto exit_error;
44 else 44 else
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index d9b7e0f306c6..b61245e1181d 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -57,6 +57,7 @@ static const char * const iio_chan_type_name_spec[] = {
57 [IIO_RESISTANCE] = "resistance", 57 [IIO_RESISTANCE] = "resistance",
58 [IIO_PH] = "ph", 58 [IIO_PH] = "ph",
59 [IIO_UVINDEX] = "uvindex", 59 [IIO_UVINDEX] = "uvindex",
60 [IIO_GRAVITY] = "gravity",
60}; 61};
61 62
62static const char * const iio_ev_type_text[] = { 63static const char * const iio_ev_type_text[] = {
@@ -149,6 +150,7 @@ static bool event_is_known(struct iio_event_data *event)
149 case IIO_RESISTANCE: 150 case IIO_RESISTANCE:
150 case IIO_PH: 151 case IIO_PH:
151 case IIO_UVINDEX: 152 case IIO_UVINDEX:
153 case IIO_GRAVITY:
152 break; 154 break;
153 default: 155 default:
154 return false; 156 return false;
diff --git a/tools/include/asm-generic/bitops/atomic.h b/tools/include/asm-generic/bitops/atomic.h
index 18663f59d72f..68b8c1516c5a 100644
--- a/tools/include/asm-generic/bitops/atomic.h
+++ b/tools/include/asm-generic/bitops/atomic.h
@@ -20,4 +20,7 @@ static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
20 (((unsigned long *)addr)[nr / __BITS_PER_LONG])) != 0; 20 (((unsigned long *)addr)[nr / __BITS_PER_LONG])) != 0;
21} 21}
22 22
23#define __set_bit(nr, addr) set_bit(nr, addr)
24#define __clear_bit(nr, addr) clear_bit(nr, addr)
25
23#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ */ 26#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ */
diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h
index beda1a884b50..4790f047a89c 100644
--- a/tools/include/asm/bug.h
+++ b/tools/include/asm/bug.h
@@ -12,6 +12,14 @@
12 unlikely(__ret_warn_on); \ 12 unlikely(__ret_warn_on); \
13}) 13})
14 14
15#define WARN_ON(condition) ({ \
16 int __ret_warn_on = !!(condition); \
17 if (unlikely(__ret_warn_on)) \
18 __WARN_printf("assertion failed at %s:%d\n", \
19 __FILE__, __LINE__); \
20 unlikely(__ret_warn_on); \
21})
22
15#define WARN_ON_ONCE(condition) ({ \ 23#define WARN_ON_ONCE(condition) ({ \
16 static int __warned; \ 24 static int __warned; \
17 int __ret_warn_once = !!(condition); \ 25 int __ret_warn_once = !!(condition); \
diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index eef41d500e9e..e8b9f518e36b 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -4,6 +4,7 @@
4#include <string.h> 4#include <string.h>
5#include <linux/bitops.h> 5#include <linux/bitops.h>
6#include <stdlib.h> 6#include <stdlib.h>
7#include <linux/kernel.h>
7 8
8#define DECLARE_BITMAP(name,bits) \ 9#define DECLARE_BITMAP(name,bits) \
9 unsigned long name[BITS_TO_LONGS(bits)] 10 unsigned long name[BITS_TO_LONGS(bits)]
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
index fc446343ff41..1aecad369af5 100644
--- a/tools/include/linux/bitops.h
+++ b/tools/include/linux/bitops.h
@@ -2,7 +2,6 @@
2#define _TOOLS_LINUX_BITOPS_H_ 2#define _TOOLS_LINUX_BITOPS_H_
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5#include <linux/kernel.h>
6#include <linux/compiler.h> 5#include <linux/compiler.h>
7 6
8#ifndef __WORDSIZE 7#ifndef __WORDSIZE
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index 6326ede9aece..8de163b17c0d 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -25,6 +25,8 @@
25#endif 25#endif
26 26
27#define __user 27#define __user
28#define __rcu
29#define __read_mostly
28 30
29#ifndef __attribute_const__ 31#ifndef __attribute_const__
30# define __attribute_const__ 32# define __attribute_const__
@@ -54,6 +56,8 @@
54# define unlikely(x) __builtin_expect(!!(x), 0) 56# define unlikely(x) __builtin_expect(!!(x), 0)
55#endif 57#endif
56 58
59#define uninitialized_var(x) x = *(&(x))
60
57#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) 61#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
58 62
59#include <linux/types.h> 63#include <linux/types.h>
diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h
index 41446668ccce..d5677d39c1e4 100644
--- a/tools/include/linux/log2.h
+++ b/tools/include/linux/log2.h
@@ -13,12 +13,6 @@
13#define _TOOLS_LINUX_LOG2_H 13#define _TOOLS_LINUX_LOG2_H
14 14
15/* 15/*
16 * deal with unrepresentable constant logarithms
17 */
18extern __attribute__((const, noreturn))
19int ____ilog2_NaN(void);
20
21/*
22 * non-constant log of base 2 calculators 16 * non-constant log of base 2 calculators
23 * - the arch may override these in asm/bitops.h if they can be implemented 17 * - the arch may override these in asm/bitops.h if they can be implemented
24 * more efficiently than using fls() and fls64() 18 * more efficiently than using fls() and fls64()
@@ -78,7 +72,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
78#define ilog2(n) \ 72#define ilog2(n) \
79( \ 73( \
80 __builtin_constant_p(n) ? ( \ 74 __builtin_constant_p(n) ? ( \
81 (n) < 1 ? ____ilog2_NaN() : \ 75 (n) < 2 ? 0 : \
82 (n) & (1ULL << 63) ? 63 : \ 76 (n) & (1ULL << 63) ? 63 : \
83 (n) & (1ULL << 62) ? 62 : \ 77 (n) & (1ULL << 62) ? 62 : \
84 (n) & (1ULL << 61) ? 61 : \ 78 (n) & (1ULL << 61) ? 61 : \
@@ -141,10 +135,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
141 (n) & (1ULL << 4) ? 4 : \ 135 (n) & (1ULL << 4) ? 4 : \
142 (n) & (1ULL << 3) ? 3 : \ 136 (n) & (1ULL << 3) ? 3 : \
143 (n) & (1ULL << 2) ? 2 : \ 137 (n) & (1ULL << 2) ? 2 : \
144 (n) & (1ULL << 1) ? 1 : \ 138 1 ) : \
145 (n) & (1ULL << 0) ? 0 : \
146 ____ilog2_NaN() \
147 ) : \
148 (sizeof(n) <= 4) ? \ 139 (sizeof(n) <= 4) ? \
149 __ilog2_u32(n) : \ 140 __ilog2_u32(n) : \
150 __ilog2_u64(n) \ 141 __ilog2_u64(n) \
diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h
new file mode 100644
index 000000000000..58397dcb19d6
--- /dev/null
+++ b/tools/include/linux/spinlock.h
@@ -0,0 +1,5 @@
1#define spinlock_t pthread_mutex_t
2#define DEFINE_SPINLOCK(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
3
4#define spin_lock_irqsave(x, f) (void)f, pthread_mutex_lock(x)
5#define spin_unlock_irqrestore(x, f) (void)f, pthread_mutex_unlock(x)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index d2b0ac799d03..0539a0ceef38 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -63,6 +63,12 @@ struct bpf_insn {
63 __s32 imm; /* signed immediate constant */ 63 __s32 imm; /* signed immediate constant */
64}; 64};
65 65
66/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
67struct bpf_lpm_trie_key {
68 __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
69 __u8 data[0]; /* Arbitrary size */
70};
71
66/* BPF syscall commands, see bpf(2) man-page for details. */ 72/* BPF syscall commands, see bpf(2) man-page for details. */
67enum bpf_cmd { 73enum bpf_cmd {
68 BPF_MAP_CREATE, 74 BPF_MAP_CREATE,
@@ -89,6 +95,7 @@ enum bpf_map_type {
89 BPF_MAP_TYPE_CGROUP_ARRAY, 95 BPF_MAP_TYPE_CGROUP_ARRAY,
90 BPF_MAP_TYPE_LRU_HASH, 96 BPF_MAP_TYPE_LRU_HASH,
91 BPF_MAP_TYPE_LRU_PERCPU_HASH, 97 BPF_MAP_TYPE_LRU_PERCPU_HASH,
98 BPF_MAP_TYPE_LPM_TRIE,
92}; 99};
93 100
94enum bpf_prog_type { 101enum bpf_prog_type {
@@ -437,6 +444,18 @@ union bpf_attr {
437 * @xdp_md: pointer to xdp_md 444 * @xdp_md: pointer to xdp_md
438 * @delta: An positive/negative integer to be added to xdp_md.data 445 * @delta: An positive/negative integer to be added to xdp_md.data
439 * Return: 0 on success or negative on error 446 * Return: 0 on success or negative on error
447 *
448 * int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr)
449 * Copy a NUL terminated string from unsafe address. In case the string
450 * length is smaller than size, the target is not padded with further NUL
451 * bytes. In case the string length is larger than size, just count-1
452 * bytes are copied and the last byte is set to NUL.
453 * @dst: destination address
454 * @size: maximum number of bytes to copy, including the trailing NUL
455 * @unsafe_ptr: unsafe address
456 * Return:
457 * > 0 length of the string including the trailing NUL on success
458 * < 0 error
440 */ 459 */
441#define __BPF_FUNC_MAPPER(FN) \ 460#define __BPF_FUNC_MAPPER(FN) \
442 FN(unspec), \ 461 FN(unspec), \
@@ -483,7 +502,8 @@ union bpf_attr {
483 FN(set_hash_invalid), \ 502 FN(set_hash_invalid), \
484 FN(get_numa_node_id), \ 503 FN(get_numa_node_id), \
485 FN(skb_change_head), \ 504 FN(skb_change_head), \
486 FN(xdp_adjust_head), 505 FN(xdp_adjust_head), \
506 FN(probe_read_str),
487 507
488/* integer value in 'imm' field of BPF_CALL instruction selects which helper 508/* integer value in 'imm' field of BPF_CALL instruction selects which helper
489 * function eBPF program intends to call 509 * function eBPF program intends to call
@@ -509,6 +529,7 @@ enum bpf_func_id {
509/* BPF_FUNC_l4_csum_replace flags. */ 529/* BPF_FUNC_l4_csum_replace flags. */
510#define BPF_F_PSEUDO_HDR (1ULL << 4) 530#define BPF_F_PSEUDO_HDR (1ULL << 4)
511#define BPF_F_MARK_MANGLED_0 (1ULL << 5) 531#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
532#define BPF_F_MARK_ENFORCE (1ULL << 6)
512 533
513/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */ 534/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
514#define BPF_F_INGRESS (1ULL << 0) 535#define BPF_F_INGRESS (1ULL << 0)
diff --git a/tools/include/uapi/linux/bpf_perf_event.h b/tools/include/uapi/linux/bpf_perf_event.h
new file mode 100644
index 000000000000..067427259820
--- /dev/null
+++ b/tools/include/uapi/linux/bpf_perf_event.h
@@ -0,0 +1,18 @@
1/* Copyright (c) 2016 Facebook
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
6 */
7#ifndef _UAPI__LINUX_BPF_PERF_EVENT_H__
8#define _UAPI__LINUX_BPF_PERF_EVENT_H__
9
10#include <linux/types.h>
11#include <linux/ptrace.h>
12
13struct bpf_perf_event_data {
14 struct pt_regs regs;
15 __u64 sample_period;
16};
17
18#endif /* _UAPI__LINUX_BPF_PERF_EVENT_H__ */
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 11c8d9bc762e..5d19fdf80292 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -1387,7 +1387,7 @@ static bool pci_data_iowrite(u16 port, u32 mask, u32 val)
1387 /* Allow writing to any other BAR, or expansion ROM */ 1387 /* Allow writing to any other BAR, or expansion ROM */
1388 iowrite(portoff, val, mask, &d->config_words[reg]); 1388 iowrite(portoff, val, mask, &d->config_words[reg]);
1389 return true; 1389 return true;
1390 /* We let them overide latency timer and cacheline size */ 1390 /* We let them override latency timer and cacheline size */
1391 } else if (&d->config_words[reg] == (void *)&d->config.cacheline_size) { 1391 } else if (&d->config_words[reg] == (void *)&d->config.cacheline_size) {
1392 /* Only let them change the first two fields. */ 1392 /* Only let them change the first two fields. */
1393 if (mask == 0xFFFFFFFF) 1393 if (mask == 0xFFFFFFFF)
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index e2efddf10231..1f5300e56b44 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -132,7 +132,7 @@ else
132 Q = @ 132 Q = @
133endif 133endif
134 134
135# Disable command line variables (CFLAGS) overide from top 135# Disable command line variables (CFLAGS) override from top
136# level Makefile (perf), otherwise build Makefile will get 136# level Makefile (perf), otherwise build Makefile will get
137# the same command line setup. 137# the same command line setup.
138MAKEOVERRIDES= 138MAKEOVERRIDES=
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index ae752fa4eaa7..207c2eeddab0 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -27,7 +27,7 @@
27#include "bpf.h" 27#include "bpf.h"
28 28
29/* 29/*
30 * When building perf, unistd.h is overrided. __NR_bpf is 30 * When building perf, unistd.h is overridden. __NR_bpf is
31 * required to be defined explicitly. 31 * required to be defined explicitly.
32 */ 32 */
33#ifndef __NR_bpf 33#ifndef __NR_bpf
@@ -42,13 +42,13 @@
42# endif 42# endif
43#endif 43#endif
44 44
45static __u64 ptr_to_u64(void *ptr) 45static inline __u64 ptr_to_u64(const void *ptr)
46{ 46{
47 return (__u64) (unsigned long) ptr; 47 return (__u64) (unsigned long) ptr;
48} 48}
49 49
50static int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, 50static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
51 unsigned int size) 51 unsigned int size)
52{ 52{
53 return syscall(__NR_bpf, cmd, attr, size); 53 return syscall(__NR_bpf, cmd, attr, size);
54} 54}
@@ -69,8 +69,8 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size,
69 return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); 69 return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
70} 70}
71 71
72int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns, 72int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
73 size_t insns_cnt, char *license, 73 size_t insns_cnt, const char *license,
74 __u32 kern_version, char *log_buf, size_t log_buf_sz) 74 __u32 kern_version, char *log_buf, size_t log_buf_sz)
75{ 75{
76 int fd; 76 int fd;
@@ -98,7 +98,7 @@ int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
98 return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); 98 return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
99} 99}
100 100
101int bpf_map_update_elem(int fd, void *key, void *value, 101int bpf_map_update_elem(int fd, const void *key, const void *value,
102 __u64 flags) 102 __u64 flags)
103{ 103{
104 union bpf_attr attr; 104 union bpf_attr attr;
@@ -112,7 +112,7 @@ int bpf_map_update_elem(int fd, void *key, void *value,
112 return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); 112 return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
113} 113}
114 114
115int bpf_map_lookup_elem(int fd, void *key, void *value) 115int bpf_map_lookup_elem(int fd, const void *key, void *value)
116{ 116{
117 union bpf_attr attr; 117 union bpf_attr attr;
118 118
@@ -124,7 +124,7 @@ int bpf_map_lookup_elem(int fd, void *key, void *value)
124 return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)); 124 return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
125} 125}
126 126
127int bpf_map_delete_elem(int fd, void *key) 127int bpf_map_delete_elem(int fd, const void *key)
128{ 128{
129 union bpf_attr attr; 129 union bpf_attr attr;
130 130
@@ -135,7 +135,7 @@ int bpf_map_delete_elem(int fd, void *key)
135 return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr)); 135 return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
136} 136}
137 137
138int bpf_map_get_next_key(int fd, void *key, void *next_key) 138int bpf_map_get_next_key(int fd, const void *key, void *next_key)
139{ 139{
140 union bpf_attr attr; 140 union bpf_attr attr;
141 141
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 44fb7c5f8ae6..09c3dcac0496 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -29,17 +29,17 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
29 29
30/* Recommend log buffer size */ 30/* Recommend log buffer size */
31#define BPF_LOG_BUF_SIZE 65536 31#define BPF_LOG_BUF_SIZE 65536
32int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns, 32int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
33 size_t insns_cnt, char *license, 33 size_t insns_cnt, const char *license,
34 __u32 kern_version, char *log_buf, 34 __u32 kern_version, char *log_buf,
35 size_t log_buf_sz); 35 size_t log_buf_sz);
36 36
37int bpf_map_update_elem(int fd, void *key, void *value, 37int bpf_map_update_elem(int fd, const void *key, const void *value,
38 __u64 flags); 38 __u64 flags);
39 39
40int bpf_map_lookup_elem(int fd, void *key, void *value); 40int bpf_map_lookup_elem(int fd, const void *key, void *value);
41int bpf_map_delete_elem(int fd, void *key); 41int bpf_map_delete_elem(int fd, const void *key);
42int bpf_map_get_next_key(int fd, void *key, void *next_key); 42int bpf_map_get_next_key(int fd, const void *key, void *next_key);
43int bpf_obj_pin(int fd, const char *pathname); 43int bpf_obj_pin(int fd, const char *pathname);
44int bpf_obj_get(const char *pathname); 44int bpf_obj_get(const char *pathname);
45int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type, 45int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type,
diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c
index 6d8b8f22cf55..42c15f906aac 100644
--- a/tools/lib/find_bit.c
+++ b/tools/lib/find_bit.c
@@ -34,7 +34,7 @@ static unsigned long _find_next_bit(const unsigned long *addr,
34{ 34{
35 unsigned long tmp; 35 unsigned long tmp;
36 36
37 if (!nbits || start >= nbits) 37 if (unlikely(start >= nbits))
38 return nbits; 38 return nbits;
39 39
40 tmp = addr[start / BITS_PER_LONG] ^ invert; 40 tmp = addr[start / BITS_PER_LONG] ^ invert;
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
index 47076b15eebe..9b8555ea3459 100644
--- a/tools/lib/traceevent/Makefile
+++ b/tools/lib/traceevent/Makefile
@@ -135,7 +135,7 @@ else
135 Q = @ 135 Q = @
136endif 136endif
137 137
138# Disable command line variables (CFLAGS) overide from top 138# Disable command line variables (CFLAGS) override from top
139# level Makefile (perf), otherwise build Makefile will get 139# level Makefile (perf), otherwise build Makefile will get
140# the same command line setup. 140# the same command line setup.
141MAKEOVERRIDES= 141MAKEOVERRIDES=
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 14a4f623c1a5..7ce724fc0544 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -831,6 +831,7 @@ static void free_arg(struct print_arg *arg)
831 free_flag_sym(arg->symbol.symbols); 831 free_flag_sym(arg->symbol.symbols);
832 break; 832 break;
833 case PRINT_HEX: 833 case PRINT_HEX:
834 case PRINT_HEX_STR:
834 free_arg(arg->hex.field); 835 free_arg(arg->hex.field);
835 free_arg(arg->hex.size); 836 free_arg(arg->hex.size);
836 break; 837 break;
@@ -2629,10 +2630,11 @@ out_free:
2629} 2630}
2630 2631
2631static enum event_type 2632static enum event_type
2632process_hex(struct event_format *event, struct print_arg *arg, char **tok) 2633process_hex_common(struct event_format *event, struct print_arg *arg,
2634 char **tok, enum print_arg_type type)
2633{ 2635{
2634 memset(arg, 0, sizeof(*arg)); 2636 memset(arg, 0, sizeof(*arg));
2635 arg->type = PRINT_HEX; 2637 arg->type = type;
2636 2638
2637 if (alloc_and_process_delim(event, ",", &arg->hex.field)) 2639 if (alloc_and_process_delim(event, ",", &arg->hex.field))
2638 goto out; 2640 goto out;
@@ -2651,6 +2653,19 @@ out:
2651} 2653}
2652 2654
2653static enum event_type 2655static enum event_type
2656process_hex(struct event_format *event, struct print_arg *arg, char **tok)
2657{
2658 return process_hex_common(event, arg, tok, PRINT_HEX);
2659}
2660
2661static enum event_type
2662process_hex_str(struct event_format *event, struct print_arg *arg,
2663 char **tok)
2664{
2665 return process_hex_common(event, arg, tok, PRINT_HEX_STR);
2666}
2667
2668static enum event_type
2654process_int_array(struct event_format *event, struct print_arg *arg, char **tok) 2669process_int_array(struct event_format *event, struct print_arg *arg, char **tok)
2655{ 2670{
2656 memset(arg, 0, sizeof(*arg)); 2671 memset(arg, 0, sizeof(*arg));
@@ -3009,6 +3024,10 @@ process_function(struct event_format *event, struct print_arg *arg,
3009 free_token(token); 3024 free_token(token);
3010 return process_hex(event, arg, tok); 3025 return process_hex(event, arg, tok);
3011 } 3026 }
3027 if (strcmp(token, "__print_hex_str") == 0) {
3028 free_token(token);
3029 return process_hex_str(event, arg, tok);
3030 }
3012 if (strcmp(token, "__print_array") == 0) { 3031 if (strcmp(token, "__print_array") == 0) {
3013 free_token(token); 3032 free_token(token);
3014 return process_int_array(event, arg, tok); 3033 return process_int_array(event, arg, tok);
@@ -3547,6 +3566,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
3547 case PRINT_SYMBOL: 3566 case PRINT_SYMBOL:
3548 case PRINT_INT_ARRAY: 3567 case PRINT_INT_ARRAY:
3549 case PRINT_HEX: 3568 case PRINT_HEX:
3569 case PRINT_HEX_STR:
3550 break; 3570 break;
3551 case PRINT_TYPE: 3571 case PRINT_TYPE:
3552 val = eval_num_arg(data, size, event, arg->typecast.item); 3572 val = eval_num_arg(data, size, event, arg->typecast.item);
@@ -3962,6 +3982,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3962 } 3982 }
3963 break; 3983 break;
3964 case PRINT_HEX: 3984 case PRINT_HEX:
3985 case PRINT_HEX_STR:
3965 if (arg->hex.field->type == PRINT_DYNAMIC_ARRAY) { 3986 if (arg->hex.field->type == PRINT_DYNAMIC_ARRAY) {
3966 unsigned long offset; 3987 unsigned long offset;
3967 offset = pevent_read_number(pevent, 3988 offset = pevent_read_number(pevent,
@@ -3981,7 +4002,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
3981 } 4002 }
3982 len = eval_num_arg(data, size, event, arg->hex.size); 4003 len = eval_num_arg(data, size, event, arg->hex.size);
3983 for (i = 0; i < len; i++) { 4004 for (i = 0; i < len; i++) {
3984 if (i) 4005 if (i && arg->type == PRINT_HEX)
3985 trace_seq_putc(s, ' '); 4006 trace_seq_putc(s, ' ');
3986 trace_seq_printf(s, "%02x", hex[i]); 4007 trace_seq_printf(s, "%02x", hex[i]);
3987 } 4008 }
@@ -5204,13 +5225,13 @@ int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec)
5204} 5225}
5205 5226
5206/** 5227/**
5207 * pevent_data_prempt_count - parse the preempt count from the record 5228 * pevent_data_preempt_count - parse the preempt count from the record
5208 * @pevent: a handle to the pevent 5229 * @pevent: a handle to the pevent
5209 * @rec: the record to parse 5230 * @rec: the record to parse
5210 * 5231 *
5211 * This returns the preempt count from a record. 5232 * This returns the preempt count from a record.
5212 */ 5233 */
5213int pevent_data_prempt_count(struct pevent *pevent, struct pevent_record *rec) 5234int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec)
5214{ 5235{
5215 return parse_common_pc(pevent, rec->data); 5236 return parse_common_pc(pevent, rec->data);
5216} 5237}
@@ -5727,6 +5748,13 @@ static void print_args(struct print_arg *args)
5727 print_args(args->hex.size); 5748 print_args(args->hex.size);
5728 printf(")"); 5749 printf(")");
5729 break; 5750 break;
5751 case PRINT_HEX_STR:
5752 printf("__print_hex_str(");
5753 print_args(args->hex.field);
5754 printf(", ");
5755 print_args(args->hex.size);
5756 printf(")");
5757 break;
5730 case PRINT_INT_ARRAY: 5758 case PRINT_INT_ARRAY:
5731 printf("__print_array("); 5759 printf("__print_array(");
5732 print_args(args->int_array.field); 5760 print_args(args->int_array.field);
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 7aae746ec2fe..0c03538df74c 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -140,7 +140,7 @@ struct pevent_plugin_option {
140 * struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = { 140 * struct pevent_plugin_option PEVENT_PLUGIN_OPTIONS[] = {
141 * { 141 * {
142 * .name = "option-name", 142 * .name = "option-name",
143 * .plugin_alias = "overide-file-name", (optional) 143 * .plugin_alias = "override-file-name", (optional)
144 * .description = "description of option to show users", 144 * .description = "description of option to show users",
145 * }, 145 * },
146 * { 146 * {
@@ -292,6 +292,7 @@ enum print_arg_type {
292 PRINT_FUNC, 292 PRINT_FUNC,
293 PRINT_BITMASK, 293 PRINT_BITMASK,
294 PRINT_DYNAMIC_ARRAY_LEN, 294 PRINT_DYNAMIC_ARRAY_LEN,
295 PRINT_HEX_STR,
295}; 296};
296 297
297struct print_arg { 298struct print_arg {
@@ -709,7 +710,7 @@ void pevent_data_lat_fmt(struct pevent *pevent,
709int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); 710int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
710struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); 711struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type);
711int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); 712int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec);
712int pevent_data_prempt_count(struct pevent *pevent, struct pevent_record *rec); 713int pevent_data_preempt_count(struct pevent *pevent, struct pevent_record *rec);
713int pevent_data_flags(struct pevent *pevent, struct pevent_record *rec); 714int pevent_data_flags(struct pevent *pevent, struct pevent_record *rec);
714const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); 715const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid);
715struct cmdline; 716struct cmdline;
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index f7350fcedc70..a59e061c0b4a 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -31,9 +31,8 @@
31#define INSN_CALL_DYNAMIC 8 31#define INSN_CALL_DYNAMIC 8
32#define INSN_RETURN 9 32#define INSN_RETURN 9
33#define INSN_CONTEXT_SWITCH 10 33#define INSN_CONTEXT_SWITCH 10
34#define INSN_BUG 11 34#define INSN_NOP 11
35#define INSN_NOP 12 35#define INSN_OTHER 12
36#define INSN_OTHER 13
37#define INSN_LAST INSN_OTHER 36#define INSN_LAST INSN_OTHER
38 37
39int arch_decode_instruction(struct elf *elf, struct section *sec, 38int arch_decode_instruction(struct elf *elf, struct section *sec,
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 039636ffb6c8..6ac99e3266eb 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -118,9 +118,6 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
118 op2 == 0x35) 118 op2 == 0x35)
119 /* sysenter, sysret */ 119 /* sysenter, sysret */
120 *type = INSN_CONTEXT_SWITCH; 120 *type = INSN_CONTEXT_SWITCH;
121 else if (op2 == 0x0b || op2 == 0xb9)
122 /* ud2 */
123 *type = INSN_BUG;
124 else if (op2 == 0x0d || op2 == 0x1f) 121 else if (op2 == 0x0d || op2 == 0x1f)
125 /* nopl/nopw */ 122 /* nopl/nopw */
126 *type = INSN_NOP; 123 *type = INSN_NOP;
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index e8a1f699058a..066086dd59a8 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -51,7 +51,7 @@ struct instruction {
51 unsigned int len, state; 51 unsigned int len, state;
52 unsigned char type; 52 unsigned char type;
53 unsigned long immediate; 53 unsigned long immediate;
54 bool alt_group, visited; 54 bool alt_group, visited, dead_end;
55 struct symbol *call_dest; 55 struct symbol *call_dest;
56 struct instruction *jump_dest; 56 struct instruction *jump_dest;
57 struct list_head alts; 57 struct list_head alts;
@@ -330,6 +330,54 @@ static int decode_instructions(struct objtool_file *file)
330} 330}
331 331
332/* 332/*
333 * Find all uses of the unreachable() macro, which are code path dead ends.
334 */
335static int add_dead_ends(struct objtool_file *file)
336{
337 struct section *sec;
338 struct rela *rela;
339 struct instruction *insn;
340 bool found;
341
342 sec = find_section_by_name(file->elf, ".rela.discard.unreachable");
343 if (!sec)
344 return 0;
345
346 list_for_each_entry(rela, &sec->rela_list, list) {
347 if (rela->sym->type != STT_SECTION) {
348 WARN("unexpected relocation symbol type in %s", sec->name);
349 return -1;
350 }
351 insn = find_insn(file, rela->sym->sec, rela->addend);
352 if (insn)
353 insn = list_prev_entry(insn, list);
354 else if (rela->addend == rela->sym->sec->len) {
355 found = false;
356 list_for_each_entry_reverse(insn, &file->insn_list, list) {
357 if (insn->sec == rela->sym->sec) {
358 found = true;
359 break;
360 }
361 }
362
363 if (!found) {
364 WARN("can't find unreachable insn at %s+0x%x",
365 rela->sym->sec->name, rela->addend);
366 return -1;
367 }
368 } else {
369 WARN("can't find unreachable insn at %s+0x%x",
370 rela->sym->sec->name, rela->addend);
371 return -1;
372 }
373
374 insn->dead_end = true;
375 }
376
377 return 0;
378}
379
380/*
333 * Warnings shouldn't be reported for ignored functions. 381 * Warnings shouldn't be reported for ignored functions.
334 */ 382 */
335static void add_ignores(struct objtool_file *file) 383static void add_ignores(struct objtool_file *file)
@@ -757,11 +805,20 @@ static struct rela *find_switch_table(struct objtool_file *file,
757 insn->jump_dest->offset > orig_insn->offset)) 805 insn->jump_dest->offset > orig_insn->offset))
758 break; 806 break;
759 807
808 /* look for a relocation which references .rodata */
760 text_rela = find_rela_by_dest_range(insn->sec, insn->offset, 809 text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
761 insn->len); 810 insn->len);
762 if (text_rela && text_rela->sym == file->rodata->sym) 811 if (!text_rela || text_rela->sym != file->rodata->sym)
763 return find_rela_by_dest(file->rodata, 812 continue;
764 text_rela->addend); 813
814 /*
815 * Make sure the .rodata address isn't associated with a
816 * symbol. gcc jump tables are anonymous data.
817 */
818 if (find_symbol_containing(file->rodata, text_rela->addend))
819 continue;
820
821 return find_rela_by_dest(file->rodata, text_rela->addend);
765 } 822 }
766 823
767 return NULL; 824 return NULL;
@@ -843,6 +900,10 @@ static int decode_sections(struct objtool_file *file)
843 if (ret) 900 if (ret)
844 return ret; 901 return ret;
845 902
903 ret = add_dead_ends(file);
904 if (ret)
905 return ret;
906
846 add_ignores(file); 907 add_ignores(file);
847 908
848 ret = add_jump_destinations(file); 909 ret = add_jump_destinations(file);
@@ -1037,13 +1098,13 @@ static int validate_branch(struct objtool_file *file,
1037 1098
1038 return 0; 1099 return 0;
1039 1100
1040 case INSN_BUG:
1041 return 0;
1042
1043 default: 1101 default:
1044 break; 1102 break;
1045 } 1103 }
1046 1104
1105 if (insn->dead_end)
1106 return 0;
1107
1047 insn = next_insn_same_sec(file, insn); 1108 insn = next_insn_same_sec(file, insn);
1048 if (!insn) { 1109 if (!insn) {
1049 WARN("%s: unexpected end of section", sec->name); 1110 WARN("%s: unexpected end of section", sec->name);
@@ -1220,7 +1281,7 @@ int cmd_check(int argc, const char **argv)
1220 1281
1221 INIT_LIST_HEAD(&file.insn_list); 1282 INIT_LIST_HEAD(&file.insn_list);
1222 hash_init(file.insn_hash); 1283 hash_init(file.insn_hash);
1223 file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard"); 1284 file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
1224 file.rodata = find_section_by_name(file.elf, ".rodata"); 1285 file.rodata = find_section_by_name(file.elf, ".rodata");
1225 file.ignore_unreachables = false; 1286 file.ignore_unreachables = false;
1226 file.c_file = find_section_by_name(file.elf, ".comment"); 1287 file.c_file = find_section_by_name(file.elf, ".comment");
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 0d7983ac63ef..d897702ce742 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -85,6 +85,18 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
85 return NULL; 85 return NULL;
86} 86}
87 87
88struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
89{
90 struct symbol *sym;
91
92 list_for_each_entry(sym, &sec->symbol_list, list)
93 if (sym->type != STT_SECTION &&
94 offset >= sym->offset && offset < sym->offset + sym->len)
95 return sym;
96
97 return NULL;
98}
99
88struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, 100struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
89 unsigned int len) 101 unsigned int len)
90{ 102{
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index aa1ff6596684..731973e1a3f5 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -79,6 +79,7 @@ struct elf {
79struct elf *elf_open(const char *name); 79struct elf *elf_open(const char *name);
80struct section *find_section_by_name(struct elf *elf, const char *name); 80struct section *find_section_by_name(struct elf *elf, const char *name);
81struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); 81struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
82struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
82struct rela *find_rela_by_dest(struct section *sec, unsigned long offset); 83struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
83struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, 84struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
84 unsigned int len); 85 unsigned int len);
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt
index 8ffbd272952d..a89273d8e744 100644
--- a/tools/perf/Documentation/perf-annotate.txt
+++ b/tools/perf/Documentation/perf-annotate.txt
@@ -39,6 +39,10 @@ OPTIONS
39--verbose:: 39--verbose::
40 Be more verbose. (Show symbol address, etc) 40 Be more verbose. (Show symbol address, etc)
41 41
42-q::
43--quiet::
44 Do not show any message. (Suppress -v)
45
42-D:: 46-D::
43--dump-raw-trace:: 47--dump-raw-trace::
44 Dump raw trace in ASCII. 48 Dump raw trace in ASCII.
diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 66dbe3dee74b..a79c84ae61aa 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -73,6 +73,10 @@ OPTIONS
73 Be verbose, for instance, show the raw counts in addition to the 73 Be verbose, for instance, show the raw counts in addition to the
74 diff. 74 diff.
75 75
76-q::
77--quiet::
78 Do not show any message. (Suppress -v)
79
76-f:: 80-f::
77--force:: 81--force::
78 Don't do ownership validation. 82 Don't do ownership validation.
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 27256bc68eda..b16003ec14a7 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -157,7 +157,7 @@ OPTIONS
157 157
158-a:: 158-a::
159--all-cpus:: 159--all-cpus::
160 System-wide collection from all CPUs. 160 System-wide collection from all CPUs (default if no target is specified).
161 161
162-p:: 162-p::
163--pid=:: 163--pid=::
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index f2914f03ae7b..c04cc0647c16 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -25,6 +25,10 @@ OPTIONS
25--verbose:: 25--verbose::
26 Be more verbose. (show symbol address, etc) 26 Be more verbose. (show symbol address, etc)
27 27
28-q::
29--quiet::
30 Do not show any message. (Suppress -v)
31
28-n:: 32-n::
29--show-nr-samples:: 33--show-nr-samples::
30 Show the number of samples for each symbol 34 Show the number of samples for each symbol
diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index d96ccd4844df..aecf2a87e7d6 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -63,7 +63,7 @@ report::
63 63
64-a:: 64-a::
65--all-cpus:: 65--all-cpus::
66 system-wide collection from all CPUs 66 system-wide collection from all CPUs (default if no target is specified)
67 67
68-c:: 68-c::
69--scale:: 69--scale::
diff --git a/tools/perf/Documentation/tips.txt b/tools/perf/Documentation/tips.txt
index 8a6479c0eac9..170b0289a7bc 100644
--- a/tools/perf/Documentation/tips.txt
+++ b/tools/perf/Documentation/tips.txt
@@ -22,7 +22,7 @@ If you have debuginfo enabled, try: perf report -s sym,srcline
22For memory address profiling, try: perf mem record / perf mem report 22For memory address profiling, try: perf mem record / perf mem report
23For tracepoint events, try: perf report -s trace_fields 23For tracepoint events, try: perf report -s trace_fields
24To record callchains for each sample: perf record -g 24To record callchains for each sample: perf record -g
25To record every process run by an user: perf record -u <user> 25To record every process run by a user: perf record -u <user>
26Skip collecing build-id when recording: perf record -B 26Skip collecing build-id when recording: perf record -B
27To change sampling frequency to 100 Hz: perf record -F 100 27To change sampling frequency to 100 Hz: perf record -F 100
28See assembly instructions with percentage: perf annotate <symbol> 28See assembly instructions with percentage: perf annotate <symbol>
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 2b941efadb04..27c9fbca7bd9 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -175,6 +175,10 @@ PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
175PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) 175PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
176PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 176PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
177 177
178ifeq ($(CC), clang)
179 PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS))
180endif
181
178FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) 182FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS)
179FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) 183FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS)
180FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) 184FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS)
@@ -601,6 +605,9 @@ else
601 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) 605 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
602 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil 606 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil
603 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 607 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
608 ifeq ($(CC), clang)
609 PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS))
610 endif
604 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 611 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
605 612
606 ifneq ($(feature-libpython), 1) 613 ifneq ($(feature-libpython), 1)
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 4da19b6ba94a..79fe31f20a17 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -726,13 +726,13 @@ config-clean:
726 $(call QUIET_CLEAN, config) 726 $(call QUIET_CLEAN, config)
727 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null 727 $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ $(if $(OUTPUT),OUTPUT=$(OUTPUT)feature/,) clean >/dev/null
728 728
729clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean 729clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean fixdep-clean
730 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS) 730 $(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
731 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete 731 $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
732 $(Q)$(RM) $(OUTPUT).config-detected 732 $(Q)$(RM) $(OUTPUT).config-detected
733 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(OUTPUT)$(LIBJVMTI).so 733 $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32 $(OUTPUT)pmu-events/jevents $(OUTPUT)$(LIBJVMTI).so
734 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ 734 $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \
735 $(OUTPUT)util/intel-pt-decoder/inat-tables.c $(OUTPUT)fixdep \ 735 $(OUTPUT)util/intel-pt-decoder/inat-tables.c \
736 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ 736 $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \
737 $(OUTPUT)pmu-events/pmu-events.c 737 $(OUTPUT)pmu-events/pmu-events.c
738 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean 738 $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index ebb628332a6e..4f52d85f5ebc 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -410,6 +410,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
410 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 410 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
411 OPT_INCR('v', "verbose", &verbose, 411 OPT_INCR('v', "verbose", &verbose,
412 "be more verbose (show symbol address, etc)"), 412 "be more verbose (show symbol address, etc)"),
413 OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"),
413 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 414 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
414 "dump raw trace in ASCII"), 415 "dump raw trace in ASCII"),
415 OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"), 416 OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
@@ -463,6 +464,9 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
463 annotate.sym_hist_filter = argv[0]; 464 annotate.sym_hist_filter = argv[0];
464 } 465 }
465 466
467 if (quiet)
468 perf_quiet_option();
469
466 file.path = input_name; 470 file.path = input_name;
467 471
468 annotate.session = perf_session__new(&file, false, &annotate.tool); 472 annotate.session = perf_session__new(&file, false, &annotate.tool);
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 70a289347591..1b96a3122228 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -691,7 +691,7 @@ static void hists__process(struct hists *hists)
691 hists__precompute(hists); 691 hists__precompute(hists);
692 hists__output_resort(hists, NULL); 692 hists__output_resort(hists, NULL);
693 693
694 hists__fprintf(hists, true, 0, 0, 0, stdout, 694 hists__fprintf(hists, !quiet, 0, 0, 0, stdout,
695 symbol_conf.use_callchain); 695 symbol_conf.use_callchain);
696} 696}
697 697
@@ -739,12 +739,14 @@ static void data_process(void)
739 hists__link(hists_base, hists); 739 hists__link(hists_base, hists);
740 } 740 }
741 741
742 fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", 742 if (!quiet) {
743 perf_evsel__name(evsel_base)); 743 fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
744 perf_evsel__name(evsel_base));
745 }
744 746
745 first = false; 747 first = false;
746 748
747 if (verbose || data__files_cnt > 2) 749 if (verbose > 0 || ((data__files_cnt > 2) && !quiet))
748 data__fprintf(); 750 data__fprintf();
749 751
750 /* Don't sort callchain for perf diff */ 752 /* Don't sort callchain for perf diff */
@@ -807,6 +809,7 @@ static const char * const diff_usage[] = {
807static const struct option options[] = { 809static const struct option options[] = {
808 OPT_INCR('v', "verbose", &verbose, 810 OPT_INCR('v', "verbose", &verbose,
809 "be more verbose (show symbol address, etc)"), 811 "be more verbose (show symbol address, etc)"),
812 OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
810 OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, 813 OPT_BOOLEAN('b', "baseline-only", &show_baseline_only,
811 "Show only items with match in baseline"), 814 "Show only items with match in baseline"),
812 OPT_CALLBACK('c', "compute", &compute, 815 OPT_CALLBACK('c', "compute", &compute,
@@ -1328,6 +1331,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
1328 1331
1329 argc = parse_options(argc, argv, options, diff_usage, 0); 1332 argc = parse_options(argc, argv, options, diff_usage, 0);
1330 1333
1334 if (quiet)
1335 perf_quiet_option();
1336
1331 if (symbol__init(NULL) < 0) 1337 if (symbol__init(NULL) < 0)
1332 return -1; 1338 return -1;
1333 1339
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index cd7bc4d104e2..6114e07ca613 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -42,8 +42,8 @@ static int parse_record_events(const struct option *opt,
42 42
43 fprintf(stderr, "%-13s%-*s%s\n", 43 fprintf(stderr, "%-13s%-*s%s\n",
44 e->tag, 44 e->tag,
45 verbose ? 25 : 0, 45 verbose > 0 ? 25 : 0,
46 verbose ? perf_mem_events__name(j) : "", 46 verbose > 0 ? perf_mem_events__name(j) : "",
47 e->supported ? ": available" : ""); 47 e->supported ? ": available" : "");
48 } 48 }
49 exit(0); 49 exit(0);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6cd6776052e7..bc84a375295d 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -432,7 +432,7 @@ static int record__open(struct record *rec)
432try_again: 432try_again:
433 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) { 433 if (perf_evsel__open(pos, pos->cpus, pos->threads) < 0) {
434 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { 434 if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
435 if (verbose) 435 if (verbose > 0)
436 ui__warning("%s\n", msg); 436 ui__warning("%s\n", msg);
437 goto try_again; 437 goto try_again;
438 } 438 }
@@ -1677,8 +1677,12 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
1677 1677
1678 argc = parse_options(argc, argv, record_options, record_usage, 1678 argc = parse_options(argc, argv, record_options, record_usage,
1679 PARSE_OPT_STOP_AT_NON_OPTION); 1679 PARSE_OPT_STOP_AT_NON_OPTION);
1680 if (quiet)
1681 perf_quiet_option();
1682
1683 /* Make system wide (-a) the default target. */
1680 if (!argc && target__none(&rec->opts.target)) 1684 if (!argc && target__none(&rec->opts.target))
1681 usage_with_options(record_usage, record_options); 1685 rec->opts.target.system_wide = true;
1682 1686
1683 if (nr_cgroups && !rec->opts.target.system_wide) { 1687 if (nr_cgroups && !rec->opts.target.system_wide) {
1684 usage_with_options_msg(record_usage, record_options, 1688 usage_with_options_msg(record_usage, record_options,
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index dbd7fa028861..0a88670e56f3 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -320,6 +320,9 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
320 size_t size = sizeof(buf); 320 size_t size = sizeof(buf);
321 int socked_id = hists->socket_filter; 321 int socked_id = hists->socket_filter;
322 322
323 if (quiet)
324 return 0;
325
323 if (symbol_conf.filter_relative) { 326 if (symbol_conf.filter_relative) {
324 nr_samples = hists->stats.nr_non_filtered_samples; 327 nr_samples = hists->stats.nr_non_filtered_samples;
325 nr_events = hists->stats.total_non_filtered_period; 328 nr_events = hists->stats.total_non_filtered_period;
@@ -372,7 +375,11 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
372{ 375{
373 struct perf_evsel *pos; 376 struct perf_evsel *pos;
374 377
375 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n", evlist->stats.total_lost_samples); 378 if (!quiet) {
379 fprintf(stdout, "#\n# Total Lost Samples: %" PRIu64 "\n#\n",
380 evlist->stats.total_lost_samples);
381 }
382
376 evlist__for_each_entry(evlist, pos) { 383 evlist__for_each_entry(evlist, pos) {
377 struct hists *hists = evsel__hists(pos); 384 struct hists *hists = evsel__hists(pos);
378 const char *evname = perf_evsel__name(pos); 385 const char *evname = perf_evsel__name(pos);
@@ -382,7 +389,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
382 continue; 389 continue;
383 390
384 hists__fprintf_nr_sample_events(hists, rep, evname, stdout); 391 hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
385 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout, 392 hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout,
386 symbol_conf.use_callchain); 393 symbol_conf.use_callchain);
387 fprintf(stdout, "\n\n"); 394 fprintf(stdout, "\n\n");
388 } 395 }
@@ -716,6 +723,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
716 "input file name"), 723 "input file name"),
717 OPT_INCR('v', "verbose", &verbose, 724 OPT_INCR('v', "verbose", &verbose,
718 "be more verbose (show symbol address, etc)"), 725 "be more verbose (show symbol address, etc)"),
726 OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any message"),
719 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 727 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
720 "dump raw trace in ASCII"), 728 "dump raw trace in ASCII"),
721 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 729 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
@@ -863,6 +871,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
863 report.symbol_filter_str = argv[0]; 871 report.symbol_filter_str = argv[0];
864 } 872 }
865 873
874 if (quiet)
875 perf_quiet_option();
876
866 if (symbol_conf.vmlinux_name && 877 if (symbol_conf.vmlinux_name &&
867 access(symbol_conf.vmlinux_name, R_OK)) { 878 access(symbol_conf.vmlinux_name, R_OK)) {
868 pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name); 879 pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name);
@@ -983,14 +994,14 @@ repeat:
983 goto error; 994 goto error;
984 } 995 }
985 996
986 if (report.header || report.header_only) { 997 if ((report.header || report.header_only) && !quiet) {
987 perf_session__fprintf_info(session, stdout, 998 perf_session__fprintf_info(session, stdout,
988 report.show_full_info); 999 report.show_full_info);
989 if (report.header_only) { 1000 if (report.header_only) {
990 ret = 0; 1001 ret = 0;
991 goto error; 1002 goto error;
992 } 1003 }
993 } else if (use_browser == 0) { 1004 } else if (use_browser == 0 && !quiet) {
994 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n", 1005 fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
995 stdout); 1006 stdout);
996 } 1007 }
@@ -1009,7 +1020,7 @@ repeat:
1009 * providing it only in verbose mode not to bloat too 1020 * providing it only in verbose mode not to bloat too
1010 * much struct symbol. 1021 * much struct symbol.
1011 */ 1022 */
1012 if (verbose) { 1023 if (verbose > 0) {
1013 /* 1024 /*
1014 * XXX: Need to provide a less kludgy way to ask for 1025 * XXX: Need to provide a less kludgy way to ask for
1015 * more space per symbol, the u32 is for the index on 1026 * more space per symbol, the u32 is for the index on
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 270eb2d8ca6b..b94cf0de715a 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -460,7 +460,7 @@ static struct task_desc *register_pid(struct perf_sched *sched,
460 BUG_ON(!sched->tasks); 460 BUG_ON(!sched->tasks);
461 sched->tasks[task->nr] = task; 461 sched->tasks[task->nr] = task;
462 462
463 if (verbose) 463 if (verbose > 0)
464 printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm); 464 printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm);
465 465
466 return task; 466 return task;
@@ -794,7 +794,7 @@ replay_wakeup_event(struct perf_sched *sched,
794 const u32 pid = perf_evsel__intval(evsel, sample, "pid"); 794 const u32 pid = perf_evsel__intval(evsel, sample, "pid");
795 struct task_desc *waker, *wakee; 795 struct task_desc *waker, *wakee;
796 796
797 if (verbose) { 797 if (verbose > 0) {
798 printf("sched_wakeup event %p\n", evsel); 798 printf("sched_wakeup event %p\n", evsel);
799 799
800 printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid); 800 printf(" ... pid %d woke up %s/%d\n", sample->tid, comm, pid);
@@ -822,7 +822,7 @@ static int replay_switch_event(struct perf_sched *sched,
822 int cpu = sample->cpu; 822 int cpu = sample->cpu;
823 s64 delta; 823 s64 delta;
824 824
825 if (verbose) 825 if (verbose > 0)
826 printf("sched_switch event %p\n", evsel); 826 printf("sched_switch event %p\n", evsel);
827 827
828 if (cpu >= MAX_CPUS || cpu < 0) 828 if (cpu >= MAX_CPUS || cpu < 0)
@@ -870,7 +870,7 @@ static int replay_fork_event(struct perf_sched *sched,
870 goto out_put; 870 goto out_put;
871 } 871 }
872 872
873 if (verbose) { 873 if (verbose > 0) {
874 printf("fork event\n"); 874 printf("fork event\n");
875 printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid); 875 printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid);
876 printf("... child: %s/%d\n", thread__comm_str(child), child->tid); 876 printf("... child: %s/%d\n", thread__comm_str(child), child->tid);
@@ -1573,7 +1573,7 @@ static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1573 1573
1574 timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp)); 1574 timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp));
1575 color_fprintf(stdout, color, " %12s secs ", stimestamp); 1575 color_fprintf(stdout, color, " %12s secs ", stimestamp);
1576 if (new_shortname || (verbose && sched_in->tid)) { 1576 if (new_shortname || (verbose > 0 && sched_in->tid)) {
1577 const char *pid_color = color; 1577 const char *pid_color = color;
1578 1578
1579 if (thread__has_color(sched_in)) 1579 if (thread__has_color(sched_in))
@@ -2050,7 +2050,7 @@ static void save_task_callchain(struct perf_sched *sched,
2050 2050
2051 if (thread__resolve_callchain(thread, cursor, evsel, sample, 2051 if (thread__resolve_callchain(thread, cursor, evsel, sample,
2052 NULL, NULL, sched->max_stack + 2) != 0) { 2052 NULL, NULL, sched->max_stack + 2) != 0) {
2053 if (verbose) 2053 if (verbose > 0)
2054 error("Failed to resolve callchain. Skipping\n"); 2054 error("Failed to resolve callchain. Skipping\n");
2055 2055
2056 return; 2056 return;
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f28719178b51..13b54999ad79 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -573,7 +573,7 @@ try_again:
573 if (errno == EINVAL || errno == ENOSYS || 573 if (errno == EINVAL || errno == ENOSYS ||
574 errno == ENOENT || errno == EOPNOTSUPP || 574 errno == ENOENT || errno == EOPNOTSUPP ||
575 errno == ENXIO) { 575 errno == ENXIO) {
576 if (verbose) 576 if (verbose > 0)
577 ui__warning("%s event is not supported by the kernel.\n", 577 ui__warning("%s event is not supported by the kernel.\n",
578 perf_evsel__name(counter)); 578 perf_evsel__name(counter));
579 counter->supported = false; 579 counter->supported = false;
@@ -582,7 +582,7 @@ try_again:
582 !(counter->leader->nr_members > 1)) 582 !(counter->leader->nr_members > 1))
583 continue; 583 continue;
584 } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { 584 } else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
585 if (verbose) 585 if (verbose > 0)
586 ui__warning("%s\n", msg); 586 ui__warning("%s\n", msg);
587 goto try_again; 587 goto try_again;
588 } 588 }
@@ -1765,7 +1765,7 @@ static inline int perf_env__get_cpu(struct perf_env *env, struct cpu_map *map, i
1765 1765
1766 cpu = map->map[idx]; 1766 cpu = map->map[idx];
1767 1767
1768 if (cpu >= env->nr_cpus_online) 1768 if (cpu >= env->nr_cpus_avail)
1769 return -1; 1769 return -1;
1770 1770
1771 return cpu; 1771 return cpu;
@@ -2445,8 +2445,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
2445 } else if (big_num_opt == 0) /* User passed --no-big-num */ 2445 } else if (big_num_opt == 0) /* User passed --no-big-num */
2446 big_num = false; 2446 big_num = false;
2447 2447
2448 /* Make system wide (-a) the default target. */
2448 if (!argc && target__none(&target)) 2449 if (!argc && target__none(&target))
2449 usage_with_options(stat_usage, stat_options); 2450 target.system_wide = true;
2450 2451
2451 if (run_count < 0) { 2452 if (run_count < 0) {
2452 pr_err("Run count must be a positive number\n"); 2453 pr_err("Run count must be a positive number\n");
@@ -2538,7 +2539,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
2538 2539
2539 status = 0; 2540 status = 0;
2540 for (run_idx = 0; forever || run_idx < run_count; run_idx++) { 2541 for (run_idx = 0; forever || run_idx < run_count; run_idx++) {
2541 if (run_count != 1 && verbose) 2542 if (run_count != 1 && verbose > 0)
2542 fprintf(output, "[ perf stat: executing run #%d ... ]\n", 2543 fprintf(output, "[ perf stat: executing run #%d ... ]\n",
2543 run_idx + 1); 2544 run_idx + 1);
2544 2545
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 5a7fd7af3a6d..ab9077915763 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -871,7 +871,7 @@ try_again:
871 if (perf_evsel__open(counter, top->evlist->cpus, 871 if (perf_evsel__open(counter, top->evlist->cpus,
872 top->evlist->threads) < 0) { 872 top->evlist->threads) < 0) {
873 if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) { 873 if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
874 if (verbose) 874 if (verbose > 0)
875 ui__warning("%s\n", msg); 875 ui__warning("%s\n", msg);
876 goto try_again; 876 goto try_again;
877 } 877 }
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 40ef9b293d1b..256f1fac6f7e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1399,7 +1399,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
1399 return &trace->syscalls.table[id]; 1399 return &trace->syscalls.table[id];
1400 1400
1401out_cant_read: 1401out_cant_read:
1402 if (verbose) { 1402 if (verbose > 0) {
1403 fprintf(trace->output, "Problems reading syscall %d", id); 1403 fprintf(trace->output, "Problems reading syscall %d", id);
1404 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) 1404 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
1405 fprintf(trace->output, "(%s)", trace->syscalls.table[id].name); 1405 fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
@@ -1801,10 +1801,10 @@ static void print_location(FILE *f, struct perf_sample *sample,
1801 bool print_dso, bool print_sym) 1801 bool print_dso, bool print_sym)
1802{ 1802{
1803 1803
1804 if ((verbose || print_dso) && al->map) 1804 if ((verbose > 0 || print_dso) && al->map)
1805 fprintf(f, "%s@", al->map->dso->long_name); 1805 fprintf(f, "%s@", al->map->dso->long_name);
1806 1806
1807 if ((verbose || print_sym) && al->sym) 1807 if ((verbose > 0 || print_sym) && al->sym)
1808 fprintf(f, "%s+0x%" PRIx64, al->sym->name, 1808 fprintf(f, "%s+0x%" PRIx64, al->sym->name,
1809 al->addr - al->sym->start); 1809 al->addr - al->sym->start);
1810 else if (al->map) 1810 else if (al->map)
diff --git a/tools/perf/pmu-events/json.c b/tools/perf/pmu-events/json.c
index f67bbb0aa36e..0544398d6e2d 100644
--- a/tools/perf/pmu-events/json.c
+++ b/tools/perf/pmu-events/json.c
@@ -49,7 +49,7 @@ static char *mapfile(const char *fn, size_t *size)
49 int err; 49 int err;
50 int fd = open(fn, O_RDONLY); 50 int fd = open(fn, O_RDONLY);
51 51
52 if (fd < 0 && verbose && fn) { 52 if (fd < 0 && verbose > 0 && fn) {
53 pr_err("Error opening events file '%s': %s\n", fn, 53 pr_err("Error opening events file '%s': %s\n", fn,
54 strerror(errno)); 54 strerror(errno));
55 } 55 }
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index 28d1605b0338..88dc51f4c27b 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -144,7 +144,7 @@ static int run_dir(const char *d, const char *perf)
144 int vcnt = min(verbose, (int) sizeof(v) - 1); 144 int vcnt = min(verbose, (int) sizeof(v) - 1);
145 char cmd[3*PATH_MAX]; 145 char cmd[3*PATH_MAX];
146 146
147 if (verbose) 147 if (verbose > 0)
148 vcnt++; 148 vcnt++;
149 149
150 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s", 150 snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s",
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 37e326bfd2dc..83c4669cbc5b 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -299,7 +299,7 @@ static int run_test(struct test *test, int subtest)
299 if (!dont_fork) { 299 if (!dont_fork) {
300 pr_debug("test child forked, pid %d\n", getpid()); 300 pr_debug("test child forked, pid %d\n", getpid());
301 301
302 if (!verbose) { 302 if (verbose <= 0) {
303 int nullfd = open("/dev/null", O_WRONLY); 303 int nullfd = open("/dev/null", O_WRONLY);
304 304
305 if (nullfd >= 0) { 305 if (nullfd >= 0) {
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index ff5bc6363a79..d1f693041324 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -599,7 +599,7 @@ static int do_test_code_reading(bool try_kcore)
599 continue; 599 continue;
600 } 600 }
601 601
602 if (verbose) { 602 if (verbose > 0) {
603 char errbuf[512]; 603 char errbuf[512];
604 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); 604 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
605 pr_debug("perf_evlist__open() failed!\n%s\n", errbuf); 605 pr_debug("perf_evlist__open() failed!\n%s\n", errbuf);
diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c
index a2b5ff9bf83d..bc5982f42dc3 100644
--- a/tools/perf/tests/fdarray.c
+++ b/tools/perf/tests/fdarray.c
@@ -19,7 +19,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE
19{ 19{
20 int printed = 0; 20 int printed = 0;
21 21
22 if (!verbose) 22 if (verbose <= 0)
23 return 0; 23 return 0;
24 24
25 printed += fprintf(fp, "\n%s: ", prefix); 25 printed += fprintf(fp, "\n%s: ", prefix);
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index d357dab72e68..482b5365e68d 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -76,7 +76,7 @@ test_llvm__fetch_bpf_obj(void **p_obj_buf,
76 * Skip this test if user's .perfconfig doesn't set [llvm] section 76 * Skip this test if user's .perfconfig doesn't set [llvm] section
77 * and clang is not found in $PATH, and this is not perf test -v 77 * and clang is not found in $PATH, and this is not perf test -v
78 */ 78 */
79 if (!force && (verbose == 0 && 79 if (!force && (verbose <= 0 &&
80 !llvm_param.user_set_param && 80 !llvm_param.user_set_param &&
81 llvm__search_clang())) { 81 llvm__search_clang())) {
82 pr_debug("No clang and no verbosive, skip this test\n"); 82 pr_debug("No clang and no verbosive, skip this test\n");
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index aa9276bfe3e9..1dc838014422 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1808,7 +1808,7 @@ static void debug_warn(const char *warn, va_list params)
1808{ 1808{
1809 char msg[1024]; 1809 char msg[1024];
1810 1810
1811 if (!verbose) 1811 if (verbose <= 0)
1812 return; 1812 return;
1813 1813
1814 vsnprintf(msg, sizeof(msg), warn, params); 1814 vsnprintf(msg, sizeof(msg), warn, params);
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 541da7a68f91..87893f3ba5f1 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -172,13 +172,13 @@ int test__PERF_RECORD(int subtest __maybe_unused)
172 172
173 err = perf_evlist__parse_sample(evlist, event, &sample); 173 err = perf_evlist__parse_sample(evlist, event, &sample);
174 if (err < 0) { 174 if (err < 0) {
175 if (verbose) 175 if (verbose > 0)
176 perf_event__fprintf(event, stderr); 176 perf_event__fprintf(event, stderr);
177 pr_debug("Couldn't parse sample\n"); 177 pr_debug("Couldn't parse sample\n");
178 goto out_delete_evlist; 178 goto out_delete_evlist;
179 } 179 }
180 180
181 if (verbose) { 181 if (verbose > 0) {
182 pr_info("%" PRIu64" %d ", sample.time, sample.cpu); 182 pr_info("%" PRIu64" %d ", sample.time, sample.cpu);
183 perf_event__fprintf(event, stderr); 183 perf_event__fprintf(event, stderr);
184 } 184 }
diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c
index 7a52834ee0d0..fa79509da535 100644
--- a/tools/perf/tests/python-use.c
+++ b/tools/perf/tests/python-use.c
@@ -15,7 +15,7 @@ int test__python_use(int subtest __maybe_unused)
15 int ret; 15 int ret;
16 16
17 if (asprintf(&cmd, "echo \"import sys ; sys.path.append('%s'); import perf\" | %s %s", 17 if (asprintf(&cmd, "echo \"import sys ; sys.path.append('%s'); import perf\" | %s %s",
18 PYTHONPATH, PYTHON, verbose ? "" : "2> /dev/null") < 0) 18 PYTHONPATH, PYTHON, verbose > 0 ? "" : "2> /dev/null") < 0)
19 return -1; 19 return -1;
20 20
21 ret = system(cmd) ? -1 : 0; 21 ret = system(cmd) ? -1 : 0;
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c
index a4a4b4625ac3..f2d2e542d0ee 100644
--- a/tools/perf/tests/thread-map.c
+++ b/tools/perf/tests/thread-map.c
@@ -109,7 +109,7 @@ int test__thread_map_remove(int subtest __maybe_unused)
109 TEST_ASSERT_VAL("failed to allocate thread_map", 109 TEST_ASSERT_VAL("failed to allocate thread_map",
110 threads); 110 threads);
111 111
112 if (verbose) 112 if (verbose > 0)
113 thread_map__fprintf(threads, stderr); 113 thread_map__fprintf(threads, stderr);
114 114
115 TEST_ASSERT_VAL("failed to remove thread", 115 TEST_ASSERT_VAL("failed to remove thread",
@@ -117,7 +117,7 @@ int test__thread_map_remove(int subtest __maybe_unused)
117 117
118 TEST_ASSERT_VAL("thread_map count != 1", threads->nr == 1); 118 TEST_ASSERT_VAL("thread_map count != 1", threads->nr == 1);
119 119
120 if (verbose) 120 if (verbose > 0)
121 thread_map__fprintf(threads, stderr); 121 thread_map__fprintf(threads, stderr);
122 122
123 TEST_ASSERT_VAL("failed to remove thread", 123 TEST_ASSERT_VAL("failed to remove thread",
@@ -125,7 +125,7 @@ int test__thread_map_remove(int subtest __maybe_unused)
125 125
126 TEST_ASSERT_VAL("thread_map count != 0", threads->nr == 0); 126 TEST_ASSERT_VAL("thread_map count != 0", threads->nr == 0);
127 127
128 if (verbose) 128 if (verbose > 0)
129 thread_map__fprintf(threads, stderr); 129 thread_map__fprintf(threads, stderr);
130 130
131 TEST_ASSERT_VAL("failed to not remove thread", 131 TEST_ASSERT_VAL("failed to not remove thread",
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 98fe69ac553c..803f893550d6 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -65,7 +65,9 @@ static int check_cpu_topology(char *path, struct cpu_map *map)
65 session = perf_session__new(&file, false, NULL); 65 session = perf_session__new(&file, false, NULL);
66 TEST_ASSERT_VAL("can't get session", session); 66 TEST_ASSERT_VAL("can't get session", session);
67 67
68 for (i = 0; i < session->header.env.nr_cpus_online; i++) { 68 for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
69 if (!cpu_map__has(map, i))
70 continue;
69 pr_debug("CPU %d, core %d, socket %d\n", i, 71 pr_debug("CPU %d, core %d, socket %d\n", i,
70 session->header.env.cpu[i].core_id, 72 session->header.env.cpu[i].core_id,
71 session->header.env.cpu[i].socket_id); 73 session->header.env.cpu[i].socket_id);
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c
index a5082331f246..862b043e5924 100644
--- a/tools/perf/tests/vmlinux-kallsyms.c
+++ b/tools/perf/tests/vmlinux-kallsyms.c
@@ -168,7 +168,7 @@ next_pair:
168 err = -1; 168 err = -1;
169 } 169 }
170 170
171 if (!verbose) 171 if (verbose <= 0)
172 goto out; 172 goto out;
173 173
174 header_printed = false; 174 header_printed = false;
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index 98a34664bb7e..9ce142de536d 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -73,7 +73,7 @@ static int map_browser__run(struct map_browser *browser)
73 73
74 if (ui_browser__show(&browser->b, browser->map->dso->long_name, 74 if (ui_browser__show(&browser->b, browser->map->dso->long_name,
75 "Press ESC to exit, %s / to search", 75 "Press ESC to exit, %s / to search",
76 verbose ? "" : "restart with -v to use") < 0) 76 verbose > 0 ? "" : "restart with -v to use") < 0)
77 return -1; 77 return -1;
78 78
79 while (1) { 79 while (1) {
@@ -81,7 +81,7 @@ static int map_browser__run(struct map_browser *browser)
81 81
82 switch (key) { 82 switch (key) {
83 case '/': 83 case '/':
84 if (verbose) 84 if (verbose > 0)
85 map_browser__search(browser); 85 map_browser__search(browser);
86 default: 86 default:
87 break; 87 break;
@@ -117,7 +117,7 @@ int map__browse(struct map *map)
117 117
118 if (maxaddr < pos->end) 118 if (maxaddr < pos->end)
119 maxaddr = pos->end; 119 maxaddr = pos->end;
120 if (verbose) { 120 if (verbose > 0) {
121 u32 *idx = symbol__browser_index(pos); 121 u32 *idx = symbol__browser_index(pos);
122 *idx = mb.b.nr_entries; 122 *idx = mb.b.nr_entries;
123 } 123 }
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 18cfcdc90356..5d632dca672a 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -648,7 +648,7 @@ unsigned int hists__sort_list_width(struct hists *hists)
648 ret += fmt->width(fmt, &dummy_hpp, hists); 648 ret += fmt->width(fmt, &dummy_hpp, hists);
649 } 649 }
650 650
651 if (verbose && hists__has(hists, sym)) /* Addr + origin */ 651 if (verbose > 0 && hists__has(hists, sym)) /* Addr + origin */
652 ret += 3 + BITS_PER_LONG / 4; 652 ret += 3 + BITS_PER_LONG / 4;
653 653
654 return ret; 654 return ret;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 06cc04e5806a..273f21fa32b5 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1768,7 +1768,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
1768 printf("%-*.*s----\n", 1768 printf("%-*.*s----\n",
1769 graph_dotted_len, graph_dotted_len, graph_dotted_line); 1769 graph_dotted_len, graph_dotted_len, graph_dotted_line);
1770 1770
1771 if (verbose) 1771 if (verbose > 0)
1772 symbol__annotate_hits(sym, evsel); 1772 symbol__annotate_hits(sym, evsel);
1773 1773
1774 list_for_each_entry(pos, &notes->src->source, node) { 1774 list_for_each_entry(pos, &notes->src->source, node) {
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
index 8fdee24725a7..eafbf11442b2 100644
--- a/tools/perf/util/cgroup.c
+++ b/tools/perf/util/cgroup.c
@@ -12,8 +12,8 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen)
12{ 12{
13 FILE *fp; 13 FILE *fp;
14 char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1]; 14 char mountpoint[PATH_MAX + 1], tokens[PATH_MAX + 1], type[PATH_MAX + 1];
15 char path_v1[PATH_MAX + 1], path_v2[PATH_MAX + 2], *path;
15 char *token, *saved_ptr = NULL; 16 char *token, *saved_ptr = NULL;
16 int found = 0;
17 17
18 fp = fopen("/proc/mounts", "r"); 18 fp = fopen("/proc/mounts", "r");
19 if (!fp) 19 if (!fp)
@@ -24,31 +24,43 @@ cgroupfs_find_mountpoint(char *buf, size_t maxlen)
24 * and inspect every cgroupfs mount point to find one that has 24 * and inspect every cgroupfs mount point to find one that has
25 * perf_event subsystem 25 * perf_event subsystem
26 */ 26 */
27 path_v1[0] = '\0';
28 path_v2[0] = '\0';
29
27 while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %" 30 while (fscanf(fp, "%*s %"STR(PATH_MAX)"s %"STR(PATH_MAX)"s %"
28 STR(PATH_MAX)"s %*d %*d\n", 31 STR(PATH_MAX)"s %*d %*d\n",
29 mountpoint, type, tokens) == 3) { 32 mountpoint, type, tokens) == 3) {
30 33
31 if (!strcmp(type, "cgroup")) { 34 if (!path_v1[0] && !strcmp(type, "cgroup")) {
32 35
33 token = strtok_r(tokens, ",", &saved_ptr); 36 token = strtok_r(tokens, ",", &saved_ptr);
34 37
35 while (token != NULL) { 38 while (token != NULL) {
36 if (!strcmp(token, "perf_event")) { 39 if (!strcmp(token, "perf_event")) {
37 found = 1; 40 strcpy(path_v1, mountpoint);
38 break; 41 break;
39 } 42 }
40 token = strtok_r(NULL, ",", &saved_ptr); 43 token = strtok_r(NULL, ",", &saved_ptr);
41 } 44 }
42 } 45 }
43 if (found) 46
47 if (!path_v2[0] && !strcmp(type, "cgroup2"))
48 strcpy(path_v2, mountpoint);
49
50 if (path_v1[0] && path_v2[0])
44 break; 51 break;
45 } 52 }
46 fclose(fp); 53 fclose(fp);
47 if (!found) 54
55 if (path_v1[0])
56 path = path_v1;
57 else if (path_v2[0])
58 path = path_v2;
59 else
48 return -1; 60 return -1;
49 61
50 if (strlen(mountpoint) < maxlen) { 62 if (strlen(path) < maxlen) {
51 strcpy(buf, mountpoint); 63 strcpy(buf, path);
52 return 0; 64 return 0;
53 } 65 }
54 return -1; 66 return -1;
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 2c0b52264a46..8c7504939113 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -9,6 +9,7 @@
9#include "asm/bug.h" 9#include "asm/bug.h"
10 10
11static int max_cpu_num; 11static int max_cpu_num;
12static int max_present_cpu_num;
12static int max_node_num; 13static int max_node_num;
13static int *cpunode_map; 14static int *cpunode_map;
14 15
@@ -442,6 +443,7 @@ static void set_max_cpu_num(void)
442 443
443 /* set up default */ 444 /* set up default */
444 max_cpu_num = 4096; 445 max_cpu_num = 4096;
446 max_present_cpu_num = 4096;
445 447
446 mnt = sysfs__mountpoint(); 448 mnt = sysfs__mountpoint();
447 if (!mnt) 449 if (!mnt)
@@ -455,6 +457,17 @@ static void set_max_cpu_num(void)
455 } 457 }
456 458
457 ret = get_max_num(path, &max_cpu_num); 459 ret = get_max_num(path, &max_cpu_num);
460 if (ret)
461 goto out;
462
463 /* get the highest present cpu number for a sparse allocation */
464 ret = snprintf(path, PATH_MAX, "%s/devices/system/cpu/present", mnt);
465 if (ret == PATH_MAX) {
466 pr_err("sysfs path crossed PATH_MAX(%d) size\n", PATH_MAX);
467 goto out;
468 }
469
470 ret = get_max_num(path, &max_present_cpu_num);
458 471
459out: 472out:
460 if (ret) 473 if (ret)
@@ -505,6 +518,15 @@ int cpu__max_cpu(void)
505 return max_cpu_num; 518 return max_cpu_num;
506} 519}
507 520
521int cpu__max_present_cpu(void)
522{
523 if (unlikely(!max_present_cpu_num))
524 set_max_cpu_num();
525
526 return max_present_cpu_num;
527}
528
529
508int cpu__get_node(int cpu) 530int cpu__get_node(int cpu)
509{ 531{
510 if (unlikely(cpunode_map == NULL)) { 532 if (unlikely(cpunode_map == NULL)) {
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 06bd689f5989..1a0549af8f5c 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -62,6 +62,7 @@ int cpu__setup_cpunode_map(void);
62 62
63int cpu__max_node(void); 63int cpu__max_node(void);
64int cpu__max_cpu(void); 64int cpu__max_cpu(void);
65int cpu__max_present_cpu(void);
65int cpu__get_node(int cpu); 66int cpu__get_node(int cpu);
66 67
67int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, 68int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
index c1838b643108..03eb81f30d0d 100644
--- a/tools/perf/util/debug.c
+++ b/tools/perf/util/debug.c
@@ -203,11 +203,28 @@ int perf_debug_option(const char *str)
203 v = (v < 0) || (v > 10) ? 0 : v; 203 v = (v < 0) || (v > 10) ? 0 : v;
204 } 204 }
205 205
206 if (quiet)
207 v = -1;
208
206 *var->ptr = v; 209 *var->ptr = v;
207 free(s); 210 free(s);
208 return 0; 211 return 0;
209} 212}
210 213
214int perf_quiet_option(void)
215{
216 struct debug_variable *var = &debug_variables[0];
217
218 /* disable all debug messages */
219 while (var->name) {
220 *var->ptr = -1;
221 var++;
222 }
223
224 quiet = true;
225 return 0;
226}
227
211#define DEBUG_WRAPPER(__n, __l) \ 228#define DEBUG_WRAPPER(__n, __l) \
212static int pr_ ## __n ## _wrapper(const char *fmt, ...) \ 229static int pr_ ## __n ## _wrapper(const char *fmt, ...) \
213{ \ 230{ \
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index d242adc3d5a2..98832f5531d3 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -54,5 +54,6 @@ int veprintf(int level, int var, const char *fmt, va_list args);
54 54
55int perf_debug_option(const char *str); 55int perf_debug_option(const char *str);
56void perf_debug_setup(void); 56void perf_debug_setup(void);
57int perf_quiet_option(void);
57 58
58#endif /* __PERF_DEBUG_H */ 59#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 28d41e709128..d38b62a700ca 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -951,7 +951,7 @@ static struct dso *__dso__findlink_by_longname(struct rb_root *root,
951 if (rc == 0) { 951 if (rc == 0) {
952 /* 952 /*
953 * In case the new DSO is a duplicate of an existing 953 * In case the new DSO is a duplicate of an existing
954 * one, print an one-time warning & put the new entry 954 * one, print a one-time warning & put the new entry
955 * at the end of the list of duplicates. 955 * at the end of the list of duplicates.
956 */ 956 */
957 if (!dso || (dso == this)) 957 if (!dso || (dso == this))
@@ -1058,7 +1058,7 @@ int dso__name_len(const struct dso *dso)
1058{ 1058{
1059 if (!dso) 1059 if (!dso)
1060 return strlen("[unknown]"); 1060 return strlen("[unknown]");
1061 if (verbose) 1061 if (verbose > 0)
1062 return dso->long_name_len; 1062 return dso->long_name_len;
1063 1063
1064 return dso->short_name_len; 1064 return dso->short_name_len;
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index bb964e86b09d..075fc77286bf 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -66,7 +66,7 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
66 return 0; 66 return 0;
67 67
68 if (env->nr_cpus_avail == 0) 68 if (env->nr_cpus_avail == 0)
69 env->nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF); 69 env->nr_cpus_avail = cpu__max_present_cpu();
70 70
71 nr_cpus = env->nr_cpus_avail; 71 nr_cpus = env->nr_cpus_avail;
72 if (nr_cpus == -1) 72 if (nr_cpus == -1)
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 3d12c16e5103..05714d548584 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -295,11 +295,7 @@ static int write_nrcpus(int fd, struct perf_header *h __maybe_unused,
295 u32 nrc, nra; 295 u32 nrc, nra;
296 int ret; 296 int ret;
297 297
298 nr = sysconf(_SC_NPROCESSORS_CONF); 298 nrc = cpu__max_present_cpu();
299 if (nr < 0)
300 return -1;
301
302 nrc = (u32)(nr & UINT_MAX);
303 299
304 nr = sysconf(_SC_NPROCESSORS_ONLN); 300 nr = sysconf(_SC_NPROCESSORS_ONLN);
305 if (nr < 0) 301 if (nr < 0)
@@ -505,24 +501,29 @@ static void free_cpu_topo(struct cpu_topo *tp)
505 501
506static struct cpu_topo *build_cpu_topology(void) 502static struct cpu_topo *build_cpu_topology(void)
507{ 503{
508 struct cpu_topo *tp; 504 struct cpu_topo *tp = NULL;
509 void *addr; 505 void *addr;
510 u32 nr, i; 506 u32 nr, i;
511 size_t sz; 507 size_t sz;
512 long ncpus; 508 long ncpus;
513 int ret = -1; 509 int ret = -1;
510 struct cpu_map *map;
514 511
515 ncpus = sysconf(_SC_NPROCESSORS_CONF); 512 ncpus = cpu__max_present_cpu();
516 if (ncpus < 0) 513
514 /* build online CPU map */
515 map = cpu_map__new(NULL);
516 if (map == NULL) {
517 pr_debug("failed to get system cpumap\n");
517 return NULL; 518 return NULL;
519 }
518 520
519 nr = (u32)(ncpus & UINT_MAX); 521 nr = (u32)(ncpus & UINT_MAX);
520 522
521 sz = nr * sizeof(char *); 523 sz = nr * sizeof(char *);
522
523 addr = calloc(1, sizeof(*tp) + 2 * sz); 524 addr = calloc(1, sizeof(*tp) + 2 * sz);
524 if (!addr) 525 if (!addr)
525 return NULL; 526 goto out_free;
526 527
527 tp = addr; 528 tp = addr;
528 tp->cpu_nr = nr; 529 tp->cpu_nr = nr;
@@ -532,10 +533,16 @@ static struct cpu_topo *build_cpu_topology(void)
532 tp->thread_siblings = addr; 533 tp->thread_siblings = addr;
533 534
534 for (i = 0; i < nr; i++) { 535 for (i = 0; i < nr; i++) {
536 if (!cpu_map__has(map, i))
537 continue;
538
535 ret = build_cpu_topo(tp, i); 539 ret = build_cpu_topo(tp, i);
536 if (ret < 0) 540 if (ret < 0)
537 break; 541 break;
538 } 542 }
543
544out_free:
545 cpu_map__put(map);
539 if (ret) { 546 if (ret) {
540 free_cpu_topo(tp); 547 free_cpu_topo(tp);
541 tp = NULL; 548 tp = NULL;
@@ -1126,7 +1133,7 @@ static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
1126{ 1133{
1127 int nr, i; 1134 int nr, i;
1128 char *str; 1135 char *str;
1129 int cpu_nr = ph->env.nr_cpus_online; 1136 int cpu_nr = ph->env.nr_cpus_avail;
1130 1137
1131 nr = ph->env.nr_sibling_cores; 1138 nr = ph->env.nr_sibling_cores;
1132 str = ph->env.sibling_cores; 1139 str = ph->env.sibling_cores;
@@ -1781,7 +1788,7 @@ static int process_cpu_topology(struct perf_file_section *section,
1781 u32 nr, i; 1788 u32 nr, i;
1782 char *str; 1789 char *str;
1783 struct strbuf sb; 1790 struct strbuf sb;
1784 int cpu_nr = ph->env.nr_cpus_online; 1791 int cpu_nr = ph->env.nr_cpus_avail;
1785 u64 size = 0; 1792 u64 size = 0;
1786 1793
1787 ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); 1794 ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu));
@@ -1862,7 +1869,7 @@ static int process_cpu_topology(struct perf_file_section *section,
1862 if (ph->needs_swap) 1869 if (ph->needs_swap)
1863 nr = bswap_32(nr); 1870 nr = bswap_32(nr);
1864 1871
1865 if (nr > (u32)cpu_nr) { 1872 if (nr != (u32)-1 && nr > (u32)cpu_nr) {
1866 pr_debug("socket_id number is too big." 1873 pr_debug("socket_id number is too big."
1867 "You may need to upgrade the perf tool.\n"); 1874 "You may need to upgrade the perf tool.\n");
1868 goto free_cpu; 1875 goto free_cpu;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 32c6a939e4cc..eaf72a938fb4 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -69,7 +69,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
69 */ 69 */
70 if (h->ms.sym) { 70 if (h->ms.sym) {
71 symlen = h->ms.sym->namelen + 4; 71 symlen = h->ms.sym->namelen + 4;
72 if (verbose) 72 if (verbose > 0)
73 symlen += BITS_PER_LONG / 4 + 2 + 3; 73 symlen += BITS_PER_LONG / 4 + 2 + 3;
74 hists__new_col_len(hists, HISTC_SYMBOL, symlen); 74 hists__new_col_len(hists, HISTC_SYMBOL, symlen);
75 } else { 75 } else {
@@ -93,7 +93,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
93 if (h->branch_info) { 93 if (h->branch_info) {
94 if (h->branch_info->from.sym) { 94 if (h->branch_info->from.sym) {
95 symlen = (int)h->branch_info->from.sym->namelen + 4; 95 symlen = (int)h->branch_info->from.sym->namelen + 4;
96 if (verbose) 96 if (verbose > 0)
97 symlen += BITS_PER_LONG / 4 + 2 + 3; 97 symlen += BITS_PER_LONG / 4 + 2 + 3;
98 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); 98 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
99 99
@@ -107,7 +107,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
107 107
108 if (h->branch_info->to.sym) { 108 if (h->branch_info->to.sym) {
109 symlen = (int)h->branch_info->to.sym->namelen + 4; 109 symlen = (int)h->branch_info->to.sym->namelen + 4;
110 if (verbose) 110 if (verbose > 0)
111 symlen += BITS_PER_LONG / 4 + 2 + 3; 111 symlen += BITS_PER_LONG / 4 + 2 + 3;
112 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); 112 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
113 113
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
index 7913363bde5c..4f3c758d875d 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
@@ -31,7 +31,7 @@
31#error Instruction buffer size too small 31#error Instruction buffer size too small
32#endif 32#endif
33 33
34/* Based on branch_type() from perf_event_intel_lbr.c */ 34/* Based on branch_type() from arch/x86/events/intel/lbr.c */
35static void intel_pt_insn_decoder(struct insn *insn, 35static void intel_pt_insn_decoder(struct insn *insn,
36 struct intel_pt_insn *intel_pt_insn) 36 struct intel_pt_insn *intel_pt_insn)
37{ 37{
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 281e44af31e2..67a8aebc67ab 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -2318,24 +2318,20 @@ int parse_events__is_hardcoded_term(struct parse_events_term *term)
2318 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; 2318 return term->type_term != PARSE_EVENTS__TERM_TYPE_USER;
2319} 2319}
2320 2320
2321static int new_term(struct parse_events_term **_term, int type_val, 2321static int new_term(struct parse_events_term **_term,
2322 int type_term, char *config, 2322 struct parse_events_term *temp,
2323 char *str, u64 num, int err_term, int err_val) 2323 char *str, u64 num)
2324{ 2324{
2325 struct parse_events_term *term; 2325 struct parse_events_term *term;
2326 2326
2327 term = zalloc(sizeof(*term)); 2327 term = malloc(sizeof(*term));
2328 if (!term) 2328 if (!term)
2329 return -ENOMEM; 2329 return -ENOMEM;
2330 2330
2331 *term = *temp;
2331 INIT_LIST_HEAD(&term->list); 2332 INIT_LIST_HEAD(&term->list);
2332 term->type_val = type_val;
2333 term->type_term = type_term;
2334 term->config = config;
2335 term->err_term = err_term;
2336 term->err_val = err_val;
2337 2333
2338 switch (type_val) { 2334 switch (term->type_val) {
2339 case PARSE_EVENTS__TERM_TYPE_NUM: 2335 case PARSE_EVENTS__TERM_TYPE_NUM:
2340 term->val.num = num; 2336 term->val.num = num;
2341 break; 2337 break;
@@ -2353,15 +2349,22 @@ static int new_term(struct parse_events_term **_term, int type_val,
2353 2349
2354int parse_events_term__num(struct parse_events_term **term, 2350int parse_events_term__num(struct parse_events_term **term,
2355 int type_term, char *config, u64 num, 2351 int type_term, char *config, u64 num,
2352 bool no_value,
2356 void *loc_term_, void *loc_val_) 2353 void *loc_term_, void *loc_val_)
2357{ 2354{
2358 YYLTYPE *loc_term = loc_term_; 2355 YYLTYPE *loc_term = loc_term_;
2359 YYLTYPE *loc_val = loc_val_; 2356 YYLTYPE *loc_val = loc_val_;
2360 2357
2361 return new_term(term, PARSE_EVENTS__TERM_TYPE_NUM, type_term, 2358 struct parse_events_term temp = {
2362 config, NULL, num, 2359 .type_val = PARSE_EVENTS__TERM_TYPE_NUM,
2363 loc_term ? loc_term->first_column : 0, 2360 .type_term = type_term,
2364 loc_val ? loc_val->first_column : 0); 2361 .config = config,
2362 .no_value = no_value,
2363 .err_term = loc_term ? loc_term->first_column : 0,
2364 .err_val = loc_val ? loc_val->first_column : 0,
2365 };
2366
2367 return new_term(term, &temp, NULL, num);
2365} 2368}
2366 2369
2367int parse_events_term__str(struct parse_events_term **term, 2370int parse_events_term__str(struct parse_events_term **term,
@@ -2371,37 +2374,45 @@ int parse_events_term__str(struct parse_events_term **term,
2371 YYLTYPE *loc_term = loc_term_; 2374 YYLTYPE *loc_term = loc_term_;
2372 YYLTYPE *loc_val = loc_val_; 2375 YYLTYPE *loc_val = loc_val_;
2373 2376
2374 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, type_term, 2377 struct parse_events_term temp = {
2375 config, str, 0, 2378 .type_val = PARSE_EVENTS__TERM_TYPE_STR,
2376 loc_term ? loc_term->first_column : 0, 2379 .type_term = type_term,
2377 loc_val ? loc_val->first_column : 0); 2380 .config = config,
2381 .err_term = loc_term ? loc_term->first_column : 0,
2382 .err_val = loc_val ? loc_val->first_column : 0,
2383 };
2384
2385 return new_term(term, &temp, str, 0);
2378} 2386}
2379 2387
2380int parse_events_term__sym_hw(struct parse_events_term **term, 2388int parse_events_term__sym_hw(struct parse_events_term **term,
2381 char *config, unsigned idx) 2389 char *config, unsigned idx)
2382{ 2390{
2383 struct event_symbol *sym; 2391 struct event_symbol *sym;
2392 struct parse_events_term temp = {
2393 .type_val = PARSE_EVENTS__TERM_TYPE_STR,
2394 .type_term = PARSE_EVENTS__TERM_TYPE_USER,
2395 .config = config ?: (char *) "event",
2396 };
2384 2397
2385 BUG_ON(idx >= PERF_COUNT_HW_MAX); 2398 BUG_ON(idx >= PERF_COUNT_HW_MAX);
2386 sym = &event_symbols_hw[idx]; 2399 sym = &event_symbols_hw[idx];
2387 2400
2388 if (config) 2401 return new_term(term, &temp, (char *) sym->symbol, 0);
2389 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
2390 PARSE_EVENTS__TERM_TYPE_USER, config,
2391 (char *) sym->symbol, 0, 0, 0);
2392 else
2393 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
2394 PARSE_EVENTS__TERM_TYPE_USER,
2395 (char *) "event", (char *) sym->symbol,
2396 0, 0, 0);
2397} 2402}
2398 2403
2399int parse_events_term__clone(struct parse_events_term **new, 2404int parse_events_term__clone(struct parse_events_term **new,
2400 struct parse_events_term *term) 2405 struct parse_events_term *term)
2401{ 2406{
2402 return new_term(new, term->type_val, term->type_term, term->config, 2407 struct parse_events_term temp = {
2403 term->val.str, term->val.num, 2408 .type_val = term->type_val,
2404 term->err_term, term->err_val); 2409 .type_term = term->type_term,
2410 .config = term->config,
2411 .err_term = term->err_term,
2412 .err_val = term->err_val,
2413 };
2414
2415 return new_term(new, &temp, term->val.str, term->val.num);
2405} 2416}
2406 2417
2407void parse_events_terms__purge(struct list_head *terms) 2418void parse_events_terms__purge(struct list_head *terms)
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index da246a3ddb69..1af6a267c21b 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -94,6 +94,7 @@ struct parse_events_term {
94 int type_term; 94 int type_term;
95 struct list_head list; 95 struct list_head list;
96 bool used; 96 bool used;
97 bool no_value;
97 98
98 /* error string indexes for within parsed string */ 99 /* error string indexes for within parsed string */
99 int err_term; 100 int err_term;
@@ -122,6 +123,7 @@ void parse_events__shrink_config_terms(void);
122int parse_events__is_hardcoded_term(struct parse_events_term *term); 123int parse_events__is_hardcoded_term(struct parse_events_term *term);
123int parse_events_term__num(struct parse_events_term **term, 124int parse_events_term__num(struct parse_events_term **term,
124 int type_term, char *config, u64 num, 125 int type_term, char *config, u64 num,
126 bool novalue,
125 void *loc_term, void *loc_val); 127 void *loc_term, void *loc_val);
126int parse_events_term__str(struct parse_events_term **term, 128int parse_events_term__str(struct parse_events_term **term,
127 int type_term, char *config, char *str, 129 int type_term, char *config, char *str,
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index a14b47ab3879..30f018ea1370 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -252,7 +252,7 @@ PE_KERNEL_PMU_EVENT sep_dc
252 if (!strcasecmp(alias->name, $1)) { 252 if (!strcasecmp(alias->name, $1)) {
253 ALLOC_LIST(head); 253 ALLOC_LIST(head);
254 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 254 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
255 $1, 1, &@1, NULL)); 255 $1, 1, false, &@1, NULL));
256 list_add_tail(&term->list, head); 256 list_add_tail(&term->list, head);
257 257
258 if (!parse_events_add_pmu(data, list, 258 if (!parse_events_add_pmu(data, list,
@@ -282,7 +282,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
282 282
283 ALLOC_LIST(head); 283 ALLOC_LIST(head);
284 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 284 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
285 &pmu_name, 1, &@1, NULL)); 285 &pmu_name, 1, false, &@1, NULL));
286 list_add_tail(&term->list, head); 286 list_add_tail(&term->list, head);
287 287
288 ALLOC_LIST(list); 288 ALLOC_LIST(list);
@@ -548,7 +548,7 @@ PE_NAME '=' PE_VALUE
548 struct parse_events_term *term; 548 struct parse_events_term *term;
549 549
550 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 550 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
551 $1, $3, &@1, &@3)); 551 $1, $3, false, &@1, &@3));
552 $$ = term; 552 $$ = term;
553} 553}
554| 554|
@@ -566,7 +566,7 @@ PE_NAME
566 struct parse_events_term *term; 566 struct parse_events_term *term;
567 567
568 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 568 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
569 $1, 1, &@1, NULL)); 569 $1, 1, true, &@1, NULL));
570 $$ = term; 570 $$ = term;
571} 571}
572| 572|
@@ -591,7 +591,7 @@ PE_TERM '=' PE_VALUE
591{ 591{
592 struct parse_events_term *term; 592 struct parse_events_term *term;
593 593
594 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, &@1, &@3)); 594 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3));
595 $$ = term; 595 $$ = term;
596} 596}
597| 597|
@@ -599,7 +599,7 @@ PE_TERM
599{ 599{
600 struct parse_events_term *term; 600 struct parse_events_term *term;
601 601
602 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL)); 602 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL));
603 $$ = term; 603 $$ = term;
604} 604}
605| 605|
@@ -620,7 +620,7 @@ PE_NAME array '=' PE_VALUE
620 struct parse_events_term *term; 620 struct parse_events_term *term;
621 621
622 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 622 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
623 $1, $4, &@1, &@4)); 623 $1, $4, false, &@1, &@4));
624 term->array = $2; 624 term->array = $2;
625 $$ = term; 625 $$ = term;
626} 626}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 49bfee0e3d9e..12f84dd2ac5d 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -745,7 +745,7 @@ static int pmu_resolve_param_term(struct parse_events_term *term,
745 } 745 }
746 } 746 }
747 747
748 if (verbose) 748 if (verbose > 0)
749 printf("Required parameter '%s' not specified\n", term->config); 749 printf("Required parameter '%s' not specified\n", term->config);
750 750
751 return -1; 751 return -1;
@@ -803,7 +803,7 @@ static int pmu_config_term(struct list_head *formats,
803 803
804 format = pmu_find_format(formats, term->config); 804 format = pmu_find_format(formats, term->config);
805 if (!format) { 805 if (!format) {
806 if (verbose) 806 if (verbose > 0)
807 printf("Invalid event/parameter '%s'\n", term->config); 807 printf("Invalid event/parameter '%s'\n", term->config);
808 if (err) { 808 if (err) {
809 char *pmu_term = pmu_formats_string(formats); 809 char *pmu_term = pmu_formats_string(formats);
@@ -834,11 +834,20 @@ static int pmu_config_term(struct list_head *formats,
834 * Either directly use a numeric term, or try to translate string terms 834 * Either directly use a numeric term, or try to translate string terms
835 * using event parameters. 835 * using event parameters.
836 */ 836 */
837 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 837 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
838 if (term->no_value &&
839 bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) {
840 if (err) {
841 err->idx = term->err_val;
842 err->str = strdup("no value assigned for term");
843 }
844 return -EINVAL;
845 }
846
838 val = term->val.num; 847 val = term->val.num;
839 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 848 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
840 if (strcmp(term->val.str, "?")) { 849 if (strcmp(term->val.str, "?")) {
841 if (verbose) { 850 if (verbose > 0) {
842 pr_info("Invalid sysfs entry %s=%s\n", 851 pr_info("Invalid sysfs entry %s=%s\n",
843 term->config, term->val.str); 852 term->config, term->val.str);
844 } 853 }
@@ -1223,7 +1232,7 @@ void print_pmu_events(const char *event_glob, bool name_only, bool quiet_flag,
1223 printf("%*s", 8, "["); 1232 printf("%*s", 8, "[");
1224 wordwrap(aliases[j].desc, 8, columns, 0); 1233 wordwrap(aliases[j].desc, 8, columns, 0);
1225 printf("]\n"); 1234 printf("]\n");
1226 if (verbose) 1235 if (verbose > 0)
1227 printf("%*s%s/%s/\n", 8, "", aliases[j].pmu, aliases[j].str); 1236 printf("%*s%s/%s/\n", 8, "", aliases[j].pmu, aliases[j].str);
1228 } else 1237 } else
1229 printf(" %-50s [Kernel PMU event]\n", aliases[j].name); 1238 printf(" %-50s [Kernel PMU event]\n", aliases[j].name);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 35f5b7b7715c..28fb62c32678 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -594,7 +594,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
594 pr_debug("try to find information at %" PRIx64 " in %s\n", addr, 594 pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
595 tp->module ? : "kernel"); 595 tp->module ? : "kernel");
596 596
597 dinfo = debuginfo_cache__open(tp->module, verbose == 0); 597 dinfo = debuginfo_cache__open(tp->module, verbose <= 0);
598 if (dinfo) 598 if (dinfo)
599 ret = debuginfo__find_probe_point(dinfo, 599 ret = debuginfo__find_probe_point(dinfo,
600 (unsigned long)addr, pp); 600 (unsigned long)addr, pp);
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 0d9d6e0803b8..57cd268d4275 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -464,7 +464,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
464 /* Verify it is a data structure */ 464 /* Verify it is a data structure */
465 tag = dwarf_tag(&type); 465 tag = dwarf_tag(&type);
466 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 466 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
467 pr_warning("%s is not a data structure nor an union.\n", 467 pr_warning("%s is not a data structure nor a union.\n",
468 varname); 468 varname);
469 return -EINVAL; 469 return -EINVAL;
470 } 470 }
@@ -479,7 +479,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
479 } else { 479 } else {
480 /* Verify it is a data structure */ 480 /* Verify it is a data structure */
481 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 481 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) {
482 pr_warning("%s is not a data structure nor an union.\n", 482 pr_warning("%s is not a data structure nor a union.\n",
483 varname); 483 varname);
484 return -EINVAL; 484 return -EINVAL;
485 } 485 }
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index c1555fd0035a..dff043a29589 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -217,6 +217,7 @@ static void define_event_symbols(struct event_format *event,
217 cur_field_name); 217 cur_field_name);
218 break; 218 break;
219 case PRINT_HEX: 219 case PRINT_HEX:
220 case PRINT_HEX_STR:
220 define_event_symbols(event, ev_name, args->hex.field); 221 define_event_symbols(event, ev_name, args->hex.field);
221 define_event_symbols(event, ev_name, args->hex.size); 222 define_event_symbols(event, ev_name, args->hex.size);
222 break; 223 break;
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 089438da1f7f..783326cfbaa6 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -236,6 +236,7 @@ static void define_event_symbols(struct event_format *event,
236 cur_field_name); 236 cur_field_name);
237 break; 237 break;
238 case PRINT_HEX: 238 case PRINT_HEX:
239 case PRINT_HEX_STR:
239 define_event_symbols(event, ev_name, args->hex.field); 240 define_event_symbols(event, ev_name, args->hex.field);
240 define_event_symbols(event, ev_name, args->hex.size); 241 define_event_symbols(event, ev_name, args->hex.size);
241 break; 242 break;
@@ -368,10 +369,10 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
368 if (node->map) { 369 if (node->map) {
369 struct map *map = node->map; 370 struct map *map = node->map;
370 const char *dsoname = "[unknown]"; 371 const char *dsoname = "[unknown]";
371 if (map && map->dso && (map->dso->name || map->dso->long_name)) { 372 if (map && map->dso) {
372 if (symbol_conf.show_kernel_path && map->dso->long_name) 373 if (symbol_conf.show_kernel_path && map->dso->long_name)
373 dsoname = map->dso->long_name; 374 dsoname = map->dso->long_name;
374 else if (map->dso->name) 375 else
375 dsoname = map->dso->name; 376 dsoname = map->dso->name;
376 } 377 }
377 pydict_set_item_string_decref(pyelem, "dso", 378 pydict_set_item_string_decref(pyelem, "dso",
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4cdbc8f5f14d..1dd617d116b5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -932,7 +932,7 @@ static void branch_stack__printf(struct perf_sample *sample)
932 932
933 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n", 933 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n",
934 i, e->from, e->to, 934 i, e->from, e->to,
935 e->flags.cycles, 935 (unsigned short)e->flags.cycles,
936 e->flags.mispred ? "M" : " ", 936 e->flags.mispred ? "M" : " ",
937 e->flags.predicted ? "P" : " ", 937 e->flags.predicted ? "P" : " ",
938 e->flags.abort ? "A" : " ", 938 e->flags.abort ? "A" : " ",
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index c8680984d2d6..af415febbc46 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -1,8 +1,15 @@
1#!/usr/bin/python2 1#!/usr/bin/python2
2 2
3from distutils.core import setup, Extension
4from os import getenv 3from os import getenv
5 4
5cc = getenv("CC")
6if cc == "clang":
7 from _sysconfigdata import build_time_vars
8 from re import sub
9 build_time_vars["CFLAGS"] = sub("-specs=[^ ]+", "", build_time_vars["CFLAGS"])
10
11from distutils.core import setup, Extension
12
6from distutils.command.build_ext import build_ext as _build_ext 13from distutils.command.build_ext import build_ext as _build_ext
7from distutils.command.install_lib import install_lib as _install_lib 14from distutils.command.install_lib import install_lib as _install_lib
8 15
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index df622f4e301e..0ff622288d24 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -151,7 +151,7 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
151 if (!dso_l || !dso_r) 151 if (!dso_l || !dso_r)
152 return cmp_null(dso_r, dso_l); 152 return cmp_null(dso_r, dso_l);
153 153
154 if (verbose) { 154 if (verbose > 0) {
155 dso_name_l = dso_l->long_name; 155 dso_name_l = dso_l->long_name;
156 dso_name_r = dso_r->long_name; 156 dso_name_r = dso_r->long_name;
157 } else { 157 } else {
@@ -172,8 +172,8 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
172 size_t size, unsigned int width) 172 size_t size, unsigned int width)
173{ 173{
174 if (map && map->dso) { 174 if (map && map->dso) {
175 const char *dso_name = !verbose ? map->dso->short_name : 175 const char *dso_name = verbose > 0 ? map->dso->long_name :
176 map->dso->long_name; 176 map->dso->short_name;
177 return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); 177 return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name);
178 } 178 }
179 179
@@ -261,7 +261,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
261{ 261{
262 size_t ret = 0; 262 size_t ret = 0;
263 263
264 if (verbose) { 264 if (verbose > 0) {
265 char o = map ? dso__symtab_origin(map->dso) : '!'; 265 char o = map ? dso__symtab_origin(map->dso) : '!';
266 ret += repsep_snprintf(bf, size, "%-#*llx %c ", 266 ret += repsep_snprintf(bf, size, "%-#*llx %c ",
267 BITS_PER_LONG / 4 + 2, ip, o); 267 BITS_PER_LONG / 4 + 2, ip, o);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 7aff317fc7c4..796c847e2f00 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -108,7 +108,7 @@ struct hist_entry {
108 /* 108 /*
109 * Since perf diff only supports the stdio output, TUI 109 * Since perf diff only supports the stdio output, TUI
110 * fields are only accessed from perf report (or perf 110 * fields are only accessed from perf report (or perf
111 * top). So make it an union to reduce memory usage. 111 * top). So make it a union to reduce memory usage.
112 */ 112 */
113 struct hist_entry_diff diff; 113 struct hist_entry_diff diff;
114 struct /* for TUI */ { 114 struct /* for TUI */ {
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 39345c2ddfc2..0d51334a9b46 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -344,7 +344,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,
344 for (i = 0; i < 3; i++) 344 for (i = 0; i < 3; i++)
345 update_stats(&ps->res_stats[i], count[i]); 345 update_stats(&ps->res_stats[i], count[i]);
346 346
347 if (verbose) { 347 if (verbose > 0) {
348 fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", 348 fprintf(config->output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
349 perf_evsel__name(counter), count[0], count[1], count[2]); 349 perf_evsel__name(counter), count[0], count[1], count[2]);
350 } 350 }
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index adbc6c02c3aa..4e59ddeb4eda 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -213,7 +213,7 @@ static bool want_demangle(bool is_kernel_sym)
213 213
214static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name) 214static char *demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
215{ 215{
216 int demangle_flags = verbose ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS; 216 int demangle_flags = verbose > 0 ? (DMGL_PARAMS | DMGL_ANSI) : DMGL_NO_OPTS;
217 char *demangled = NULL; 217 char *demangled = NULL;
218 218
219 /* 219 /*
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 70e389bc4af7..9b4d8ba22fed 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -202,7 +202,7 @@ void symbols__fixup_end(struct rb_root *symbols)
202 202
203 /* Last entry */ 203 /* Last entry */
204 if (curr->end == curr->start) 204 if (curr->end == curr->start)
205 curr->end = roundup(curr->start, 4096); 205 curr->end = roundup(curr->start, 4096) + 4096;
206} 206}
207 207
208void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) 208void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c
index 590d12a25f6e..3e701f0e9c14 100644
--- a/tools/power/cpupower/utils/cpufreq-info.c
+++ b/tools/power/cpupower/utils/cpufreq-info.c
@@ -285,20 +285,24 @@ static int get_freq_hardware(unsigned int cpu, unsigned int human)
285 285
286/* --hwlimits / -l */ 286/* --hwlimits / -l */
287 287
288static int get_hardware_limits(unsigned int cpu) 288static int get_hardware_limits(unsigned int cpu, unsigned int human)
289{ 289{
290 unsigned long min, max; 290 unsigned long min, max;
291 291
292 printf(_(" hardware limits: "));
293 if (cpufreq_get_hardware_limits(cpu, &min, &max)) { 292 if (cpufreq_get_hardware_limits(cpu, &min, &max)) {
294 printf(_("Not Available\n")); 293 printf(_("Not Available\n"));
295 return -EINVAL; 294 return -EINVAL;
296 } 295 }
297 296
298 print_speed(min); 297 if (human) {
299 printf(" - "); 298 printf(_(" hardware limits: "));
300 print_speed(max); 299 print_speed(min);
301 printf("\n"); 300 printf(" - ");
301 print_speed(max);
302 printf("\n");
303 } else {
304 printf("%lu %lu\n", min, max);
305 }
302 return 0; 306 return 0;
303} 307}
304 308
@@ -456,7 +460,7 @@ static void debug_output_one(unsigned int cpu)
456 get_related_cpus(cpu); 460 get_related_cpus(cpu);
457 get_affected_cpus(cpu); 461 get_affected_cpus(cpu);
458 get_latency(cpu, 1); 462 get_latency(cpu, 1);
459 get_hardware_limits(cpu); 463 get_hardware_limits(cpu, 1);
460 464
461 freqs = cpufreq_get_available_frequencies(cpu); 465 freqs = cpufreq_get_available_frequencies(cpu);
462 if (freqs) { 466 if (freqs) {
@@ -622,7 +626,7 @@ int cmd_freq_info(int argc, char **argv)
622 ret = get_driver(cpu); 626 ret = get_driver(cpu);
623 break; 627 break;
624 case 'l': 628 case 'l':
625 ret = get_hardware_limits(cpu); 629 ret = get_hardware_limits(cpu, human);
626 break; 630 break;
627 case 'w': 631 case 'w':
628 ret = get_freq_hardware(cpu, human); 632 ret = get_freq_hardware(cpu, human);
@@ -639,7 +643,6 @@ int cmd_freq_info(int argc, char **argv)
639 } 643 }
640 if (ret) 644 if (ret)
641 return ret; 645 return ret;
642 printf("\n");
643 } 646 }
644 return ret; 647 return ret;
645} 648}
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 03cb639b292e..fedca3285326 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -16,9 +16,9 @@ idle power-state statistics, temperature and power on X86 processors.
16There are two ways to invoke turbostat. 16There are two ways to invoke turbostat.
17The first method is to supply a 17The first method is to supply a
18\fBcommand\fP, which is forked and statistics are printed 18\fBcommand\fP, which is forked and statistics are printed
19upon its completion. 19in one-shot upon its completion.
20The second method is to omit the command, 20The second method is to omit the command,
21and turbostat displays statistics every 5 seconds. 21and turbostat displays statistics every 5 seconds interval.
22The 5-second interval can be changed using the --interval option. 22The 5-second interval can be changed using the --interval option.
23.PP 23.PP
24Some information is not available on older processors. 24Some information is not available on older processors.
@@ -28,9 +28,10 @@ name as necessary to disambiguate it from others is necessary. Note that option
28.PP 28.PP
29\fB--add attributes\fP add column with counter having specified 'attributes'. The 'location' attribute is required, all others are optional. 29\fB--add attributes\fP add column with counter having specified 'attributes'. The 'location' attribute is required, all others are optional.
30.nf 30.nf
31 location: {\fBmsrDDD\fP | \fBmsr0xXXX\fP} 31 location: {\fBmsrDDD\fP | \fBmsr0xXXX\fP | \fB/sys/path...\fP}
32 msrDDD is a decimal offset, eg. msr16 32 msrDDD is a decimal offset, eg. msr16
33 msr0xXXX is a hex offset, eg. msr0x10 33 msr0xXXX is a hex offset, eg. msr0x10
34 /sys/path... is an absolute path to a sysfs attribute
34 35
35 scope: {\fBcpu\fP | \fBcore\fP | \fBpackage\fP} 36 scope: {\fBcpu\fP | \fBcore\fP | \fBpackage\fP}
36 sample and print the counter for every cpu, core, or package. 37 sample and print the counter for every cpu, core, or package.
@@ -45,12 +46,21 @@ name as necessary to disambiguate it from others is necessary. Note that option
45 'delta' shows the difference in values during the measurement interval. 46 'delta' shows the difference in values during the measurement interval.
46 'percent' shows the delta as a percentage of the cycles elapsed. 47 'percent' shows the delta as a percentage of the cycles elapsed.
47 default: delta 48 default: delta
49
50 name: "name_string"
51 Any string that does not match a key-word above is used
52 as the column header.
48.fi 53.fi
49.PP 54.PP
55\fB--cpu cpu-set\fP limit output to system summary plus the specified cpu-set. If cpu-set is the string "core", then the system summary plus the first CPU in each core are printed -- eg. subsequent HT siblings are not printed. Or if cpu-set is the string "package", then the system summary plus the first CPU in each package is printed. Otherwise, the system summary plus the specified set of CPUs are printed. The cpu-set is ordered from low to high, comma delimited with ".." and "-" permitted to denote a range. eg. 1,2,8,14..17,21-44
56.PP
57\fB--hide column\fP do not show the specified columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--hide sysfs" to hide the sysfs statistics columns as a group.
58.PP
59\fB--show column\fP show only the specified columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--show sysfs" to show the sysfs statistics columns as a group.
60.PP
50\fB--Dump\fP displays the raw counter values. 61\fB--Dump\fP displays the raw counter values.
51.PP 62.PP
52\fB--debug\fP displays additional system configuration information. Invoking this parameter 63\fB--quiet\fP Do not decode and print the system configuration header information.
53more than once may also enable internal turbostat debug information.
54.PP 64.PP
55\fB--interval seconds\fP overrides the default 5.0 second measurement interval. 65\fB--interval seconds\fP overrides the default 5.0 second measurement interval.
56.PP 66.PP
@@ -61,9 +71,7 @@ The file is truncated if it already exists, and it is created if it does not exi
61.PP 71.PP
62\fB--Joules\fP displays energy in Joules, rather than dividing Joules by time to print power in Watts. 72\fB--Joules\fP displays energy in Joules, rather than dividing Joules by time to print power in Watts.
63.PP 73.PP
64\fB--Package\fP limits output to the system summary plus the 1st thread in each Package. 74\fB--list\fP display column header names available for use by --show and --hide, then exit.
65.PP
66\fB--processor\fP limits output to the system summary plus the 1st thread in each processor of each package. Ie. it skips hyper-threaded siblings.
67.PP 75.PP
68\fB--Summary\fP limits output to a 1-line System Summary for each interval. 76\fB--Summary\fP limits output to a 1-line System Summary for each interval.
69.PP 77.PP
@@ -74,24 +82,25 @@ The file is truncated if it already exists, and it is created if it does not exi
74The \fBcommand\fP parameter forks \fBcommand\fP, and upon its exit, 82The \fBcommand\fP parameter forks \fBcommand\fP, and upon its exit,
75displays the statistics gathered since it was forked. 83displays the statistics gathered since it was forked.
76.PP 84.PP
77.SH DEFAULT FIELD DESCRIPTIONS 85.SH ROW DESCRIPTIONS
86The system configuration dump (if --quiet is not used) is followed by statistics. The first row of the statistics labels the content of each column (below). The second row of statistics is the system summary line. The system summary line has a '-' in the columns for the Package, Core, and CPU. The contents of the system summary line depends on the type of column. Columns that count items (eg. IRQ) show the sum across all CPUs in the system. Columns that show a percentage show the average across all CPUs in the system. Columns that dump raw MSR values simply show 0 in the summary. After the system summary row, each row describes a specific Package/Core/CPU. Note that if the --cpu parameter is used to limit which specific CPUs are displayed, turbostat will still collect statistics for all CPUs in the system and will still show the system summary for all CPUs in the system.
87.SH COLUMN DESCRIPTIONS
78.nf 88.nf
89\fBCore\fP processor core number. Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology (HT).
79\fBCPU\fP Linux CPU (logical processor) number. Yes, it is okay that on many systems the CPUs are not listed in numerical order -- for efficiency reasons, turbostat runs in topology order, so HT siblings appear together. 90\fBCPU\fP Linux CPU (logical processor) number. Yes, it is okay that on many systems the CPUs are not listed in numerical order -- for efficiency reasons, turbostat runs in topology order, so HT siblings appear together.
80\fBAVG_MHz\fP number of cycles executed divided by time elapsed. 91\fBPackage\fP processor package number -- not present on systems with a single processor package.
81\fBBusy%\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state. 92\fBAvg_MHz\fP number of cycles executed divided by time elapsed. Note that this includes idle-time when 0 instructions are executed.
82\fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state). 93\fBBusy%\fP percent of the measurement interval that the CPU executes instructions, aka. % of time in "C0" state.
94\fBBzy_MHz\fP average clock rate while the CPU was not idle (ie. in "c0" state).
83\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval. 95\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval.
84.fi 96\fBIRQ\fP The number of interrupts serviced by that CPU during the measurement interval. The system total line is the sum of interrupts serviced across all CPUs. turbostat parses /proc/interrupts to generate this summary.
85.PP 97\fBSMI\fP The number of System Management Interrupts serviced CPU during the measurement interval. While this counter is actually per-CPU, SMI are triggered on all processors, so the number should be the same for all CPUs.
86.SH DEBUG FIELD DESCRIPTIONS 98\fBC1, C2, C3...\fP The number times Linux requested the C1, C2, C3 idle state during the measurement interval. The system summary line shows the sum for all CPUs. These are C-state names as exported in /sys/devices/system/cpu/cpu*/cpuidle/state*/name. While their names are generic, their attributes are processor specific. They the system description section of output shows what MWAIT sub-states they are mapped to on each system.
87.nf 99\fBC1%, C2%, C3%\fP The residency percentage that Linux requested C1, C2, C3.... The system summary is the average of all CPUs in the system. Note that these are software, reflecting what was requested. The hardware counters reflect what was actually achieved.
88\fBPackage\fP processor package number. 100\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. These numbers are from hardware residency counters.
89\fBCore\fP processor core number.
90Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology (HT).
91\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states.
92\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor. 101\fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor.
93\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor. 102\fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor.
94\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. 103\fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. These numbers are from hardware residency counters.
95\fBPkgWatt\fP Watts consumed by the whole package. 104\fBPkgWatt\fP Watts consumed by the whole package.
96\fBCorWatt\fP Watts consumed by the core part of the package. 105\fBCorWatt\fP Watts consumed by the core part of the package.
97\fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors. 106\fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors.
@@ -99,51 +108,110 @@ Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading T
99\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. 108\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package.
100\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM. 109\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
101.fi 110.fi
111.SH TOO MUCH INFORMATION EXAMPLE
112By default, turbostat dumps all possible information -- a system configuration header, followed by columns for all counters.
113This is ideal for remote debugging, use the "--out" option to save everything to a text file, and get that file to the expert helping you debug.
102.PP 114.PP
103.SH PERIODIC EXAMPLE 115When you are not interested in all that information, and there are several ways to see only what you want. First the "--quiet" option will skip the configuration information, and turbostat will show only the counter columns. Second, you can reduce the columns with the "--hide" and "--show" options. If you use the "--show" option, then turbostat will show only the columns you list. If you use the "--hide" option, turbostat will show all columns, except the ones you list.
104Without any parameters, turbostat displays statistics ever 5 seconds. 116.PP
105Periodic output goes to stdout, by default, unless --out is used to specify an output file. 117To find out what columns are available for --show and --hide, the "--list" option is available. For convenience, the special strings "sysfs" can be used to refer to all of the sysfs C-state counters at once:
106The 5-second interval can be changed with th "-i sec" option. 118.nf
107Or a command may be specified as in "FORK EXAMPLE" below. 119sudo ./turbostat --show sysfs --quiet sleep 10
12010.003837 sec
121 C1 C1E C3 C6 C7s C1% C1E% C3% C6% C7s%
122 4 21 2 2 459 0.14 0.82 0.00 0.00 98.93
123 1 17 2 2 130 0.00 0.02 0.00 0.00 99.80
124 0 0 0 0 31 0.00 0.00 0.00 0.00 99.95
125 2 1 0 0 52 1.14 6.49 0.00 0.00 92.21
126 1 2 0 0 52 0.00 0.08 0.00 0.00 99.86
127 0 0 0 0 71 0.00 0.00 0.00 0.00 99.89
128 0 0 0 0 25 0.00 0.00 0.00 0.00 99.96
129 0 0 0 0 74 0.00 0.00 0.00 0.00 99.94
130 0 1 0 0 24 0.00 0.00 0.00 0.00 99.84
131.fi
132.PP
133.SH ONE SHOT COMMAND EXAMPLE
134If turbostat is invoked with a command, it will fork that command
135and output the statistics gathered after the command exits.
136In this case, turbostat output goes to stderr, by default.
137Output can instead be saved to a file using the --out option.
138In this example, the "sleep 10" command is forked, and turbostat waits for it to complete before saving all statistics into "ts.out". Note that "sleep 10" is not part of turbostat, but is simply an example of a command that turbostat can fork. The "ts.out" file is what you want to edit in a very wide window, paste into a spreadsheet, or attach to a bugzilla entry.
139
108.nf 140.nf
109[root@hsw]# ./turbostat 141[root@hsw]# ./turbostat -o ts.out sleep 10
110 CPU Avg_MHz Busy% Bzy_MHz TSC_MHz 142[root@hsw]#
111 - 488 12.51 3898 3498 143.fi
112 0 0 0.01 3885 3498
113 4 3897 99.99 3898 3498
114 1 0 0.00 3861 3498
115 5 0 0.00 3882 3498
116 2 1 0.02 3894 3498
117 6 2 0.06 3898 3498
118 3 0 0.00 3849 3498
119 7 0 0.00 3877 3498
120 144
145.SH PERIODIC INTERVAL EXAMPLE
146Without a command to fork, turbostat displays statistics ever 5 seconds.
147Periodic output goes to stdout, by default, unless --out is used to specify an output file.
148The 5-second interval can be changed with the "-i sec" option.
149.nf
150sudo ./turbostat --quiet --hide sysfs,IRQ,SMI,CoreTmp,PkgTmp,GFX%rc6,GFXMHz,PkgWatt,CorWatt,GFXWatt
151 Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz CPU%c1 CPU%c3 CPU%c6 CPU%c7
152 - - 488 12.52 3900 3498 12.50 0.00 0.00 74.98
153 0 0 5 0.13 3900 3498 99.87 0.00 0.00 0.00
154 0 4 3897 99.99 3900 3498 0.01
155 1 1 0 0.00 3856 3498 0.01 0.00 0.00 99.98
156 1 5 0 0.00 3861 3498 0.01
157 2 2 1 0.02 3889 3498 0.03 0.00 0.00 99.95
158 2 6 0 0.00 3863 3498 0.05
159 3 3 0 0.01 3869 3498 0.02 0.00 0.00 99.97
160 3 7 0 0.00 3878 3498 0.03
161 Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz CPU%c1 CPU%c3 CPU%c6 CPU%c7
162 - - 491 12.59 3900 3498 12.42 0.00 0.00 74.99
163 0 0 27 0.69 3900 3498 99.31 0.00 0.00 0.00
164 0 4 3898 99.99 3900 3498 0.01
165 1 1 0 0.00 3883 3498 0.01 0.00 0.00 99.99
166 1 5 0 0.00 3898 3498 0.01
167 2 2 0 0.01 3889 3498 0.02 0.00 0.00 99.98
168 2 6 0 0.00 3889 3498 0.02
169 3 3 0 0.00 3856 3498 0.01 0.00 0.00 99.99
170 3 7 0 0.00 3897 3498 0.01
121.fi 171.fi
122.SH DEBUG EXAMPLE 172This example also shows the use of the --hide option to skip columns that are not wanted.
123The "--debug" option prints additional system information before measurements: 173Note that cpu4 in this example is 99.99% busy, while the other CPUs are all under 1% busy.
174Notice that cpu4's HT sibling is cpu0, which is under 1% busy, but can get into CPU%c1 only,
175because its cpu4's activity on shared hardware keeps it from entering a deeper C-state.
124 176
125The first row of statistics is a summary for the entire system. 177.SH SYSTEM CONFIGURATION INFORMATION EXAMPLE
126For residency % columns, the summary is a weighted average. 178
127For Temperature columns, the summary is the column maximum. 179By default, turbostat always dumps system configuration information
128For Watts columns, the summary is a system total. 180before taking measurements. In the example above, "--quiet" is used
129Subsequent rows show per-CPU statistics. 181to suppress that output. Here is an example of the configuration information:
130.nf 182.nf
131turbostat version 4.1 10-Feb, 2015 - Len Brown <lenb@kernel.org> 183turbostat version 2017.02.15 - Len Brown <lenb@kernel.org>
132CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3c:3 (6:60:3) 184CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3c:3 (6:60:3)
133CPUID(6): APERF, DTS, PTM, EPB 185CPUID(1): SSE3 MONITOR - EIST TM2 TSC MSR ACPI-TM TM
186CPUID(6): APERF, TURBO, DTS, PTM, No-HWP, No-HWPnotify, No-HWPwindow, No-HWPepp, No-HWPpkg, EPB
187cpu4: MSR_IA32_MISC_ENABLE: 0x00850089 (TCC EIST No-MWAIT PREFETCH TURBO)
188CPUID(7): No-SGX
189cpu4: MSR_MISC_PWR_MGMT: 0x00400000 (ENable-EIST_Coordination DISable-EPB DISable-OOB)
134RAPL: 3121 sec. Joule Counter Range, at 84 Watts 190RAPL: 3121 sec. Joule Counter Range, at 84 Watts
135cpu0: MSR_NHM_PLATFORM_INFO: 0x80838f3012300 191cpu4: MSR_PLATFORM_INFO: 0x80838f3012300
1368 * 100 = 800 MHz max efficiency 1928 * 100.0 = 800.0 MHz max efficiency frequency
13735 * 100 = 3500 MHz TSC frequency 19335 * 100.0 = 3500.0 MHz base frequency
138cpu0: MSR_IA32_POWER_CTL: 0x0004005d (C1E auto-promotion: DISabled) 194cpu4: MSR_IA32_POWER_CTL: 0x0004005d (C1E auto-promotion: DISabled)
139cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e000400 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, UNlocked: pkg-cstate-limit=0: pc0) 195cpu4: MSR_TURBO_RATIO_LIMIT: 0x25262727
140cpu0: MSR_TURBO_RATIO_LIMIT: 0x25262727 19637 * 100.0 = 3700.0 MHz max turbo 4 active cores
14137 * 100 = 3700 MHz max turbo 4 active cores 19738 * 100.0 = 3800.0 MHz max turbo 3 active cores
14238 * 100 = 3800 MHz max turbo 3 active cores 19839 * 100.0 = 3900.0 MHz max turbo 2 active cores
14339 * 100 = 3900 MHz max turbo 2 active cores 19939 * 100.0 = 3900.0 MHz max turbo 1 active cores
14439 * 100 = 3900 MHz max turbo 1 active cores 200cpu4: MSR_CONFIG_TDP_NOMINAL: 0x00000023 (base_ratio=35)
201cpu4: MSR_CONFIG_TDP_LEVEL_1: 0x00000000 ()
202cpu4: MSR_CONFIG_TDP_LEVEL_2: 0x00000000 ()
203cpu4: MSR_CONFIG_TDP_CONTROL: 0x80000000 ( lock=1)
204cpu4: MSR_TURBO_ACTIVATION_RATIO: 0x00000000 (MAX_NON_TURBO_RATIO=0 lock=0)
205cpu4: MSR_PKG_CST_CONFIG_CONTROL: 0x1e000400 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, UNlocked: pkg-cstate-limit=0: pc0)
206cpu4: POLL: CPUIDLE CORE POLL IDLE
207cpu4: C1: MWAIT 0x00
208cpu4: C1E: MWAIT 0x01
209cpu4: C3: MWAIT 0x10
210cpu4: C6: MWAIT 0x20
211cpu4: C7s: MWAIT 0x32
212cpu4: MSR_MISC_FEATURE_CONTROL: 0x00000000 (L2-Prefetch L2-Prefetch-pair L1-Prefetch L1-IP-Prefetch)
145cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced) 213cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced)
146cpu0: MSR_CORE_PERF_LIMIT_REASONS, 0x31200000 (Active: ) (Logged: Auto-HWP, Amps, MultiCoreTurbo, Transitions, ) 214cpu0: MSR_CORE_PERF_LIMIT_REASONS, 0x31200000 (Active: ) (Logged: Transitions, MultiCoreTurbo, Amps, Auto-HWP, )
147cpu0: MSR_GFX_PERF_LIMIT_REASONS, 0x00000000 (Active: ) (Logged: ) 215cpu0: MSR_GFX_PERF_LIMIT_REASONS, 0x00000000 (Active: ) (Logged: )
148cpu0: MSR_RING_PERF_LIMIT_REASONS, 0x0d000000 (Active: ) (Logged: Amps, PkgPwrL1, PkgPwrL2, ) 216cpu0: MSR_RING_PERF_LIMIT_REASONS, 0x0d000000 (Active: ) (Logged: Amps, PkgPwrL1, PkgPwrL2, )
149cpu0: MSR_RAPL_POWER_UNIT: 0x000a0e03 (0.125000 Watts, 0.000061 Joules, 0.000977 sec.) 217cpu0: MSR_RAPL_POWER_UNIT: 0x000a0e03 (0.125000 Watts, 0.000061 Joules, 0.000977 sec.)
@@ -158,23 +226,14 @@ cpu0: MSR_PP1_POLICY: 0
158cpu0: MSR_PP1_POWER_LIMIT: 0x00000000 (UNlocked) 226cpu0: MSR_PP1_POWER_LIMIT: 0x00000000 (UNlocked)
159cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled) 227cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
160cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00641400 (100 C) 228cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00641400 (100 C)
161cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x88340800 (48 C) 229cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x884c0800 (24 C)
162cpu0: MSR_IA32_THERM_STATUS: 0x88340000 (48 C +/- 1) 230cpu0: MSR_IA32_THERM_STATUS: 0x884c0000 (24 C +/- 1)
163cpu1: MSR_IA32_THERM_STATUS: 0x88440000 (32 C +/- 1) 231cpu1: MSR_IA32_THERM_STATUS: 0x88510000 (19 C +/- 1)
164cpu2: MSR_IA32_THERM_STATUS: 0x88450000 (31 C +/- 1) 232cpu2: MSR_IA32_THERM_STATUS: 0x884e0000 (22 C +/- 1)
165cpu3: MSR_IA32_THERM_STATUS: 0x88490000 (27 C +/- 1) 233cpu3: MSR_IA32_THERM_STATUS: 0x88510000 (19 C +/- 1)
166 Core CPU Avg_MHz Busy% Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp PkgWatt CorWatt GFXWatt 234cpu4: MSR_PKGC3_IRTL: 0x00008842 (valid, 67584 ns)
167 - - 493 12.64 3898 3498 0 12.64 0.00 0.00 74.72 47 47 21.62 13.74 0.00 235cpu4: MSR_PKGC6_IRTL: 0x00008873 (valid, 117760 ns)
168 0 0 4 0.11 3894 3498 0 99.89 0.00 0.00 0.00 47 47 21.62 13.74 0.00 236cpu4: MSR_PKGC7_IRTL: 0x00008891 (valid, 148480 ns)
169 0 4 3897 99.98 3898 3498 0 0.02
170 1 1 7 0.17 3887 3498 0 0.04 0.00 0.00 99.79 32
171 1 5 0 0.00 3885 3498 0 0.21
172 2 2 29 0.76 3895 3498 0 0.10 0.01 0.01 99.13 32
173 2 6 2 0.06 3896 3498 0 0.80
174 3 3 1 0.02 3832 3498 0 0.03 0.00 0.00 99.95 28
175 3 7 0 0.00 3879 3498 0 0.04
176^C
177
178.fi 237.fi
179The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency 238The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency
180available at the minimum package voltage. The \fBTSC frequency\fP is the base 239available at the minimum package voltage. The \fBTSC frequency\fP is the base
@@ -184,42 +243,22 @@ should be sustainable on all CPUs indefinitely, given nominal power and cooling.
184The remaining rows show what maximum turbo frequency is possible 243The remaining rows show what maximum turbo frequency is possible
185depending on the number of idle cores. Note that not all information is 244depending on the number of idle cores. Note that not all information is
186available on all processors. 245available on all processors.
187.PP 246.SH ADD COUNTER EXAMPLE
188The --debug option adds additional columns to the measurement ouput, including CPU idle power-state residency processor temperature sensor readinds. 247Here we limit turbostat to showing just the CPU number for cpu0 - cpu3.
189See the field definitions above. 248We add a counter showing the 32-bit raw value of MSR 0x199 (MSR_IA32_PERF_CTL),
190.SH FORK EXAMPLE 249labeling it with the column header, "PRF_CTRL", and display it only once,
191If turbostat is invoked with a command, it will fork that command 250afte the conclusion of a 0.1 second sleep.
192and output the statistics gathered after the command exits.
193In this case, turbostat output goes to stderr, by default.
194Output can instead be saved to a file using the --out option.
195eg. Here a cycle soaker is run on 1 CPU (see %c0) for a few seconds
196until ^C while the other CPUs are mostly idle:
197
198.nf 251.nf
199root@hsw: turbostat cat /dev/zero > /dev/null 252sudo ./turbostat --quiet --cpu 0-3 --show CPU --add msr0x199,u32,raw,PRF_CTRL sleep .1
200^C 2530.101604 sec
201 CPU Avg_MHz Busy% Bzy_MHz TSC_MHz 254CPU PRF_CTRL
202 - 482 12.51 3854 3498 255- 0x00000000
203 0 0 0.01 1960 3498 2560 0x00000c00
204 4 0 0.00 2128 3498 2571 0x00000800
205 1 0 0.00 3003 3498 2582 0x00000a00
206 5 3854 99.98 3855 3498 2593 0x00000800
207 2 0 0.01 3504 3498
208 6 3 0.08 3884 3498
209 3 0 0.00 2553 3498
210 7 0 0.00 2126 3498
21110.783983 sec
212 260
213.fi 261.fi
214Above the cycle soaker drives cpu5 up its 3.9 GHz turbo limit.
215The first row shows the average MHz and Busy% across all the processors in the system.
216
217Note that the Avg_MHz column reflects the total number of cycles executed
218divided by the measurement interval. If the Busy% column is 100%,
219then the processor was running at that speed the entire interval.
220The Avg_MHz multiplied by the Busy% results in the Bzy_MHz --
221which is the average frequency while the processor was executing --
222not including any non-busy idle time.
223 262
224.SH NOTES 263.SH NOTES
225 264
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index f13f61b065c6..828dccd3f01e 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -49,17 +49,14 @@ FILE *outf;
49int *fd_percpu; 49int *fd_percpu;
50struct timespec interval_ts = {5, 0}; 50struct timespec interval_ts = {5, 0};
51unsigned int debug; 51unsigned int debug;
52unsigned int quiet;
53unsigned int sums_need_wide_columns;
52unsigned int rapl_joules; 54unsigned int rapl_joules;
53unsigned int summary_only; 55unsigned int summary_only;
56unsigned int list_header_only;
54unsigned int dump_only; 57unsigned int dump_only;
55unsigned int do_nhm_cstates;
56unsigned int do_snb_cstates; 58unsigned int do_snb_cstates;
57unsigned int do_knl_cstates; 59unsigned int do_knl_cstates;
58unsigned int do_pc2;
59unsigned int do_pc3;
60unsigned int do_pc6;
61unsigned int do_pc7;
62unsigned int do_c8_c9_c10;
63unsigned int do_skl_residency; 60unsigned int do_skl_residency;
64unsigned int do_slm_cstates; 61unsigned int do_slm_cstates;
65unsigned int use_c1_residency_msr; 62unsigned int use_c1_residency_msr;
@@ -71,25 +68,19 @@ unsigned int units = 1000000; /* MHz etc */
71unsigned int genuine_intel; 68unsigned int genuine_intel;
72unsigned int has_invariant_tsc; 69unsigned int has_invariant_tsc;
73unsigned int do_nhm_platform_info; 70unsigned int do_nhm_platform_info;
71unsigned int no_MSR_MISC_PWR_MGMT;
74unsigned int aperf_mperf_multiplier = 1; 72unsigned int aperf_mperf_multiplier = 1;
75int do_irq = 1;
76int do_smi;
77double bclk; 73double bclk;
78double base_hz; 74double base_hz;
79unsigned int has_base_hz; 75unsigned int has_base_hz;
80double tsc_tweak = 1.0; 76double tsc_tweak = 1.0;
81unsigned int show_pkg;
82unsigned int show_core;
83unsigned int show_cpu;
84unsigned int show_pkg_only; 77unsigned int show_pkg_only;
85unsigned int show_core_only; 78unsigned int show_core_only;
86char *output_buffer, *outp; 79char *output_buffer, *outp;
87unsigned int do_rapl; 80unsigned int do_rapl;
88unsigned int do_dts; 81unsigned int do_dts;
89unsigned int do_ptm; 82unsigned int do_ptm;
90unsigned int do_gfx_rc6_ms;
91unsigned long long gfx_cur_rc6_ms; 83unsigned long long gfx_cur_rc6_ms;
92unsigned int do_gfx_mhz;
93unsigned int gfx_cur_mhz; 84unsigned int gfx_cur_mhz;
94unsigned int tcc_activation_temp; 85unsigned int tcc_activation_temp;
95unsigned int tcc_activation_temp_override; 86unsigned int tcc_activation_temp_override;
@@ -109,6 +100,7 @@ unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
109unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */ 100unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
110unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ 101unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
111unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ 102unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
103unsigned int has_misc_feature_control;
112 104
113#define RAPL_PKG (1 << 0) 105#define RAPL_PKG (1 << 0)
114 /* 0x610 MSR_PKG_POWER_LIMIT */ 106 /* 0x610 MSR_PKG_POWER_LIMIT */
@@ -148,34 +140,38 @@ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
148 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters 140 * Usually truncated to 7 characters, but also handles 18 columns for raw 64-bit counters
149 */ 141 */
150#define NAME_BYTES 20 142#define NAME_BYTES 20
143#define PATH_BYTES 128
151 144
152int backwards_count; 145int backwards_count;
153char *progname; 146char *progname;
154 147
155cpu_set_t *cpu_present_set, *cpu_affinity_set; 148#define CPU_SUBSET_MAXCPUS 1024 /* need to use before probe... */
156size_t cpu_present_setsize, cpu_affinity_setsize; 149cpu_set_t *cpu_present_set, *cpu_affinity_set, *cpu_subset;
150size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
151#define MAX_ADDED_COUNTERS 16
157 152
158struct thread_data { 153struct thread_data {
159 unsigned long long tsc; 154 unsigned long long tsc;
160 unsigned long long aperf; 155 unsigned long long aperf;
161 unsigned long long mperf; 156 unsigned long long mperf;
162 unsigned long long c1; 157 unsigned long long c1;
163 unsigned int irq_count; 158 unsigned long long irq_count;
164 unsigned int smi_count; 159 unsigned int smi_count;
165 unsigned int cpu_id; 160 unsigned int cpu_id;
166 unsigned int flags; 161 unsigned int flags;
167#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 162#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
168#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 163#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
169 unsigned long long counter[1]; 164 unsigned long long counter[MAX_ADDED_COUNTERS];
170} *thread_even, *thread_odd; 165} *thread_even, *thread_odd;
171 166
172struct core_data { 167struct core_data {
173 unsigned long long c3; 168 unsigned long long c3;
174 unsigned long long c6; 169 unsigned long long c6;
175 unsigned long long c7; 170 unsigned long long c7;
171 unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */
176 unsigned int core_temp_c; 172 unsigned int core_temp_c;
177 unsigned int core_id; 173 unsigned int core_id;
178 unsigned long long counter[1]; 174 unsigned long long counter[MAX_ADDED_COUNTERS];
179} *core_even, *core_odd; 175} *core_even, *core_odd;
180 176
181struct pkg_data { 177struct pkg_data {
@@ -200,7 +196,7 @@ struct pkg_data {
200 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */ 196 unsigned int rapl_pkg_perf_status; /* MSR_PKG_PERF_STATUS */
201 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */ 197 unsigned int rapl_dram_perf_status; /* MSR_DRAM_PERF_STATUS */
202 unsigned int pkg_temp_c; 198 unsigned int pkg_temp_c;
203 unsigned long long counter[1]; 199 unsigned long long counter[MAX_ADDED_COUNTERS];
204} *package_even, *package_odd; 200} *package_even, *package_odd;
205 201
206#define ODD_COUNTERS thread_odd, core_odd, package_odd 202#define ODD_COUNTERS thread_odd, core_odd, package_odd
@@ -215,22 +211,27 @@ struct pkg_data {
215#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no) 211#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
216 212
217enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE}; 213enum counter_scope {SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE};
218enum counter_type {COUNTER_CYCLES, COUNTER_SECONDS}; 214enum counter_type {COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC};
219enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT}; 215enum counter_format {FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT};
220 216
221struct msr_counter { 217struct msr_counter {
222 unsigned int msr_num; 218 unsigned int msr_num;
223 char name[NAME_BYTES]; 219 char name[NAME_BYTES];
220 char path[PATH_BYTES];
224 unsigned int width; 221 unsigned int width;
225 enum counter_type type; 222 enum counter_type type;
226 enum counter_format format; 223 enum counter_format format;
227 struct msr_counter *next; 224 struct msr_counter *next;
225 unsigned int flags;
226#define FLAGS_HIDE (1 << 0)
227#define FLAGS_SHOW (1 << 1)
228#define SYSFS_PERCPU (1 << 1)
228}; 229};
229 230
230struct sys_counters { 231struct sys_counters {
231 unsigned int thread_counter_bytes; 232 unsigned int added_thread_counters;
232 unsigned int core_counter_bytes; 233 unsigned int added_core_counters;
233 unsigned int package_counter_bytes; 234 unsigned int added_package_counters;
234 struct msr_counter *tp; 235 struct msr_counter *tp;
235 struct msr_counter *cp; 236 struct msr_counter *cp;
236 struct msr_counter *pp; 237 struct msr_counter *pp;
@@ -334,147 +335,333 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
334 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); 335 retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset);
335 336
336 if (retval != sizeof *msr) 337 if (retval != sizeof *msr)
337 err(-1, "msr %d offset 0x%llx read failed", cpu, (unsigned long long)offset); 338 err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
338 339
339 return 0; 340 return 0;
340} 341}
341 342
342/* 343/*
343 * Example Format w/ field column widths: 344 * Each string in this array is compared in --show and --hide cmdline.
344 * 345 * Thus, strings that are proper sub-sets must follow their more specific peers.
345 * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz IRQ SMI Busy% CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 ThreadC CoreTmp CoreCnt PkgTmp GFXMHz Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt PkgCnt 346 */
346 * 12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678 347struct msr_counter bic[] = {
348 { 0x0, "Package" },
349 { 0x0, "Avg_MHz" },
350 { 0x0, "Bzy_MHz" },
351 { 0x0, "TSC_MHz" },
352 { 0x0, "IRQ" },
353 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL},
354 { 0x0, "Busy%" },
355 { 0x0, "CPU%c1" },
356 { 0x0, "CPU%c3" },
357 { 0x0, "CPU%c6" },
358 { 0x0, "CPU%c7" },
359 { 0x0, "ThreadC" },
360 { 0x0, "CoreTmp" },
361 { 0x0, "CoreCnt" },
362 { 0x0, "PkgTmp" },
363 { 0x0, "GFX%rc6" },
364 { 0x0, "GFXMHz" },
365 { 0x0, "Pkg%pc2" },
366 { 0x0, "Pkg%pc3" },
367 { 0x0, "Pkg%pc6" },
368 { 0x0, "Pkg%pc7" },
369 { 0x0, "Pkg%pc8" },
370 { 0x0, "Pkg%pc9" },
371 { 0x0, "Pkg%pc10" },
372 { 0x0, "PkgWatt" },
373 { 0x0, "CorWatt" },
374 { 0x0, "GFXWatt" },
375 { 0x0, "PkgCnt" },
376 { 0x0, "RAMWatt" },
377 { 0x0, "PKG_%" },
378 { 0x0, "RAM_%" },
379 { 0x0, "Pkg_J" },
380 { 0x0, "Cor_J" },
381 { 0x0, "GFX_J" },
382 { 0x0, "RAM_J" },
383 { 0x0, "Core" },
384 { 0x0, "CPU" },
385 { 0x0, "Mod%c6" },
386 { 0x0, "sysfs" },
387};
388
389#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
390#define BIC_Package (1ULL << 0)
391#define BIC_Avg_MHz (1ULL << 1)
392#define BIC_Bzy_MHz (1ULL << 2)
393#define BIC_TSC_MHz (1ULL << 3)
394#define BIC_IRQ (1ULL << 4)
395#define BIC_SMI (1ULL << 5)
396#define BIC_Busy (1ULL << 6)
397#define BIC_CPU_c1 (1ULL << 7)
398#define BIC_CPU_c3 (1ULL << 8)
399#define BIC_CPU_c6 (1ULL << 9)
400#define BIC_CPU_c7 (1ULL << 10)
401#define BIC_ThreadC (1ULL << 11)
402#define BIC_CoreTmp (1ULL << 12)
403#define BIC_CoreCnt (1ULL << 13)
404#define BIC_PkgTmp (1ULL << 14)
405#define BIC_GFX_rc6 (1ULL << 15)
406#define BIC_GFXMHz (1ULL << 16)
407#define BIC_Pkgpc2 (1ULL << 17)
408#define BIC_Pkgpc3 (1ULL << 18)
409#define BIC_Pkgpc6 (1ULL << 19)
410#define BIC_Pkgpc7 (1ULL << 20)
411#define BIC_Pkgpc8 (1ULL << 21)
412#define BIC_Pkgpc9 (1ULL << 22)
413#define BIC_Pkgpc10 (1ULL << 23)
414#define BIC_PkgWatt (1ULL << 24)
415#define BIC_CorWatt (1ULL << 25)
416#define BIC_GFXWatt (1ULL << 26)
417#define BIC_PkgCnt (1ULL << 27)
418#define BIC_RAMWatt (1ULL << 28)
419#define BIC_PKG__ (1ULL << 29)
420#define BIC_RAM__ (1ULL << 30)
421#define BIC_Pkg_J (1ULL << 31)
422#define BIC_Cor_J (1ULL << 32)
423#define BIC_GFX_J (1ULL << 33)
424#define BIC_RAM_J (1ULL << 34)
425#define BIC_Core (1ULL << 35)
426#define BIC_CPU (1ULL << 36)
427#define BIC_Mod_c6 (1ULL << 37)
428#define BIC_sysfs (1ULL << 38)
429
430unsigned long long bic_enabled = 0xFFFFFFFFFFFFFFFFULL;
431unsigned long long bic_present = BIC_sysfs;
432
433#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
434#define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
435#define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
436
437#define MAX_DEFERRED 16
438char *deferred_skip_names[MAX_DEFERRED];
439int deferred_skip_index;
440
441/*
442 * HIDE_LIST - hide this list of counters, show the rest [default]
443 * SHOW_LIST - show this list of counters, hide the rest
347 */ 444 */
445enum show_hide_mode { SHOW_LIST, HIDE_LIST } global_show_hide_mode = HIDE_LIST;
348 446
349void print_header(void) 447void help(void)
350{ 448{
351 struct msr_counter *mp; 449 fprintf(outf,
450 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
451 "\n"
452 "Turbostat forks the specified COMMAND and prints statistics\n"
453 "when COMMAND completes.\n"
454 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
455 "to print statistics, until interrupted.\n"
456 "--add add a counter\n"
457 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
458 "--cpu cpu-set limit output to summary plus cpu-set:\n"
459 " {core | package | j,k,l..m,n-p }\n"
460 "--quiet skip decoding system configuration header\n"
461 "--interval sec Override default 5-second measurement interval\n"
462 "--help print this help message\n"
463 "--list list column headers only\n"
464 "--out file create or truncate \"file\" for all output\n"
465 "--version print version information\n"
466 "\n"
467 "For more help, run \"man turbostat\"\n");
468}
352 469
353 if (show_pkg) 470/*
354 outp += sprintf(outp, "\tPackage"); 471 * bic_lookup
355 if (show_core) 472 * for all the strings in comma separate name_list,
356 outp += sprintf(outp, "\tCore"); 473 * set the approprate bit in return value.
357 if (show_cpu) 474 */
358 outp += sprintf(outp, "\tCPU"); 475unsigned long long bic_lookup(char *name_list, enum show_hide_mode mode)
359 if (has_aperf) 476{
360 outp += sprintf(outp, "\tAvg_MHz"); 477 int i;
361 if (has_aperf) 478 unsigned long long retval = 0;
362 outp += sprintf(outp, "\tBusy%%");
363 if (has_aperf)
364 outp += sprintf(outp, "\tBzy_MHz");
365 outp += sprintf(outp, "\tTSC_MHz");
366 479
367 if (!debug) 480 while (name_list) {
368 goto done; 481 char *comma;
369 482
370 if (do_irq) 483 comma = strchr(name_list, ',');
371 outp += sprintf(outp, "\tIRQ"); 484
372 if (do_smi) 485 if (comma)
373 outp += sprintf(outp, "\tSMI"); 486 *comma = '\0';
374 487
375 if (do_nhm_cstates) 488 for (i = 0; i < MAX_BIC; ++i) {
376 outp += sprintf(outp, "\tCPU%%c1"); 489 if (!strcmp(name_list, bic[i].name)) {
377 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) 490 retval |= (1ULL << i);
378 outp += sprintf(outp, "\tCPU%%c3"); 491 break;
379 if (do_nhm_cstates) 492 }
380 outp += sprintf(outp, "\tCPU%%c6"); 493 }
381 if (do_snb_cstates) 494 if (i == MAX_BIC) {
382 outp += sprintf(outp, "\tCPU%%c7"); 495 if (mode == SHOW_LIST) {
496 fprintf(stderr, "Invalid counter name: %s\n", name_list);
497 exit(-1);
498 }
499 deferred_skip_names[deferred_skip_index++] = name_list;
500 if (debug)
501 fprintf(stderr, "deferred \"%s\"\n", name_list);
502 if (deferred_skip_index >= MAX_DEFERRED) {
503 fprintf(stderr, "More than max %d un-recognized --skip options '%s'\n",
504 MAX_DEFERRED, name_list);
505 help();
506 exit(1);
507 }
508 }
509
510 name_list = comma;
511 if (name_list)
512 name_list++;
513
514 }
515 return retval;
516}
517
518
519void print_header(char *delim)
520{
521 struct msr_counter *mp;
522 int printed = 0;
523
524 if (DO_BIC(BIC_Package))
525 outp += sprintf(outp, "%sPackage", (printed++ ? delim : ""));
526 if (DO_BIC(BIC_Core))
527 outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
528 if (DO_BIC(BIC_CPU))
529 outp += sprintf(outp, "%sCPU", (printed++ ? delim : ""));
530 if (DO_BIC(BIC_Avg_MHz))
531 outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : ""));
532 if (DO_BIC(BIC_Busy))
533 outp += sprintf(outp, "%sBusy%%", (printed++ ? delim : ""));
534 if (DO_BIC(BIC_Bzy_MHz))
535 outp += sprintf(outp, "%sBzy_MHz", (printed++ ? delim : ""));
536 if (DO_BIC(BIC_TSC_MHz))
537 outp += sprintf(outp, "%sTSC_MHz", (printed++ ? delim : ""));
538
539 if (DO_BIC(BIC_IRQ)) {
540 if (sums_need_wide_columns)
541 outp += sprintf(outp, "%s IRQ", (printed++ ? delim : ""));
542 else
543 outp += sprintf(outp, "%sIRQ", (printed++ ? delim : ""));
544 }
545
546 if (DO_BIC(BIC_SMI))
547 outp += sprintf(outp, "%sSMI", (printed++ ? delim : ""));
383 548
384 for (mp = sys.tp; mp; mp = mp->next) { 549 for (mp = sys.tp; mp; mp = mp->next) {
550
385 if (mp->format == FORMAT_RAW) { 551 if (mp->format == FORMAT_RAW) {
386 if (mp->width == 64) 552 if (mp->width == 64)
387 outp += sprintf(outp, "\t%18.18s", mp->name); 553 outp += sprintf(outp, "%s%18.18s", (printed++ ? delim : ""), mp->name);
388 else 554 else
389 outp += sprintf(outp, "\t%10.10s", mp->name); 555 outp += sprintf(outp, "%s%10.10s", (printed++ ? delim : ""), mp->name);
390 } else { 556 } else {
391 outp += sprintf(outp, "\t%-7.7s", mp->name); 557 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
558 outp += sprintf(outp, "%s%8s", (printed++ ? delim : ""), mp->name);
559 else
560 outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), mp->name);
392 } 561 }
393 } 562 }
394 563
395 if (do_dts) 564 if (DO_BIC(BIC_CPU_c1))
396 outp += sprintf(outp, "\tCoreTmp"); 565 outp += sprintf(outp, "%sCPU%%c1", (printed++ ? delim : ""));
566 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates)
567 outp += sprintf(outp, "%sCPU%%c3", (printed++ ? delim : ""));
568 if (DO_BIC(BIC_CPU_c6))
569 outp += sprintf(outp, "%sCPU%%c6", (printed++ ? delim : ""));
570 if (DO_BIC(BIC_CPU_c7))
571 outp += sprintf(outp, "%sCPU%%c7", (printed++ ? delim : ""));
572
573 if (DO_BIC(BIC_Mod_c6))
574 outp += sprintf(outp, "%sMod%%c6", (printed++ ? delim : ""));
575
576 if (DO_BIC(BIC_CoreTmp))
577 outp += sprintf(outp, "%sCoreTmp", (printed++ ? delim : ""));
397 578
398 for (mp = sys.cp; mp; mp = mp->next) { 579 for (mp = sys.cp; mp; mp = mp->next) {
399 if (mp->format == FORMAT_RAW) { 580 if (mp->format == FORMAT_RAW) {
400 if (mp->width == 64) 581 if (mp->width == 64)
401 outp += sprintf(outp, "\t%18.18s", mp->name); 582 outp += sprintf(outp, "%s%18.18s", delim, mp->name);
402 else 583 else
403 outp += sprintf(outp, "\t%10.10s", mp->name); 584 outp += sprintf(outp, "%s%10.10s", delim, mp->name);
404 } else { 585 } else {
405 outp += sprintf(outp, "\t%-7.7s", mp->name); 586 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
587 outp += sprintf(outp, "%s%8s", delim, mp->name);
588 else
589 outp += sprintf(outp, "%s%s", delim, mp->name);
406 } 590 }
407 } 591 }
408 592
409 if (do_ptm) 593 if (DO_BIC(BIC_PkgTmp))
410 outp += sprintf(outp, "\tPkgTmp"); 594 outp += sprintf(outp, "%sPkgTmp", (printed++ ? delim : ""));
411 595
412 if (do_gfx_rc6_ms) 596 if (DO_BIC(BIC_GFX_rc6))
413 outp += sprintf(outp, "\tGFX%%rc6"); 597 outp += sprintf(outp, "%sGFX%%rc6", (printed++ ? delim : ""));
414 598
415 if (do_gfx_mhz) 599 if (DO_BIC(BIC_GFXMHz))
416 outp += sprintf(outp, "\tGFXMHz"); 600 outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : ""));
417 601
418 if (do_skl_residency) { 602 if (do_skl_residency) {
419 outp += sprintf(outp, "\tTotl%%C0"); 603 outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : ""));
420 outp += sprintf(outp, "\tAny%%C0"); 604 outp += sprintf(outp, "%sAny%%C0", (printed++ ? delim : ""));
421 outp += sprintf(outp, "\tGFX%%C0"); 605 outp += sprintf(outp, "%sGFX%%C0", (printed++ ? delim : ""));
422 outp += sprintf(outp, "\tCPUGFX%%"); 606 outp += sprintf(outp, "%sCPUGFX%%", (printed++ ? delim : ""));
423 }
424
425 if (do_pc2)
426 outp += sprintf(outp, "\tPkg%%pc2");
427 if (do_pc3)
428 outp += sprintf(outp, "\tPkg%%pc3");
429 if (do_pc6)
430 outp += sprintf(outp, "\tPkg%%pc6");
431 if (do_pc7)
432 outp += sprintf(outp, "\tPkg%%pc7");
433 if (do_c8_c9_c10) {
434 outp += sprintf(outp, "\tPkg%%pc8");
435 outp += sprintf(outp, "\tPkg%%pc9");
436 outp += sprintf(outp, "\tPk%%pc10");
437 } 607 }
438 608
609 if (DO_BIC(BIC_Pkgpc2))
610 outp += sprintf(outp, "%sPkg%%pc2", (printed++ ? delim : ""));
611 if (DO_BIC(BIC_Pkgpc3))
612 outp += sprintf(outp, "%sPkg%%pc3", (printed++ ? delim : ""));
613 if (DO_BIC(BIC_Pkgpc6))
614 outp += sprintf(outp, "%sPkg%%pc6", (printed++ ? delim : ""));
615 if (DO_BIC(BIC_Pkgpc7))
616 outp += sprintf(outp, "%sPkg%%pc7", (printed++ ? delim : ""));
617 if (DO_BIC(BIC_Pkgpc8))
618 outp += sprintf(outp, "%sPkg%%pc8", (printed++ ? delim : ""));
619 if (DO_BIC(BIC_Pkgpc9))
620 outp += sprintf(outp, "%sPkg%%pc9", (printed++ ? delim : ""));
621 if (DO_BIC(BIC_Pkgpc10))
622 outp += sprintf(outp, "%sPk%%pc10", (printed++ ? delim : ""));
623
439 if (do_rapl && !rapl_joules) { 624 if (do_rapl && !rapl_joules) {
440 if (do_rapl & RAPL_PKG) 625 if (DO_BIC(BIC_PkgWatt))
441 outp += sprintf(outp, "\tPkgWatt"); 626 outp += sprintf(outp, "%sPkgWatt", (printed++ ? delim : ""));
442 if (do_rapl & RAPL_CORES_ENERGY_STATUS) 627 if (DO_BIC(BIC_CorWatt))
443 outp += sprintf(outp, "\tCorWatt"); 628 outp += sprintf(outp, "%sCorWatt", (printed++ ? delim : ""));
444 if (do_rapl & RAPL_GFX) 629 if (DO_BIC(BIC_GFXWatt))
445 outp += sprintf(outp, "\tGFXWatt"); 630 outp += sprintf(outp, "%sGFXWatt", (printed++ ? delim : ""));
446 if (do_rapl & RAPL_DRAM) 631 if (DO_BIC(BIC_RAMWatt))
447 outp += sprintf(outp, "\tRAMWatt"); 632 outp += sprintf(outp, "%sRAMWatt", (printed++ ? delim : ""));
448 if (do_rapl & RAPL_PKG_PERF_STATUS) 633 if (DO_BIC(BIC_PKG__))
449 outp += sprintf(outp, "\tPKG_%%"); 634 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
450 if (do_rapl & RAPL_DRAM_PERF_STATUS) 635 if (DO_BIC(BIC_RAM__))
451 outp += sprintf(outp, "\tRAM_%%"); 636 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
452 } else if (do_rapl && rapl_joules) { 637 } else if (do_rapl && rapl_joules) {
453 if (do_rapl & RAPL_PKG) 638 if (DO_BIC(BIC_Pkg_J))
454 outp += sprintf(outp, "\tPkg_J"); 639 outp += sprintf(outp, "%sPkg_J", (printed++ ? delim : ""));
455 if (do_rapl & RAPL_CORES_ENERGY_STATUS) 640 if (DO_BIC(BIC_Cor_J))
456 outp += sprintf(outp, "\tCor_J"); 641 outp += sprintf(outp, "%sCor_J", (printed++ ? delim : ""));
457 if (do_rapl & RAPL_GFX) 642 if (DO_BIC(BIC_GFX_J))
458 outp += sprintf(outp, "\tGFX_J"); 643 outp += sprintf(outp, "%sGFX_J", (printed++ ? delim : ""));
459 if (do_rapl & RAPL_DRAM) 644 if (DO_BIC(BIC_RAM_J))
460 outp += sprintf(outp, "\tRAM_J"); 645 outp += sprintf(outp, "%sRAM_J", (printed++ ? delim : ""));
461 if (do_rapl & RAPL_PKG_PERF_STATUS) 646 if (DO_BIC(BIC_PKG__))
462 outp += sprintf(outp, "\tPKG_%%"); 647 outp += sprintf(outp, "%sPKG_%%", (printed++ ? delim : ""));
463 if (do_rapl & RAPL_DRAM_PERF_STATUS) 648 if (DO_BIC(BIC_RAM__))
464 outp += sprintf(outp, "\tRAM_%%"); 649 outp += sprintf(outp, "%sRAM_%%", (printed++ ? delim : ""));
465 } 650 }
466 for (mp = sys.pp; mp; mp = mp->next) { 651 for (mp = sys.pp; mp; mp = mp->next) {
467 if (mp->format == FORMAT_RAW) { 652 if (mp->format == FORMAT_RAW) {
468 if (mp->width == 64) 653 if (mp->width == 64)
469 outp += sprintf(outp, "\t%18.18s", mp->name); 654 outp += sprintf(outp, "%s%18.18s", delim, mp->name);
470 else 655 else
471 outp += sprintf(outp, "\t%10.10s", mp->name); 656 outp += sprintf(outp, "%s%10.10s", delim, mp->name);
472 } else { 657 } else {
473 outp += sprintf(outp, "\t%-7.7s", mp->name); 658 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
659 outp += sprintf(outp, "%s%8s", delim, mp->name);
660 else
661 outp += sprintf(outp, "%s%s", delim, mp->name);
474 } 662 }
475 } 663 }
476 664
477done:
478 outp += sprintf(outp, "\n"); 665 outp += sprintf(outp, "\n");
479} 666}
480 667
@@ -494,10 +681,10 @@ int dump_counters(struct thread_data *t, struct core_data *c,
494 outp += sprintf(outp, "mperf: %016llX\n", t->mperf); 681 outp += sprintf(outp, "mperf: %016llX\n", t->mperf);
495 outp += sprintf(outp, "c1: %016llX\n", t->c1); 682 outp += sprintf(outp, "c1: %016llX\n", t->c1);
496 683
497 if (do_irq) 684 if (DO_BIC(BIC_IRQ))
498 outp += sprintf(outp, "IRQ: %08X\n", t->irq_count); 685 outp += sprintf(outp, "IRQ: %lld\n", t->irq_count);
499 if (do_smi) 686 if (DO_BIC(BIC_SMI))
500 outp += sprintf(outp, "SMI: %08X\n", t->smi_count); 687 outp += sprintf(outp, "SMI: %d\n", t->smi_count);
501 688
502 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 689 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
503 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n", 690 outp += sprintf(outp, "tADDED [%d] msr0x%x: %08llX\n",
@@ -516,6 +703,7 @@ int dump_counters(struct thread_data *t, struct core_data *c,
516 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n", 703 outp += sprintf(outp, "cADDED [%d] msr0x%x: %08llX\n",
517 i, mp->msr_num, c->counter[i]); 704 i, mp->msr_num, c->counter[i]);
518 } 705 }
706 outp += sprintf(outp, "mc6_us: %016llX\n", c->mc6_us);
519 } 707 }
520 708
521 if (p) { 709 if (p) {
@@ -527,11 +715,11 @@ int dump_counters(struct thread_data *t, struct core_data *c,
527 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0); 715 outp += sprintf(outp, "CPU + GFX: %016llX\n", p->pkg_both_core_gfxe_c0);
528 716
529 outp += sprintf(outp, "pc2: %016llX\n", p->pc2); 717 outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
530 if (do_pc3) 718 if (DO_BIC(BIC_Pkgpc3))
531 outp += sprintf(outp, "pc3: %016llX\n", p->pc3); 719 outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
532 if (do_pc6) 720 if (DO_BIC(BIC_Pkgpc6))
533 outp += sprintf(outp, "pc6: %016llX\n", p->pc6); 721 outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
534 if (do_pc7) 722 if (DO_BIC(BIC_Pkgpc7))
535 outp += sprintf(outp, "pc7: %016llX\n", p->pc7); 723 outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
536 outp += sprintf(outp, "pc8: %016llX\n", p->pc8); 724 outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
537 outp += sprintf(outp, "pc9: %016llX\n", p->pc9); 725 outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
@@ -563,10 +751,12 @@ int dump_counters(struct thread_data *t, struct core_data *c,
563int format_counters(struct thread_data *t, struct core_data *c, 751int format_counters(struct thread_data *t, struct core_data *c,
564 struct pkg_data *p) 752 struct pkg_data *p)
565{ 753{
566 double interval_float; 754 double interval_float, tsc;
567 char *fmt8; 755 char *fmt8;
568 int i; 756 int i;
569 struct msr_counter *mp; 757 struct msr_counter *mp;
758 char *delim = "\t";
759 int printed = 0;
570 760
571 /* if showing only 1st thread in core and this isn't one, bail out */ 761 /* if showing only 1st thread in core and this isn't one, bail out */
572 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 762 if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
@@ -576,106 +766,126 @@ int format_counters(struct thread_data *t, struct core_data *c,
576 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) 766 if (show_pkg_only && !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
577 return 0; 767 return 0;
578 768
769 /*if not summary line and --cpu is used */
770 if ((t != &average.threads) &&
771 (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset)))
772 return 0;
773
579 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; 774 interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
580 775
776 tsc = t->tsc * tsc_tweak;
777
581 /* topo columns, print blanks on 1st (average) line */ 778 /* topo columns, print blanks on 1st (average) line */
582 if (t == &average.threads) { 779 if (t == &average.threads) {
583 if (show_pkg) 780 if (DO_BIC(BIC_Package))
584 outp += sprintf(outp, "\t-"); 781 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
585 if (show_core) 782 if (DO_BIC(BIC_Core))
586 outp += sprintf(outp, "\t-"); 783 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
587 if (show_cpu) 784 if (DO_BIC(BIC_CPU))
588 outp += sprintf(outp, "\t-"); 785 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
589 } else { 786 } else {
590 if (show_pkg) { 787 if (DO_BIC(BIC_Package)) {
591 if (p) 788 if (p)
592 outp += sprintf(outp, "\t%d", p->package_id); 789 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id);
593 else 790 else
594 outp += sprintf(outp, "\t-"); 791 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
595 } 792 }
596 if (show_core) { 793 if (DO_BIC(BIC_Core)) {
597 if (c) 794 if (c)
598 outp += sprintf(outp, "\t%d", c->core_id); 795 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_id);
599 else 796 else
600 outp += sprintf(outp, "\t-"); 797 outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
601 } 798 }
602 if (show_cpu) 799 if (DO_BIC(BIC_CPU))
603 outp += sprintf(outp, "\t%d", t->cpu_id); 800 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
604 } 801 }
605 802
606 /* Avg_MHz */ 803 if (DO_BIC(BIC_Avg_MHz))
607 if (has_aperf) 804 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
608 outp += sprintf(outp, "\t%.0f",
609 1.0 / units * t->aperf / interval_float); 805 1.0 / units * t->aperf / interval_float);
610 806
611 /* Busy% */ 807 if (DO_BIC(BIC_Busy))
612 if (has_aperf) 808 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->mperf/tsc);
613 outp += sprintf(outp, "\t%.2f", 100.0 * t->mperf/t->tsc/tsc_tweak);
614 809
615 /* Bzy_MHz */ 810 if (DO_BIC(BIC_Bzy_MHz)) {
616 if (has_aperf) {
617 if (has_base_hz) 811 if (has_base_hz)
618 outp += sprintf(outp, "\t%.0f", base_hz / units * t->aperf / t->mperf); 812 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), base_hz / units * t->aperf / t->mperf);
619 else 813 else
620 outp += sprintf(outp, "\t%.0f", 814 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""),
621 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); 815 tsc / units * t->aperf / t->mperf / interval_float);
622 } 816 }
623 817
624 /* TSC_MHz */ 818 if (DO_BIC(BIC_TSC_MHz))
625 outp += sprintf(outp, "\t%.0f", 1.0 * t->tsc/units/interval_float); 819 outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 * t->tsc/units/interval_float);
626
627 if (!debug)
628 goto done;
629 820
630 /* IRQ */ 821 /* IRQ */
631 if (do_irq) 822 if (DO_BIC(BIC_IRQ)) {
632 outp += sprintf(outp, "\t%d", t->irq_count); 823 if (sums_need_wide_columns)
824 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->irq_count);
825 else
826 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->irq_count);
827 }
633 828
634 /* SMI */ 829 /* SMI */
635 if (do_smi) 830 if (DO_BIC(BIC_SMI))
636 outp += sprintf(outp, "\t%d", t->smi_count); 831 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->smi_count);
637
638 if (do_nhm_cstates)
639 outp += sprintf(outp, "\t%.2f", 100.0 * t->c1/t->tsc);
640
641 /* print per-core data only for 1st thread in core */
642 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
643 goto done;
644
645 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates)
646 outp += sprintf(outp, "\t%.2f", 100.0 * c->c3/t->tsc);
647 if (do_nhm_cstates)
648 outp += sprintf(outp, "\t%.2f", 100.0 * c->c6/t->tsc);
649 if (do_snb_cstates)
650 outp += sprintf(outp, "\t%.2f", 100.0 * c->c7/t->tsc);
651 832
833 /* Added counters */
652 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 834 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
653 if (mp->format == FORMAT_RAW) { 835 if (mp->format == FORMAT_RAW) {
654 if (mp->width == 32) 836 if (mp->width == 32)
655 outp += sprintf(outp, "\t0x%08lx", (unsigned long) t->counter[i]); 837 outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) t->counter[i]);
656 else 838 else
657 outp += sprintf(outp, "\t0x%016llx", t->counter[i]); 839 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]);
658 } else if (mp->format == FORMAT_DELTA) { 840 } else if (mp->format == FORMAT_DELTA) {
659 outp += sprintf(outp, "\t%8lld", t->counter[i]); 841 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
842 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->counter[i]);
843 else
844 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), t->counter[i]);
660 } else if (mp->format == FORMAT_PERCENT) { 845 } else if (mp->format == FORMAT_PERCENT) {
661 outp += sprintf(outp, "\t%.2f", 100.0 * t->counter[i]/t->tsc); 846 if (mp->type == COUNTER_USEC)
847 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), t->counter[i]/interval_float/10000);
848 else
849 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->counter[i]/tsc);
662 } 850 }
663 } 851 }
664 852
853 /* C1 */
854 if (DO_BIC(BIC_CPU_c1))
855 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * t->c1/tsc);
665 856
666 if (do_dts) 857
667 outp += sprintf(outp, "\t%d", c->core_temp_c); 858 /* print per-core data only for 1st thread in core */
859 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
860 goto done;
861
862 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates)
863 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c3/tsc);
864 if (DO_BIC(BIC_CPU_c6))
865 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c6/tsc);
866 if (DO_BIC(BIC_CPU_c7))
867 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->c7/tsc);
868
869 /* Mod%c6 */
870 if (DO_BIC(BIC_Mod_c6))
871 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->mc6_us / tsc);
872
873 if (DO_BIC(BIC_CoreTmp))
874 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c);
668 875
669 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 876 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
670 if (mp->format == FORMAT_RAW) { 877 if (mp->format == FORMAT_RAW) {
671 if (mp->width == 32) 878 if (mp->width == 32)
672 outp += sprintf(outp, "\t0x%08lx", (unsigned long) c->counter[i]); 879 outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) c->counter[i]);
673 else 880 else
674 outp += sprintf(outp, "\t0x%016llx", c->counter[i]); 881 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]);
675 } else if (mp->format == FORMAT_DELTA) { 882 } else if (mp->format == FORMAT_DELTA) {
676 outp += sprintf(outp, "\t%8lld", c->counter[i]); 883 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
884 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), c->counter[i]);
885 else
886 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->counter[i]);
677 } else if (mp->format == FORMAT_PERCENT) { 887 } else if (mp->format == FORMAT_PERCENT) {
678 outp += sprintf(outp, "\t%.2f", 100.0 * c->counter[i]/t->tsc); 888 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * c->counter[i]/tsc);
679 } 889 }
680 } 890 }
681 891
@@ -684,95 +894,89 @@ int format_counters(struct thread_data *t, struct core_data *c,
684 goto done; 894 goto done;
685 895
686 /* PkgTmp */ 896 /* PkgTmp */
687 if (do_ptm) 897 if (DO_BIC(BIC_PkgTmp))
688 outp += sprintf(outp, "\t%d", p->pkg_temp_c); 898 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->pkg_temp_c);
689 899
690 /* GFXrc6 */ 900 /* GFXrc6 */
691 if (do_gfx_rc6_ms) { 901 if (DO_BIC(BIC_GFX_rc6)) {
692 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */ 902 if (p->gfx_rc6_ms == -1) { /* detect GFX counter reset */
693 outp += sprintf(outp, "\t**.**"); 903 outp += sprintf(outp, "%s**.**", (printed++ ? delim : ""));
694 } else { 904 } else {
695 outp += sprintf(outp, "\t%.2f", 905 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""),
696 p->gfx_rc6_ms / 10.0 / interval_float); 906 p->gfx_rc6_ms / 10.0 / interval_float);
697 } 907 }
698 } 908 }
699 909
700 /* GFXMHz */ 910 /* GFXMHz */
701 if (do_gfx_mhz) 911 if (DO_BIC(BIC_GFXMHz))
702 outp += sprintf(outp, "\t%d", p->gfx_mhz); 912 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz);
703 913
704 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */ 914 /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */
705 if (do_skl_residency) { 915 if (do_skl_residency) {
706 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_wtd_core_c0/t->tsc); 916 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0/tsc);
707 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_core_c0/t->tsc); 917 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0/tsc);
708 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_any_gfxe_c0/t->tsc); 918 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0/tsc);
709 outp += sprintf(outp, "\t%.2f", 100.0 * p->pkg_both_core_gfxe_c0/t->tsc); 919 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0/tsc);
710 }
711
712 if (do_pc2)
713 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc2/t->tsc);
714 if (do_pc3)
715 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc3/t->tsc);
716 if (do_pc6)
717 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc6/t->tsc);
718 if (do_pc7)
719 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc7/t->tsc);
720 if (do_c8_c9_c10) {
721 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc8/t->tsc);
722 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc9/t->tsc);
723 outp += sprintf(outp, "\t%.2f", 100.0 * p->pc10/t->tsc);
724 } 920 }
725 921
922 if (DO_BIC(BIC_Pkgpc2))
923 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2/tsc);
924 if (DO_BIC(BIC_Pkgpc3))
925 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc3/tsc);
926 if (DO_BIC(BIC_Pkgpc6))
927 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc6/tsc);
928 if (DO_BIC(BIC_Pkgpc7))
929 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc7/tsc);
930 if (DO_BIC(BIC_Pkgpc8))
931 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc8/tsc);
932 if (DO_BIC(BIC_Pkgpc9))
933 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc9/tsc);
934 if (DO_BIC(BIC_Pkgpc10))
935 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc10/tsc);
936
726 /* 937 /*
727 * If measurement interval exceeds minimum RAPL Joule Counter range, 938 * If measurement interval exceeds minimum RAPL Joule Counter range,
728 * indicate that results are suspect by printing "**" in fraction place. 939 * indicate that results are suspect by printing "**" in fraction place.
729 */ 940 */
730 if (interval_float < rapl_joule_counter_range) 941 if (interval_float < rapl_joule_counter_range)
731 fmt8 = "\t%.2f"; 942 fmt8 = "%s%.2f";
732 else 943 else
733 fmt8 = "%6.0f**"; 944 fmt8 = "%6.0f**";
734 945
735 if (do_rapl && !rapl_joules) { 946 if (DO_BIC(BIC_PkgWatt))
736 if (do_rapl & RAPL_PKG) 947 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units / interval_float);
737 outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float); 948 if (DO_BIC(BIC_CorWatt))
738 if (do_rapl & RAPL_CORES_ENERGY_STATUS) 949 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units / interval_float);
739 outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float); 950 if (DO_BIC(BIC_GFXWatt))
740 if (do_rapl & RAPL_GFX) 951 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units / interval_float);
741 outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float); 952 if (DO_BIC(BIC_RAMWatt))
742 if (do_rapl & RAPL_DRAM) 953 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units / interval_float);
743 outp += sprintf(outp, fmt8, p->energy_dram * rapl_dram_energy_units / interval_float); 954 if (DO_BIC(BIC_Pkg_J))
744 if (do_rapl & RAPL_PKG_PERF_STATUS) 955 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_pkg * rapl_energy_units);
745 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); 956 if (DO_BIC(BIC_Cor_J))
746 if (do_rapl & RAPL_DRAM_PERF_STATUS) 957 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_cores * rapl_energy_units);
747 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); 958 if (DO_BIC(BIC_GFX_J))
748 } else if (do_rapl && rapl_joules) { 959 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_gfx * rapl_energy_units);
749 if (do_rapl & RAPL_PKG) 960 if (DO_BIC(BIC_RAM_J))
750 outp += sprintf(outp, fmt8, 961 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), p->energy_dram * rapl_dram_energy_units);
751 p->energy_pkg * rapl_energy_units); 962 if (DO_BIC(BIC_PKG__))
752 if (do_rapl & RAPL_CORES) 963 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
753 outp += sprintf(outp, fmt8, 964 if (DO_BIC(BIC_RAM__))
754 p->energy_cores * rapl_energy_units); 965 outp += sprintf(outp, fmt8, (printed++ ? delim : ""), 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
755 if (do_rapl & RAPL_GFX) 966
756 outp += sprintf(outp, fmt8,
757 p->energy_gfx * rapl_energy_units);
758 if (do_rapl & RAPL_DRAM)
759 outp += sprintf(outp, fmt8,
760 p->energy_dram * rapl_dram_energy_units);
761 if (do_rapl & RAPL_PKG_PERF_STATUS)
762 outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
763 if (do_rapl & RAPL_DRAM_PERF_STATUS)
764 outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
765 }
766 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 967 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
767 if (mp->format == FORMAT_RAW) { 968 if (mp->format == FORMAT_RAW) {
768 if (mp->width == 32) 969 if (mp->width == 32)
769 outp += sprintf(outp, "\t0x%08lx", (unsigned long) p->counter[i]); 970 outp += sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int) p->counter[i]);
770 else 971 else
771 outp += sprintf(outp, "\t0x%016llx", p->counter[i]); 972 outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), p->counter[i]);
772 } else if (mp->format == FORMAT_DELTA) { 973 } else if (mp->format == FORMAT_DELTA) {
773 outp += sprintf(outp, "\t%8lld", p->counter[i]); 974 if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns)
975 outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), p->counter[i]);
976 else
977 outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), p->counter[i]);
774 } else if (mp->format == FORMAT_PERCENT) { 978 } else if (mp->format == FORMAT_PERCENT) {
775 outp += sprintf(outp, "\t%.2f", 100.0 * p->counter[i]/t->tsc); 979 outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->counter[i]/tsc);
776 } 980 }
777 } 981 }
778 982
@@ -807,7 +1011,7 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_
807 static int printed; 1011 static int printed;
808 1012
809 if (!printed || !summary_only) 1013 if (!printed || !summary_only)
810 print_header(); 1014 print_header("\t");
811 1015
812 if (topo.num_cpus > 1) 1016 if (topo.num_cpus > 1)
813 format_counters(&average.threads, &average.cores, 1017 format_counters(&average.threads, &average.cores,
@@ -841,11 +1045,11 @@ delta_package(struct pkg_data *new, struct pkg_data *old)
841 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0; 1045 old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0;
842 } 1046 }
843 old->pc2 = new->pc2 - old->pc2; 1047 old->pc2 = new->pc2 - old->pc2;
844 if (do_pc3) 1048 if (DO_BIC(BIC_Pkgpc3))
845 old->pc3 = new->pc3 - old->pc3; 1049 old->pc3 = new->pc3 - old->pc3;
846 if (do_pc6) 1050 if (DO_BIC(BIC_Pkgpc6))
847 old->pc6 = new->pc6 - old->pc6; 1051 old->pc6 = new->pc6 - old->pc6;
848 if (do_pc7) 1052 if (DO_BIC(BIC_Pkgpc7))
849 old->pc7 = new->pc7 - old->pc7; 1053 old->pc7 = new->pc7 - old->pc7;
850 old->pc8 = new->pc8 - old->pc8; 1054 old->pc8 = new->pc8 - old->pc8;
851 old->pc9 = new->pc9 - old->pc9; 1055 old->pc9 = new->pc9 - old->pc9;
@@ -887,6 +1091,7 @@ delta_core(struct core_data *new, struct core_data *old)
887 old->c6 = new->c6 - old->c6; 1091 old->c6 = new->c6 - old->c6;
888 old->c7 = new->c7 - old->c7; 1092 old->c7 = new->c7 - old->c7;
889 old->core_temp_c = new->core_temp_c; 1093 old->core_temp_c = new->core_temp_c;
1094 old->mc6_us = new->mc6_us - old->mc6_us;
890 1095
891 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 1096 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
892 if (mp->format == FORMAT_RAW) 1097 if (mp->format == FORMAT_RAW)
@@ -916,7 +1121,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
916 1121
917 old->c1 = new->c1 - old->c1; 1122 old->c1 = new->c1 - old->c1;
918 1123
919 if (has_aperf) { 1124 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
920 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) { 1125 if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
921 old->aperf = new->aperf - old->aperf; 1126 old->aperf = new->aperf - old->aperf;
922 old->mperf = new->mperf - old->mperf; 1127 old->mperf = new->mperf - old->mperf;
@@ -941,7 +1146,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
941 old->c1 = 0; 1146 old->c1 = 0;
942 else { 1147 else {
943 /* normal case, derive c1 */ 1148 /* normal case, derive c1 */
944 old->c1 = old->tsc - old->mperf - core_delta->c3 1149 old->c1 = (old->tsc * tsc_tweak) - old->mperf - core_delta->c3
945 - core_delta->c6 - core_delta->c7; 1150 - core_delta->c6 - core_delta->c7;
946 } 1151 }
947 } 1152 }
@@ -952,10 +1157,10 @@ delta_thread(struct thread_data *new, struct thread_data *old,
952 old->mperf = 1; /* divide by 0 protection */ 1157 old->mperf = 1; /* divide by 0 protection */
953 } 1158 }
954 1159
955 if (do_irq) 1160 if (DO_BIC(BIC_IRQ))
956 old->irq_count = new->irq_count - old->irq_count; 1161 old->irq_count = new->irq_count - old->irq_count;
957 1162
958 if (do_smi) 1163 if (DO_BIC(BIC_SMI))
959 old->smi_count = new->smi_count - old->smi_count; 1164 old->smi_count = new->smi_count - old->smi_count;
960 1165
961 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 1166 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
@@ -1008,6 +1213,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
1008 c->c3 = 0; 1213 c->c3 = 0;
1009 c->c6 = 0; 1214 c->c6 = 0;
1010 c->c7 = 0; 1215 c->c7 = 0;
1216 c->mc6_us = 0;
1011 c->core_temp_c = 0; 1217 c->core_temp_c = 0;
1012 1218
1013 p->pkg_wtd_core_c0 = 0; 1219 p->pkg_wtd_core_c0 = 0;
@@ -1016,11 +1222,11 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
1016 p->pkg_both_core_gfxe_c0 = 0; 1222 p->pkg_both_core_gfxe_c0 = 0;
1017 1223
1018 p->pc2 = 0; 1224 p->pc2 = 0;
1019 if (do_pc3) 1225 if (DO_BIC(BIC_Pkgpc3))
1020 p->pc3 = 0; 1226 p->pc3 = 0;
1021 if (do_pc6) 1227 if (DO_BIC(BIC_Pkgpc6))
1022 p->pc6 = 0; 1228 p->pc6 = 0;
1023 if (do_pc7) 1229 if (DO_BIC(BIC_Pkgpc7))
1024 p->pc7 = 0; 1230 p->pc7 = 0;
1025 p->pc8 = 0; 1231 p->pc8 = 0;
1026 p->pc9 = 0; 1232 p->pc9 = 0;
@@ -1036,7 +1242,6 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
1036 1242
1037 p->gfx_rc6_ms = 0; 1243 p->gfx_rc6_ms = 0;
1038 p->gfx_mhz = 0; 1244 p->gfx_mhz = 0;
1039
1040 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) 1245 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next)
1041 t->counter[i] = 0; 1246 t->counter[i] = 0;
1042 1247
@@ -1073,6 +1278,7 @@ int sum_counters(struct thread_data *t, struct core_data *c,
1073 average.cores.c3 += c->c3; 1278 average.cores.c3 += c->c3;
1074 average.cores.c6 += c->c6; 1279 average.cores.c6 += c->c6;
1075 average.cores.c7 += c->c7; 1280 average.cores.c7 += c->c7;
1281 average.cores.mc6_us += c->mc6_us;
1076 1282
1077 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); 1283 average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c);
1078 1284
@@ -1094,11 +1300,11 @@ int sum_counters(struct thread_data *t, struct core_data *c,
1094 } 1300 }
1095 1301
1096 average.packages.pc2 += p->pc2; 1302 average.packages.pc2 += p->pc2;
1097 if (do_pc3) 1303 if (DO_BIC(BIC_Pkgpc3))
1098 average.packages.pc3 += p->pc3; 1304 average.packages.pc3 += p->pc3;
1099 if (do_pc6) 1305 if (DO_BIC(BIC_Pkgpc6))
1100 average.packages.pc6 += p->pc6; 1306 average.packages.pc6 += p->pc6;
1101 if (do_pc7) 1307 if (DO_BIC(BIC_Pkgpc7))
1102 average.packages.pc7 += p->pc7; 1308 average.packages.pc7 += p->pc7;
1103 average.packages.pc8 += p->pc8; 1309 average.packages.pc8 += p->pc8;
1104 average.packages.pc9 += p->pc9; 1310 average.packages.pc9 += p->pc9;
@@ -1143,9 +1349,13 @@ void compute_average(struct thread_data *t, struct core_data *c,
1143 average.threads.mperf /= topo.num_cpus; 1349 average.threads.mperf /= topo.num_cpus;
1144 average.threads.c1 /= topo.num_cpus; 1350 average.threads.c1 /= topo.num_cpus;
1145 1351
1352 if (average.threads.irq_count > 9999999)
1353 sums_need_wide_columns = 1;
1354
1146 average.cores.c3 /= topo.num_cores; 1355 average.cores.c3 /= topo.num_cores;
1147 average.cores.c6 /= topo.num_cores; 1356 average.cores.c6 /= topo.num_cores;
1148 average.cores.c7 /= topo.num_cores; 1357 average.cores.c7 /= topo.num_cores;
1358 average.cores.mc6_us /= topo.num_cores;
1149 1359
1150 if (do_skl_residency) { 1360 if (do_skl_residency) {
1151 average.packages.pkg_wtd_core_c0 /= topo.num_packages; 1361 average.packages.pkg_wtd_core_c0 /= topo.num_packages;
@@ -1155,11 +1365,11 @@ void compute_average(struct thread_data *t, struct core_data *c,
1155 } 1365 }
1156 1366
1157 average.packages.pc2 /= topo.num_packages; 1367 average.packages.pc2 /= topo.num_packages;
1158 if (do_pc3) 1368 if (DO_BIC(BIC_Pkgpc3))
1159 average.packages.pc3 /= topo.num_packages; 1369 average.packages.pc3 /= topo.num_packages;
1160 if (do_pc6) 1370 if (DO_BIC(BIC_Pkgpc6))
1161 average.packages.pc6 /= topo.num_packages; 1371 average.packages.pc6 /= topo.num_packages;
1162 if (do_pc7) 1372 if (DO_BIC(BIC_Pkgpc7))
1163 average.packages.pc7 /= topo.num_packages; 1373 average.packages.pc7 /= topo.num_packages;
1164 1374
1165 average.packages.pc8 /= topo.num_packages; 1375 average.packages.pc8 /= topo.num_packages;
@@ -1169,16 +1379,29 @@ void compute_average(struct thread_data *t, struct core_data *c,
1169 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 1379 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1170 if (mp->format == FORMAT_RAW) 1380 if (mp->format == FORMAT_RAW)
1171 continue; 1381 continue;
1382 if (mp->type == COUNTER_ITEMS) {
1383 if (average.threads.counter[i] > 9999999)
1384 sums_need_wide_columns = 1;
1385 continue;
1386 }
1172 average.threads.counter[i] /= topo.num_cpus; 1387 average.threads.counter[i] /= topo.num_cpus;
1173 } 1388 }
1174 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 1389 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1175 if (mp->format == FORMAT_RAW) 1390 if (mp->format == FORMAT_RAW)
1176 continue; 1391 continue;
1392 if (mp->type == COUNTER_ITEMS) {
1393 if (average.cores.counter[i] > 9999999)
1394 sums_need_wide_columns = 1;
1395 }
1177 average.cores.counter[i] /= topo.num_cores; 1396 average.cores.counter[i] /= topo.num_cores;
1178 } 1397 }
1179 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 1398 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1180 if (mp->format == FORMAT_RAW) 1399 if (mp->format == FORMAT_RAW)
1181 continue; 1400 continue;
1401 if (mp->type == COUNTER_ITEMS) {
1402 if (average.packages.counter[i] > 9999999)
1403 sums_need_wide_columns = 1;
1404 }
1182 average.packages.counter[i] /= topo.num_packages; 1405 average.packages.counter[i] /= topo.num_packages;
1183 } 1406 }
1184} 1407}
@@ -1193,6 +1416,60 @@ static unsigned long long rdtsc(void)
1193} 1416}
1194 1417
1195/* 1418/*
1419 * Open a file, and exit on failure
1420 */
1421FILE *fopen_or_die(const char *path, const char *mode)
1422{
1423 FILE *filep = fopen(path, mode);
1424
1425 if (!filep)
1426 err(1, "%s: open failed", path);
1427 return filep;
1428}
1429/*
1430 * snapshot_sysfs_counter()
1431 *
1432 * return snapshot of given counter
1433 */
1434unsigned long long snapshot_sysfs_counter(char *path)
1435{
1436 FILE *fp;
1437 int retval;
1438 unsigned long long counter;
1439
1440 fp = fopen_or_die(path, "r");
1441
1442 retval = fscanf(fp, "%lld", &counter);
1443 if (retval != 1)
1444 err(1, "snapshot_sysfs_counter(%s)", path);
1445
1446 fclose(fp);
1447
1448 return counter;
1449}
1450
1451int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
1452{
1453 if (mp->msr_num != 0) {
1454 if (get_msr(cpu, mp->msr_num, counterp))
1455 return -1;
1456 } else {
1457 char path[128];
1458
1459 if (mp->flags & SYSFS_PERCPU) {
1460 sprintf(path, "/sys/devices/system/cpu/cpu%d/%s",
1461 cpu, mp->path);
1462
1463 *counterp = snapshot_sysfs_counter(path);
1464 } else {
1465 *counterp = snapshot_sysfs_counter(mp->path);
1466 }
1467 }
1468
1469 return 0;
1470}
1471
1472/*
1196 * get_counters(...) 1473 * get_counters(...)
1197 * migrate to cpu 1474 * migrate to cpu
1198 * acquire and record local counters for that cpu 1475 * acquire and record local counters for that cpu
@@ -1213,7 +1490,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
1213retry: 1490retry:
1214 t->tsc = rdtsc(); /* we are running on local CPU of interest */ 1491 t->tsc = rdtsc(); /* we are running on local CPU of interest */
1215 1492
1216 if (has_aperf) { 1493 if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
1217 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time; 1494 unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
1218 1495
1219 /* 1496 /*
@@ -1269,35 +1546,33 @@ retry:
1269 t->mperf = t->mperf * aperf_mperf_multiplier; 1546 t->mperf = t->mperf * aperf_mperf_multiplier;
1270 } 1547 }
1271 1548
1272 if (do_irq) 1549 if (DO_BIC(BIC_IRQ))
1273 t->irq_count = irqs_per_cpu[cpu]; 1550 t->irq_count = irqs_per_cpu[cpu];
1274 if (do_smi) { 1551 if (DO_BIC(BIC_SMI)) {
1275 if (get_msr(cpu, MSR_SMI_COUNT, &msr)) 1552 if (get_msr(cpu, MSR_SMI_COUNT, &msr))
1276 return -5; 1553 return -5;
1277 t->smi_count = msr & 0xFFFFFFFF; 1554 t->smi_count = msr & 0xFFFFFFFF;
1278 } 1555 }
1279 1556 if (DO_BIC(BIC_CPU_c1) && use_c1_residency_msr) {
1280 if (use_c1_residency_msr) {
1281 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1)) 1557 if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1))
1282 return -6; 1558 return -6;
1283 } 1559 }
1284 1560
1285 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { 1561 for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) {
1286 if (get_msr(cpu, mp->msr_num, &t->counter[i])) 1562 if (get_mp(cpu, mp, &t->counter[i]))
1287 return -10; 1563 return -10;
1288 } 1564 }
1289 1565
1290
1291 /* collect core counters only for 1st thread in core */ 1566 /* collect core counters only for 1st thread in core */
1292 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) 1567 if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
1293 return 0; 1568 return 0;
1294 1569
1295 if (do_nhm_cstates && !do_slm_cstates && !do_knl_cstates) { 1570 if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates) {
1296 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) 1571 if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
1297 return -6; 1572 return -6;
1298 } 1573 }
1299 1574
1300 if (do_nhm_cstates && !do_knl_cstates) { 1575 if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) {
1301 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) 1576 if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
1302 return -7; 1577 return -7;
1303 } else if (do_knl_cstates) { 1578 } else if (do_knl_cstates) {
@@ -1305,18 +1580,22 @@ retry:
1305 return -7; 1580 return -7;
1306 } 1581 }
1307 1582
1308 if (do_snb_cstates) 1583 if (DO_BIC(BIC_CPU_c7))
1309 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7)) 1584 if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
1310 return -8; 1585 return -8;
1311 1586
1312 if (do_dts) { 1587 if (DO_BIC(BIC_Mod_c6))
1588 if (get_msr(cpu, MSR_MODULE_C6_RES_MS, &c->mc6_us))
1589 return -8;
1590
1591 if (DO_BIC(BIC_CoreTmp)) {
1313 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr)) 1592 if (get_msr(cpu, MSR_IA32_THERM_STATUS, &msr))
1314 return -9; 1593 return -9;
1315 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); 1594 c->core_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1316 } 1595 }
1317 1596
1318 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { 1597 for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) {
1319 if (get_msr(cpu, mp->msr_num, &c->counter[i])) 1598 if (get_mp(cpu, mp, &c->counter[i]))
1320 return -10; 1599 return -10;
1321 } 1600 }
1322 1601
@@ -1334,26 +1613,35 @@ retry:
1334 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0)) 1613 if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0))
1335 return -13; 1614 return -13;
1336 } 1615 }
1337 if (do_pc3) 1616 if (DO_BIC(BIC_Pkgpc3))
1338 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) 1617 if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
1339 return -9; 1618 return -9;
1340 if (do_pc6) 1619 if (DO_BIC(BIC_Pkgpc6)) {
1341 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) 1620 if (do_slm_cstates) {
1342 return -10; 1621 if (get_msr(cpu, MSR_ATOM_PKG_C6_RESIDENCY, &p->pc6))
1343 if (do_pc2) 1622 return -10;
1623 } else {
1624 if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
1625 return -10;
1626 }
1627 }
1628
1629 if (DO_BIC(BIC_Pkgpc2))
1344 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2)) 1630 if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
1345 return -11; 1631 return -11;
1346 if (do_pc7) 1632 if (DO_BIC(BIC_Pkgpc7))
1347 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) 1633 if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
1348 return -12; 1634 return -12;
1349 if (do_c8_c9_c10) { 1635 if (DO_BIC(BIC_Pkgpc8))
1350 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8)) 1636 if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
1351 return -13; 1637 return -13;
1638 if (DO_BIC(BIC_Pkgpc9))
1352 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9)) 1639 if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9))
1353 return -13; 1640 return -13;
1641 if (DO_BIC(BIC_Pkgpc10))
1354 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10)) 1642 if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10))
1355 return -13; 1643 return -13;
1356 } 1644
1357 if (do_rapl & RAPL_PKG) { 1645 if (do_rapl & RAPL_PKG) {
1358 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr)) 1646 if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr))
1359 return -13; 1647 return -13;
@@ -1384,20 +1672,20 @@ retry:
1384 return -16; 1672 return -16;
1385 p->rapl_dram_perf_status = msr & 0xFFFFFFFF; 1673 p->rapl_dram_perf_status = msr & 0xFFFFFFFF;
1386 } 1674 }
1387 if (do_ptm) { 1675 if (DO_BIC(BIC_PkgTmp)) {
1388 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr)) 1676 if (get_msr(cpu, MSR_IA32_PACKAGE_THERM_STATUS, &msr))
1389 return -17; 1677 return -17;
1390 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F); 1678 p->pkg_temp_c = tcc_activation_temp - ((msr >> 16) & 0x7F);
1391 } 1679 }
1392 1680
1393 if (do_gfx_rc6_ms) 1681 if (DO_BIC(BIC_GFX_rc6))
1394 p->gfx_rc6_ms = gfx_cur_rc6_ms; 1682 p->gfx_rc6_ms = gfx_cur_rc6_ms;
1395 1683
1396 if (do_gfx_mhz) 1684 if (DO_BIC(BIC_GFXMHz))
1397 p->gfx_mhz = gfx_cur_mhz; 1685 p->gfx_mhz = gfx_cur_mhz;
1398 1686
1399 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { 1687 for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) {
1400 if (get_msr(cpu, mp->msr_num, &p->counter[i])) 1688 if (get_mp(cpu, mp, &p->counter[i]))
1401 return -10; 1689 return -10;
1402 } 1690 }
1403 1691
@@ -1433,8 +1721,8 @@ char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
1433int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1721int nhm_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1434int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1722int snb_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1435int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1723int hsw_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCL__8, PCL__9, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1436int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1724int slv_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
1437int amt_pkg_cstate_limits[16] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1725int amt_pkg_cstate_limits[16] = {PCLUNL, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1438int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1726int phi_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1439int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1727int bxt_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
1440int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV}; 1728int skx_pkg_cstate_limits[16] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLUNL, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV, PCLRSV};
@@ -1457,11 +1745,11 @@ dump_nhm_platform_info(void)
1457 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr); 1745 fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr);
1458 1746
1459 ratio = (msr >> 40) & 0xFF; 1747 ratio = (msr >> 40) & 0xFF;
1460 fprintf(outf, "%d * %.0f = %.0f MHz max efficiency frequency\n", 1748 fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n",
1461 ratio, bclk, ratio * bclk); 1749 ratio, bclk, ratio * bclk);
1462 1750
1463 ratio = (msr >> 8) & 0xFF; 1751 ratio = (msr >> 8) & 0xFF;
1464 fprintf(outf, "%d * %.0f = %.0f MHz base frequency\n", 1752 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
1465 ratio, bclk, ratio * bclk); 1753 ratio, bclk, ratio * bclk);
1466 1754
1467 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr); 1755 get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr);
@@ -1483,12 +1771,12 @@ dump_hsw_turbo_ratio_limits(void)
1483 1771
1484 ratio = (msr >> 8) & 0xFF; 1772 ratio = (msr >> 8) & 0xFF;
1485 if (ratio) 1773 if (ratio)
1486 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 18 active cores\n", 1774 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 18 active cores\n",
1487 ratio, bclk, ratio * bclk); 1775 ratio, bclk, ratio * bclk);
1488 1776
1489 ratio = (msr >> 0) & 0xFF; 1777 ratio = (msr >> 0) & 0xFF;
1490 if (ratio) 1778 if (ratio)
1491 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 17 active cores\n", 1779 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 17 active cores\n",
1492 ratio, bclk, ratio * bclk); 1780 ratio, bclk, ratio * bclk);
1493 return; 1781 return;
1494} 1782}
@@ -1505,99 +1793,175 @@ dump_ivt_turbo_ratio_limits(void)
1505 1793
1506 ratio = (msr >> 56) & 0xFF; 1794 ratio = (msr >> 56) & 0xFF;
1507 if (ratio) 1795 if (ratio)
1508 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 16 active cores\n", 1796 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 16 active cores\n",
1509 ratio, bclk, ratio * bclk); 1797 ratio, bclk, ratio * bclk);
1510 1798
1511 ratio = (msr >> 48) & 0xFF; 1799 ratio = (msr >> 48) & 0xFF;
1512 if (ratio) 1800 if (ratio)
1513 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 15 active cores\n", 1801 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 15 active cores\n",
1514 ratio, bclk, ratio * bclk); 1802 ratio, bclk, ratio * bclk);
1515 1803
1516 ratio = (msr >> 40) & 0xFF; 1804 ratio = (msr >> 40) & 0xFF;
1517 if (ratio) 1805 if (ratio)
1518 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 14 active cores\n", 1806 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 14 active cores\n",
1519 ratio, bclk, ratio * bclk); 1807 ratio, bclk, ratio * bclk);
1520 1808
1521 ratio = (msr >> 32) & 0xFF; 1809 ratio = (msr >> 32) & 0xFF;
1522 if (ratio) 1810 if (ratio)
1523 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 13 active cores\n", 1811 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 13 active cores\n",
1524 ratio, bclk, ratio * bclk); 1812 ratio, bclk, ratio * bclk);
1525 1813
1526 ratio = (msr >> 24) & 0xFF; 1814 ratio = (msr >> 24) & 0xFF;
1527 if (ratio) 1815 if (ratio)
1528 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 12 active cores\n", 1816 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 12 active cores\n",
1529 ratio, bclk, ratio * bclk); 1817 ratio, bclk, ratio * bclk);
1530 1818
1531 ratio = (msr >> 16) & 0xFF; 1819 ratio = (msr >> 16) & 0xFF;
1532 if (ratio) 1820 if (ratio)
1533 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 11 active cores\n", 1821 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 11 active cores\n",
1534 ratio, bclk, ratio * bclk); 1822 ratio, bclk, ratio * bclk);
1535 1823
1536 ratio = (msr >> 8) & 0xFF; 1824 ratio = (msr >> 8) & 0xFF;
1537 if (ratio) 1825 if (ratio)
1538 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 10 active cores\n", 1826 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 10 active cores\n",
1539 ratio, bclk, ratio * bclk); 1827 ratio, bclk, ratio * bclk);
1540 1828
1541 ratio = (msr >> 0) & 0xFF; 1829 ratio = (msr >> 0) & 0xFF;
1542 if (ratio) 1830 if (ratio)
1543 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 9 active cores\n", 1831 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 9 active cores\n",
1544 ratio, bclk, ratio * bclk); 1832 ratio, bclk, ratio * bclk);
1545 return; 1833 return;
1546} 1834}
1835int has_turbo_ratio_group_limits(int family, int model)
1836{
1837
1838 if (!genuine_intel)
1839 return 0;
1840
1841 switch (model) {
1842 case INTEL_FAM6_ATOM_GOLDMONT:
1843 case INTEL_FAM6_SKYLAKE_X:
1844 case INTEL_FAM6_ATOM_DENVERTON:
1845 return 1;
1846 }
1847 return 0;
1848}
1547 1849
1548static void 1850static void
1549dump_nhm_turbo_ratio_limits(void) 1851dump_turbo_ratio_limits(int family, int model)
1550{ 1852{
1551 unsigned long long msr; 1853 unsigned long long msr, core_counts;
1552 unsigned int ratio; 1854 unsigned int ratio, group_size;
1553 1855
1554 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr); 1856 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
1555
1556 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr); 1857 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr);
1557 1858
1859 if (has_turbo_ratio_group_limits(family, model)) {
1860 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts);
1861 fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts);
1862 } else {
1863 core_counts = 0x0807060504030201;
1864 }
1865
1558 ratio = (msr >> 56) & 0xFF; 1866 ratio = (msr >> 56) & 0xFF;
1867 group_size = (core_counts >> 56) & 0xFF;
1559 if (ratio) 1868 if (ratio)
1560 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 8 active cores\n", 1869 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1561 ratio, bclk, ratio * bclk); 1870 ratio, bclk, ratio * bclk, group_size);
1562 1871
1563 ratio = (msr >> 48) & 0xFF; 1872 ratio = (msr >> 48) & 0xFF;
1873 group_size = (core_counts >> 48) & 0xFF;
1564 if (ratio) 1874 if (ratio)
1565 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 7 active cores\n", 1875 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1566 ratio, bclk, ratio * bclk); 1876 ratio, bclk, ratio * bclk, group_size);
1567 1877
1568 ratio = (msr >> 40) & 0xFF; 1878 ratio = (msr >> 40) & 0xFF;
1879 group_size = (core_counts >> 40) & 0xFF;
1569 if (ratio) 1880 if (ratio)
1570 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 6 active cores\n", 1881 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1571 ratio, bclk, ratio * bclk); 1882 ratio, bclk, ratio * bclk, group_size);
1572 1883
1573 ratio = (msr >> 32) & 0xFF; 1884 ratio = (msr >> 32) & 0xFF;
1885 group_size = (core_counts >> 32) & 0xFF;
1574 if (ratio) 1886 if (ratio)
1575 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 5 active cores\n", 1887 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1576 ratio, bclk, ratio * bclk); 1888 ratio, bclk, ratio * bclk, group_size);
1577 1889
1578 ratio = (msr >> 24) & 0xFF; 1890 ratio = (msr >> 24) & 0xFF;
1891 group_size = (core_counts >> 24) & 0xFF;
1579 if (ratio) 1892 if (ratio)
1580 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 4 active cores\n", 1893 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1581 ratio, bclk, ratio * bclk); 1894 ratio, bclk, ratio * bclk, group_size);
1582 1895
1583 ratio = (msr >> 16) & 0xFF; 1896 ratio = (msr >> 16) & 0xFF;
1897 group_size = (core_counts >> 16) & 0xFF;
1584 if (ratio) 1898 if (ratio)
1585 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 3 active cores\n", 1899 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1586 ratio, bclk, ratio * bclk); 1900 ratio, bclk, ratio * bclk, group_size);
1587 1901
1588 ratio = (msr >> 8) & 0xFF; 1902 ratio = (msr >> 8) & 0xFF;
1903 group_size = (core_counts >> 8) & 0xFF;
1589 if (ratio) 1904 if (ratio)
1590 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 2 active cores\n", 1905 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1591 ratio, bclk, ratio * bclk); 1906 ratio, bclk, ratio * bclk, group_size);
1592 1907
1593 ratio = (msr >> 0) & 0xFF; 1908 ratio = (msr >> 0) & 0xFF;
1909 group_size = (core_counts >> 0) & 0xFF;
1594 if (ratio) 1910 if (ratio)
1595 fprintf(outf, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", 1911 fprintf(outf, "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1596 ratio, bclk, ratio * bclk); 1912 ratio, bclk, ratio * bclk, group_size);
1597 return; 1913 return;
1598} 1914}
1599 1915
1600static void 1916static void
1917dump_atom_turbo_ratio_limits(void)
1918{
1919 unsigned long long msr;
1920 unsigned int ratio;
1921
1922 get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr);
1923 fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
1924
1925 ratio = (msr >> 0) & 0x3F;
1926 if (ratio)
1927 fprintf(outf, "%d * %.1f = %.1f MHz minimum operating frequency\n",
1928 ratio, bclk, ratio * bclk);
1929
1930 ratio = (msr >> 8) & 0x3F;
1931 if (ratio)
1932 fprintf(outf, "%d * %.1f = %.1f MHz low frequency mode (LFM)\n",
1933 ratio, bclk, ratio * bclk);
1934
1935 ratio = (msr >> 16) & 0x3F;
1936 if (ratio)
1937 fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n",
1938 ratio, bclk, ratio * bclk);
1939
1940 get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr);
1941 fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF);
1942
1943 ratio = (msr >> 24) & 0x3F;
1944 if (ratio)
1945 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 4 active cores\n",
1946 ratio, bclk, ratio * bclk);
1947
1948 ratio = (msr >> 16) & 0x3F;
1949 if (ratio)
1950 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 3 active cores\n",
1951 ratio, bclk, ratio * bclk);
1952
1953 ratio = (msr >> 8) & 0x3F;
1954 if (ratio)
1955 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 2 active cores\n",
1956 ratio, bclk, ratio * bclk);
1957
1958 ratio = (msr >> 0) & 0x3F;
1959 if (ratio)
1960 fprintf(outf, "%d * %.1f = %.1f MHz max turbo 1 active core\n",
1961 ratio, bclk, ratio * bclk);
1962}
1963
1964static void
1601dump_knl_turbo_ratio_limits(void) 1965dump_knl_turbo_ratio_limits(void)
1602{ 1966{
1603 const unsigned int buckets_no = 7; 1967 const unsigned int buckets_no = 7;
@@ -1652,7 +2016,7 @@ dump_knl_turbo_ratio_limits(void)
1652 for (i = buckets_no - 1; i >= 0; i--) 2016 for (i = buckets_no - 1; i >= 0; i--)
1653 if (i > 0 ? ratio[i] != ratio[i - 1] : 1) 2017 if (i > 0 ? ratio[i] != ratio[i - 1] : 1)
1654 fprintf(outf, 2018 fprintf(outf,
1655 "%d * %.0f = %.0f MHz max turbo %d active cores\n", 2019 "%d * %.1f = %.1f MHz max turbo %d active cores\n",
1656 ratio[i], bclk, ratio[i] * bclk, cores[i]); 2020 ratio[i], bclk, ratio[i] * bclk, cores[i]);
1657} 2021}
1658 2022
@@ -1661,12 +2025,12 @@ dump_nhm_cst_cfg(void)
1661{ 2025{
1662 unsigned long long msr; 2026 unsigned long long msr;
1663 2027
1664 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); 2028 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
1665 2029
1666#define SNB_C1_AUTO_UNDEMOTE (1UL << 27) 2030#define SNB_C1_AUTO_UNDEMOTE (1UL << 27)
1667#define SNB_C3_AUTO_UNDEMOTE (1UL << 28) 2031#define SNB_C3_AUTO_UNDEMOTE (1UL << 28)
1668 2032
1669 fprintf(outf, "cpu%d: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", base_cpu, msr); 2033 fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr);
1670 2034
1671 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n", 2035 fprintf(outf, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
1672 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "", 2036 (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
@@ -1810,16 +2174,6 @@ void free_all_buffers(void)
1810 free(irqs_per_cpu); 2174 free(irqs_per_cpu);
1811} 2175}
1812 2176
1813/*
1814 * Open a file, and exit on failure
1815 */
1816FILE *fopen_or_die(const char *path, const char *mode)
1817{
1818 FILE *filep = fopen(path, mode);
1819 if (!filep)
1820 err(1, "%s: open failed", path);
1821 return filep;
1822}
1823 2177
1824/* 2178/*
1825 * Parse a file containing a single int. 2179 * Parse a file containing a single int.
@@ -2148,13 +2502,14 @@ int snapshot_gfx_mhz(void)
2148 */ 2502 */
2149int snapshot_proc_sysfs_files(void) 2503int snapshot_proc_sysfs_files(void)
2150{ 2504{
2151 if (snapshot_proc_interrupts()) 2505 if (DO_BIC(BIC_IRQ))
2152 return 1; 2506 if (snapshot_proc_interrupts())
2507 return 1;
2153 2508
2154 if (do_gfx_rc6_ms) 2509 if (DO_BIC(BIC_GFX_rc6))
2155 snapshot_gfx_rc6_ms(); 2510 snapshot_gfx_rc6_ms();
2156 2511
2157 if (do_gfx_mhz) 2512 if (DO_BIC(BIC_GFXMHz))
2158 snapshot_gfx_mhz(); 2513 snapshot_gfx_mhz();
2159 2514
2160 return 0; 2515 return 0;
@@ -2283,7 +2638,9 @@ void check_permissions()
2283 * MSR_SMI_COUNT 0x00000034 2638 * MSR_SMI_COUNT 0x00000034
2284 * 2639 *
2285 * MSR_PLATFORM_INFO 0x000000ce 2640 * MSR_PLATFORM_INFO 0x000000ce
2286 * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 2641 * MSR_PKG_CST_CONFIG_CONTROL 0x000000e2
2642 *
2643 * MSR_MISC_PWR_MGMT 0x000001aa
2287 * 2644 *
2288 * MSR_PKG_C3_RESIDENCY 0x000003f8 2645 * MSR_PKG_C3_RESIDENCY 0x000003f8
2289 * MSR_PKG_C6_RESIDENCY 0x000003f9 2646 * MSR_PKG_C6_RESIDENCY 0x000003f9
@@ -2291,7 +2648,8 @@ void check_permissions()
2291 * MSR_CORE_C6_RESIDENCY 0x000003fd 2648 * MSR_CORE_C6_RESIDENCY 0x000003fd
2292 * 2649 *
2293 * Side effect: 2650 * Side effect:
2294 * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL 2651 * sets global pkg_cstate_limit to decode MSR_PKG_CST_CONFIG_CONTROL
2652 * sets has_misc_feature_control
2295 */ 2653 */
2296int probe_nhm_msrs(unsigned int family, unsigned int model) 2654int probe_nhm_msrs(unsigned int family, unsigned int model)
2297{ 2655{
@@ -2322,6 +2680,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
2322 case INTEL_FAM6_IVYBRIDGE: /* IVB */ 2680 case INTEL_FAM6_IVYBRIDGE: /* IVB */
2323 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */ 2681 case INTEL_FAM6_IVYBRIDGE_X: /* IVB Xeon */
2324 pkg_cstate_limits = snb_pkg_cstate_limits; 2682 pkg_cstate_limits = snb_pkg_cstate_limits;
2683 has_misc_feature_control = 1;
2325 break; 2684 break;
2326 case INTEL_FAM6_HASWELL_CORE: /* HSW */ 2685 case INTEL_FAM6_HASWELL_CORE: /* HSW */
2327 case INTEL_FAM6_HASWELL_X: /* HSX */ 2686 case INTEL_FAM6_HASWELL_X: /* HSX */
@@ -2336,29 +2695,34 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
2336 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 2695 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2337 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 2696 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2338 pkg_cstate_limits = hsw_pkg_cstate_limits; 2697 pkg_cstate_limits = hsw_pkg_cstate_limits;
2698 has_misc_feature_control = 1;
2339 break; 2699 break;
2340 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 2700 case INTEL_FAM6_SKYLAKE_X: /* SKX */
2341 pkg_cstate_limits = skx_pkg_cstate_limits; 2701 pkg_cstate_limits = skx_pkg_cstate_limits;
2702 has_misc_feature_control = 1;
2342 break; 2703 break;
2343 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ 2704 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2705 no_MSR_MISC_PWR_MGMT = 1;
2344 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ 2706 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
2345 pkg_cstate_limits = slv_pkg_cstate_limits; 2707 pkg_cstate_limits = slv_pkg_cstate_limits;
2346 break; 2708 break;
2347 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */ 2709 case INTEL_FAM6_ATOM_AIRMONT: /* AMT */
2348 pkg_cstate_limits = amt_pkg_cstate_limits; 2710 pkg_cstate_limits = amt_pkg_cstate_limits;
2711 no_MSR_MISC_PWR_MGMT = 1;
2349 break; 2712 break;
2350 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */ 2713 case INTEL_FAM6_XEON_PHI_KNL: /* PHI */
2351 case INTEL_FAM6_XEON_PHI_KNM: 2714 case INTEL_FAM6_XEON_PHI_KNM:
2352 pkg_cstate_limits = phi_pkg_cstate_limits; 2715 pkg_cstate_limits = phi_pkg_cstate_limits;
2353 break; 2716 break;
2354 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 2717 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
2718 case INTEL_FAM6_ATOM_GEMINI_LAKE:
2355 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 2719 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
2356 pkg_cstate_limits = bxt_pkg_cstate_limits; 2720 pkg_cstate_limits = bxt_pkg_cstate_limits;
2357 break; 2721 break;
2358 default: 2722 default:
2359 return 0; 2723 return 0;
2360 } 2724 }
2361 get_msr(base_cpu, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr); 2725 get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr);
2362 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; 2726 pkg_cstate_limit = pkg_cstate_limits[msr & 0xF];
2363 2727
2364 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr); 2728 get_msr(base_cpu, MSR_PLATFORM_INFO, &msr);
@@ -2368,8 +2732,69 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
2368 has_base_hz = 1; 2732 has_base_hz = 1;
2369 return 1; 2733 return 1;
2370} 2734}
2371int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model) 2735/*
2736 * SLV client has support for unique MSRs:
2737 *
2738 * MSR_CC6_DEMOTION_POLICY_CONFIG
2739 * MSR_MC6_DEMOTION_POLICY_CONFIG
2740 */
2741
2742int has_slv_msrs(unsigned int family, unsigned int model)
2372{ 2743{
2744 if (!genuine_intel)
2745 return 0;
2746
2747 switch (model) {
2748 case INTEL_FAM6_ATOM_SILVERMONT1:
2749 case INTEL_FAM6_ATOM_MERRIFIELD:
2750 case INTEL_FAM6_ATOM_MOOREFIELD:
2751 return 1;
2752 }
2753 return 0;
2754}
2755int is_dnv(unsigned int family, unsigned int model)
2756{
2757
2758 if (!genuine_intel)
2759 return 0;
2760
2761 switch (model) {
2762 case INTEL_FAM6_ATOM_DENVERTON:
2763 return 1;
2764 }
2765 return 0;
2766}
2767int is_bdx(unsigned int family, unsigned int model)
2768{
2769
2770 if (!genuine_intel)
2771 return 0;
2772
2773 switch (model) {
2774 case INTEL_FAM6_BROADWELL_X:
2775 case INTEL_FAM6_BROADWELL_XEON_D:
2776 return 1;
2777 }
2778 return 0;
2779}
2780int is_skx(unsigned int family, unsigned int model)
2781{
2782
2783 if (!genuine_intel)
2784 return 0;
2785
2786 switch (model) {
2787 case INTEL_FAM6_SKYLAKE_X:
2788 return 1;
2789 }
2790 return 0;
2791}
2792
2793int has_turbo_ratio_limit(unsigned int family, unsigned int model)
2794{
2795 if (has_slv_msrs(family, model))
2796 return 0;
2797
2373 switch (model) { 2798 switch (model) {
2374 /* Nehalem compatible, but do not include turbo-ratio limit support */ 2799 /* Nehalem compatible, but do not include turbo-ratio limit support */
2375 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */ 2800 case INTEL_FAM6_NEHALEM_EX: /* Nehalem-EX Xeon - Beckton */
@@ -2381,6 +2806,13 @@ int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
2381 return 1; 2806 return 1;
2382 } 2807 }
2383} 2808}
2809int has_atom_turbo_ratio_limit(unsigned int family, unsigned int model)
2810{
2811 if (has_slv_msrs(family, model))
2812 return 1;
2813
2814 return 0;
2815}
2384int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) 2816int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
2385{ 2817{
2386 if (!genuine_intel) 2818 if (!genuine_intel)
@@ -2429,6 +2861,22 @@ int has_knl_turbo_ratio_limit(unsigned int family, unsigned int model)
2429 return 0; 2861 return 0;
2430 } 2862 }
2431} 2863}
2864int has_glm_turbo_ratio_limit(unsigned int family, unsigned int model)
2865{
2866 if (!genuine_intel)
2867 return 0;
2868
2869 if (family != 6)
2870 return 0;
2871
2872 switch (model) {
2873 case INTEL_FAM6_ATOM_GOLDMONT:
2874 case INTEL_FAM6_SKYLAKE_X:
2875 return 1;
2876 default:
2877 return 0;
2878 }
2879}
2432int has_config_tdp(unsigned int family, unsigned int model) 2880int has_config_tdp(unsigned int family, unsigned int model)
2433{ 2881{
2434 if (!genuine_intel) 2882 if (!genuine_intel)
@@ -2475,8 +2923,11 @@ dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
2475 if (has_ivt_turbo_ratio_limit(family, model)) 2923 if (has_ivt_turbo_ratio_limit(family, model))
2476 dump_ivt_turbo_ratio_limits(); 2924 dump_ivt_turbo_ratio_limits();
2477 2925
2478 if (has_nhm_turbo_ratio_limit(family, model)) 2926 if (has_turbo_ratio_limit(family, model))
2479 dump_nhm_turbo_ratio_limits(); 2927 dump_turbo_ratio_limits(family, model);
2928
2929 if (has_atom_turbo_ratio_limit(family, model))
2930 dump_atom_turbo_ratio_limits();
2480 2931
2481 if (has_knl_turbo_ratio_limit(family, model)) 2932 if (has_knl_turbo_ratio_limit(family, model))
2482 dump_knl_turbo_ratio_limits(); 2933 dump_knl_turbo_ratio_limits();
@@ -2487,6 +2938,96 @@ dump_cstate_pstate_config_info(unsigned int family, unsigned int model)
2487 dump_nhm_cst_cfg(); 2938 dump_nhm_cst_cfg();
2488} 2939}
2489 2940
2941static void
2942dump_sysfs_cstate_config(void)
2943{
2944 char path[64];
2945 char name_buf[16];
2946 char desc[64];
2947 FILE *input;
2948 int state;
2949 char *sp;
2950
2951 if (!DO_BIC(BIC_sysfs))
2952 return;
2953
2954 for (state = 0; state < 10; ++state) {
2955
2956 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
2957 base_cpu, state);
2958 input = fopen(path, "r");
2959 if (input == NULL)
2960 continue;
2961 fgets(name_buf, sizeof(name_buf), input);
2962
2963 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
2964 sp = strchr(name_buf, '-');
2965 if (!sp)
2966 sp = strchrnul(name_buf, '\n');
2967 *sp = '\0';
2968
2969 fclose(input);
2970
2971 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
2972 base_cpu, state);
2973 input = fopen(path, "r");
2974 if (input == NULL)
2975 continue;
2976 fgets(desc, sizeof(desc), input);
2977
2978 fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
2979 fclose(input);
2980 }
2981}
2982static void
2983dump_sysfs_pstate_config(void)
2984{
2985 char path[64];
2986 char driver_buf[64];
2987 char governor_buf[64];
2988 FILE *input;
2989 int turbo;
2990
2991 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver",
2992 base_cpu);
2993 input = fopen(path, "r");
2994 if (input == NULL) {
2995 fprintf(stderr, "NSFOD %s\n", path);
2996 return;
2997 }
2998 fgets(driver_buf, sizeof(driver_buf), input);
2999 fclose(input);
3000
3001 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
3002 base_cpu);
3003 input = fopen(path, "r");
3004 if (input == NULL) {
3005 fprintf(stderr, "NSFOD %s\n", path);
3006 return;
3007 }
3008 fgets(governor_buf, sizeof(governor_buf), input);
3009 fclose(input);
3010
3011 fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
3012 fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf);
3013
3014 sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
3015 input = fopen(path, "r");
3016 if (input != NULL) {
3017 fscanf(input, "%d", &turbo);
3018 fprintf(outf, "cpufreq boost: %d\n", turbo);
3019 fclose(input);
3020 }
3021
3022 sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
3023 input = fopen(path, "r");
3024 if (input != NULL) {
3025 fscanf(input, "%d", &turbo);
3026 fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
3027 fclose(input);
3028 }
3029}
3030
2490 3031
2491/* 3032/*
2492 * print_epb() 3033 * print_epb()
@@ -2790,15 +3331,40 @@ void rapl_probe(unsigned int family, unsigned int model)
2790 case INTEL_FAM6_BROADWELL_CORE: /* BDW */ 3331 case INTEL_FAM6_BROADWELL_CORE: /* BDW */
2791 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */ 3332 case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
2792 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; 3333 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
3334 if (rapl_joules) {
3335 BIC_PRESENT(BIC_Pkg_J);
3336 BIC_PRESENT(BIC_Cor_J);
3337 BIC_PRESENT(BIC_GFX_J);
3338 } else {
3339 BIC_PRESENT(BIC_PkgWatt);
3340 BIC_PRESENT(BIC_CorWatt);
3341 BIC_PRESENT(BIC_GFXWatt);
3342 }
2793 break; 3343 break;
2794 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 3344 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
3345 case INTEL_FAM6_ATOM_GEMINI_LAKE:
2795 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO; 3346 do_rapl = RAPL_PKG | RAPL_PKG_POWER_INFO;
3347 if (rapl_joules)
3348 BIC_PRESENT(BIC_Pkg_J);
3349 else
3350 BIC_PRESENT(BIC_PkgWatt);
2796 break; 3351 break;
2797 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */ 3352 case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
2798 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */ 3353 case INTEL_FAM6_SKYLAKE_DESKTOP: /* SKL */
2799 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 3354 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
2800 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3355 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
2801 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; 3356 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
3357 BIC_PRESENT(BIC_PKG__);
3358 BIC_PRESENT(BIC_RAM__);
3359 if (rapl_joules) {
3360 BIC_PRESENT(BIC_Pkg_J);
3361 BIC_PRESENT(BIC_Cor_J);
3362 BIC_PRESENT(BIC_RAM_J);
3363 } else {
3364 BIC_PRESENT(BIC_PkgWatt);
3365 BIC_PRESENT(BIC_CorWatt);
3366 BIC_PRESENT(BIC_RAMWatt);
3367 }
2802 break; 3368 break;
2803 case INTEL_FAM6_HASWELL_X: /* HSX */ 3369 case INTEL_FAM6_HASWELL_X: /* HSX */
2804 case INTEL_FAM6_BROADWELL_X: /* BDX */ 3370 case INTEL_FAM6_BROADWELL_X: /* BDX */
@@ -2807,17 +3373,55 @@ void rapl_probe(unsigned int family, unsigned int model)
2807 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ 3373 case INTEL_FAM6_XEON_PHI_KNL: /* KNL */
2808 case INTEL_FAM6_XEON_PHI_KNM: 3374 case INTEL_FAM6_XEON_PHI_KNM:
2809 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; 3375 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO;
3376 BIC_PRESENT(BIC_PKG__);
3377 BIC_PRESENT(BIC_RAM__);
3378 if (rapl_joules) {
3379 BIC_PRESENT(BIC_Pkg_J);
3380 BIC_PRESENT(BIC_RAM_J);
3381 } else {
3382 BIC_PRESENT(BIC_PkgWatt);
3383 BIC_PRESENT(BIC_RAMWatt);
3384 }
2810 break; 3385 break;
2811 case INTEL_FAM6_SANDYBRIDGE_X: 3386 case INTEL_FAM6_SANDYBRIDGE_X:
2812 case INTEL_FAM6_IVYBRIDGE_X: 3387 case INTEL_FAM6_IVYBRIDGE_X:
2813 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO; 3388 do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO;
3389 BIC_PRESENT(BIC_PKG__);
3390 BIC_PRESENT(BIC_RAM__);
3391 if (rapl_joules) {
3392 BIC_PRESENT(BIC_Pkg_J);
3393 BIC_PRESENT(BIC_Cor_J);
3394 BIC_PRESENT(BIC_RAM_J);
3395 } else {
3396 BIC_PRESENT(BIC_PkgWatt);
3397 BIC_PRESENT(BIC_CorWatt);
3398 BIC_PRESENT(BIC_RAMWatt);
3399 }
2814 break; 3400 break;
2815 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */ 3401 case INTEL_FAM6_ATOM_SILVERMONT1: /* BYT */
2816 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */ 3402 case INTEL_FAM6_ATOM_SILVERMONT2: /* AVN */
2817 do_rapl = RAPL_PKG | RAPL_CORES; 3403 do_rapl = RAPL_PKG | RAPL_CORES;
3404 if (rapl_joules) {
3405 BIC_PRESENT(BIC_Pkg_J);
3406 BIC_PRESENT(BIC_Cor_J);
3407 } else {
3408 BIC_PRESENT(BIC_PkgWatt);
3409 BIC_PRESENT(BIC_CorWatt);
3410 }
2818 break; 3411 break;
2819 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 3412 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
2820 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS; 3413 do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_POWER_INFO | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO | RAPL_CORES_ENERGY_STATUS;
3414 BIC_PRESENT(BIC_PKG__);
3415 BIC_PRESENT(BIC_RAM__);
3416 if (rapl_joules) {
3417 BIC_PRESENT(BIC_Pkg_J);
3418 BIC_PRESENT(BIC_Cor_J);
3419 BIC_PRESENT(BIC_RAM_J);
3420 } else {
3421 BIC_PRESENT(BIC_PkgWatt);
3422 BIC_PRESENT(BIC_CorWatt);
3423 BIC_PRESENT(BIC_RAMWatt);
3424 }
2821 break; 3425 break;
2822 default: 3426 default:
2823 return; 3427 return;
@@ -2844,7 +3448,7 @@ void rapl_probe(unsigned int family, unsigned int model)
2844 tdp = get_tdp(model); 3448 tdp = get_tdp(model);
2845 3449
2846 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; 3450 rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
2847 if (debug) 3451 if (!quiet)
2848 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); 3452 fprintf(outf, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
2849 3453
2850 return; 3454 return;
@@ -2969,11 +3573,9 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2969 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) 3573 if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
2970 return -1; 3574 return -1;
2971 3575
2972 if (debug) { 3576 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr,
2973 fprintf(outf, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " 3577 rapl_power_units, rapl_energy_units, rapl_time_units);
2974 "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, 3578
2975 rapl_power_units, rapl_energy_units, rapl_time_units);
2976 }
2977 if (do_rapl & RAPL_PKG_POWER_INFO) { 3579 if (do_rapl & RAPL_PKG_POWER_INFO) {
2978 3580
2979 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) 3581 if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr))
@@ -2994,7 +3596,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
2994 return -9; 3596 return -9;
2995 3597
2996 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n", 3598 fprintf(outf, "cpu%d: MSR_PKG_POWER_LIMIT: 0x%08llx (%slocked)\n",
2997 cpu, msr, (msr >> 63) & 1 ? "": "UN"); 3599 cpu, msr, (msr >> 63) & 1 ? "" : "UN");
2998 3600
2999 print_power_limit_msr(cpu, msr, "PKG Limit #1"); 3601 print_power_limit_msr(cpu, msr, "PKG Limit #1");
3000 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n", 3602 fprintf(outf, "cpu%d: PKG Limit #2: %sabled (%f Watts, %f* sec, clamp %sabled)\n",
@@ -3020,40 +3622,34 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
3020 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr)) 3622 if (get_msr(cpu, MSR_DRAM_POWER_LIMIT, &msr))
3021 return -9; 3623 return -9;
3022 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n", 3624 fprintf(outf, "cpu%d: MSR_DRAM_POWER_LIMIT: 0x%08llx (%slocked)\n",
3023 cpu, msr, (msr >> 31) & 1 ? "": "UN"); 3625 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3024 3626
3025 print_power_limit_msr(cpu, msr, "DRAM Limit"); 3627 print_power_limit_msr(cpu, msr, "DRAM Limit");
3026 } 3628 }
3027 if (do_rapl & RAPL_CORE_POLICY) { 3629 if (do_rapl & RAPL_CORE_POLICY) {
3028 if (debug) { 3630 if (get_msr(cpu, MSR_PP0_POLICY, &msr))
3029 if (get_msr(cpu, MSR_PP0_POLICY, &msr)) 3631 return -7;
3030 return -7;
3031 3632
3032 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); 3633 fprintf(outf, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF);
3033 }
3034 } 3634 }
3035 if (do_rapl & RAPL_CORES_POWER_LIMIT) { 3635 if (do_rapl & RAPL_CORES_POWER_LIMIT) {
3036 if (debug) { 3636 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
3037 if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) 3637 return -9;
3038 return -9; 3638 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n",
3039 fprintf(outf, "cpu%d: MSR_PP0_POWER_LIMIT: 0x%08llx (%slocked)\n", 3639 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3040 cpu, msr, (msr >> 31) & 1 ? "": "UN"); 3640 print_power_limit_msr(cpu, msr, "Cores Limit");
3041 print_power_limit_msr(cpu, msr, "Cores Limit");
3042 }
3043 } 3641 }
3044 if (do_rapl & RAPL_GFX) { 3642 if (do_rapl & RAPL_GFX) {
3045 if (debug) { 3643 if (get_msr(cpu, MSR_PP1_POLICY, &msr))
3046 if (get_msr(cpu, MSR_PP1_POLICY, &msr)) 3644 return -8;
3047 return -8;
3048 3645
3049 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF); 3646 fprintf(outf, "cpu%d: MSR_PP1_POLICY: %lld\n", cpu, msr & 0xF);
3050 3647
3051 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr)) 3648 if (get_msr(cpu, MSR_PP1_POWER_LIMIT, &msr))
3052 return -9; 3649 return -9;
3053 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n", 3650 fprintf(outf, "cpu%d: MSR_PP1_POWER_LIMIT: 0x%08llx (%slocked)\n",
3054 cpu, msr, (msr >> 31) & 1 ? "": "UN"); 3651 cpu, msr, (msr >> 31) & 1 ? "" : "UN");
3055 print_power_limit_msr(cpu, msr, "GFX Limit"); 3652 print_power_limit_msr(cpu, msr, "GFX Limit");
3056 }
3057 } 3653 }
3058 return 0; 3654 return 0;
3059} 3655}
@@ -3090,6 +3686,7 @@ int has_snb_msrs(unsigned int family, unsigned int model)
3090 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3686 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
3091 case INTEL_FAM6_SKYLAKE_X: /* SKX */ 3687 case INTEL_FAM6_SKYLAKE_X: /* SKX */
3092 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 3688 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
3689 case INTEL_FAM6_ATOM_GEMINI_LAKE:
3093 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */ 3690 case INTEL_FAM6_ATOM_DENVERTON: /* DNV */
3094 return 1; 3691 return 1;
3095 } 3692 }
@@ -3121,6 +3718,7 @@ int has_hsw_msrs(unsigned int family, unsigned int model)
3121 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */ 3718 case INTEL_FAM6_KABYLAKE_MOBILE: /* KBL */
3122 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */ 3719 case INTEL_FAM6_KABYLAKE_DESKTOP: /* KBL */
3123 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 3720 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
3721 case INTEL_FAM6_ATOM_GEMINI_LAKE:
3124 return 1; 3722 return 1;
3125 } 3723 }
3126 return 0; 3724 return 0;
@@ -3149,8 +3747,6 @@ int has_skl_msrs(unsigned int family, unsigned int model)
3149 return 0; 3747 return 0;
3150} 3748}
3151 3749
3152
3153
3154int is_slm(unsigned int family, unsigned int model) 3750int is_slm(unsigned int family, unsigned int model)
3155{ 3751{
3156 if (!genuine_intel) 3752 if (!genuine_intel)
@@ -3201,7 +3797,8 @@ double slm_bclk(void)
3201 } 3797 }
3202 freq = slm_freq_table[i]; 3798 freq = slm_freq_table[i];
3203 3799
3204 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq); 3800 if (!quiet)
3801 fprintf(outf, "SLM BCLK: %.1f Mhz\n", freq);
3205 3802
3206 return freq; 3803 return freq;
3207} 3804}
@@ -3264,7 +3861,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
3264 3861
3265 target_c_local = (msr >> 16) & 0xFF; 3862 target_c_local = (msr >> 16) & 0xFF;
3266 3863
3267 if (debug) 3864 if (!quiet)
3268 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", 3865 fprintf(outf, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
3269 cpu, msr, target_c_local); 3866 cpu, msr, target_c_local);
3270 3867
@@ -3299,13 +3896,30 @@ void decode_misc_enable_msr(void)
3299 unsigned long long msr; 3896 unsigned long long msr;
3300 3897
3301 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr)) 3898 if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr))
3302 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%s %s %s)\n", 3899 fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n",
3303 base_cpu, msr, 3900 base_cpu, msr,
3304 msr & (1 << 3) ? "TCC" : "", 3901 msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-",
3305 msr & (1 << 16) ? "EIST" : "", 3902 msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-",
3306 msr & (1 << 18) ? "MONITOR" : ""); 3903 msr & MSR_IA32_MISC_ENABLE_MWAIT ? "No-" : "",
3904 msr & MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE ? "No-" : "",
3905 msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE ? "No-" : "");
3307} 3906}
3308 3907
3908void decode_misc_feature_control(void)
3909{
3910 unsigned long long msr;
3911
3912 if (!has_misc_feature_control)
3913 return;
3914
3915 if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr))
3916 fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n",
3917 base_cpu, msr,
3918 msr & (0 << 0) ? "No-" : "",
3919 msr & (1 << 0) ? "No-" : "",
3920 msr & (2 << 0) ? "No-" : "",
3921 msr & (3 << 0) ? "No-" : "");
3922}
3309/* 3923/*
3310 * Decode MSR_MISC_PWR_MGMT 3924 * Decode MSR_MISC_PWR_MGMT
3311 * 3925 *
@@ -3320,6 +3934,9 @@ void decode_misc_pwr_mgmt_msr(void)
3320 if (!do_nhm_platform_info) 3934 if (!do_nhm_platform_info)
3321 return; 3935 return;
3322 3936
3937 if (no_MSR_MISC_PWR_MGMT)
3938 return;
3939
3323 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr)) 3940 if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr))
3324 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n", 3941 fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n",
3325 base_cpu, msr, 3942 base_cpu, msr,
@@ -3327,11 +3944,30 @@ void decode_misc_pwr_mgmt_msr(void)
3327 msr & (1 << 1) ? "EN" : "DIS", 3944 msr & (1 << 1) ? "EN" : "DIS",
3328 msr & (1 << 8) ? "EN" : "DIS"); 3945 msr & (1 << 8) ? "EN" : "DIS");
3329} 3946}
3947/*
3948 * Decode MSR_CC6_DEMOTION_POLICY_CONFIG, MSR_MC6_DEMOTION_POLICY_CONFIG
3949 *
3950 * This MSRs are present on Silvermont processors,
3951 * Intel Atom processor E3000 series (Baytrail), and friends.
3952 */
3953void decode_c6_demotion_policy_msr(void)
3954{
3955 unsigned long long msr;
3956
3957 if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr))
3958 fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n",
3959 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
3960
3961 if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr))
3962 fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n",
3963 base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS");
3964}
3330 3965
3331void process_cpuid() 3966void process_cpuid()
3332{ 3967{
3333 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level; 3968 unsigned int eax, ebx, ecx, edx, max_level, max_extended_level;
3334 unsigned int fms, family, model, stepping; 3969 unsigned int fms, family, model, stepping;
3970 unsigned int has_turbo;
3335 3971
3336 eax = ebx = ecx = edx = 0; 3972 eax = ebx = ecx = edx = 0;
3337 3973
@@ -3340,7 +3976,7 @@ void process_cpuid()
3340 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e) 3976 if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
3341 genuine_intel = 1; 3977 genuine_intel = 1;
3342 3978
3343 if (debug) 3979 if (!quiet)
3344 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ", 3980 fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
3345 (char *)&ebx, (char *)&edx, (char *)&ecx); 3981 (char *)&ebx, (char *)&edx, (char *)&ecx);
3346 3982
@@ -3351,7 +3987,7 @@ void process_cpuid()
3351 if (family == 6 || family == 0xf) 3987 if (family == 6 || family == 0xf)
3352 model += ((fms >> 16) & 0xf) << 4; 3988 model += ((fms >> 16) & 0xf) << 4;
3353 3989
3354 if (debug) { 3990 if (!quiet) {
3355 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", 3991 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
3356 max_level, family, model, stepping, family, model, stepping); 3992 max_level, family, model, stepping, family, model, stepping);
3357 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n", 3993 fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n",
@@ -3394,8 +4030,18 @@ void process_cpuid()
3394 4030
3395 __cpuid(0x6, eax, ebx, ecx, edx); 4031 __cpuid(0x6, eax, ebx, ecx, edx);
3396 has_aperf = ecx & (1 << 0); 4032 has_aperf = ecx & (1 << 0);
4033 if (has_aperf) {
4034 BIC_PRESENT(BIC_Avg_MHz);
4035 BIC_PRESENT(BIC_Busy);
4036 BIC_PRESENT(BIC_Bzy_MHz);
4037 }
3397 do_dts = eax & (1 << 0); 4038 do_dts = eax & (1 << 0);
4039 if (do_dts)
4040 BIC_PRESENT(BIC_CoreTmp);
4041 has_turbo = eax & (1 << 1);
3398 do_ptm = eax & (1 << 6); 4042 do_ptm = eax & (1 << 6);
4043 if (do_ptm)
4044 BIC_PRESENT(BIC_PkgTmp);
3399 has_hwp = eax & (1 << 7); 4045 has_hwp = eax & (1 << 7);
3400 has_hwp_notify = eax & (1 << 8); 4046 has_hwp_notify = eax & (1 << 8);
3401 has_hwp_activity_window = eax & (1 << 9); 4047 has_hwp_activity_window = eax & (1 << 9);
@@ -3403,10 +4049,11 @@ void process_cpuid()
3403 has_hwp_pkg = eax & (1 << 11); 4049 has_hwp_pkg = eax & (1 << 11);
3404 has_epb = ecx & (1 << 3); 4050 has_epb = ecx & (1 << 3);
3405 4051
3406 if (debug) 4052 if (!quiet)
3407 fprintf(outf, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sHWP, " 4053 fprintf(outf, "CPUID(6): %sAPERF, %sTURBO, %sDTS, %sPTM, %sHWP, "
3408 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n", 4054 "%sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
3409 has_aperf ? "" : "No-", 4055 has_aperf ? "" : "No-",
4056 has_turbo ? "" : "No-",
3410 do_dts ? "" : "No-", 4057 do_dts ? "" : "No-",
3411 do_ptm ? "" : "No-", 4058 do_ptm ? "" : "No-",
3412 has_hwp ? "" : "No-", 4059 has_hwp ? "" : "No-",
@@ -3416,10 +4063,11 @@ void process_cpuid()
3416 has_hwp_pkg ? "" : "No-", 4063 has_hwp_pkg ? "" : "No-",
3417 has_epb ? "" : "No-"); 4064 has_epb ? "" : "No-");
3418 4065
3419 if (debug) 4066 if (!quiet)
3420 decode_misc_enable_msr(); 4067 decode_misc_enable_msr();
3421 4068
3422 if (max_level >= 0x7 && debug) { 4069
4070 if (max_level >= 0x7 && !quiet) {
3423 int has_sgx; 4071 int has_sgx;
3424 4072
3425 ecx = 0; 4073 ecx = 0;
@@ -3445,7 +4093,7 @@ void process_cpuid()
3445 4093
3446 if (ebx_tsc != 0) { 4094 if (ebx_tsc != 0) {
3447 4095
3448 if (debug && (ebx != 0)) 4096 if (!quiet && (ebx != 0))
3449 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n", 4097 fprintf(outf, "CPUID(0x15): eax_crystal: %d ebx_tsc: %d ecx_crystal_hz: %d\n",
3450 eax_crystal, ebx_tsc, crystal_hz); 4098 eax_crystal, ebx_tsc, crystal_hz);
3451 4099
@@ -3462,6 +4110,7 @@ void process_cpuid()
3462 crystal_hz = 25000000; /* 25.0 MHz */ 4110 crystal_hz = 25000000; /* 25.0 MHz */
3463 break; 4111 break;
3464 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */ 4112 case INTEL_FAM6_ATOM_GOLDMONT: /* BXT */
4113 case INTEL_FAM6_ATOM_GEMINI_LAKE:
3465 crystal_hz = 19200000; /* 19.2 MHz */ 4114 crystal_hz = 19200000; /* 19.2 MHz */
3466 break; 4115 break;
3467 default: 4116 default:
@@ -3470,7 +4119,7 @@ void process_cpuid()
3470 4119
3471 if (crystal_hz) { 4120 if (crystal_hz) {
3472 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal; 4121 tsc_hz = (unsigned long long) crystal_hz * ebx_tsc / eax_crystal;
3473 if (debug) 4122 if (!quiet)
3474 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n", 4123 fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n",
3475 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal); 4124 tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal);
3476 } 4125 }
@@ -3485,7 +4134,7 @@ void process_cpuid()
3485 base_mhz = max_mhz = bus_mhz = edx = 0; 4134 base_mhz = max_mhz = bus_mhz = edx = 0;
3486 4135
3487 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx); 4136 __cpuid(0x16, base_mhz, max_mhz, bus_mhz, edx);
3488 if (debug) 4137 if (!quiet)
3489 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n", 4138 fprintf(outf, "CPUID(0x16): base_mhz: %d max_mhz: %d bus_mhz: %d\n",
3490 base_mhz, max_mhz, bus_mhz); 4139 base_mhz, max_mhz, bus_mhz);
3491 } 4140 }
@@ -3493,56 +4142,96 @@ void process_cpuid()
3493 if (has_aperf) 4142 if (has_aperf)
3494 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model); 4143 aperf_mperf_multiplier = get_aperf_mperf_multiplier(family, model);
3495 4144
3496 do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model); 4145 BIC_PRESENT(BIC_IRQ);
4146 BIC_PRESENT(BIC_TSC_MHz);
4147
4148 if (probe_nhm_msrs(family, model)) {
4149 do_nhm_platform_info = 1;
4150 BIC_PRESENT(BIC_CPU_c1);
4151 BIC_PRESENT(BIC_CPU_c3);
4152 BIC_PRESENT(BIC_CPU_c6);
4153 BIC_PRESENT(BIC_SMI);
4154 }
3497 do_snb_cstates = has_snb_msrs(family, model); 4155 do_snb_cstates = has_snb_msrs(family, model);
4156
4157 if (do_snb_cstates)
4158 BIC_PRESENT(BIC_CPU_c7);
4159
3498 do_irtl_snb = has_snb_msrs(family, model); 4160 do_irtl_snb = has_snb_msrs(family, model);
3499 do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2); 4161 if (do_snb_cstates && (pkg_cstate_limit >= PCL__2))
3500 do_pc3 = (pkg_cstate_limit >= PCL__3); 4162 BIC_PRESENT(BIC_Pkgpc2);
3501 do_pc6 = (pkg_cstate_limit >= PCL__6); 4163 if (pkg_cstate_limit >= PCL__3)
3502 do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7); 4164 BIC_PRESENT(BIC_Pkgpc3);
3503 do_c8_c9_c10 = has_hsw_msrs(family, model); 4165 if (pkg_cstate_limit >= PCL__6)
4166 BIC_PRESENT(BIC_Pkgpc6);
4167 if (do_snb_cstates && (pkg_cstate_limit >= PCL__7))
4168 BIC_PRESENT(BIC_Pkgpc7);
4169 if (has_slv_msrs(family, model)) {
4170 BIC_NOT_PRESENT(BIC_Pkgpc2);
4171 BIC_NOT_PRESENT(BIC_Pkgpc3);
4172 BIC_PRESENT(BIC_Pkgpc6);
4173 BIC_NOT_PRESENT(BIC_Pkgpc7);
4174 BIC_PRESENT(BIC_Mod_c6);
4175 use_c1_residency_msr = 1;
4176 }
4177 if (is_dnv(family, model)) {
4178 BIC_PRESENT(BIC_CPU_c1);
4179 BIC_NOT_PRESENT(BIC_CPU_c3);
4180 BIC_NOT_PRESENT(BIC_Pkgpc3);
4181 BIC_NOT_PRESENT(BIC_CPU_c7);
4182 BIC_NOT_PRESENT(BIC_Pkgpc7);
4183 use_c1_residency_msr = 1;
4184 }
4185 if (is_skx(family, model)) {
4186 BIC_NOT_PRESENT(BIC_CPU_c3);
4187 BIC_NOT_PRESENT(BIC_Pkgpc3);
4188 BIC_NOT_PRESENT(BIC_CPU_c7);
4189 BIC_NOT_PRESENT(BIC_Pkgpc7);
4190 }
4191 if (is_bdx(family, model)) {
4192 BIC_NOT_PRESENT(BIC_CPU_c7);
4193 BIC_NOT_PRESENT(BIC_Pkgpc7);
4194 }
4195 if (has_hsw_msrs(family, model)) {
4196 BIC_PRESENT(BIC_Pkgpc8);
4197 BIC_PRESENT(BIC_Pkgpc9);
4198 BIC_PRESENT(BIC_Pkgpc10);
4199 }
3504 do_irtl_hsw = has_hsw_msrs(family, model); 4200 do_irtl_hsw = has_hsw_msrs(family, model);
3505 do_skl_residency = has_skl_msrs(family, model); 4201 do_skl_residency = has_skl_msrs(family, model);
3506 do_slm_cstates = is_slm(family, model); 4202 do_slm_cstates = is_slm(family, model);
3507 do_knl_cstates = is_knl(family, model); 4203 do_knl_cstates = is_knl(family, model);
3508 4204
3509 if (debug) 4205 if (!quiet)
3510 decode_misc_pwr_mgmt_msr(); 4206 decode_misc_pwr_mgmt_msr();
3511 4207
4208 if (!quiet && has_slv_msrs(family, model))
4209 decode_c6_demotion_policy_msr();
4210
3512 rapl_probe(family, model); 4211 rapl_probe(family, model);
3513 perf_limit_reasons_probe(family, model); 4212 perf_limit_reasons_probe(family, model);
3514 4213
3515 if (debug) 4214 if (!quiet)
3516 dump_cstate_pstate_config_info(family, model); 4215 dump_cstate_pstate_config_info(family, model);
3517 4216
4217 if (!quiet)
4218 dump_sysfs_cstate_config();
4219 if (!quiet)
4220 dump_sysfs_pstate_config();
4221
3518 if (has_skl_msrs(family, model)) 4222 if (has_skl_msrs(family, model))
3519 calculate_tsc_tweak(); 4223 calculate_tsc_tweak();
3520 4224
3521 do_gfx_rc6_ms = !access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK); 4225 if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
4226 BIC_PRESENT(BIC_GFX_rc6);
3522 4227
3523 do_gfx_mhz = !access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK); 4228 if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
4229 BIC_PRESENT(BIC_GFXMHz);
3524 4230
3525 return; 4231 if (!quiet)
3526} 4232 decode_misc_feature_control();
3527 4233
3528void help() 4234 return;
3529{
3530 fprintf(outf,
3531 "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
3532 "\n"
3533 "Turbostat forks the specified COMMAND and prints statistics\n"
3534 "when COMMAND completes.\n"
3535 "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
3536 "to print statistics, until interrupted.\n"
3537 "--add add a counter\n"
3538 " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n"
3539 "--debug run in \"debug\" mode\n"
3540 "--interval sec Override default 5-second measurement interval\n"
3541 "--help print this help message\n"
3542 "--out file create or truncate \"file\" for all output\n"
3543 "--version print version information\n"
3544 "\n"
3545 "For more help, run \"man turbostat\"\n");
3546} 4235}
3547 4236
3548 4237
@@ -3579,7 +4268,7 @@ void topology_probe()
3579 topo.max_cpu_num = 0; 4268 topo.max_cpu_num = 0;
3580 for_all_proc_cpus(count_cpus); 4269 for_all_proc_cpus(count_cpus);
3581 if (!summary_only && topo.num_cpus > 1) 4270 if (!summary_only && topo.num_cpus > 1)
3582 show_cpu = 1; 4271 BIC_PRESENT(BIC_CPU);
3583 4272
3584 if (debug > 1) 4273 if (debug > 1)
3585 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num); 4274 fprintf(outf, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
@@ -3599,6 +4288,15 @@ void topology_probe()
3599 for_all_proc_cpus(mark_cpu_present); 4288 for_all_proc_cpus(mark_cpu_present);
3600 4289
3601 /* 4290 /*
4291 * Validate that all cpus in cpu_subset are also in cpu_present_set
4292 */
4293 for (i = 0; i < CPU_SUBSET_MAXCPUS; ++i) {
4294 if (CPU_ISSET_S(i, cpu_subset_size, cpu_subset))
4295 if (!CPU_ISSET_S(i, cpu_present_setsize, cpu_present_set))
4296 err(1, "cpu%d not present", i);
4297 }
4298
4299 /*
3602 * Allocate and initialize cpu_affinity_set 4300 * Allocate and initialize cpu_affinity_set
3603 */ 4301 */
3604 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1)); 4302 cpu_affinity_set = CPU_ALLOC((topo.max_cpu_num + 1));
@@ -3639,15 +4337,15 @@ void topology_probe()
3639 if (debug > 1) 4337 if (debug > 1)
3640 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", 4338 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n",
3641 max_core_id, topo.num_cores_per_pkg); 4339 max_core_id, topo.num_cores_per_pkg);
3642 if (debug && !summary_only && topo.num_cores_per_pkg > 1) 4340 if (!summary_only && topo.num_cores_per_pkg > 1)
3643 show_core = 1; 4341 BIC_PRESENT(BIC_Core);
3644 4342
3645 topo.num_packages = max_package_id + 1; 4343 topo.num_packages = max_package_id + 1;
3646 if (debug > 1) 4344 if (debug > 1)
3647 fprintf(outf, "max_package_id %d, sizing for %d packages\n", 4345 fprintf(outf, "max_package_id %d, sizing for %d packages\n",
3648 max_package_id, topo.num_packages); 4346 max_package_id, topo.num_packages);
3649 if (debug && !summary_only && topo.num_packages > 1) 4347 if (!summary_only && topo.num_packages > 1)
3650 show_pkg = 1; 4348 BIC_PRESENT(BIC_Package);
3651 4349
3652 topo.num_threads_per_core = max_siblings; 4350 topo.num_threads_per_core = max_siblings;
3653 if (debug > 1) 4351 if (debug > 1)
@@ -3662,7 +4360,7 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data
3662 int i; 4360 int i;
3663 4361
3664 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg * 4362 *t = calloc(topo.num_threads_per_core * topo.num_cores_per_pkg *
3665 topo.num_packages, sizeof(struct thread_data) + sys.thread_counter_bytes); 4363 topo.num_packages, sizeof(struct thread_data));
3666 if (*t == NULL) 4364 if (*t == NULL)
3667 goto error; 4365 goto error;
3668 4366
@@ -3671,14 +4369,14 @@ allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data
3671 (*t)[i].cpu_id = -1; 4369 (*t)[i].cpu_id = -1;
3672 4370
3673 *c = calloc(topo.num_cores_per_pkg * topo.num_packages, 4371 *c = calloc(topo.num_cores_per_pkg * topo.num_packages,
3674 sizeof(struct core_data) + sys.core_counter_bytes); 4372 sizeof(struct core_data));
3675 if (*c == NULL) 4373 if (*c == NULL)
3676 goto error; 4374 goto error;
3677 4375
3678 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++) 4376 for (i = 0; i < topo.num_cores_per_pkg * topo.num_packages; i++)
3679 (*c)[i].core_id = -1; 4377 (*c)[i].core_id = -1;
3680 4378
3681 *p = calloc(topo.num_packages, sizeof(struct pkg_data) + sys.package_counter_bytes); 4379 *p = calloc(topo.num_packages, sizeof(struct pkg_data));
3682 if (*p == NULL) 4380 if (*p == NULL)
3683 goto error; 4381 goto error;
3684 4382
@@ -3789,24 +4487,24 @@ void turbostat_init()
3789 process_cpuid(); 4487 process_cpuid();
3790 4488
3791 4489
3792 if (debug) 4490 if (!quiet)
3793 for_all_cpus(print_hwp, ODD_COUNTERS); 4491 for_all_cpus(print_hwp, ODD_COUNTERS);
3794 4492
3795 if (debug) 4493 if (!quiet)
3796 for_all_cpus(print_epb, ODD_COUNTERS); 4494 for_all_cpus(print_epb, ODD_COUNTERS);
3797 4495
3798 if (debug) 4496 if (!quiet)
3799 for_all_cpus(print_perf_limit, ODD_COUNTERS); 4497 for_all_cpus(print_perf_limit, ODD_COUNTERS);
3800 4498
3801 if (debug) 4499 if (!quiet)
3802 for_all_cpus(print_rapl, ODD_COUNTERS); 4500 for_all_cpus(print_rapl, ODD_COUNTERS);
3803 4501
3804 for_all_cpus(set_temperature_target, ODD_COUNTERS); 4502 for_all_cpus(set_temperature_target, ODD_COUNTERS);
3805 4503
3806 if (debug) 4504 if (!quiet)
3807 for_all_cpus(print_thermal, ODD_COUNTERS); 4505 for_all_cpus(print_thermal, ODD_COUNTERS);
3808 4506
3809 if (debug && do_irtl_snb) 4507 if (!quiet && do_irtl_snb)
3810 print_irtl(); 4508 print_irtl();
3811} 4509}
3812 4510
@@ -3815,6 +4513,7 @@ int fork_it(char **argv)
3815 pid_t child_pid; 4513 pid_t child_pid;
3816 int status; 4514 int status;
3817 4515
4516 snapshot_proc_sysfs_files();
3818 status = for_all_cpus(get_counters, EVEN_COUNTERS); 4517 status = for_all_cpus(get_counters, EVEN_COUNTERS);
3819 if (status) 4518 if (status)
3820 exit(status); 4519 exit(status);
@@ -3826,6 +4525,7 @@ int fork_it(char **argv)
3826 if (!child_pid) { 4525 if (!child_pid) {
3827 /* child */ 4526 /* child */
3828 execvp(argv[0], argv); 4527 execvp(argv[0], argv);
4528 err(errno, "exec %s", argv[0]);
3829 } else { 4529 } else {
3830 4530
3831 /* parent */ 4531 /* parent */
@@ -3841,6 +4541,7 @@ int fork_it(char **argv)
3841 * n.b. fork_it() does not check for errors from for_all_cpus() 4541 * n.b. fork_it() does not check for errors from for_all_cpus()
3842 * because re-starting is problematic when forking 4542 * because re-starting is problematic when forking
3843 */ 4543 */
4544 snapshot_proc_sysfs_files();
3844 for_all_cpus(get_counters, ODD_COUNTERS); 4545 for_all_cpus(get_counters, ODD_COUNTERS);
3845 gettimeofday(&tv_odd, (struct timezone *)NULL); 4546 gettimeofday(&tv_odd, (struct timezone *)NULL);
3846 timersub(&tv_odd, &tv_even, &tv_delta); 4547 timersub(&tv_odd, &tv_even, &tv_delta);
@@ -3862,6 +4563,7 @@ int get_and_dump_counters(void)
3862{ 4563{
3863 int status; 4564 int status;
3864 4565
4566 snapshot_proc_sysfs_files();
3865 status = for_all_cpus(get_counters, ODD_COUNTERS); 4567 status = for_all_cpus(get_counters, ODD_COUNTERS);
3866 if (status) 4568 if (status)
3867 return status; 4569 return status;
@@ -3876,13 +4578,13 @@ int get_and_dump_counters(void)
3876} 4578}
3877 4579
3878void print_version() { 4580void print_version() {
3879 fprintf(outf, "turbostat version 4.16 24 Dec 2016" 4581 fprintf(outf, "turbostat version 17.02.24"
3880 " - Len Brown <lenb@kernel.org>\n"); 4582 " - Len Brown <lenb@kernel.org>\n");
3881} 4583}
3882 4584
3883int add_counter(unsigned int msr_num, char *name, unsigned int width, 4585int add_counter(unsigned int msr_num, char *path, char *name,
3884 enum counter_scope scope, enum counter_type type, 4586 unsigned int width, enum counter_scope scope,
3885 enum counter_format format) 4587 enum counter_type type, enum counter_format format, int flags)
3886{ 4588{
3887 struct msr_counter *msrp; 4589 struct msr_counter *msrp;
3888 4590
@@ -3894,31 +4596,46 @@ int add_counter(unsigned int msr_num, char *name, unsigned int width,
3894 4596
3895 msrp->msr_num = msr_num; 4597 msrp->msr_num = msr_num;
3896 strncpy(msrp->name, name, NAME_BYTES); 4598 strncpy(msrp->name, name, NAME_BYTES);
4599 if (path)
4600 strncpy(msrp->path, path, PATH_BYTES);
3897 msrp->width = width; 4601 msrp->width = width;
3898 msrp->type = type; 4602 msrp->type = type;
3899 msrp->format = format; 4603 msrp->format = format;
4604 msrp->flags = flags;
3900 4605
3901 switch (scope) { 4606 switch (scope) {
3902 4607
3903 case SCOPE_CPU: 4608 case SCOPE_CPU:
3904 sys.thread_counter_bytes += 64;
3905 msrp->next = sys.tp; 4609 msrp->next = sys.tp;
3906 sys.tp = msrp; 4610 sys.tp = msrp;
3907 sys.thread_counter_bytes += sizeof(unsigned long long); 4611 sys.added_thread_counters++;
4612 if (sys.added_thread_counters > MAX_ADDED_COUNTERS) {
4613 fprintf(stderr, "exceeded max %d added thread counters\n",
4614 MAX_ADDED_COUNTERS);
4615 exit(-1);
4616 }
3908 break; 4617 break;
3909 4618
3910 case SCOPE_CORE: 4619 case SCOPE_CORE:
3911 sys.core_counter_bytes += 64;
3912 msrp->next = sys.cp; 4620 msrp->next = sys.cp;
3913 sys.cp = msrp; 4621 sys.cp = msrp;
3914 sys.core_counter_bytes += sizeof(unsigned long long); 4622 sys.added_core_counters++;
4623 if (sys.added_core_counters > MAX_ADDED_COUNTERS) {
4624 fprintf(stderr, "exceeded max %d added core counters\n",
4625 MAX_ADDED_COUNTERS);
4626 exit(-1);
4627 }
3915 break; 4628 break;
3916 4629
3917 case SCOPE_PACKAGE: 4630 case SCOPE_PACKAGE:
3918 sys.package_counter_bytes += 64;
3919 msrp->next = sys.pp; 4631 msrp->next = sys.pp;
3920 sys.pp = msrp; 4632 sys.pp = msrp;
3921 sys.package_counter_bytes += sizeof(unsigned long long); 4633 sys.added_package_counters++;
4634 if (sys.added_package_counters > MAX_ADDED_COUNTERS) {
4635 fprintf(stderr, "exceeded max %d added package counters\n",
4636 MAX_ADDED_COUNTERS);
4637 exit(-1);
4638 }
3922 break; 4639 break;
3923 } 4640 }
3924 4641
@@ -3928,7 +4645,8 @@ int add_counter(unsigned int msr_num, char *name, unsigned int width,
3928void parse_add_command(char *add_command) 4645void parse_add_command(char *add_command)
3929{ 4646{
3930 int msr_num = 0; 4647 int msr_num = 0;
3931 char name_buffer[NAME_BYTES]; 4648 char *path = NULL;
4649 char name_buffer[NAME_BYTES] = "";
3932 int width = 64; 4650 int width = 64;
3933 int fail = 0; 4651 int fail = 0;
3934 enum counter_scope scope = SCOPE_CPU; 4652 enum counter_scope scope = SCOPE_CPU;
@@ -3943,6 +4661,11 @@ void parse_add_command(char *add_command)
3943 if (sscanf(add_command, "msr%d", &msr_num) == 1) 4661 if (sscanf(add_command, "msr%d", &msr_num) == 1)
3944 goto next; 4662 goto next;
3945 4663
4664 if (*add_command == '/') {
4665 path = add_command;
4666 goto next;
4667 }
4668
3946 if (sscanf(add_command, "u%d", &width) == 1) { 4669 if (sscanf(add_command, "u%d", &width) == 1) {
3947 if ((width == 32) || (width == 64)) 4670 if ((width == 32) || (width == 64))
3948 goto next; 4671 goto next;
@@ -3968,6 +4691,10 @@ void parse_add_command(char *add_command)
3968 type = COUNTER_SECONDS; 4691 type = COUNTER_SECONDS;
3969 goto next; 4692 goto next;
3970 } 4693 }
4694 if (!strncmp(add_command, "usec", strlen("usec"))) {
4695 type = COUNTER_USEC;
4696 goto next;
4697 }
3971 if (!strncmp(add_command, "raw", strlen("raw"))) { 4698 if (!strncmp(add_command, "raw", strlen("raw"))) {
3972 format = FORMAT_RAW; 4699 format = FORMAT_RAW;
3973 goto next; 4700 goto next;
@@ -3992,36 +4719,26 @@ void parse_add_command(char *add_command)
3992 4719
3993next: 4720next:
3994 add_command = strchr(add_command, ','); 4721 add_command = strchr(add_command, ',');
3995 if (add_command) 4722 if (add_command) {
4723 *add_command = '\0';
3996 add_command++; 4724 add_command++;
4725 }
3997 4726
3998 } 4727 }
3999 if (msr_num == 0) { 4728 if ((msr_num == 0) && (path == NULL)) {
4000 fprintf(stderr, "--add: (msrDDD | msr0xXXX) required\n"); 4729 fprintf(stderr, "--add: (msrDDD | msr0xXXX | /path_to_counter ) required\n");
4001 fail++; 4730 fail++;
4002 } 4731 }
4003 4732
4004 /* generate default column header */ 4733 /* generate default column header */
4005 if (*name_buffer == '\0') { 4734 if (*name_buffer == '\0') {
4006 if (format == FORMAT_RAW) { 4735 if (width == 32)
4007 if (width == 32) 4736 sprintf(name_buffer, "M0x%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
4008 sprintf(name_buffer, "msr%d", msr_num); 4737 else
4009 else 4738 sprintf(name_buffer, "M0X%x%s", msr_num, format == FORMAT_PERCENT ? "%" : "");
4010 sprintf(name_buffer, "MSR%d", msr_num);
4011 } else if (format == FORMAT_DELTA) {
4012 if (width == 32)
4013 sprintf(name_buffer, "cnt%d", msr_num);
4014 else
4015 sprintf(name_buffer, "CNT%d", msr_num);
4016 } else if (format == FORMAT_PERCENT) {
4017 if (width == 32)
4018 sprintf(name_buffer, "msr%d%%", msr_num);
4019 else
4020 sprintf(name_buffer, "MSR%d%%", msr_num);
4021 }
4022 } 4739 }
4023 4740
4024 if (add_counter(msr_num, name_buffer, width, scope, type, format)) 4741 if (add_counter(msr_num, path, name_buffer, width, scope, type, format, 0))
4025 fail++; 4742 fail++;
4026 4743
4027 if (fail) { 4744 if (fail) {
@@ -4029,20 +4746,214 @@ next:
4029 exit(1); 4746 exit(1);
4030 } 4747 }
4031} 4748}
4749
4750int is_deferred_skip(char *name)
4751{
4752 int i;
4753
4754 for (i = 0; i < deferred_skip_index; ++i)
4755 if (!strcmp(name, deferred_skip_names[i]))
4756 return 1;
4757 return 0;
4758}
4759
4760void probe_sysfs(void)
4761{
4762 char path[64];
4763 char name_buf[16];
4764 FILE *input;
4765 int state;
4766 char *sp;
4767
4768 if (!DO_BIC(BIC_sysfs))
4769 return;
4770
4771 for (state = 10; state > 0; --state) {
4772
4773 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
4774 base_cpu, state);
4775 input = fopen(path, "r");
4776 if (input == NULL)
4777 continue;
4778 fgets(name_buf, sizeof(name_buf), input);
4779
4780 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
4781 sp = strchr(name_buf, '-');
4782 if (!sp)
4783 sp = strchrnul(name_buf, '\n');
4784 *sp = '%';
4785 *(sp + 1) = '\0';
4786
4787 fclose(input);
4788
4789 sprintf(path, "cpuidle/state%d/time", state);
4790
4791 if (is_deferred_skip(name_buf))
4792 continue;
4793
4794 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_USEC,
4795 FORMAT_PERCENT, SYSFS_PERCPU);
4796 }
4797
4798 for (state = 10; state > 0; --state) {
4799
4800 sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name",
4801 base_cpu, state);
4802 input = fopen(path, "r");
4803 if (input == NULL)
4804 continue;
4805 fgets(name_buf, sizeof(name_buf), input);
4806 /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
4807 sp = strchr(name_buf, '-');
4808 if (!sp)
4809 sp = strchrnul(name_buf, '\n');
4810 *sp = '\0';
4811 fclose(input);
4812
4813 sprintf(path, "cpuidle/state%d/usage", state);
4814
4815 if (is_deferred_skip(name_buf))
4816 continue;
4817
4818 add_counter(0, path, name_buf, 64, SCOPE_CPU, COUNTER_ITEMS,
4819 FORMAT_DELTA, SYSFS_PERCPU);
4820 }
4821
4822}
4823
4824
4825/*
4826 * parse cpuset with following syntax
4827 * 1,2,4..6,8-10 and set bits in cpu_subset
4828 */
4829void parse_cpu_command(char *optarg)
4830{
4831 unsigned int start, end;
4832 char *next;
4833
4834 if (!strcmp(optarg, "core")) {
4835 if (cpu_subset)
4836 goto error;
4837 show_core_only++;
4838 return;
4839 }
4840 if (!strcmp(optarg, "package")) {
4841 if (cpu_subset)
4842 goto error;
4843 show_pkg_only++;
4844 return;
4845 }
4846 if (show_core_only || show_pkg_only)
4847 goto error;
4848
4849 cpu_subset = CPU_ALLOC(CPU_SUBSET_MAXCPUS);
4850 if (cpu_subset == NULL)
4851 err(3, "CPU_ALLOC");
4852 cpu_subset_size = CPU_ALLOC_SIZE(CPU_SUBSET_MAXCPUS);
4853
4854 CPU_ZERO_S(cpu_subset_size, cpu_subset);
4855
4856 next = optarg;
4857
4858 while (next && *next) {
4859
4860 if (*next == '-') /* no negative cpu numbers */
4861 goto error;
4862
4863 start = strtoul(next, &next, 10);
4864
4865 if (start >= CPU_SUBSET_MAXCPUS)
4866 goto error;
4867 CPU_SET_S(start, cpu_subset_size, cpu_subset);
4868
4869 if (*next == '\0')
4870 break;
4871
4872 if (*next == ',') {
4873 next += 1;
4874 continue;
4875 }
4876
4877 if (*next == '-') {
4878 next += 1; /* start range */
4879 } else if (*next == '.') {
4880 next += 1;
4881 if (*next == '.')
4882 next += 1; /* start range */
4883 else
4884 goto error;
4885 }
4886
4887 end = strtoul(next, &next, 10);
4888 if (end <= start)
4889 goto error;
4890
4891 while (++start <= end) {
4892 if (start >= CPU_SUBSET_MAXCPUS)
4893 goto error;
4894 CPU_SET_S(start, cpu_subset_size, cpu_subset);
4895 }
4896
4897 if (*next == ',')
4898 next += 1;
4899 else if (*next != '\0')
4900 goto error;
4901 }
4902
4903 return;
4904
4905error:
4906 fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
4907 help();
4908 exit(-1);
4909}
4910
4911int shown;
4912/*
4913 * parse_show_hide() - process cmdline to set default counter action
4914 */
4915void parse_show_hide(char *optarg, enum show_hide_mode new_mode)
4916{
4917 /*
4918 * --show: show only those specified
4919 * The 1st invocation will clear and replace the enabled mask
4920 * subsequent invocations can add to it.
4921 */
4922 if (new_mode == SHOW_LIST) {
4923 if (shown == 0)
4924 bic_enabled = bic_lookup(optarg, new_mode);
4925 else
4926 bic_enabled |= bic_lookup(optarg, new_mode);
4927 shown = 1;
4928
4929 return;
4930 }
4931
4932 /*
4933 * --hide: do not show those specified
4934 * multiple invocations simply clear more bits in enabled mask
4935 */
4936 bic_enabled &= ~bic_lookup(optarg, new_mode);
4937
4938}
4939
4032void cmdline(int argc, char **argv) 4940void cmdline(int argc, char **argv)
4033{ 4941{
4034 int opt; 4942 int opt;
4035 int option_index = 0; 4943 int option_index = 0;
4036 static struct option long_options[] = { 4944 static struct option long_options[] = {
4037 {"add", required_argument, 0, 'a'}, 4945 {"add", required_argument, 0, 'a'},
4946 {"cpu", required_argument, 0, 'c'},
4038 {"Dump", no_argument, 0, 'D'}, 4947 {"Dump", no_argument, 0, 'D'},
4039 {"debug", no_argument, 0, 'd'}, 4948 {"debug", no_argument, 0, 'd'}, /* internal, not documented */
4040 {"interval", required_argument, 0, 'i'}, 4949 {"interval", required_argument, 0, 'i'},
4041 {"help", no_argument, 0, 'h'}, 4950 {"help", no_argument, 0, 'h'},
4951 {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help
4042 {"Joules", no_argument, 0, 'J'}, 4952 {"Joules", no_argument, 0, 'J'},
4953 {"list", no_argument, 0, 'l'},
4043 {"out", required_argument, 0, 'o'}, 4954 {"out", required_argument, 0, 'o'},
4044 {"Package", no_argument, 0, 'p'}, 4955 {"quiet", no_argument, 0, 'q'},
4045 {"processor", no_argument, 0, 'p'}, 4956 {"show", required_argument, 0, 's'},
4046 {"Summary", no_argument, 0, 'S'}, 4957 {"Summary", no_argument, 0, 'S'},
4047 {"TCC", required_argument, 0, 'T'}, 4958 {"TCC", required_argument, 0, 'T'},
4048 {"version", no_argument, 0, 'v' }, 4959 {"version", no_argument, 0, 'v' },
@@ -4051,18 +4962,24 @@ void cmdline(int argc, char **argv)
4051 4962
4052 progname = argv[0]; 4963 progname = argv[0];
4053 4964
4054 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:PpST:v", 4965 while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:qST:v",
4055 long_options, &option_index)) != -1) { 4966 long_options, &option_index)) != -1) {
4056 switch (opt) { 4967 switch (opt) {
4057 case 'a': 4968 case 'a':
4058 parse_add_command(optarg); 4969 parse_add_command(optarg);
4059 break; 4970 break;
4971 case 'c':
4972 parse_cpu_command(optarg);
4973 break;
4060 case 'D': 4974 case 'D':
4061 dump_only++; 4975 dump_only++;
4062 break; 4976 break;
4063 case 'd': 4977 case 'd':
4064 debug++; 4978 debug++;
4065 break; 4979 break;
4980 case 'H':
4981 parse_show_hide(optarg, HIDE_LIST);
4982 break;
4066 case 'h': 4983 case 'h':
4067 default: 4984 default:
4068 help(); 4985 help();
@@ -4084,14 +5001,18 @@ void cmdline(int argc, char **argv)
4084 case 'J': 5001 case 'J':
4085 rapl_joules++; 5002 rapl_joules++;
4086 break; 5003 break;
5004 case 'l':
5005 list_header_only++;
5006 quiet++;
5007 break;
4087 case 'o': 5008 case 'o':
4088 outf = fopen_or_die(optarg, "w"); 5009 outf = fopen_or_die(optarg, "w");
4089 break; 5010 break;
4090 case 'P': 5011 case 'q':
4091 show_pkg_only++; 5012 quiet = 1;
4092 break; 5013 break;
4093 case 'p': 5014 case 's':
4094 show_core_only++; 5015 parse_show_hide(optarg, SHOW_LIST);
4095 break; 5016 break;
4096 case 'S': 5017 case 'S':
4097 summary_only++; 5018 summary_only++;
@@ -4113,15 +5034,24 @@ int main(int argc, char **argv)
4113 5034
4114 cmdline(argc, argv); 5035 cmdline(argc, argv);
4115 5036
4116 if (debug) 5037 if (!quiet)
4117 print_version(); 5038 print_version();
4118 5039
5040 probe_sysfs();
5041
4119 turbostat_init(); 5042 turbostat_init();
4120 5043
4121 /* dump counters and exit */ 5044 /* dump counters and exit */
4122 if (dump_only) 5045 if (dump_only)
4123 return get_and_dump_counters(); 5046 return get_and_dump_counters();
4124 5047
5048 /* list header and exit */
5049 if (list_header_only) {
5050 print_header(",");
5051 flush_output_stdout();
5052 return 0;
5053 }
5054
4125 /* 5055 /*
4126 * if any params left, it must be a command to fork 5056 * if any params left, it must be a command to fork
4127 */ 5057 */
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index be93ab02b490..0c8b61f8398e 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -179,6 +179,7 @@ my $localversion;
179my $iteration = 0; 179my $iteration = 0;
180my $successes = 0; 180my $successes = 0;
181my $stty_orig; 181my $stty_orig;
182my $run_command_status = 0;
182 183
183my $bisect_good; 184my $bisect_good;
184my $bisect_bad; 185my $bisect_bad;
@@ -1325,26 +1326,44 @@ sub wait_for_monitor;
1325 1326
1326sub reboot { 1327sub reboot {
1327 my ($time) = @_; 1328 my ($time) = @_;
1329 my $powercycle = 0;
1328 1330
1329 # Make sure everything has been written to disk 1331 # test if the machine can be connected to within 5 seconds
1330 run_ssh("sync"); 1332 my $stat = run_ssh("echo check machine status", 5);
1333 if (!$stat) {
1334 doprint("power cycle\n");
1335 $powercycle = 1;
1336 }
1337
1338 if ($powercycle) {
1339 run_command "$power_cycle";
1331 1340
1332 if (defined($time)) {
1333 start_monitor; 1341 start_monitor;
1334 # flush out current monitor 1342 # flush out current monitor
1335 # May contain the reboot success line 1343 # May contain the reboot success line
1336 wait_for_monitor 1; 1344 wait_for_monitor 1;
1337 }
1338 1345
1339 # try to reboot normally 1346 } else {
1340 if (run_command $reboot) { 1347 # Make sure everything has been written to disk
1341 if (defined($powercycle_after_reboot)) { 1348 run_ssh("sync");
1342 sleep $powercycle_after_reboot; 1349
1350 if (defined($time)) {
1351 start_monitor;
1352 # flush out current monitor
1353 # May contain the reboot success line
1354 wait_for_monitor 1;
1355 }
1356
1357 # try to reboot normally
1358 if (run_command $reboot) {
1359 if (defined($powercycle_after_reboot)) {
1360 sleep $powercycle_after_reboot;
1361 run_command "$power_cycle";
1362 }
1363 } else {
1364 # nope? power cycle it.
1343 run_command "$power_cycle"; 1365 run_command "$power_cycle";
1344 } 1366 }
1345 } else {
1346 # nope? power cycle it.
1347 run_command "$power_cycle";
1348 } 1367 }
1349 1368
1350 if (defined($time)) { 1369 if (defined($time)) {
@@ -1412,6 +1431,10 @@ sub dodie {
1412 system("stty $stty_orig"); 1431 system("stty $stty_orig");
1413 } 1432 }
1414 1433
1434 if (defined($post_test)) {
1435 run_command $post_test;
1436 }
1437
1415 die @_, "\n"; 1438 die @_, "\n";
1416} 1439}
1417 1440
@@ -1624,10 +1647,6 @@ sub save_logs {
1624 1647
1625sub fail { 1648sub fail {
1626 1649
1627 if (defined($post_test)) {
1628 run_command $post_test;
1629 }
1630
1631 if ($die_on_failure) { 1650 if ($die_on_failure) {
1632 dodie @_; 1651 dodie @_;
1633 } 1652 }
@@ -1660,23 +1679,26 @@ sub fail {
1660 save_logs "fail", $store_failures; 1679 save_logs "fail", $store_failures;
1661 } 1680 }
1662 1681
1682 if (defined($post_test)) {
1683 run_command $post_test;
1684 }
1685
1663 return 1; 1686 return 1;
1664} 1687}
1665 1688
1666sub run_command { 1689sub run_command {
1667 my ($command, $redirect) = @_; 1690 my ($command, $redirect, $timeout) = @_;
1668 my $start_time; 1691 my $start_time;
1669 my $end_time; 1692 my $end_time;
1670 my $dolog = 0; 1693 my $dolog = 0;
1671 my $dord = 0; 1694 my $dord = 0;
1672 my $pid; 1695 my $pid;
1673 1696
1674 $start_time = time;
1675
1676 $command =~ s/\$SSH_USER/$ssh_user/g; 1697 $command =~ s/\$SSH_USER/$ssh_user/g;
1677 $command =~ s/\$MACHINE/$machine/g; 1698 $command =~ s/\$MACHINE/$machine/g;
1678 1699
1679 doprint("$command ... "); 1700 doprint("$command ... ");
1701 $start_time = time;
1680 1702
1681 $pid = open(CMD, "$command 2>&1 |") or 1703 $pid = open(CMD, "$command 2>&1 |") or
1682 (fail "unable to exec $command" and return 0); 1704 (fail "unable to exec $command" and return 0);
@@ -1693,13 +1715,30 @@ sub run_command {
1693 $dord = 1; 1715 $dord = 1;
1694 } 1716 }
1695 1717
1696 while (<CMD>) { 1718 my $hit_timeout = 0;
1697 print LOG if ($dolog); 1719
1698 print RD if ($dord); 1720 while (1) {
1721 my $fp = \*CMD;
1722 if (defined($timeout)) {
1723 doprint "timeout = $timeout\n";
1724 }
1725 my $line = wait_for_input($fp, $timeout);
1726 if (!defined($line)) {
1727 my $now = time;
1728 if (defined($timeout) && (($now - $start_time) >= $timeout)) {
1729 doprint "Hit timeout of $timeout, killing process\n";
1730 $hit_timeout = 1;
1731 kill 9, $pid;
1732 }
1733 last;
1734 }
1735 print LOG $line if ($dolog);
1736 print RD $line if ($dord);
1699 } 1737 }
1700 1738
1701 waitpid($pid, 0); 1739 waitpid($pid, 0);
1702 my $failed = $?; 1740 # shift 8 for real exit status
1741 $run_command_status = $? >> 8;
1703 1742
1704 close(CMD); 1743 close(CMD);
1705 close(LOG) if ($dolog); 1744 close(LOG) if ($dolog);
@@ -1714,21 +1753,25 @@ sub run_command {
1714 doprint "[$delta seconds] "; 1753 doprint "[$delta seconds] ";
1715 } 1754 }
1716 1755
1717 if ($failed) { 1756 if ($hit_timeout) {
1757 $run_command_status = 1;
1758 }
1759
1760 if ($run_command_status) {
1718 doprint "FAILED!\n"; 1761 doprint "FAILED!\n";
1719 } else { 1762 } else {
1720 doprint "SUCCESS\n"; 1763 doprint "SUCCESS\n";
1721 } 1764 }
1722 1765
1723 return !$failed; 1766 return !$run_command_status;
1724} 1767}
1725 1768
1726sub run_ssh { 1769sub run_ssh {
1727 my ($cmd) = @_; 1770 my ($cmd, $timeout) = @_;
1728 my $cp_exec = $ssh_exec; 1771 my $cp_exec = $ssh_exec;
1729 1772
1730 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; 1773 $cp_exec =~ s/\$SSH_COMMAND/$cmd/g;
1731 return run_command "$cp_exec"; 1774 return run_command "$cp_exec", undef , $timeout;
1732} 1775}
1733 1776
1734sub run_scp { 1777sub run_scp {
@@ -1837,6 +1880,7 @@ sub get_grub_index {
1837sub wait_for_input 1880sub wait_for_input
1838{ 1881{
1839 my ($fp, $time) = @_; 1882 my ($fp, $time) = @_;
1883 my $start_time;
1840 my $rin; 1884 my $rin;
1841 my $rout; 1885 my $rout;
1842 my $nr; 1886 my $nr;
@@ -1852,17 +1896,22 @@ sub wait_for_input
1852 vec($rin, fileno($fp), 1) = 1; 1896 vec($rin, fileno($fp), 1) = 1;
1853 vec($rin, fileno(\*STDIN), 1) = 1; 1897 vec($rin, fileno(\*STDIN), 1) = 1;
1854 1898
1899 $start_time = time;
1900
1855 while (1) { 1901 while (1) {
1856 $nr = select($rout=$rin, undef, undef, $time); 1902 $nr = select($rout=$rin, undef, undef, $time);
1857 1903
1858 if ($nr <= 0) { 1904 last if ($nr <= 0);
1859 return undef;
1860 }
1861 1905
1862 # copy data from stdin to the console 1906 # copy data from stdin to the console
1863 if (vec($rout, fileno(\*STDIN), 1) == 1) { 1907 if (vec($rout, fileno(\*STDIN), 1) == 1) {
1864 sysread(\*STDIN, $buf, 1000); 1908 $nr = sysread(\*STDIN, $buf, 1000);
1865 syswrite($fp, $buf, 1000); 1909 syswrite($fp, $buf, $nr) if ($nr > 0);
1910 }
1911
1912 # The timeout is based on time waiting for the fp data
1913 if (vec($rout, fileno($fp), 1) != 1) {
1914 last if (defined($time) && (time - $start_time > $time));
1866 next; 1915 next;
1867 } 1916 }
1868 1917
@@ -1874,12 +1923,11 @@ sub wait_for_input
1874 last if ($ch eq "\n"); 1923 last if ($ch eq "\n");
1875 } 1924 }
1876 1925
1877 if (!length($line)) { 1926 last if (!length($line));
1878 return undef;
1879 }
1880 1927
1881 return $line; 1928 return $line;
1882 } 1929 }
1930 return undef;
1883} 1931}
1884 1932
1885sub reboot_to { 1933sub reboot_to {
@@ -2489,10 +2537,6 @@ sub halt {
2489sub success { 2537sub success {
2490 my ($i) = @_; 2538 my ($i) = @_;
2491 2539
2492 if (defined($post_test)) {
2493 run_command $post_test;
2494 }
2495
2496 $successes++; 2540 $successes++;
2497 2541
2498 my $name = ""; 2542 my $name = "";
@@ -2517,6 +2561,10 @@ sub success {
2517 doprint "Reboot and wait $sleep_time seconds\n"; 2561 doprint "Reboot and wait $sleep_time seconds\n";
2518 reboot_to_good $sleep_time; 2562 reboot_to_good $sleep_time;
2519 } 2563 }
2564
2565 if (defined($post_test)) {
2566 run_command $post_test;
2567 }
2520} 2568}
2521 2569
2522sub answer_bisect { 2570sub answer_bisect {
@@ -2537,16 +2585,15 @@ sub answer_bisect {
2537} 2585}
2538 2586
2539sub child_run_test { 2587sub child_run_test {
2540 my $failed = 0;
2541 2588
2542 # child should have no power 2589 # child should have no power
2543 $reboot_on_error = 0; 2590 $reboot_on_error = 0;
2544 $poweroff_on_error = 0; 2591 $poweroff_on_error = 0;
2545 $die_on_failure = 1; 2592 $die_on_failure = 1;
2546 2593
2547 run_command $run_test, $testlog or $failed = 1; 2594 run_command $run_test, $testlog;
2548 2595
2549 exit $failed; 2596 exit $run_command_status;
2550} 2597}
2551 2598
2552my $child_done; 2599my $child_done;
@@ -2629,7 +2676,7 @@ sub do_run_test {
2629 } 2676 }
2630 2677
2631 waitpid $child_pid, 0; 2678 waitpid $child_pid, 0;
2632 $child_exit = $?; 2679 $child_exit = $? >> 8;
2633 2680
2634 my $end_time = time; 2681 my $end_time = time;
2635 $test_time = $end_time - $start_time; 2682 $test_time = $end_time - $start_time;
@@ -3330,7 +3377,6 @@ sub config_bisect {
3330 save_config \%good_configs, $good_config; 3377 save_config \%good_configs, $good_config;
3331 save_config \%bad_configs, $bad_config; 3378 save_config \%bad_configs, $bad_config;
3332 3379
3333
3334 if (defined($config_bisect_check) && $config_bisect_check ne "0") { 3380 if (defined($config_bisect_check) && $config_bisect_check ne "0") {
3335 if ($config_bisect_check ne "good") { 3381 if ($config_bisect_check ne "good") {
3336 doprint "Testing bad config\n"; 3382 doprint "Testing bad config\n";
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 45be8b55a663..798f17655433 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -887,7 +887,7 @@ static void nfit_test0_setup(struct nfit_test *t)
887 memdev->range_index = 0+1; 887 memdev->range_index = 0+1;
888 memdev->region_index = 4+1; 888 memdev->region_index = 4+1;
889 memdev->region_size = SPA0_SIZE/2; 889 memdev->region_size = SPA0_SIZE/2;
890 memdev->region_offset = t->spa_set_dma[0]; 890 memdev->region_offset = 1;
891 memdev->address = 0; 891 memdev->address = 0;
892 memdev->interleave_index = 0; 892 memdev->interleave_index = 0;
893 memdev->interleave_ways = 2; 893 memdev->interleave_ways = 2;
@@ -902,7 +902,7 @@ static void nfit_test0_setup(struct nfit_test *t)
902 memdev->range_index = 0+1; 902 memdev->range_index = 0+1;
903 memdev->region_index = 5+1; 903 memdev->region_index = 5+1;
904 memdev->region_size = SPA0_SIZE/2; 904 memdev->region_size = SPA0_SIZE/2;
905 memdev->region_offset = t->spa_set_dma[0] + SPA0_SIZE/2; 905 memdev->region_offset = (1 << 8);
906 memdev->address = 0; 906 memdev->address = 0;
907 memdev->interleave_index = 0; 907 memdev->interleave_index = 0;
908 memdev->interleave_ways = 2; 908 memdev->interleave_ways = 2;
@@ -917,7 +917,7 @@ static void nfit_test0_setup(struct nfit_test *t)
917 memdev->range_index = 1+1; 917 memdev->range_index = 1+1;
918 memdev->region_index = 4+1; 918 memdev->region_index = 4+1;
919 memdev->region_size = SPA1_SIZE/4; 919 memdev->region_size = SPA1_SIZE/4;
920 memdev->region_offset = t->spa_set_dma[1]; 920 memdev->region_offset = (1 << 16);
921 memdev->address = SPA0_SIZE/2; 921 memdev->address = SPA0_SIZE/2;
922 memdev->interleave_index = 0; 922 memdev->interleave_index = 0;
923 memdev->interleave_ways = 4; 923 memdev->interleave_ways = 4;
@@ -932,7 +932,7 @@ static void nfit_test0_setup(struct nfit_test *t)
932 memdev->range_index = 1+1; 932 memdev->range_index = 1+1;
933 memdev->region_index = 5+1; 933 memdev->region_index = 5+1;
934 memdev->region_size = SPA1_SIZE/4; 934 memdev->region_size = SPA1_SIZE/4;
935 memdev->region_offset = t->spa_set_dma[1] + SPA1_SIZE/4; 935 memdev->region_offset = (1 << 24);
936 memdev->address = SPA0_SIZE/2; 936 memdev->address = SPA0_SIZE/2;
937 memdev->interleave_index = 0; 937 memdev->interleave_index = 0;
938 memdev->interleave_ways = 4; 938 memdev->interleave_ways = 4;
@@ -947,7 +947,7 @@ static void nfit_test0_setup(struct nfit_test *t)
947 memdev->range_index = 1+1; 947 memdev->range_index = 1+1;
948 memdev->region_index = 6+1; 948 memdev->region_index = 6+1;
949 memdev->region_size = SPA1_SIZE/4; 949 memdev->region_size = SPA1_SIZE/4;
950 memdev->region_offset = t->spa_set_dma[1] + 2*SPA1_SIZE/4; 950 memdev->region_offset = (1ULL << 32);
951 memdev->address = SPA0_SIZE/2; 951 memdev->address = SPA0_SIZE/2;
952 memdev->interleave_index = 0; 952 memdev->interleave_index = 0;
953 memdev->interleave_ways = 4; 953 memdev->interleave_ways = 4;
@@ -962,7 +962,7 @@ static void nfit_test0_setup(struct nfit_test *t)
962 memdev->range_index = 1+1; 962 memdev->range_index = 1+1;
963 memdev->region_index = 7+1; 963 memdev->region_index = 7+1;
964 memdev->region_size = SPA1_SIZE/4; 964 memdev->region_size = SPA1_SIZE/4;
965 memdev->region_offset = t->spa_set_dma[1] + 3*SPA1_SIZE/4; 965 memdev->region_offset = (1ULL << 40);
966 memdev->address = SPA0_SIZE/2; 966 memdev->address = SPA0_SIZE/2;
967 memdev->interleave_index = 0; 967 memdev->interleave_index = 0;
968 memdev->interleave_ways = 4; 968 memdev->interleave_ways = 4;
@@ -1380,7 +1380,7 @@ static void nfit_test0_setup(struct nfit_test *t)
1380 memdev->range_index = 11+1; 1380 memdev->range_index = 11+1;
1381 memdev->region_index = 9+1; 1381 memdev->region_index = 9+1;
1382 memdev->region_size = SPA0_SIZE; 1382 memdev->region_size = SPA0_SIZE;
1383 memdev->region_offset = t->spa_set_dma[2]; 1383 memdev->region_offset = (1ULL << 48);
1384 memdev->address = 0; 1384 memdev->address = 0;
1385 memdev->interleave_index = 0; 1385 memdev->interleave_index = 0;
1386 memdev->interleave_ways = 1; 1386 memdev->interleave_ways = 1;
diff --git a/tools/testing/radix-tree/.gitignore b/tools/testing/radix-tree/.gitignore
index 11d888ca6a92..d4706c0ffceb 100644
--- a/tools/testing/radix-tree/.gitignore
+++ b/tools/testing/radix-tree/.gitignore
@@ -1,2 +1,6 @@
1generated/map-shift.h
2idr.c
3idr-test
1main 4main
5multiorder
2radix-tree.c 6radix-tree.c
diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile
index 3635e4d3eca7..6a9480c03cbd 100644
--- a/tools/testing/radix-tree/Makefile
+++ b/tools/testing/radix-tree/Makefile
@@ -1,29 +1,50 @@
1 1
2CFLAGS += -I. -I../../include -g -O2 -Wall -D_LGPL_SOURCE 2CFLAGS += -I. -I../../include -g -O2 -Wall -D_LGPL_SOURCE -fsanitize=address
3LDFLAGS += -lpthread -lurcu 3LDFLAGS += -fsanitize=address
4TARGETS = main 4LDLIBS+= -lpthread -lurcu
5OFILES = main.o radix-tree.o linux.o test.o tag_check.o find_next_bit.o \ 5TARGETS = main idr-test multiorder
6 regression1.o regression2.o regression3.o multiorder.o \ 6CORE_OFILES := radix-tree.o idr.o linux.o test.o find_bit.o
7 iteration_check.o benchmark.o 7OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression3.o \
8 8 tag_check.o multiorder.o idr-test.o iteration_check.o benchmark.o
9ifdef BENCHMARK 9
10 CFLAGS += -DBENCHMARK=1 10ifndef SHIFT
11 SHIFT=3
11endif 12endif
12 13
13targets: $(TARGETS) 14ifeq ($(BUILD), 32)
15 CFLAGS += -m32
16 LDFLAGS += -m32
17endif
18
19targets: mapshift $(TARGETS)
14 20
15main: $(OFILES) 21main: $(OFILES)
16 $(CC) $(CFLAGS) $(LDFLAGS) $(OFILES) -o main 22
23idr-test: idr-test.o $(CORE_OFILES)
24
25multiorder: multiorder.o $(CORE_OFILES)
17 26
18clean: 27clean:
19 $(RM) -f $(TARGETS) *.o radix-tree.c 28 $(RM) $(TARGETS) *.o radix-tree.c idr.c generated/map-shift.h
20 29
21find_next_bit.o: ../../lib/find_bit.c 30vpath %.c ../../lib
22 $(CC) $(CFLAGS) -c -o $@ $<
23 31
24$(OFILES): *.h */*.h \ 32$(OFILES): Makefile *.h */*.h generated/map-shift.h \
25 ../../include/linux/*.h \ 33 ../../include/linux/*.h \
26 ../../../include/linux/radix-tree.h 34 ../../include/asm/*.h \
35 ../../../include/linux/radix-tree.h \
36 ../../../include/linux/idr.h
27 37
28radix-tree.c: ../../../lib/radix-tree.c 38radix-tree.c: ../../../lib/radix-tree.c
29 sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@ 39 sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@
40
41idr.c: ../../../lib/idr.c
42 sed -e 's/^static //' -e 's/__always_inline //' -e 's/inline //' < $< > $@
43
44.PHONY: mapshift
45
46mapshift:
47 @if ! grep -qws $(SHIFT) generated/map-shift.h; then \
48 echo "#define RADIX_TREE_MAP_SHIFT $(SHIFT)" > \
49 generated/map-shift.h; \
50 fi
diff --git a/tools/testing/radix-tree/benchmark.c b/tools/testing/radix-tree/benchmark.c
index 215ca86c7605..99c40f3ed133 100644
--- a/tools/testing/radix-tree/benchmark.c
+++ b/tools/testing/radix-tree/benchmark.c
@@ -17,6 +17,9 @@
17#include <time.h> 17#include <time.h>
18#include "test.h" 18#include "test.h"
19 19
20#define for_each_index(i, base, order) \
21 for (i = base; i < base + (1 << order); i++)
22
20#define NSEC_PER_SEC 1000000000L 23#define NSEC_PER_SEC 1000000000L
21 24
22static long long benchmark_iter(struct radix_tree_root *root, bool tagged) 25static long long benchmark_iter(struct radix_tree_root *root, bool tagged)
@@ -57,27 +60,176 @@ again:
57 return nsec; 60 return nsec;
58} 61}
59 62
63static void benchmark_insert(struct radix_tree_root *root,
64 unsigned long size, unsigned long step, int order)
65{
66 struct timespec start, finish;
67 unsigned long index;
68 long long nsec;
69
70 clock_gettime(CLOCK_MONOTONIC, &start);
71
72 for (index = 0 ; index < size ; index += step)
73 item_insert_order(root, index, order);
74
75 clock_gettime(CLOCK_MONOTONIC, &finish);
76
77 nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
78 (finish.tv_nsec - start.tv_nsec);
79
80 printv(2, "Size: %8ld, step: %8ld, order: %d, insertion: %15lld ns\n",
81 size, step, order, nsec);
82}
83
84static void benchmark_tagging(struct radix_tree_root *root,
85 unsigned long size, unsigned long step, int order)
86{
87 struct timespec start, finish;
88 unsigned long index;
89 long long nsec;
90
91 clock_gettime(CLOCK_MONOTONIC, &start);
92
93 for (index = 0 ; index < size ; index += step)
94 radix_tree_tag_set(root, index, 0);
95
96 clock_gettime(CLOCK_MONOTONIC, &finish);
97
98 nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
99 (finish.tv_nsec - start.tv_nsec);
100
101 printv(2, "Size: %8ld, step: %8ld, order: %d, tagging: %17lld ns\n",
102 size, step, order, nsec);
103}
104
105static void benchmark_delete(struct radix_tree_root *root,
106 unsigned long size, unsigned long step, int order)
107{
108 struct timespec start, finish;
109 unsigned long index, i;
110 long long nsec;
111
112 clock_gettime(CLOCK_MONOTONIC, &start);
113
114 for (index = 0 ; index < size ; index += step)
115 for_each_index(i, index, order)
116 item_delete(root, i);
117
118 clock_gettime(CLOCK_MONOTONIC, &finish);
119
120 nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
121 (finish.tv_nsec - start.tv_nsec);
122
123 printv(2, "Size: %8ld, step: %8ld, order: %d, deletion: %16lld ns\n",
124 size, step, order, nsec);
125}
126
60static void benchmark_size(unsigned long size, unsigned long step, int order) 127static void benchmark_size(unsigned long size, unsigned long step, int order)
61{ 128{
62 RADIX_TREE(tree, GFP_KERNEL); 129 RADIX_TREE(tree, GFP_KERNEL);
63 long long normal, tagged; 130 long long normal, tagged;
64 unsigned long index;
65 131
66 for (index = 0 ; index < size ; index += step) { 132 benchmark_insert(&tree, size, step, order);
67 item_insert_order(&tree, index, order); 133 benchmark_tagging(&tree, size, step, order);
68 radix_tree_tag_set(&tree, index, 0);
69 }
70 134
71 tagged = benchmark_iter(&tree, true); 135 tagged = benchmark_iter(&tree, true);
72 normal = benchmark_iter(&tree, false); 136 normal = benchmark_iter(&tree, false);
73 137
74 printf("Size %ld, step %6ld, order %d tagged %10lld ns, normal %10lld ns\n", 138 printv(2, "Size: %8ld, step: %8ld, order: %d, tagged iteration: %8lld ns\n",
75 size, step, order, tagged, normal); 139 size, step, order, tagged);
140 printv(2, "Size: %8ld, step: %8ld, order: %d, normal iteration: %8lld ns\n",
141 size, step, order, normal);
142
143 benchmark_delete(&tree, size, step, order);
76 144
77 item_kill_tree(&tree); 145 item_kill_tree(&tree);
78 rcu_barrier(); 146 rcu_barrier();
79} 147}
80 148
149static long long __benchmark_split(unsigned long index,
150 int old_order, int new_order)
151{
152 struct timespec start, finish;
153 long long nsec;
154 RADIX_TREE(tree, GFP_ATOMIC);
155
156 item_insert_order(&tree, index, old_order);
157
158 clock_gettime(CLOCK_MONOTONIC, &start);
159 radix_tree_split(&tree, index, new_order);
160 clock_gettime(CLOCK_MONOTONIC, &finish);
161 nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
162 (finish.tv_nsec - start.tv_nsec);
163
164 item_kill_tree(&tree);
165
166 return nsec;
167
168}
169
170static void benchmark_split(unsigned long size, unsigned long step)
171{
172 int i, j, idx;
173 long long nsec = 0;
174
175
176 for (idx = 0; idx < size; idx += step) {
177 for (i = 3; i < 11; i++) {
178 for (j = 0; j < i; j++) {
179 nsec += __benchmark_split(idx, i, j);
180 }
181 }
182 }
183
184 printv(2, "Size %8ld, step %8ld, split time %10lld ns\n",
185 size, step, nsec);
186
187}
188
189static long long __benchmark_join(unsigned long index,
190 unsigned order1, unsigned order2)
191{
192 unsigned long loc;
193 struct timespec start, finish;
194 long long nsec;
195 void *item, *item2 = item_create(index + 1, order1);
196 RADIX_TREE(tree, GFP_KERNEL);
197
198 item_insert_order(&tree, index, order2);
199 item = radix_tree_lookup(&tree, index);
200
201 clock_gettime(CLOCK_MONOTONIC, &start);
202 radix_tree_join(&tree, index + 1, order1, item2);
203 clock_gettime(CLOCK_MONOTONIC, &finish);
204 nsec = (finish.tv_sec - start.tv_sec) * NSEC_PER_SEC +
205 (finish.tv_nsec - start.tv_nsec);
206
207 loc = find_item(&tree, item);
208 if (loc == -1)
209 free(item);
210
211 item_kill_tree(&tree);
212
213 return nsec;
214}
215
216static void benchmark_join(unsigned long step)
217{
218 int i, j, idx;
219 long long nsec = 0;
220
221 for (idx = 0; idx < 1 << 10; idx += step) {
222 for (i = 1; i < 15; i++) {
223 for (j = 0; j < i; j++) {
224 nsec += __benchmark_join(idx, i, j);
225 }
226 }
227 }
228
229 printv(2, "Size %8d, step %8ld, join time %10lld ns\n",
230 1 << 10, step, nsec);
231}
232
81void benchmark(void) 233void benchmark(void)
82{ 234{
83 unsigned long size[] = {1 << 10, 1 << 20, 0}; 235 unsigned long size[] = {1 << 10, 1 << 20, 0};
@@ -85,8 +237,8 @@ void benchmark(void)
85 128, 256, 512, 12345, 0}; 237 128, 256, 512, 12345, 0};
86 int c, s; 238 int c, s;
87 239
88 printf("starting benchmarks\n"); 240 printv(1, "starting benchmarks\n");
89 printf("RADIX_TREE_MAP_SHIFT = %d\n", RADIX_TREE_MAP_SHIFT); 241 printv(1, "RADIX_TREE_MAP_SHIFT = %d\n", RADIX_TREE_MAP_SHIFT);
90 242
91 for (c = 0; size[c]; c++) 243 for (c = 0; size[c]; c++)
92 for (s = 0; step[s]; s++) 244 for (s = 0; step[s]; s++)
@@ -95,4 +247,11 @@ void benchmark(void)
95 for (c = 0; size[c]; c++) 247 for (c = 0; size[c]; c++)
96 for (s = 0; step[s]; s++) 248 for (s = 0; step[s]; s++)
97 benchmark_size(size[c], step[s] << 9, 9); 249 benchmark_size(size[c], step[s] << 9, 9);
250
251 for (c = 0; size[c]; c++)
252 for (s = 0; step[s]; s++)
253 benchmark_split(size[c], step[s]);
254
255 for (s = 0; step[s]; s++)
256 benchmark_join(step[s]);
98} 257}
diff --git a/tools/testing/radix-tree/generated/autoconf.h b/tools/testing/radix-tree/generated/autoconf.h
index ad18cf5a2a3a..cf88dc5b8832 100644
--- a/tools/testing/radix-tree/generated/autoconf.h
+++ b/tools/testing/radix-tree/generated/autoconf.h
@@ -1,3 +1 @@
1#define CONFIG_RADIX_TREE_MULTIORDER 1 #define CONFIG_RADIX_TREE_MULTIORDER 1
2#define CONFIG_SHMEM 1
3#define CONFIG_SWAP 1
diff --git a/tools/testing/radix-tree/idr-test.c b/tools/testing/radix-tree/idr-test.c
new file mode 100644
index 000000000000..30cd0b296f1a
--- /dev/null
+++ b/tools/testing/radix-tree/idr-test.c
@@ -0,0 +1,516 @@
1/*
2 * idr-test.c: Test the IDR API
3 * Copyright (c) 2016 Matthew Wilcox <willy@infradead.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */
14#include <linux/bitmap.h>
15#include <linux/idr.h>
16#include <linux/slab.h>
17#include <linux/kernel.h>
18#include <linux/errno.h>
19
20#include "test.h"
21
22#define DUMMY_PTR ((void *)0x12)
23
24int item_idr_free(int id, void *p, void *data)
25{
26 struct item *item = p;
27 assert(item->index == id);
28 free(p);
29
30 return 0;
31}
32
33void item_idr_remove(struct idr *idr, int id)
34{
35 struct item *item = idr_find(idr, id);
36 assert(item->index == id);
37 idr_remove(idr, id);
38 free(item);
39}
40
41void idr_alloc_test(void)
42{
43 unsigned long i;
44 DEFINE_IDR(idr);
45
46 assert(idr_alloc_cyclic(&idr, DUMMY_PTR, 0, 0x4000, GFP_KERNEL) == 0);
47 assert(idr_alloc_cyclic(&idr, DUMMY_PTR, 0x3ffd, 0x4000, GFP_KERNEL) == 0x3ffd);
48 idr_remove(&idr, 0x3ffd);
49 idr_remove(&idr, 0);
50
51 for (i = 0x3ffe; i < 0x4003; i++) {
52 int id;
53 struct item *item;
54
55 if (i < 0x4000)
56 item = item_create(i, 0);
57 else
58 item = item_create(i - 0x3fff, 0);
59
60 id = idr_alloc_cyclic(&idr, item, 1, 0x4000, GFP_KERNEL);
61 assert(id == item->index);
62 }
63
64 idr_for_each(&idr, item_idr_free, &idr);
65 idr_destroy(&idr);
66}
67
68void idr_replace_test(void)
69{
70 DEFINE_IDR(idr);
71
72 idr_alloc(&idr, (void *)-1, 10, 11, GFP_KERNEL);
73 idr_replace(&idr, &idr, 10);
74
75 idr_destroy(&idr);
76}
77
78/*
79 * Unlike the radix tree, you can put a NULL pointer -- with care -- into
80 * the IDR. Some interfaces, like idr_find() do not distinguish between
81 * "present, value is NULL" and "not present", but that's exactly what some
82 * users want.
83 */
84void idr_null_test(void)
85{
86 int i;
87 DEFINE_IDR(idr);
88
89 assert(idr_is_empty(&idr));
90
91 assert(idr_alloc(&idr, NULL, 0, 0, GFP_KERNEL) == 0);
92 assert(!idr_is_empty(&idr));
93 idr_remove(&idr, 0);
94 assert(idr_is_empty(&idr));
95
96 assert(idr_alloc(&idr, NULL, 0, 0, GFP_KERNEL) == 0);
97 assert(!idr_is_empty(&idr));
98 idr_destroy(&idr);
99 assert(idr_is_empty(&idr));
100
101 for (i = 0; i < 10; i++) {
102 assert(idr_alloc(&idr, NULL, 0, 0, GFP_KERNEL) == i);
103 }
104
105 assert(idr_replace(&idr, DUMMY_PTR, 3) == NULL);
106 assert(idr_replace(&idr, DUMMY_PTR, 4) == NULL);
107 assert(idr_replace(&idr, NULL, 4) == DUMMY_PTR);
108 assert(idr_replace(&idr, DUMMY_PTR, 11) == ERR_PTR(-ENOENT));
109 idr_remove(&idr, 5);
110 assert(idr_alloc(&idr, NULL, 0, 0, GFP_KERNEL) == 5);
111 idr_remove(&idr, 5);
112
113 for (i = 0; i < 9; i++) {
114 idr_remove(&idr, i);
115 assert(!idr_is_empty(&idr));
116 }
117 idr_remove(&idr, 8);
118 assert(!idr_is_empty(&idr));
119 idr_remove(&idr, 9);
120 assert(idr_is_empty(&idr));
121
122 assert(idr_alloc(&idr, NULL, 0, 0, GFP_KERNEL) == 0);
123 assert(idr_replace(&idr, DUMMY_PTR, 3) == ERR_PTR(-ENOENT));
124 assert(idr_replace(&idr, DUMMY_PTR, 0) == NULL);
125 assert(idr_replace(&idr, NULL, 0) == DUMMY_PTR);
126
127 idr_destroy(&idr);
128 assert(idr_is_empty(&idr));
129
130 for (i = 1; i < 10; i++) {
131 assert(idr_alloc(&idr, NULL, 1, 0, GFP_KERNEL) == i);
132 }
133
134 idr_destroy(&idr);
135 assert(idr_is_empty(&idr));
136}
137
138void idr_nowait_test(void)
139{
140 unsigned int i;
141 DEFINE_IDR(idr);
142
143 idr_preload(GFP_KERNEL);
144
145 for (i = 0; i < 3; i++) {
146 struct item *item = item_create(i, 0);
147 assert(idr_alloc(&idr, item, i, i + 1, GFP_NOWAIT) == i);
148 }
149
150 idr_preload_end();
151
152 idr_for_each(&idr, item_idr_free, &idr);
153 idr_destroy(&idr);
154}
155
156void idr_get_next_test(void)
157{
158 unsigned long i;
159 int nextid;
160 DEFINE_IDR(idr);
161
162 int indices[] = {4, 7, 9, 15, 65, 128, 1000, 99999, 0};
163
164 for(i = 0; indices[i]; i++) {
165 struct item *item = item_create(indices[i], 0);
166 assert(idr_alloc(&idr, item, indices[i], indices[i+1],
167 GFP_KERNEL) == indices[i]);
168 }
169
170 for(i = 0, nextid = 0; indices[i]; i++) {
171 idr_get_next(&idr, &nextid);
172 assert(nextid == indices[i]);
173 nextid++;
174 }
175
176 idr_for_each(&idr, item_idr_free, &idr);
177 idr_destroy(&idr);
178}
179
180void idr_checks(void)
181{
182 unsigned long i;
183 DEFINE_IDR(idr);
184
185 for (i = 0; i < 10000; i++) {
186 struct item *item = item_create(i, 0);
187 assert(idr_alloc(&idr, item, 0, 20000, GFP_KERNEL) == i);
188 }
189
190 assert(idr_alloc(&idr, DUMMY_PTR, 5, 30, GFP_KERNEL) < 0);
191
192 for (i = 0; i < 5000; i++)
193 item_idr_remove(&idr, i);
194
195 idr_remove(&idr, 3);
196
197 idr_for_each(&idr, item_idr_free, &idr);
198 idr_destroy(&idr);
199
200 assert(idr_is_empty(&idr));
201
202 idr_remove(&idr, 3);
203 idr_remove(&idr, 0);
204
205 for (i = INT_MAX - 3UL; i < INT_MAX + 1UL; i++) {
206 struct item *item = item_create(i, 0);
207 assert(idr_alloc(&idr, item, i, i + 10, GFP_KERNEL) == i);
208 }
209 assert(idr_alloc(&idr, DUMMY_PTR, i - 2, i, GFP_KERNEL) == -ENOSPC);
210
211 idr_for_each(&idr, item_idr_free, &idr);
212 idr_destroy(&idr);
213 idr_destroy(&idr);
214
215 assert(idr_is_empty(&idr));
216
217 for (i = 1; i < 10000; i++) {
218 struct item *item = item_create(i, 0);
219 assert(idr_alloc(&idr, item, 1, 20000, GFP_KERNEL) == i);
220 }
221
222 idr_for_each(&idr, item_idr_free, &idr);
223 idr_destroy(&idr);
224
225 idr_replace_test();
226 idr_alloc_test();
227 idr_null_test();
228 idr_nowait_test();
229 idr_get_next_test();
230}
231
232/*
233 * Check that we get the correct error when we run out of memory doing
234 * allocations. To ensure we run out of memory, just "forget" to preload.
235 * The first test is for not having a bitmap available, and the second test
236 * is for not being able to allocate a level of the radix tree.
237 */
238void ida_check_nomem(void)
239{
240 DEFINE_IDA(ida);
241 int id, err;
242
243 err = ida_get_new_above(&ida, 256, &id);
244 assert(err == -EAGAIN);
245 err = ida_get_new_above(&ida, 1UL << 30, &id);
246 assert(err == -EAGAIN);
247}
248
249/*
250 * Check what happens when we fill a leaf and then delete it. This may
251 * discover mishandling of IDR_FREE.
252 */
253void ida_check_leaf(void)
254{
255 DEFINE_IDA(ida);
256 int id;
257 unsigned long i;
258
259 for (i = 0; i < IDA_BITMAP_BITS; i++) {
260 assert(ida_pre_get(&ida, GFP_KERNEL));
261 assert(!ida_get_new(&ida, &id));
262 assert(id == i);
263 }
264
265 ida_destroy(&ida);
266 assert(ida_is_empty(&ida));
267
268 assert(ida_pre_get(&ida, GFP_KERNEL));
269 assert(!ida_get_new(&ida, &id));
270 assert(id == 0);
271 ida_destroy(&ida);
272 assert(ida_is_empty(&ida));
273}
274
275/*
276 * Check handling of conversions between exceptional entries and full bitmaps.
277 */
278void ida_check_conv(void)
279{
280 DEFINE_IDA(ida);
281 int id;
282 unsigned long i;
283
284 for (i = 0; i < IDA_BITMAP_BITS * 2; i += IDA_BITMAP_BITS) {
285 assert(ida_pre_get(&ida, GFP_KERNEL));
286 assert(!ida_get_new_above(&ida, i + 1, &id));
287 assert(id == i + 1);
288 assert(!ida_get_new_above(&ida, i + BITS_PER_LONG, &id));
289 assert(id == i + BITS_PER_LONG);
290 ida_remove(&ida, i + 1);
291 ida_remove(&ida, i + BITS_PER_LONG);
292 assert(ida_is_empty(&ida));
293 }
294
295 assert(ida_pre_get(&ida, GFP_KERNEL));
296
297 for (i = 0; i < IDA_BITMAP_BITS * 2; i++) {
298 assert(ida_pre_get(&ida, GFP_KERNEL));
299 assert(!ida_get_new(&ida, &id));
300 assert(id == i);
301 }
302
303 for (i = IDA_BITMAP_BITS * 2; i > 0; i--) {
304 ida_remove(&ida, i - 1);
305 }
306 assert(ida_is_empty(&ida));
307
308 for (i = 0; i < IDA_BITMAP_BITS + BITS_PER_LONG - 4; i++) {
309 assert(ida_pre_get(&ida, GFP_KERNEL));
310 assert(!ida_get_new(&ida, &id));
311 assert(id == i);
312 }
313
314 for (i = IDA_BITMAP_BITS + BITS_PER_LONG - 4; i > 0; i--) {
315 ida_remove(&ida, i - 1);
316 }
317 assert(ida_is_empty(&ida));
318
319 radix_tree_cpu_dead(1);
320 for (i = 0; i < 1000000; i++) {
321 int err = ida_get_new(&ida, &id);
322 if (err == -EAGAIN) {
323 assert((i % IDA_BITMAP_BITS) == (BITS_PER_LONG - 2));
324 assert(ida_pre_get(&ida, GFP_KERNEL));
325 err = ida_get_new(&ida, &id);
326 } else {
327 assert((i % IDA_BITMAP_BITS) != (BITS_PER_LONG - 2));
328 }
329 assert(!err);
330 assert(id == i);
331 }
332 ida_destroy(&ida);
333}
334
335/*
336 * Check allocations up to and slightly above the maximum allowed (2^31-1) ID.
337 * Allocating up to 2^31-1 should succeed, and then allocating the next one
338 * should fail.
339 */
340void ida_check_max(void)
341{
342 DEFINE_IDA(ida);
343 int id, err;
344 unsigned long i, j;
345
346 for (j = 1; j < 65537; j *= 2) {
347 unsigned long base = (1UL << 31) - j;
348 for (i = 0; i < j; i++) {
349 assert(ida_pre_get(&ida, GFP_KERNEL));
350 assert(!ida_get_new_above(&ida, base, &id));
351 assert(id == base + i);
352 }
353 assert(ida_pre_get(&ida, GFP_KERNEL));
354 err = ida_get_new_above(&ida, base, &id);
355 assert(err == -ENOSPC);
356 ida_destroy(&ida);
357 assert(ida_is_empty(&ida));
358 rcu_barrier();
359 }
360}
361
362void ida_check_random(void)
363{
364 DEFINE_IDA(ida);
365 DECLARE_BITMAP(bitmap, 2048);
366 int id, err;
367 unsigned int i;
368 time_t s = time(NULL);
369
370 repeat:
371 memset(bitmap, 0, sizeof(bitmap));
372 for (i = 0; i < 100000; i++) {
373 int i = rand();
374 int bit = i & 2047;
375 if (test_bit(bit, bitmap)) {
376 __clear_bit(bit, bitmap);
377 ida_remove(&ida, bit);
378 } else {
379 __set_bit(bit, bitmap);
380 do {
381 ida_pre_get(&ida, GFP_KERNEL);
382 err = ida_get_new_above(&ida, bit, &id);
383 } while (err == -ENOMEM);
384 assert(!err);
385 assert(id == bit);
386 }
387 }
388 ida_destroy(&ida);
389 if (time(NULL) < s + 10)
390 goto repeat;
391}
392
393void ida_simple_get_remove_test(void)
394{
395 DEFINE_IDA(ida);
396 unsigned long i;
397
398 for (i = 0; i < 10000; i++) {
399 assert(ida_simple_get(&ida, 0, 20000, GFP_KERNEL) == i);
400 }
401 assert(ida_simple_get(&ida, 5, 30, GFP_KERNEL) < 0);
402
403 for (i = 0; i < 10000; i++) {
404 ida_simple_remove(&ida, i);
405 }
406 assert(ida_is_empty(&ida));
407
408 ida_destroy(&ida);
409}
410
411void ida_checks(void)
412{
413 DEFINE_IDA(ida);
414 int id;
415 unsigned long i;
416
417 radix_tree_cpu_dead(1);
418 ida_check_nomem();
419
420 for (i = 0; i < 10000; i++) {
421 assert(ida_pre_get(&ida, GFP_KERNEL));
422 assert(!ida_get_new(&ida, &id));
423 assert(id == i);
424 }
425
426 ida_remove(&ida, 20);
427 ida_remove(&ida, 21);
428 for (i = 0; i < 3; i++) {
429 assert(ida_pre_get(&ida, GFP_KERNEL));
430 assert(!ida_get_new(&ida, &id));
431 if (i == 2)
432 assert(id == 10000);
433 }
434
435 for (i = 0; i < 5000; i++)
436 ida_remove(&ida, i);
437
438 assert(ida_pre_get(&ida, GFP_KERNEL));
439 assert(!ida_get_new_above(&ida, 5000, &id));
440 assert(id == 10001);
441
442 ida_destroy(&ida);
443
444 assert(ida_is_empty(&ida));
445
446 assert(ida_pre_get(&ida, GFP_KERNEL));
447 assert(!ida_get_new_above(&ida, 1, &id));
448 assert(id == 1);
449
450 ida_remove(&ida, id);
451 assert(ida_is_empty(&ida));
452 ida_destroy(&ida);
453 assert(ida_is_empty(&ida));
454
455 assert(ida_pre_get(&ida, GFP_KERNEL));
456 assert(!ida_get_new_above(&ida, 1, &id));
457 ida_destroy(&ida);
458 assert(ida_is_empty(&ida));
459
460 assert(ida_pre_get(&ida, GFP_KERNEL));
461 assert(!ida_get_new_above(&ida, 1, &id));
462 assert(id == 1);
463 assert(ida_pre_get(&ida, GFP_KERNEL));
464 assert(!ida_get_new_above(&ida, 1025, &id));
465 assert(id == 1025);
466 assert(ida_pre_get(&ida, GFP_KERNEL));
467 assert(!ida_get_new_above(&ida, 10000, &id));
468 assert(id == 10000);
469 ida_remove(&ida, 1025);
470 ida_destroy(&ida);
471 assert(ida_is_empty(&ida));
472
473 ida_check_leaf();
474 ida_check_max();
475 ida_check_conv();
476 ida_check_random();
477 ida_simple_get_remove_test();
478
479 radix_tree_cpu_dead(1);
480}
481
482static void *ida_random_fn(void *arg)
483{
484 rcu_register_thread();
485 ida_check_random();
486 rcu_unregister_thread();
487 return NULL;
488}
489
490void ida_thread_tests(void)
491{
492 pthread_t threads[10];
493 int i;
494
495 for (i = 0; i < ARRAY_SIZE(threads); i++)
496 if (pthread_create(&threads[i], NULL, ida_random_fn, NULL)) {
497 perror("creating ida thread");
498 exit(1);
499 }
500
501 while (i--)
502 pthread_join(threads[i], NULL);
503}
504
505int __weak main(void)
506{
507 radix_tree_init();
508 idr_checks();
509 ida_checks();
510 ida_thread_tests();
511 radix_tree_cpu_dead(1);
512 rcu_barrier();
513 if (nr_allocated)
514 printf("nr_allocated = %d\n", nr_allocated);
515 return 0;
516}
diff --git a/tools/testing/radix-tree/iteration_check.c b/tools/testing/radix-tree/iteration_check.c
index 7572b7ed930e..a92bab513701 100644
--- a/tools/testing/radix-tree/iteration_check.c
+++ b/tools/testing/radix-tree/iteration_check.c
@@ -177,7 +177,7 @@ void iteration_test(unsigned order, unsigned test_duration)
177{ 177{
178 int i; 178 int i;
179 179
180 printf("Running %siteration tests for %d seconds\n", 180 printv(1, "Running %siteration tests for %d seconds\n",
181 order > 0 ? "multiorder " : "", test_duration); 181 order > 0 ? "multiorder " : "", test_duration);
182 182
183 max_order = order; 183 max_order = order;
diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/linux.c
index d31ea7c9abec..cf48c8473f48 100644
--- a/tools/testing/radix-tree/linux.c
+++ b/tools/testing/radix-tree/linux.c
@@ -5,7 +5,7 @@
5#include <unistd.h> 5#include <unistd.h>
6#include <assert.h> 6#include <assert.h>
7 7
8#include <linux/mempool.h> 8#include <linux/gfp.h>
9#include <linux/poison.h> 9#include <linux/poison.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <linux/radix-tree.h> 11#include <linux/radix-tree.h>
@@ -13,6 +13,8 @@
13 13
14int nr_allocated; 14int nr_allocated;
15int preempt_count; 15int preempt_count;
16int kmalloc_verbose;
17int test_verbose;
16 18
17struct kmem_cache { 19struct kmem_cache {
18 pthread_mutex_t lock; 20 pthread_mutex_t lock;
@@ -22,27 +24,6 @@ struct kmem_cache {
22 void (*ctor)(void *); 24 void (*ctor)(void *);
23}; 25};
24 26
25void *mempool_alloc(mempool_t *pool, int gfp_mask)
26{
27 return pool->alloc(gfp_mask, pool->data);
28}
29
30void mempool_free(void *element, mempool_t *pool)
31{
32 pool->free(element, pool->data);
33}
34
35mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
36 mempool_free_t *free_fn, void *pool_data)
37{
38 mempool_t *ret = malloc(sizeof(*ret));
39
40 ret->alloc = alloc_fn;
41 ret->free = free_fn;
42 ret->data = pool_data;
43 return ret;
44}
45
46void *kmem_cache_alloc(struct kmem_cache *cachep, int flags) 27void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
47{ 28{
48 struct radix_tree_node *node; 29 struct radix_tree_node *node;
@@ -54,9 +35,9 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
54 if (cachep->nr_objs) { 35 if (cachep->nr_objs) {
55 cachep->nr_objs--; 36 cachep->nr_objs--;
56 node = cachep->objs; 37 node = cachep->objs;
57 cachep->objs = node->private_data; 38 cachep->objs = node->parent;
58 pthread_mutex_unlock(&cachep->lock); 39 pthread_mutex_unlock(&cachep->lock);
59 node->private_data = NULL; 40 node->parent = NULL;
60 } else { 41 } else {
61 pthread_mutex_unlock(&cachep->lock); 42 pthread_mutex_unlock(&cachep->lock);
62 node = malloc(cachep->size); 43 node = malloc(cachep->size);
@@ -65,6 +46,8 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, int flags)
65 } 46 }
66 47
67 uatomic_inc(&nr_allocated); 48 uatomic_inc(&nr_allocated);
49 if (kmalloc_verbose)
50 printf("Allocating %p from slab\n", node);
68 return node; 51 return node;
69} 52}
70 53
@@ -72,6 +55,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
72{ 55{
73 assert(objp); 56 assert(objp);
74 uatomic_dec(&nr_allocated); 57 uatomic_dec(&nr_allocated);
58 if (kmalloc_verbose)
59 printf("Freeing %p to slab\n", objp);
75 pthread_mutex_lock(&cachep->lock); 60 pthread_mutex_lock(&cachep->lock);
76 if (cachep->nr_objs > 10) { 61 if (cachep->nr_objs > 10) {
77 memset(objp, POISON_FREE, cachep->size); 62 memset(objp, POISON_FREE, cachep->size);
@@ -79,7 +64,7 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
79 } else { 64 } else {
80 struct radix_tree_node *node = objp; 65 struct radix_tree_node *node = objp;
81 cachep->nr_objs++; 66 cachep->nr_objs++;
82 node->private_data = cachep->objs; 67 node->parent = cachep->objs;
83 cachep->objs = node; 68 cachep->objs = node;
84 } 69 }
85 pthread_mutex_unlock(&cachep->lock); 70 pthread_mutex_unlock(&cachep->lock);
@@ -89,6 +74,8 @@ void *kmalloc(size_t size, gfp_t gfp)
89{ 74{
90 void *ret = malloc(size); 75 void *ret = malloc(size);
91 uatomic_inc(&nr_allocated); 76 uatomic_inc(&nr_allocated);
77 if (kmalloc_verbose)
78 printf("Allocating %p from malloc\n", ret);
92 return ret; 79 return ret;
93} 80}
94 81
@@ -97,6 +84,8 @@ void kfree(void *p)
97 if (!p) 84 if (!p)
98 return; 85 return;
99 uatomic_dec(&nr_allocated); 86 uatomic_dec(&nr_allocated);
87 if (kmalloc_verbose)
88 printf("Freeing %p to malloc\n", p);
100 free(p); 89 free(p);
101} 90}
102 91
diff --git a/tools/testing/radix-tree/linux/bitops.h b/tools/testing/radix-tree/linux/bitops.h
deleted file mode 100644
index a13e9bc76eec..000000000000
--- a/tools/testing/radix-tree/linux/bitops.h
+++ /dev/null
@@ -1,160 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
2#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
3
4#include <linux/types.h>
5#include <linux/bitops/find.h>
6#include <linux/bitops/hweight.h>
7#include <linux/kernel.h>
8
9#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
10#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
11#define BITS_PER_BYTE 8
12#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
13
14/**
15 * __set_bit - Set a bit in memory
16 * @nr: the bit to set
17 * @addr: the address to start counting from
18 *
19 * Unlike set_bit(), this function is non-atomic and may be reordered.
20 * If it's called on the same region of memory simultaneously, the effect
21 * may be that only one operation succeeds.
22 */
23static inline void __set_bit(int nr, volatile unsigned long *addr)
24{
25 unsigned long mask = BIT_MASK(nr);
26 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
27
28 *p |= mask;
29}
30
31static inline void __clear_bit(int nr, volatile unsigned long *addr)
32{
33 unsigned long mask = BIT_MASK(nr);
34 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
35
36 *p &= ~mask;
37}
38
39/**
40 * __change_bit - Toggle a bit in memory
41 * @nr: the bit to change
42 * @addr: the address to start counting from
43 *
44 * Unlike change_bit(), this function is non-atomic and may be reordered.
45 * If it's called on the same region of memory simultaneously, the effect
46 * may be that only one operation succeeds.
47 */
48static inline void __change_bit(int nr, volatile unsigned long *addr)
49{
50 unsigned long mask = BIT_MASK(nr);
51 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
52
53 *p ^= mask;
54}
55
56/**
57 * __test_and_set_bit - Set a bit and return its old value
58 * @nr: Bit to set
59 * @addr: Address to count from
60 *
61 * This operation is non-atomic and can be reordered.
62 * If two examples of this operation race, one can appear to succeed
63 * but actually fail. You must protect multiple accesses with a lock.
64 */
65static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
66{
67 unsigned long mask = BIT_MASK(nr);
68 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
69 unsigned long old = *p;
70
71 *p = old | mask;
72 return (old & mask) != 0;
73}
74
75/**
76 * __test_and_clear_bit - Clear a bit and return its old value
77 * @nr: Bit to clear
78 * @addr: Address to count from
79 *
80 * This operation is non-atomic and can be reordered.
81 * If two examples of this operation race, one can appear to succeed
82 * but actually fail. You must protect multiple accesses with a lock.
83 */
84static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
85{
86 unsigned long mask = BIT_MASK(nr);
87 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
88 unsigned long old = *p;
89
90 *p = old & ~mask;
91 return (old & mask) != 0;
92}
93
94/* WARNING: non atomic and it can be reordered! */
95static inline int __test_and_change_bit(int nr,
96 volatile unsigned long *addr)
97{
98 unsigned long mask = BIT_MASK(nr);
99 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
100 unsigned long old = *p;
101
102 *p = old ^ mask;
103 return (old & mask) != 0;
104}
105
106/**
107 * test_bit - Determine whether a bit is set
108 * @nr: bit number to test
109 * @addr: Address to start counting from
110 */
111static inline int test_bit(int nr, const volatile unsigned long *addr)
112{
113 return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
114}
115
116/**
117 * __ffs - find first bit in word.
118 * @word: The word to search
119 *
120 * Undefined if no bit exists, so code should check against 0 first.
121 */
122static inline unsigned long __ffs(unsigned long word)
123{
124 int num = 0;
125
126 if ((word & 0xffffffff) == 0) {
127 num += 32;
128 word >>= 32;
129 }
130 if ((word & 0xffff) == 0) {
131 num += 16;
132 word >>= 16;
133 }
134 if ((word & 0xff) == 0) {
135 num += 8;
136 word >>= 8;
137 }
138 if ((word & 0xf) == 0) {
139 num += 4;
140 word >>= 4;
141 }
142 if ((word & 0x3) == 0) {
143 num += 2;
144 word >>= 2;
145 }
146 if ((word & 0x1) == 0)
147 num += 1;
148 return num;
149}
150
151unsigned long find_next_bit(const unsigned long *addr,
152 unsigned long size,
153 unsigned long offset);
154
155static inline unsigned long hweight_long(unsigned long w)
156{
157 return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
158}
159
160#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/__ffs.h b/tools/testing/radix-tree/linux/bitops/__ffs.h
deleted file mode 100644
index 9a3274aecf83..000000000000
--- a/tools/testing/radix-tree/linux/bitops/__ffs.h
+++ /dev/null
@@ -1,43 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS___FFS_H_
2#define _ASM_GENERIC_BITOPS___FFS_H_
3
4#include <asm/types.h>
5
6/**
7 * __ffs - find first bit in word.
8 * @word: The word to search
9 *
10 * Undefined if no bit exists, so code should check against 0 first.
11 */
12static inline unsigned long __ffs(unsigned long word)
13{
14 int num = 0;
15
16#if BITS_PER_LONG == 64
17 if ((word & 0xffffffff) == 0) {
18 num += 32;
19 word >>= 32;
20 }
21#endif
22 if ((word & 0xffff) == 0) {
23 num += 16;
24 word >>= 16;
25 }
26 if ((word & 0xff) == 0) {
27 num += 8;
28 word >>= 8;
29 }
30 if ((word & 0xf) == 0) {
31 num += 4;
32 word >>= 4;
33 }
34 if ((word & 0x3) == 0) {
35 num += 2;
36 word >>= 2;
37 }
38 if ((word & 0x1) == 0)
39 num += 1;
40 return num;
41}
42
43#endif /* _ASM_GENERIC_BITOPS___FFS_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/ffs.h b/tools/testing/radix-tree/linux/bitops/ffs.h
deleted file mode 100644
index fbbb43af7dc0..000000000000
--- a/tools/testing/radix-tree/linux/bitops/ffs.h
+++ /dev/null
@@ -1,41 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_FFS_H_
2#define _ASM_GENERIC_BITOPS_FFS_H_
3
4/**
5 * ffs - find first bit set
6 * @x: the word to search
7 *
8 * This is defined the same way as
9 * the libc and compiler builtin ffs routines, therefore
10 * differs in spirit from the above ffz (man ffs).
11 */
12static inline int ffs(int x)
13{
14 int r = 1;
15
16 if (!x)
17 return 0;
18 if (!(x & 0xffff)) {
19 x >>= 16;
20 r += 16;
21 }
22 if (!(x & 0xff)) {
23 x >>= 8;
24 r += 8;
25 }
26 if (!(x & 0xf)) {
27 x >>= 4;
28 r += 4;
29 }
30 if (!(x & 3)) {
31 x >>= 2;
32 r += 2;
33 }
34 if (!(x & 1)) {
35 x >>= 1;
36 r += 1;
37 }
38 return r;
39}
40
41#endif /* _ASM_GENERIC_BITOPS_FFS_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/ffz.h b/tools/testing/radix-tree/linux/bitops/ffz.h
deleted file mode 100644
index 6744bd4cdf46..000000000000
--- a/tools/testing/radix-tree/linux/bitops/ffz.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
2#define _ASM_GENERIC_BITOPS_FFZ_H_
3
4/*
5 * ffz - find first zero in word.
6 * @word: The word to search
7 *
8 * Undefined if no zero exists, so code should check against ~0UL first.
9 */
10#define ffz(x) __ffs(~(x))
11
12#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/find.h b/tools/testing/radix-tree/linux/bitops/find.h
deleted file mode 100644
index 72a51e5a12ef..000000000000
--- a/tools/testing/radix-tree/linux/bitops/find.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_FIND_H_
2#define _ASM_GENERIC_BITOPS_FIND_H_
3
4extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
5 size, unsigned long offset);
6
7extern unsigned long find_next_zero_bit(const unsigned long *addr, unsigned
8 long size, unsigned long offset);
9
10#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
11#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
12
13#endif /*_ASM_GENERIC_BITOPS_FIND_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/fls.h b/tools/testing/radix-tree/linux/bitops/fls.h
deleted file mode 100644
index 850859bc5069..000000000000
--- a/tools/testing/radix-tree/linux/bitops/fls.h
+++ /dev/null
@@ -1,41 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_FLS_H_
2#define _ASM_GENERIC_BITOPS_FLS_H_
3
4/**
5 * fls - find last (most-significant) bit set
6 * @x: the word to search
7 *
8 * This is defined the same way as ffs.
9 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
10 */
11
12static inline int fls(int x)
13{
14 int r = 32;
15
16 if (!x)
17 return 0;
18 if (!(x & 0xffff0000u)) {
19 x <<= 16;
20 r -= 16;
21 }
22 if (!(x & 0xff000000u)) {
23 x <<= 8;
24 r -= 8;
25 }
26 if (!(x & 0xf0000000u)) {
27 x <<= 4;
28 r -= 4;
29 }
30 if (!(x & 0xc0000000u)) {
31 x <<= 2;
32 r -= 2;
33 }
34 if (!(x & 0x80000000u)) {
35 x <<= 1;
36 r -= 1;
37 }
38 return r;
39}
40
41#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/fls64.h b/tools/testing/radix-tree/linux/bitops/fls64.h
deleted file mode 100644
index 1b6b17ce2428..000000000000
--- a/tools/testing/radix-tree/linux/bitops/fls64.h
+++ /dev/null
@@ -1,14 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
2#define _ASM_GENERIC_BITOPS_FLS64_H_
3
4#include <asm/types.h>
5
6static inline int fls64(__u64 x)
7{
8 __u32 h = x >> 32;
9 if (h)
10 return fls(h) + 32;
11 return fls(x);
12}
13
14#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/hweight.h b/tools/testing/radix-tree/linux/bitops/hweight.h
deleted file mode 100644
index fbbc383771da..000000000000
--- a/tools/testing/radix-tree/linux/bitops/hweight.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
2#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
3
4#include <asm/types.h>
5
6extern unsigned int hweight32(unsigned int w);
7extern unsigned int hweight16(unsigned int w);
8extern unsigned int hweight8(unsigned int w);
9extern unsigned long hweight64(__u64 w);
10
11#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/le.h b/tools/testing/radix-tree/linux/bitops/le.h
deleted file mode 100644
index b9c7e5d2d2ad..000000000000
--- a/tools/testing/radix-tree/linux/bitops/le.h
+++ /dev/null
@@ -1,53 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_LE_H_
2#define _ASM_GENERIC_BITOPS_LE_H_
3
4#include <asm/types.h>
5#include <asm/byteorder.h>
6
7#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
8#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
9
10#if defined(__LITTLE_ENDIAN)
11
12#define generic_test_le_bit(nr, addr) test_bit(nr, addr)
13#define generic___set_le_bit(nr, addr) __set_bit(nr, addr)
14#define generic___clear_le_bit(nr, addr) __clear_bit(nr, addr)
15
16#define generic_test_and_set_le_bit(nr, addr) test_and_set_bit(nr, addr)
17#define generic_test_and_clear_le_bit(nr, addr) test_and_clear_bit(nr, addr)
18
19#define generic___test_and_set_le_bit(nr, addr) __test_and_set_bit(nr, addr)
20#define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr)
21
22#define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset)
23
24#elif defined(__BIG_ENDIAN)
25
26#define generic_test_le_bit(nr, addr) \
27 test_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
28#define generic___set_le_bit(nr, addr) \
29 __set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
30#define generic___clear_le_bit(nr, addr) \
31 __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
32
33#define generic_test_and_set_le_bit(nr, addr) \
34 test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
35#define generic_test_and_clear_le_bit(nr, addr) \
36 test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
37
38#define generic___test_and_set_le_bit(nr, addr) \
39 __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
40#define generic___test_and_clear_le_bit(nr, addr) \
41 __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
42
43extern unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
44 unsigned long size, unsigned long offset);
45
46#else
47#error "Please fix <asm/byteorder.h>"
48#endif
49
50#define generic_find_first_zero_le_bit(addr, size) \
51 generic_find_next_zero_le_bit((addr), (size), 0)
52
53#endif /* _ASM_GENERIC_BITOPS_LE_H_ */
diff --git a/tools/testing/radix-tree/linux/bitops/non-atomic.h b/tools/testing/radix-tree/linux/bitops/non-atomic.h
deleted file mode 100644
index 6a1bcb9d2c4a..000000000000
--- a/tools/testing/radix-tree/linux/bitops/non-atomic.h
+++ /dev/null
@@ -1,110 +0,0 @@
1#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
2#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
3
4#include <asm/types.h>
5
6#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
7
8/**
9 * __set_bit - Set a bit in memory
10 * @nr: the bit to set
11 * @addr: the address to start counting from
12 *
13 * Unlike set_bit(), this function is non-atomic and may be reordered.
14 * If it's called on the same region of memory simultaneously, the effect
15 * may be that only one operation succeeds.
16 */
17static inline void __set_bit(int nr, volatile unsigned long *addr)
18{
19 unsigned long mask = BIT_MASK(nr);
20 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
21
22 *p |= mask;
23}
24
25static inline void __clear_bit(int nr, volatile unsigned long *addr)
26{
27 unsigned long mask = BIT_MASK(nr);
28 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
29
30 *p &= ~mask;
31}
32
33/**
34 * __change_bit - Toggle a bit in memory
35 * @nr: the bit to change
36 * @addr: the address to start counting from
37 *
38 * Unlike change_bit(), this function is non-atomic and may be reordered.
39 * If it's called on the same region of memory simultaneously, the effect
40 * may be that only one operation succeeds.
41 */
42static inline void __change_bit(int nr, volatile unsigned long *addr)
43{
44 unsigned long mask = BIT_MASK(nr);
45 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
46
47 *p ^= mask;
48}
49
50/**
51 * __test_and_set_bit - Set a bit and return its old value
52 * @nr: Bit to set
53 * @addr: Address to count from
54 *
55 * This operation is non-atomic and can be reordered.
56 * If two examples of this operation race, one can appear to succeed
57 * but actually fail. You must protect multiple accesses with a lock.
58 */
59static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
60{
61 unsigned long mask = BIT_MASK(nr);
62 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
63 unsigned long old = *p;
64
65 *p = old | mask;
66 return (old & mask) != 0;
67}
68
69/**
70 * __test_and_clear_bit - Clear a bit and return its old value
71 * @nr: Bit to clear
72 * @addr: Address to count from
73 *
74 * This operation is non-atomic and can be reordered.
75 * If two examples of this operation race, one can appear to succeed
76 * but actually fail. You must protect multiple accesses with a lock.
77 */
78static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
79{
80 unsigned long mask = BIT_MASK(nr);
81 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
82 unsigned long old = *p;
83
84 *p = old & ~mask;
85 return (old & mask) != 0;
86}
87
88/* WARNING: non atomic and it can be reordered! */
89static inline int __test_and_change_bit(int nr,
90 volatile unsigned long *addr)
91{
92 unsigned long mask = BIT_MASK(nr);
93 unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
94 unsigned long old = *p;
95
96 *p = old ^ mask;
97 return (old & mask) != 0;
98}
99
100/**
101 * test_bit - Determine whether a bit is set
102 * @nr: bit number to test
103 * @addr: Address to start counting from
104 */
105static inline int test_bit(int nr, const volatile unsigned long *addr)
106{
107 return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
108}
109
110#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
diff --git a/tools/testing/radix-tree/linux/export.h b/tools/testing/radix-tree/linux/export.h
deleted file mode 100644
index b6afd131998d..000000000000
--- a/tools/testing/radix-tree/linux/export.h
+++ /dev/null
@@ -1,2 +0,0 @@
1
2#define EXPORT_SYMBOL(sym)
diff --git a/tools/testing/radix-tree/linux/gfp.h b/tools/testing/radix-tree/linux/gfp.h
index 5b09b2ce6c33..39a0dcb9475a 100644
--- a/tools/testing/radix-tree/linux/gfp.h
+++ b/tools/testing/radix-tree/linux/gfp.h
@@ -1,6 +1,8 @@
1#ifndef _GFP_H 1#ifndef _GFP_H
2#define _GFP_H 2#define _GFP_H
3 3
4#include <linux/types.h>
5
4#define __GFP_BITS_SHIFT 26 6#define __GFP_BITS_SHIFT 26
5#define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) 7#define __GFP_BITS_MASK ((gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
6 8
@@ -13,10 +15,12 @@
13#define __GFP_DIRECT_RECLAIM 0x400000u 15#define __GFP_DIRECT_RECLAIM 0x400000u
14#define __GFP_KSWAPD_RECLAIM 0x2000000u 16#define __GFP_KSWAPD_RECLAIM 0x2000000u
15 17
16#define __GFP_RECLAIM (__GFP_DIRECT_RECLAIM|__GFP_KSWAPD_RECLAIM) 18#define __GFP_RECLAIM (__GFP_DIRECT_RECLAIM|__GFP_KSWAPD_RECLAIM)
19
20#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
21#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
22#define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM)
17 23
18#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
19#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
20 24
21static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) 25static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags)
22{ 26{
diff --git a/tools/testing/radix-tree/linux/idr.h b/tools/testing/radix-tree/linux/idr.h
new file mode 100644
index 000000000000..4e342f2e37cf
--- /dev/null
+++ b/tools/testing/radix-tree/linux/idr.h
@@ -0,0 +1 @@
#include "../../../../include/linux/idr.h"
diff --git a/tools/testing/radix-tree/linux/init.h b/tools/testing/radix-tree/linux/init.h
index 360cabb3c4e7..1bb0afc21309 100644
--- a/tools/testing/radix-tree/linux/init.h
+++ b/tools/testing/radix-tree/linux/init.h
@@ -1 +1 @@
/* An empty file stub that allows radix-tree.c to compile. */ #define __init
diff --git a/tools/testing/radix-tree/linux/kernel.h b/tools/testing/radix-tree/linux/kernel.h
index 9b43b4975d83..b21a77fddcf7 100644
--- a/tools/testing/radix-tree/linux/kernel.h
+++ b/tools/testing/radix-tree/linux/kernel.h
@@ -1,64 +1,21 @@
1#ifndef _KERNEL_H 1#ifndef _KERNEL_H
2#define _KERNEL_H 2#define _KERNEL_H
3 3
4#include <assert.h> 4#include "../../include/linux/kernel.h"
5#include <string.h> 5#include <string.h>
6#include <stdio.h> 6#include <stdio.h>
7#include <stddef.h>
8#include <limits.h> 7#include <limits.h>
9 8
10#include "../../include/linux/compiler.h" 9#include <linux/compiler.h>
11#include "../../include/linux/err.h" 10#include <linux/err.h>
11#include <linux/bitops.h>
12#include <linux/log2.h>
12#include "../../../include/linux/kconfig.h" 13#include "../../../include/linux/kconfig.h"
13 14
14#ifdef BENCHMARK
15#define RADIX_TREE_MAP_SHIFT 6
16#else
17#define RADIX_TREE_MAP_SHIFT 3
18#endif
19
20#ifndef NULL
21#define NULL 0
22#endif
23
24#define BUG_ON(expr) assert(!(expr))
25#define WARN_ON(expr) assert(!(expr))
26#define __init
27#define __must_check
28#define panic(expr)
29#define printk printf 15#define printk printf
30#define __force
31#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
32#define pr_debug printk 16#define pr_debug printk
33 17#define pr_cont printk
34#define smp_rmb() barrier()
35#define smp_wmb() barrier()
36#define cpu_relax() barrier()
37 18
38#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 19#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
39 20
40#define container_of(ptr, type, member) ({ \
41 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
42 (type *)( (char *)__mptr - offsetof(type, member) );})
43#define min(a, b) ((a) < (b) ? (a) : (b))
44
45#define cond_resched() sched_yield()
46
47static inline int in_interrupt(void)
48{
49 return 0;
50}
51
52/*
53 * This looks more complex than it should be. But we need to
54 * get the type for the ~ right in round_down (it needs to be
55 * as wide as the result!), and we want to evaluate the macro
56 * arguments just once each.
57 */
58#define __round_mask(x, y) ((__typeof__(x))((y)-1))
59#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
60#define round_down(x, y) ((x) & ~__round_mask(x, y))
61
62#define xchg(ptr, x) uatomic_xchg(ptr, x)
63
64#endif /* _KERNEL_H */ 21#endif /* _KERNEL_H */
diff --git a/tools/testing/radix-tree/linux/mempool.h b/tools/testing/radix-tree/linux/mempool.h
deleted file mode 100644
index 6a2dc55b41d6..000000000000
--- a/tools/testing/radix-tree/linux/mempool.h
+++ /dev/null
@@ -1,16 +0,0 @@
1
2#include <linux/slab.h>
3
4typedef void *(mempool_alloc_t)(int gfp_mask, void *pool_data);
5typedef void (mempool_free_t)(void *element, void *pool_data);
6
7typedef struct {
8 mempool_alloc_t *alloc;
9 mempool_free_t *free;
10 void *data;
11} mempool_t;
12
13void *mempool_alloc(mempool_t *pool, int gfp_mask);
14void mempool_free(void *element, mempool_t *pool);
15mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
16 mempool_free_t *free_fn, void *pool_data);
diff --git a/tools/testing/radix-tree/linux/percpu.h b/tools/testing/radix-tree/linux/percpu.h
index 5837f1d56f17..3ea01a1a88c2 100644
--- a/tools/testing/radix-tree/linux/percpu.h
+++ b/tools/testing/radix-tree/linux/percpu.h
@@ -1,7 +1,10 @@
1 1#define DECLARE_PER_CPU(type, val) extern type val
2#define DEFINE_PER_CPU(type, val) type val 2#define DEFINE_PER_CPU(type, val) type val
3 3
4#define __get_cpu_var(var) var 4#define __get_cpu_var(var) var
5#define this_cpu_ptr(var) var 5#define this_cpu_ptr(var) var
6#define this_cpu_read(var) var
7#define this_cpu_xchg(var, val) uatomic_xchg(&var, val)
8#define this_cpu_cmpxchg(var, old, new) uatomic_cmpxchg(&var, old, new)
6#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); }) 9#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
7#define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu)) 10#define per_cpu(var, cpu) (*per_cpu_ptr(&(var), cpu))
diff --git a/tools/testing/radix-tree/linux/preempt.h b/tools/testing/radix-tree/linux/preempt.h
index 65c04c226965..35c5ac81529f 100644
--- a/tools/testing/radix-tree/linux/preempt.h
+++ b/tools/testing/radix-tree/linux/preempt.h
@@ -1,4 +1,14 @@
1#ifndef __LINUX_PREEMPT_H
2#define __LINUX_PREEMPT_H
3
1extern int preempt_count; 4extern int preempt_count;
2 5
3#define preempt_disable() uatomic_inc(&preempt_count) 6#define preempt_disable() uatomic_inc(&preempt_count)
4#define preempt_enable() uatomic_dec(&preempt_count) 7#define preempt_enable() uatomic_dec(&preempt_count)
8
9static inline int in_interrupt(void)
10{
11 return 0;
12}
13
14#endif /* __LINUX_PREEMPT_H */
diff --git a/tools/testing/radix-tree/linux/radix-tree.h b/tools/testing/radix-tree/linux/radix-tree.h
index ce694ddd4aea..bf1bb231f9b5 100644
--- a/tools/testing/radix-tree/linux/radix-tree.h
+++ b/tools/testing/radix-tree/linux/radix-tree.h
@@ -1 +1,26 @@
1#ifndef _TEST_RADIX_TREE_H
2#define _TEST_RADIX_TREE_H
3
4#include "generated/map-shift.h"
1#include "../../../../include/linux/radix-tree.h" 5#include "../../../../include/linux/radix-tree.h"
6
7extern int kmalloc_verbose;
8extern int test_verbose;
9
10static inline void trace_call_rcu(struct rcu_head *head,
11 void (*func)(struct rcu_head *head))
12{
13 if (kmalloc_verbose)
14 printf("Delaying free of %p to slab\n", (char *)head -
15 offsetof(struct radix_tree_node, rcu_head));
16 call_rcu(head, func);
17}
18
19#define printv(verbosity_level, fmt, ...) \
20 if(test_verbose >= verbosity_level) \
21 printf(fmt, ##__VA_ARGS__)
22
23#undef call_rcu
24#define call_rcu(x, y) trace_call_rcu(x, y)
25
26#endif /* _TEST_RADIX_TREE_H */
diff --git a/tools/testing/radix-tree/linux/types.h b/tools/testing/radix-tree/linux/types.h
deleted file mode 100644
index 8491d89873bb..000000000000
--- a/tools/testing/radix-tree/linux/types.h
+++ /dev/null
@@ -1,23 +0,0 @@
1#ifndef _TYPES_H
2#define _TYPES_H
3
4#include "../../include/linux/types.h"
5
6#define __rcu
7#define __read_mostly
8
9static inline void INIT_LIST_HEAD(struct list_head *list)
10{
11 list->next = list;
12 list->prev = list;
13}
14
15typedef struct {
16 unsigned int x;
17} spinlock_t;
18
19#define uninitialized_var(x) x = x
20
21#include <linux/gfp.h>
22
23#endif
diff --git a/tools/testing/radix-tree/main.c b/tools/testing/radix-tree/main.c
index f7e9801a6754..bc9a78449572 100644
--- a/tools/testing/radix-tree/main.c
+++ b/tools/testing/radix-tree/main.c
@@ -3,6 +3,7 @@
3#include <unistd.h> 3#include <unistd.h>
4#include <time.h> 4#include <time.h>
5#include <assert.h> 5#include <assert.h>
6#include <limits.h>
6 7
7#include <linux/slab.h> 8#include <linux/slab.h>
8#include <linux/radix-tree.h> 9#include <linux/radix-tree.h>
@@ -67,7 +68,7 @@ void big_gang_check(bool long_run)
67 68
68 for (i = 0; i < (long_run ? 1000 : 3); i++) { 69 for (i = 0; i < (long_run ? 1000 : 3); i++) {
69 __big_gang_check(); 70 __big_gang_check();
70 printf("%d ", i); 71 printv(2, "%d ", i);
71 fflush(stdout); 72 fflush(stdout);
72 } 73 }
73} 74}
@@ -128,14 +129,19 @@ void check_copied_tags(struct radix_tree_root *tree, unsigned long start, unsign
128 putchar('.'); */ 129 putchar('.'); */
129 if (idx[i] < start || idx[i] > end) { 130 if (idx[i] < start || idx[i] > end) {
130 if (item_tag_get(tree, idx[i], totag)) { 131 if (item_tag_get(tree, idx[i], totag)) {
131 printf("%lu-%lu: %lu, tags %d-%d\n", start, end, idx[i], item_tag_get(tree, idx[i], fromtag), item_tag_get(tree, idx[i], totag)); 132 printv(2, "%lu-%lu: %lu, tags %d-%d\n", start,
133 end, idx[i], item_tag_get(tree, idx[i],
134 fromtag),
135 item_tag_get(tree, idx[i], totag));
132 } 136 }
133 assert(!item_tag_get(tree, idx[i], totag)); 137 assert(!item_tag_get(tree, idx[i], totag));
134 continue; 138 continue;
135 } 139 }
136 if (item_tag_get(tree, idx[i], fromtag) ^ 140 if (item_tag_get(tree, idx[i], fromtag) ^
137 item_tag_get(tree, idx[i], totag)) { 141 item_tag_get(tree, idx[i], totag)) {
138 printf("%lu-%lu: %lu, tags %d-%d\n", start, end, idx[i], item_tag_get(tree, idx[i], fromtag), item_tag_get(tree, idx[i], totag)); 142 printv(2, "%lu-%lu: %lu, tags %d-%d\n", start, end,
143 idx[i], item_tag_get(tree, idx[i], fromtag),
144 item_tag_get(tree, idx[i], totag));
139 } 145 }
140 assert(!(item_tag_get(tree, idx[i], fromtag) ^ 146 assert(!(item_tag_get(tree, idx[i], fromtag) ^
141 item_tag_get(tree, idx[i], totag))); 147 item_tag_get(tree, idx[i], totag)));
@@ -237,7 +243,7 @@ static void __locate_check(struct radix_tree_root *tree, unsigned long index,
237 item = item_lookup(tree, index); 243 item = item_lookup(tree, index);
238 index2 = find_item(tree, item); 244 index2 = find_item(tree, item);
239 if (index != index2) { 245 if (index != index2) {
240 printf("index %ld order %d inserted; found %ld\n", 246 printv(2, "index %ld order %d inserted; found %ld\n",
241 index, order, index2); 247 index, order, index2);
242 abort(); 248 abort();
243 } 249 }
@@ -288,43 +294,48 @@ static void single_thread_tests(bool long_run)
288{ 294{
289 int i; 295 int i;
290 296
291 printf("starting single_thread_tests: %d allocated, preempt %d\n", 297 printv(1, "starting single_thread_tests: %d allocated, preempt %d\n",
292 nr_allocated, preempt_count); 298 nr_allocated, preempt_count);
293 multiorder_checks(); 299 multiorder_checks();
294 rcu_barrier(); 300 rcu_barrier();
295 printf("after multiorder_check: %d allocated, preempt %d\n", 301 printv(2, "after multiorder_check: %d allocated, preempt %d\n",
296 nr_allocated, preempt_count); 302 nr_allocated, preempt_count);
297 locate_check(); 303 locate_check();
298 rcu_barrier(); 304 rcu_barrier();
299 printf("after locate_check: %d allocated, preempt %d\n", 305 printv(2, "after locate_check: %d allocated, preempt %d\n",
300 nr_allocated, preempt_count); 306 nr_allocated, preempt_count);
301 tag_check(); 307 tag_check();
302 rcu_barrier(); 308 rcu_barrier();
303 printf("after tag_check: %d allocated, preempt %d\n", 309 printv(2, "after tag_check: %d allocated, preempt %d\n",
304 nr_allocated, preempt_count); 310 nr_allocated, preempt_count);
305 gang_check(); 311 gang_check();
306 rcu_barrier(); 312 rcu_barrier();
307 printf("after gang_check: %d allocated, preempt %d\n", 313 printv(2, "after gang_check: %d allocated, preempt %d\n",
308 nr_allocated, preempt_count); 314 nr_allocated, preempt_count);
309 add_and_check(); 315 add_and_check();
310 rcu_barrier(); 316 rcu_barrier();
311 printf("after add_and_check: %d allocated, preempt %d\n", 317 printv(2, "after add_and_check: %d allocated, preempt %d\n",
312 nr_allocated, preempt_count); 318 nr_allocated, preempt_count);
313 dynamic_height_check(); 319 dynamic_height_check();
314 rcu_barrier(); 320 rcu_barrier();
315 printf("after dynamic_height_check: %d allocated, preempt %d\n", 321 printv(2, "after dynamic_height_check: %d allocated, preempt %d\n",
322 nr_allocated, preempt_count);
323 idr_checks();
324 ida_checks();
325 rcu_barrier();
326 printv(2, "after idr_checks: %d allocated, preempt %d\n",
316 nr_allocated, preempt_count); 327 nr_allocated, preempt_count);
317 big_gang_check(long_run); 328 big_gang_check(long_run);
318 rcu_barrier(); 329 rcu_barrier();
319 printf("after big_gang_check: %d allocated, preempt %d\n", 330 printv(2, "after big_gang_check: %d allocated, preempt %d\n",
320 nr_allocated, preempt_count); 331 nr_allocated, preempt_count);
321 for (i = 0; i < (long_run ? 2000 : 3); i++) { 332 for (i = 0; i < (long_run ? 2000 : 3); i++) {
322 copy_tag_check(); 333 copy_tag_check();
323 printf("%d ", i); 334 printv(2, "%d ", i);
324 fflush(stdout); 335 fflush(stdout);
325 } 336 }
326 rcu_barrier(); 337 rcu_barrier();
327 printf("after copy_tag_check: %d allocated, preempt %d\n", 338 printv(2, "after copy_tag_check: %d allocated, preempt %d\n",
328 nr_allocated, preempt_count); 339 nr_allocated, preempt_count);
329} 340}
330 341
@@ -334,25 +345,30 @@ int main(int argc, char **argv)
334 int opt; 345 int opt;
335 unsigned int seed = time(NULL); 346 unsigned int seed = time(NULL);
336 347
337 while ((opt = getopt(argc, argv, "ls:")) != -1) { 348 while ((opt = getopt(argc, argv, "ls:v")) != -1) {
338 if (opt == 'l') 349 if (opt == 'l')
339 long_run = true; 350 long_run = true;
340 else if (opt == 's') 351 else if (opt == 's')
341 seed = strtoul(optarg, NULL, 0); 352 seed = strtoul(optarg, NULL, 0);
353 else if (opt == 'v')
354 test_verbose++;
342 } 355 }
343 356
344 printf("random seed %u\n", seed); 357 printf("random seed %u\n", seed);
345 srand(seed); 358 srand(seed);
346 359
360 printf("running tests\n");
361
347 rcu_register_thread(); 362 rcu_register_thread();
348 radix_tree_init(); 363 radix_tree_init();
349 364
350 regression1_test(); 365 regression1_test();
351 regression2_test(); 366 regression2_test();
352 regression3_test(); 367 regression3_test();
353 iteration_test(0, 10); 368 iteration_test(0, 10 + 90 * long_run);
354 iteration_test(7, 20); 369 iteration_test(7, 10 + 90 * long_run);
355 single_thread_tests(long_run); 370 single_thread_tests(long_run);
371 ida_thread_tests();
356 372
357 /* Free any remaining preallocated nodes */ 373 /* Free any remaining preallocated nodes */
358 radix_tree_cpu_dead(0); 374 radix_tree_cpu_dead(0);
@@ -360,9 +376,11 @@ int main(int argc, char **argv)
360 benchmark(); 376 benchmark();
361 377
362 rcu_barrier(); 378 rcu_barrier();
363 printf("after rcu_barrier: %d allocated, preempt %d\n", 379 printv(2, "after rcu_barrier: %d allocated, preempt %d\n",
364 nr_allocated, preempt_count); 380 nr_allocated, preempt_count);
365 rcu_unregister_thread(); 381 rcu_unregister_thread();
366 382
383 printf("tests completed\n");
384
367 exit(0); 385 exit(0);
368} 386}
diff --git a/tools/testing/radix-tree/multiorder.c b/tools/testing/radix-tree/multiorder.c
index f79812a5e070..06c71178d07d 100644
--- a/tools/testing/radix-tree/multiorder.c
+++ b/tools/testing/radix-tree/multiorder.c
@@ -30,7 +30,7 @@ static void __multiorder_tag_test(int index, int order)
30 /* our canonical entry */ 30 /* our canonical entry */
31 base = index & ~((1 << order) - 1); 31 base = index & ~((1 << order) - 1);
32 32
33 printf("Multiorder tag test with index %d, canonical entry %d\n", 33 printv(2, "Multiorder tag test with index %d, canonical entry %d\n",
34 index, base); 34 index, base);
35 35
36 err = item_insert_order(&tree, index, order); 36 err = item_insert_order(&tree, index, order);
@@ -150,7 +150,7 @@ static void multiorder_check(unsigned long index, int order)
150 struct item *item2 = item_create(min, order); 150 struct item *item2 = item_create(min, order);
151 RADIX_TREE(tree, GFP_KERNEL); 151 RADIX_TREE(tree, GFP_KERNEL);
152 152
153 printf("Multiorder index %ld, order %d\n", index, order); 153 printv(2, "Multiorder index %ld, order %d\n", index, order);
154 154
155 assert(item_insert_order(&tree, index, order) == 0); 155 assert(item_insert_order(&tree, index, order) == 0);
156 156
@@ -188,7 +188,7 @@ static void multiorder_shrink(unsigned long index, int order)
188 RADIX_TREE(tree, GFP_KERNEL); 188 RADIX_TREE(tree, GFP_KERNEL);
189 struct radix_tree_node *node; 189 struct radix_tree_node *node;
190 190
191 printf("Multiorder shrink index %ld, order %d\n", index, order); 191 printv(2, "Multiorder shrink index %ld, order %d\n", index, order);
192 192
193 assert(item_insert_order(&tree, 0, order) == 0); 193 assert(item_insert_order(&tree, 0, order) == 0);
194 194
@@ -209,7 +209,8 @@ static void multiorder_shrink(unsigned long index, int order)
209 item_check_absent(&tree, i); 209 item_check_absent(&tree, i);
210 210
211 if (!item_delete(&tree, 0)) { 211 if (!item_delete(&tree, 0)) {
212 printf("failed to delete index %ld (order %d)\n", index, order); abort(); 212 printv(2, "failed to delete index %ld (order %d)\n", index, order);
213 abort();
213 } 214 }
214 215
215 for (i = 0; i < 2*max; i++) 216 for (i = 0; i < 2*max; i++)
@@ -234,7 +235,7 @@ void multiorder_iteration(void)
234 void **slot; 235 void **slot;
235 int i, j, err; 236 int i, j, err;
236 237
237 printf("Multiorder iteration test\n"); 238 printv(1, "Multiorder iteration test\n");
238 239
239#define NUM_ENTRIES 11 240#define NUM_ENTRIES 11
240 int index[NUM_ENTRIES] = {0, 2, 4, 8, 16, 32, 34, 36, 64, 72, 128}; 241 int index[NUM_ENTRIES] = {0, 2, 4, 8, 16, 32, 34, 36, 64, 72, 128};
@@ -275,7 +276,7 @@ void multiorder_tagged_iteration(void)
275 void **slot; 276 void **slot;
276 int i, j; 277 int i, j;
277 278
278 printf("Multiorder tagged iteration test\n"); 279 printv(1, "Multiorder tagged iteration test\n");
279 280
280#define MT_NUM_ENTRIES 9 281#define MT_NUM_ENTRIES 9
281 int index[MT_NUM_ENTRIES] = {0, 2, 4, 16, 32, 40, 64, 72, 128}; 282 int index[MT_NUM_ENTRIES] = {0, 2, 4, 16, 32, 40, 64, 72, 128};
@@ -355,6 +356,10 @@ void multiorder_tagged_iteration(void)
355 item_kill_tree(&tree); 356 item_kill_tree(&tree);
356} 357}
357 358
359/*
360 * Basic join checks: make sure we can't find an entry in the tree after
361 * a larger entry has replaced it
362 */
358static void multiorder_join1(unsigned long index, 363static void multiorder_join1(unsigned long index,
359 unsigned order1, unsigned order2) 364 unsigned order1, unsigned order2)
360{ 365{
@@ -373,6 +378,10 @@ static void multiorder_join1(unsigned long index,
373 item_kill_tree(&tree); 378 item_kill_tree(&tree);
374} 379}
375 380
381/*
382 * Check that the accounting of exceptional entries is handled correctly
383 * by joining an exceptional entry to a normal pointer.
384 */
376static void multiorder_join2(unsigned order1, unsigned order2) 385static void multiorder_join2(unsigned order1, unsigned order2)
377{ 386{
378 RADIX_TREE(tree, GFP_KERNEL); 387 RADIX_TREE(tree, GFP_KERNEL);
@@ -386,6 +395,9 @@ static void multiorder_join2(unsigned order1, unsigned order2)
386 assert(item2 == (void *)0x12UL); 395 assert(item2 == (void *)0x12UL);
387 assert(node->exceptional == 1); 396 assert(node->exceptional == 1);
388 397
398 item2 = radix_tree_lookup(&tree, 0);
399 free(item2);
400
389 radix_tree_join(&tree, 0, order1, item1); 401 radix_tree_join(&tree, 0, order1, item1);
390 item2 = __radix_tree_lookup(&tree, 1 << order2, &node, NULL); 402 item2 = __radix_tree_lookup(&tree, 1 << order2, &node, NULL);
391 assert(item2 == item1); 403 assert(item2 == item1);
@@ -453,7 +465,7 @@ static void check_mem(unsigned old_order, unsigned new_order, unsigned alloc)
453{ 465{
454 struct radix_tree_preload *rtp = &radix_tree_preloads; 466 struct radix_tree_preload *rtp = &radix_tree_preloads;
455 if (rtp->nr != 0) 467 if (rtp->nr != 0)
456 printf("split(%u %u) remaining %u\n", old_order, new_order, 468 printv(2, "split(%u %u) remaining %u\n", old_order, new_order,
457 rtp->nr); 469 rtp->nr);
458 /* 470 /*
459 * Can't check for equality here as some nodes may have been 471 * Can't check for equality here as some nodes may have been
@@ -461,7 +473,7 @@ static void check_mem(unsigned old_order, unsigned new_order, unsigned alloc)
461 * nodes allocated since they should have all been preloaded. 473 * nodes allocated since they should have all been preloaded.
462 */ 474 */
463 if (nr_allocated > alloc) 475 if (nr_allocated > alloc)
464 printf("split(%u %u) allocated %u %u\n", old_order, new_order, 476 printv(2, "split(%u %u) allocated %u %u\n", old_order, new_order,
465 alloc, nr_allocated); 477 alloc, nr_allocated);
466} 478}
467 479
@@ -471,6 +483,7 @@ static void __multiorder_split(int old_order, int new_order)
471 void **slot; 483 void **slot;
472 struct radix_tree_iter iter; 484 struct radix_tree_iter iter;
473 unsigned alloc; 485 unsigned alloc;
486 struct item *item;
474 487
475 radix_tree_preload(GFP_KERNEL); 488 radix_tree_preload(GFP_KERNEL);
476 assert(item_insert_order(&tree, 0, old_order) == 0); 489 assert(item_insert_order(&tree, 0, old_order) == 0);
@@ -479,7 +492,7 @@ static void __multiorder_split(int old_order, int new_order)
479 /* Wipe out the preloaded cache or it'll confuse check_mem() */ 492 /* Wipe out the preloaded cache or it'll confuse check_mem() */
480 radix_tree_cpu_dead(0); 493 radix_tree_cpu_dead(0);
481 494
482 radix_tree_tag_set(&tree, 0, 2); 495 item = radix_tree_tag_set(&tree, 0, 2);
483 496
484 radix_tree_split_preload(old_order, new_order, GFP_KERNEL); 497 radix_tree_split_preload(old_order, new_order, GFP_KERNEL);
485 alloc = nr_allocated; 498 alloc = nr_allocated;
@@ -492,6 +505,7 @@ static void __multiorder_split(int old_order, int new_order)
492 radix_tree_preload_end(); 505 radix_tree_preload_end();
493 506
494 item_kill_tree(&tree); 507 item_kill_tree(&tree);
508 free(item);
495} 509}
496 510
497static void __multiorder_split2(int old_order, int new_order) 511static void __multiorder_split2(int old_order, int new_order)
@@ -633,3 +647,10 @@ void multiorder_checks(void)
633 647
634 radix_tree_cpu_dead(0); 648 radix_tree_cpu_dead(0);
635} 649}
650
651int __weak main(void)
652{
653 radix_tree_init();
654 multiorder_checks();
655 return 0;
656}
diff --git a/tools/testing/radix-tree/regression1.c b/tools/testing/radix-tree/regression1.c
index 0d6813a61b37..bf97742fc18c 100644
--- a/tools/testing/radix-tree/regression1.c
+++ b/tools/testing/radix-tree/regression1.c
@@ -193,7 +193,7 @@ void regression1_test(void)
193 long arg; 193 long arg;
194 194
195 /* Regression #1 */ 195 /* Regression #1 */
196 printf("running regression test 1, should finish in under a minute\n"); 196 printv(1, "running regression test 1, should finish in under a minute\n");
197 nr_threads = 2; 197 nr_threads = 2;
198 pthread_barrier_init(&worker_barrier, NULL, nr_threads); 198 pthread_barrier_init(&worker_barrier, NULL, nr_threads);
199 199
@@ -216,5 +216,5 @@ void regression1_test(void)
216 216
217 free(threads); 217 free(threads);
218 218
219 printf("regression test 1, done\n"); 219 printv(1, "regression test 1, done\n");
220} 220}
diff --git a/tools/testing/radix-tree/regression2.c b/tools/testing/radix-tree/regression2.c
index a41325d7a170..42dd2a33ed24 100644
--- a/tools/testing/radix-tree/regression2.c
+++ b/tools/testing/radix-tree/regression2.c
@@ -80,7 +80,7 @@ void regression2_test(void)
80 unsigned long int start, end; 80 unsigned long int start, end;
81 struct page *pages[1]; 81 struct page *pages[1];
82 82
83 printf("running regression test 2 (should take milliseconds)\n"); 83 printv(1, "running regression test 2 (should take milliseconds)\n");
84 /* 0. */ 84 /* 0. */
85 for (i = 0; i <= max_slots - 1; i++) { 85 for (i = 0; i <= max_slots - 1; i++) {
86 p = page_alloc(); 86 p = page_alloc();
@@ -103,7 +103,7 @@ void regression2_test(void)
103 103
104 /* 4. */ 104 /* 4. */
105 for (i = max_slots - 1; i >= 0; i--) 105 for (i = max_slots - 1; i >= 0; i--)
106 radix_tree_delete(&mt_tree, i); 106 free(radix_tree_delete(&mt_tree, i));
107 107
108 /* 5. */ 108 /* 5. */
109 // NOTE: start should not be 0 because radix_tree_gang_lookup_tag_slot 109 // NOTE: start should not be 0 because radix_tree_gang_lookup_tag_slot
@@ -114,7 +114,9 @@ void regression2_test(void)
114 PAGECACHE_TAG_TOWRITE); 114 PAGECACHE_TAG_TOWRITE);
115 115
116 /* We remove all the remained nodes */ 116 /* We remove all the remained nodes */
117 radix_tree_delete(&mt_tree, max_slots); 117 free(radix_tree_delete(&mt_tree, max_slots));
118 118
119 printf("regression test 2, done\n"); 119 BUG_ON(!radix_tree_empty(&mt_tree));
120
121 printv(1, "regression test 2, done\n");
120} 122}
diff --git a/tools/testing/radix-tree/regression3.c b/tools/testing/radix-tree/regression3.c
index b594841fae85..670c3d2ae7b1 100644
--- a/tools/testing/radix-tree/regression3.c
+++ b/tools/testing/radix-tree/regression3.c
@@ -34,21 +34,21 @@ void regression3_test(void)
34 void **slot; 34 void **slot;
35 bool first; 35 bool first;
36 36
37 printf("running regression test 3 (should take milliseconds)\n"); 37 printv(1, "running regression test 3 (should take milliseconds)\n");
38 38
39 radix_tree_insert(&root, 0, ptr0); 39 radix_tree_insert(&root, 0, ptr0);
40 radix_tree_tag_set(&root, 0, 0); 40 radix_tree_tag_set(&root, 0, 0);
41 41
42 first = true; 42 first = true;
43 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) { 43 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
44 printf("tagged %ld %p\n", iter.index, *slot); 44 printv(2, "tagged %ld %p\n", iter.index, *slot);
45 if (first) { 45 if (first) {
46 radix_tree_insert(&root, 1, ptr); 46 radix_tree_insert(&root, 1, ptr);
47 radix_tree_tag_set(&root, 1, 0); 47 radix_tree_tag_set(&root, 1, 0);
48 first = false; 48 first = false;
49 } 49 }
50 if (radix_tree_deref_retry(*slot)) { 50 if (radix_tree_deref_retry(*slot)) {
51 printf("retry at %ld\n", iter.index); 51 printv(2, "retry at %ld\n", iter.index);
52 slot = radix_tree_iter_retry(&iter); 52 slot = radix_tree_iter_retry(&iter);
53 continue; 53 continue;
54 } 54 }
@@ -57,13 +57,13 @@ void regression3_test(void)
57 57
58 first = true; 58 first = true;
59 radix_tree_for_each_slot(slot, &root, &iter, 0) { 59 radix_tree_for_each_slot(slot, &root, &iter, 0) {
60 printf("slot %ld %p\n", iter.index, *slot); 60 printv(2, "slot %ld %p\n", iter.index, *slot);
61 if (first) { 61 if (first) {
62 radix_tree_insert(&root, 1, ptr); 62 radix_tree_insert(&root, 1, ptr);
63 first = false; 63 first = false;
64 } 64 }
65 if (radix_tree_deref_retry(*slot)) { 65 if (radix_tree_deref_retry(*slot)) {
66 printk("retry at %ld\n", iter.index); 66 printv(2, "retry at %ld\n", iter.index);
67 slot = radix_tree_iter_retry(&iter); 67 slot = radix_tree_iter_retry(&iter);
68 continue; 68 continue;
69 } 69 }
@@ -72,30 +72,30 @@ void regression3_test(void)
72 72
73 first = true; 73 first = true;
74 radix_tree_for_each_contig(slot, &root, &iter, 0) { 74 radix_tree_for_each_contig(slot, &root, &iter, 0) {
75 printk("contig %ld %p\n", iter.index, *slot); 75 printv(2, "contig %ld %p\n", iter.index, *slot);
76 if (first) { 76 if (first) {
77 radix_tree_insert(&root, 1, ptr); 77 radix_tree_insert(&root, 1, ptr);
78 first = false; 78 first = false;
79 } 79 }
80 if (radix_tree_deref_retry(*slot)) { 80 if (radix_tree_deref_retry(*slot)) {
81 printk("retry at %ld\n", iter.index); 81 printv(2, "retry at %ld\n", iter.index);
82 slot = radix_tree_iter_retry(&iter); 82 slot = radix_tree_iter_retry(&iter);
83 continue; 83 continue;
84 } 84 }
85 } 85 }
86 86
87 radix_tree_for_each_slot(slot, &root, &iter, 0) { 87 radix_tree_for_each_slot(slot, &root, &iter, 0) {
88 printf("slot %ld %p\n", iter.index, *slot); 88 printv(2, "slot %ld %p\n", iter.index, *slot);
89 if (!iter.index) { 89 if (!iter.index) {
90 printf("next at %ld\n", iter.index); 90 printv(2, "next at %ld\n", iter.index);
91 slot = radix_tree_iter_resume(slot, &iter); 91 slot = radix_tree_iter_resume(slot, &iter);
92 } 92 }
93 } 93 }
94 94
95 radix_tree_for_each_contig(slot, &root, &iter, 0) { 95 radix_tree_for_each_contig(slot, &root, &iter, 0) {
96 printf("contig %ld %p\n", iter.index, *slot); 96 printv(2, "contig %ld %p\n", iter.index, *slot);
97 if (!iter.index) { 97 if (!iter.index) {
98 printf("next at %ld\n", iter.index); 98 printv(2, "next at %ld\n", iter.index);
99 slot = radix_tree_iter_resume(slot, &iter); 99 slot = radix_tree_iter_resume(slot, &iter);
100 } 100 }
101 } 101 }
@@ -103,9 +103,9 @@ void regression3_test(void)
103 radix_tree_tag_set(&root, 0, 0); 103 radix_tree_tag_set(&root, 0, 0);
104 radix_tree_tag_set(&root, 1, 0); 104 radix_tree_tag_set(&root, 1, 0);
105 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) { 105 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
106 printf("tagged %ld %p\n", iter.index, *slot); 106 printv(2, "tagged %ld %p\n", iter.index, *slot);
107 if (!iter.index) { 107 if (!iter.index) {
108 printf("next at %ld\n", iter.index); 108 printv(2, "next at %ld\n", iter.index);
109 slot = radix_tree_iter_resume(slot, &iter); 109 slot = radix_tree_iter_resume(slot, &iter);
110 } 110 }
111 } 111 }
@@ -113,5 +113,5 @@ void regression3_test(void)
113 radix_tree_delete(&root, 0); 113 radix_tree_delete(&root, 0);
114 radix_tree_delete(&root, 1); 114 radix_tree_delete(&root, 1);
115 115
116 printf("regression test 3 passed\n"); 116 printv(1, "regression test 3 passed\n");
117} 117}
diff --git a/tools/testing/radix-tree/tag_check.c b/tools/testing/radix-tree/tag_check.c
index fd98c132207a..36dcf7d6945d 100644
--- a/tools/testing/radix-tree/tag_check.c
+++ b/tools/testing/radix-tree/tag_check.c
@@ -49,10 +49,10 @@ void simple_checks(void)
49 } 49 }
50 verify_tag_consistency(&tree, 0); 50 verify_tag_consistency(&tree, 0);
51 verify_tag_consistency(&tree, 1); 51 verify_tag_consistency(&tree, 1);
52 printf("before item_kill_tree: %d allocated\n", nr_allocated); 52 printv(2, "before item_kill_tree: %d allocated\n", nr_allocated);
53 item_kill_tree(&tree); 53 item_kill_tree(&tree);
54 rcu_barrier(); 54 rcu_barrier();
55 printf("after item_kill_tree: %d allocated\n", nr_allocated); 55 printv(2, "after item_kill_tree: %d allocated\n", nr_allocated);
56} 56}
57 57
58/* 58/*
@@ -257,7 +257,7 @@ static void do_thrash(struct radix_tree_root *tree, char *thrash_state, int tag)
257 257
258 gang_check(tree, thrash_state, tag); 258 gang_check(tree, thrash_state, tag);
259 259
260 printf("%d(%d) %d(%d) %d(%d) %d(%d) / " 260 printv(2, "%d(%d) %d(%d) %d(%d) %d(%d) / "
261 "%d(%d) present, %d(%d) tagged\n", 261 "%d(%d) present, %d(%d) tagged\n",
262 insert_chunk, nr_inserted, 262 insert_chunk, nr_inserted,
263 delete_chunk, nr_deleted, 263 delete_chunk, nr_deleted,
@@ -296,13 +296,13 @@ static void __leak_check(void)
296{ 296{
297 RADIX_TREE(tree, GFP_KERNEL); 297 RADIX_TREE(tree, GFP_KERNEL);
298 298
299 printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); 299 printv(2, "%d: nr_allocated=%d\n", __LINE__, nr_allocated);
300 item_insert(&tree, 1000000); 300 item_insert(&tree, 1000000);
301 printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); 301 printv(2, "%d: nr_allocated=%d\n", __LINE__, nr_allocated);
302 item_delete(&tree, 1000000); 302 item_delete(&tree, 1000000);
303 printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); 303 printv(2, "%d: nr_allocated=%d\n", __LINE__, nr_allocated);
304 item_kill_tree(&tree); 304 item_kill_tree(&tree);
305 printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated); 305 printv(2, "%d: nr_allocated=%d\n", __LINE__, nr_allocated);
306} 306}
307 307
308static void single_check(void) 308static void single_check(void)
@@ -330,21 +330,50 @@ static void single_check(void)
330 item_kill_tree(&tree); 330 item_kill_tree(&tree);
331} 331}
332 332
333void radix_tree_clear_tags_test(void)
334{
335 unsigned long index;
336 struct radix_tree_node *node;
337 struct radix_tree_iter iter;
338 void **slot;
339
340 RADIX_TREE(tree, GFP_KERNEL);
341
342 item_insert(&tree, 0);
343 item_tag_set(&tree, 0, 0);
344 __radix_tree_lookup(&tree, 0, &node, &slot);
345 radix_tree_clear_tags(&tree, node, slot);
346 assert(item_tag_get(&tree, 0, 0) == 0);
347
348 for (index = 0; index < 1000; index++) {
349 item_insert(&tree, index);
350 item_tag_set(&tree, index, 0);
351 }
352
353 radix_tree_for_each_slot(slot, &tree, &iter, 0) {
354 radix_tree_clear_tags(&tree, iter.node, slot);
355 assert(item_tag_get(&tree, iter.index, 0) == 0);
356 }
357
358 item_kill_tree(&tree);
359}
360
333void tag_check(void) 361void tag_check(void)
334{ 362{
335 single_check(); 363 single_check();
336 extend_checks(); 364 extend_checks();
337 contract_checks(); 365 contract_checks();
338 rcu_barrier(); 366 rcu_barrier();
339 printf("after extend_checks: %d allocated\n", nr_allocated); 367 printv(2, "after extend_checks: %d allocated\n", nr_allocated);
340 __leak_check(); 368 __leak_check();
341 leak_check(); 369 leak_check();
342 rcu_barrier(); 370 rcu_barrier();
343 printf("after leak_check: %d allocated\n", nr_allocated); 371 printv(2, "after leak_check: %d allocated\n", nr_allocated);
344 simple_checks(); 372 simple_checks();
345 rcu_barrier(); 373 rcu_barrier();
346 printf("after simple_checks: %d allocated\n", nr_allocated); 374 printv(2, "after simple_checks: %d allocated\n", nr_allocated);
347 thrash_tags(); 375 thrash_tags();
348 rcu_barrier(); 376 rcu_barrier();
349 printf("after thrash_tags: %d allocated\n", nr_allocated); 377 printv(2, "after thrash_tags: %d allocated\n", nr_allocated);
378 radix_tree_clear_tags_test();
350} 379}
diff --git a/tools/testing/radix-tree/test.c b/tools/testing/radix-tree/test.c
index e5726e373646..1a257d738a1e 100644
--- a/tools/testing/radix-tree/test.c
+++ b/tools/testing/radix-tree/test.c
@@ -29,15 +29,28 @@ int __item_insert(struct radix_tree_root *root, struct item *item)
29 return __radix_tree_insert(root, item->index, item->order, item); 29 return __radix_tree_insert(root, item->index, item->order, item);
30} 30}
31 31
32int item_insert(struct radix_tree_root *root, unsigned long index) 32struct item *item_create(unsigned long index, unsigned int order)
33{ 33{
34 return __item_insert(root, item_create(index, 0)); 34 struct item *ret = malloc(sizeof(*ret));
35
36 ret->index = index;
37 ret->order = order;
38 return ret;
35} 39}
36 40
37int item_insert_order(struct radix_tree_root *root, unsigned long index, 41int item_insert_order(struct radix_tree_root *root, unsigned long index,
38 unsigned order) 42 unsigned order)
39{ 43{
40 return __item_insert(root, item_create(index, order)); 44 struct item *item = item_create(index, order);
45 int err = __item_insert(root, item);
46 if (err)
47 free(item);
48 return err;
49}
50
51int item_insert(struct radix_tree_root *root, unsigned long index)
52{
53 return item_insert_order(root, index, 0);
41} 54}
42 55
43void item_sanity(struct item *item, unsigned long index) 56void item_sanity(struct item *item, unsigned long index)
@@ -61,15 +74,6 @@ int item_delete(struct radix_tree_root *root, unsigned long index)
61 return 0; 74 return 0;
62} 75}
63 76
64struct item *item_create(unsigned long index, unsigned int order)
65{
66 struct item *ret = malloc(sizeof(*ret));
67
68 ret->index = index;
69 ret->order = order;
70 return ret;
71}
72
73void item_check_present(struct radix_tree_root *root, unsigned long index) 77void item_check_present(struct radix_tree_root *root, unsigned long index)
74{ 78{
75 struct item *item; 79 struct item *item;
diff --git a/tools/testing/radix-tree/test.h b/tools/testing/radix-tree/test.h
index 056a23b56467..0f8220cc6166 100644
--- a/tools/testing/radix-tree/test.h
+++ b/tools/testing/radix-tree/test.h
@@ -34,6 +34,9 @@ void tag_check(void);
34void multiorder_checks(void); 34void multiorder_checks(void);
35void iteration_test(unsigned order, unsigned duration); 35void iteration_test(unsigned order, unsigned duration);
36void benchmark(void); 36void benchmark(void);
37void idr_checks(void);
38void ida_checks(void);
39void ida_thread_tests(void);
37 40
38struct item * 41struct item *
39item_tag_set(struct radix_tree_root *root, unsigned long index, int tag); 42item_tag_set(struct radix_tree_root *root, unsigned long index, int tag);
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 831022b12848..d8593f1251ec 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,6 +1,7 @@
1TARGETS = bpf 1TARGETS = bpf
2TARGETS += breakpoints 2TARGETS += breakpoints
3TARGETS += capabilities 3TARGETS += capabilities
4TARGETS += cpufreq
4TARGETS += cpu-hotplug 5TARGETS += cpu-hotplug
5TARGETS += efivarfs 6TARGETS += efivarfs
6TARGETS += exec 7TARGETS += exec
@@ -8,6 +9,7 @@ TARGETS += firmware
8TARGETS += ftrace 9TARGETS += ftrace
9TARGETS += futex 10TARGETS += futex
10TARGETS += gpio 11TARGETS += gpio
12TARGETS += intel_pstate
11TARGETS += ipc 13TARGETS += ipc
12TARGETS += kcmp 14TARGETS += kcmp
13TARGETS += lib 15TARGETS += lib
@@ -24,6 +26,7 @@ TARGETS += ptrace
24TARGETS += seccomp 26TARGETS += seccomp
25TARGETS += sigaltstack 27TARGETS += sigaltstack
26TARGETS += size 28TARGETS += size
29TARGETS += splice
27TARGETS += static_keys 30TARGETS += static_keys
28TARGETS += sync 31TARGETS += sync
29TARGETS += sysctl 32TARGETS += sysctl
@@ -49,29 +52,44 @@ override LDFLAGS =
49override MAKEFLAGS = 52override MAKEFLAGS =
50endif 53endif
51 54
55BUILD := $(O)
56ifndef BUILD
57 BUILD := $(KBUILD_OUTPUT)
58endif
59ifndef BUILD
60 BUILD := $(shell pwd)
61endif
62
63export BUILD
52all: 64all:
53 for TARGET in $(TARGETS); do \ 65 for TARGET in $(TARGETS); do \
54 make -C $$TARGET; \ 66 BUILD_TARGET=$$BUILD/$$TARGET; \
67 mkdir $$BUILD_TARGET -p; \
68 make OUTPUT=$$BUILD_TARGET -C $$TARGET;\
55 done; 69 done;
56 70
57run_tests: all 71run_tests: all
58 for TARGET in $(TARGETS); do \ 72 for TARGET in $(TARGETS); do \
59 make -C $$TARGET run_tests; \ 73 BUILD_TARGET=$$BUILD/$$TARGET; \
74 make OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\
60 done; 75 done;
61 76
62hotplug: 77hotplug:
63 for TARGET in $(TARGETS_HOTPLUG); do \ 78 for TARGET in $(TARGETS_HOTPLUG); do \
64 make -C $$TARGET; \ 79 BUILD_TARGET=$$BUILD/$$TARGET; \
80 make OUTPUT=$$BUILD_TARGET -C $$TARGET;\
65 done; 81 done;
66 82
67run_hotplug: hotplug 83run_hotplug: hotplug
68 for TARGET in $(TARGETS_HOTPLUG); do \ 84 for TARGET in $(TARGETS_HOTPLUG); do \
69 make -C $$TARGET run_full_test; \ 85 BUILD_TARGET=$$BUILD/$$TARGET; \
86 make OUTPUT=$$BUILD_TARGET -C $$TARGET run_full_test;\
70 done; 87 done;
71 88
72clean_hotplug: 89clean_hotplug:
73 for TARGET in $(TARGETS_HOTPLUG); do \ 90 for TARGET in $(TARGETS_HOTPLUG); do \
74 make -C $$TARGET clean; \ 91 BUILD_TARGET=$$BUILD/$$TARGET; \
92 make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\
75 done; 93 done;
76 94
77run_pstore_crash: 95run_pstore_crash:
@@ -86,7 +104,8 @@ ifdef INSTALL_PATH
86 @# Ask all targets to install their files 104 @# Ask all targets to install their files
87 mkdir -p $(INSTALL_PATH) 105 mkdir -p $(INSTALL_PATH)
88 for TARGET in $(TARGETS); do \ 106 for TARGET in $(TARGETS); do \
89 make -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \ 107 BUILD_TARGET=$$BUILD/$$TARGET; \
108 make OUTPUT=$$BUILD_TARGET -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install; \
90 done; 109 done;
91 110
92 @# Ask all targets to emit their test scripts 111 @# Ask all targets to emit their test scripts
@@ -95,10 +114,11 @@ ifdef INSTALL_PATH
95 echo "ROOT=\$$PWD" >> $(ALL_SCRIPT) 114 echo "ROOT=\$$PWD" >> $(ALL_SCRIPT)
96 115
97 for TARGET in $(TARGETS); do \ 116 for TARGET in $(TARGETS); do \
117 BUILD_TARGET=$$BUILD/$$TARGET; \
98 echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ 118 echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \
99 echo "echo ========================================" >> $(ALL_SCRIPT); \ 119 echo "echo ========================================" >> $(ALL_SCRIPT); \
100 echo "cd $$TARGET" >> $(ALL_SCRIPT); \ 120 echo "cd $$TARGET" >> $(ALL_SCRIPT); \
101 make -s --no-print-directory -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ 121 make -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \
102 echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ 122 echo "cd \$$ROOT" >> $(ALL_SCRIPT); \
103 done; 123 done;
104 124
@@ -109,7 +129,8 @@ endif
109 129
110clean: 130clean:
111 for TARGET in $(TARGETS); do \ 131 for TARGET in $(TARGETS); do \
112 make -C $$TARGET clean; \ 132 BUILD_TARGET=$$BUILD/$$TARGET; \
133 make OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\
113 done; 134 done;
114 135
115.PHONY: install 136.PHONY: install
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 071431bedde8..541d9d7fad5a 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -1,3 +1,5 @@
1test_verifier 1test_verifier
2test_maps 2test_maps
3test_lru_map 3test_lru_map
4test_lpm_map
5test_tag
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 7a5f24543a5f..67531f47781b 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -1,13 +1,22 @@
1CFLAGS += -Wall -O2 -I../../../../usr/include 1LIBDIR := ../../../lib
2BPFOBJ := $(LIBDIR)/bpf/bpf.o
2 3
3test_objs = test_verifier test_maps test_lru_map 4CFLAGS += -Wall -O2 -lcap -I../../../include/uapi -I$(LIBDIR) $(BPFOBJ)
4 5
5TEST_PROGS := test_verifier test_maps test_lru_map test_kmod.sh 6TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map
6TEST_FILES := $(test_objs)
7 7
8all: $(test_objs) 8TEST_PROGS := test_kmod.sh
9 9
10include ../lib.mk 10all: $(TEST_GEN_PROGS)
11
12.PHONY: all clean force
13
14# force a rebuild of BPFOBJ when its dependencies are updated
15force:
11 16
12clean: 17$(BPFOBJ): force
13 $(RM) $(test_objs) 18 $(MAKE) -C $(dir $(BPFOBJ))
19
20$(test_objs): $(BPFOBJ)
21
22include ../lib.mk
diff --git a/tools/testing/selftests/bpf/bpf_sys.h b/tools/testing/selftests/bpf/bpf_sys.h
deleted file mode 100644
index 6b4565f2a3f2..000000000000
--- a/tools/testing/selftests/bpf/bpf_sys.h
+++ /dev/null
@@ -1,108 +0,0 @@
1#ifndef __BPF_SYS__
2#define __BPF_SYS__
3
4#include <stdint.h>
5#include <stdlib.h>
6
7#include <sys/syscall.h>
8
9#include <linux/bpf.h>
10
11static inline __u64 bpf_ptr_to_u64(const void *ptr)
12{
13 return (__u64)(unsigned long) ptr;
14}
15
16static inline int bpf(int cmd, union bpf_attr *attr, unsigned int size)
17{
18#ifdef __NR_bpf
19 return syscall(__NR_bpf, cmd, attr, size);
20#else
21 fprintf(stderr, "No bpf syscall, kernel headers too old?\n");
22 errno = ENOSYS;
23 return -1;
24#endif
25}
26
27static inline int bpf_map_lookup(int fd, const void *key, void *value)
28{
29 union bpf_attr attr = {};
30
31 attr.map_fd = fd;
32 attr.key = bpf_ptr_to_u64(key);
33 attr.value = bpf_ptr_to_u64(value);
34
35 return bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
36}
37
38static inline int bpf_map_update(int fd, const void *key, const void *value,
39 uint64_t flags)
40{
41 union bpf_attr attr = {};
42
43 attr.map_fd = fd;
44 attr.key = bpf_ptr_to_u64(key);
45 attr.value = bpf_ptr_to_u64(value);
46 attr.flags = flags;
47
48 return bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
49}
50
51static inline int bpf_map_delete(int fd, const void *key)
52{
53 union bpf_attr attr = {};
54
55 attr.map_fd = fd;
56 attr.key = bpf_ptr_to_u64(key);
57
58 return bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
59}
60
61static inline int bpf_map_next_key(int fd, const void *key, void *next_key)
62{
63 union bpf_attr attr = {};
64
65 attr.map_fd = fd;
66 attr.key = bpf_ptr_to_u64(key);
67 attr.next_key = bpf_ptr_to_u64(next_key);
68
69 return bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
70}
71
72static inline int bpf_map_create(enum bpf_map_type type, uint32_t size_key,
73 uint32_t size_value, uint32_t max_elem,
74 uint32_t flags)
75{
76 union bpf_attr attr = {};
77
78 attr.map_type = type;
79 attr.key_size = size_key;
80 attr.value_size = size_value;
81 attr.max_entries = max_elem;
82 attr.map_flags = flags;
83
84 return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
85}
86
87static inline int bpf_prog_load(enum bpf_prog_type type,
88 const struct bpf_insn *insns, size_t size_insns,
89 const char *license, char *log, size_t size_log)
90{
91 union bpf_attr attr = {};
92
93 attr.prog_type = type;
94 attr.insns = bpf_ptr_to_u64(insns);
95 attr.insn_cnt = size_insns / sizeof(struct bpf_insn);
96 attr.license = bpf_ptr_to_u64(license);
97
98 if (size_log > 0) {
99 attr.log_buf = bpf_ptr_to_u64(log);
100 attr.log_size = size_log;
101 attr.log_level = 1;
102 log[0] = 0;
103 }
104
105 return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
106}
107
108#endif /* __BPF_SYS__ */
diff --git a/tools/testing/selftests/bpf/test_lpm_map.c b/tools/testing/selftests/bpf/test_lpm_map.c
new file mode 100644
index 000000000000..e97565243d59
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_lpm_map.c
@@ -0,0 +1,358 @@
1/*
2 * Randomized tests for eBPF longest-prefix-match maps
3 *
4 * This program runs randomized tests against the lpm-bpf-map. It implements a
5 * "Trivial Longest Prefix Match" (tlpm) based on simple, linear, singly linked
6 * lists. The implementation should be pretty straightforward.
7 *
8 * Based on tlpm, this inserts randomized data into bpf-lpm-maps and verifies
9 * the trie-based bpf-map implementation behaves the same way as tlpm.
10 */
11
12#include <assert.h>
13#include <errno.h>
14#include <inttypes.h>
15#include <linux/bpf.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <time.h>
20#include <unistd.h>
21#include <arpa/inet.h>
22#include <sys/time.h>
23#include <sys/resource.h>
24
25#include <bpf/bpf.h>
26#include "bpf_util.h"
27
28struct tlpm_node {
29 struct tlpm_node *next;
30 size_t n_bits;
31 uint8_t key[];
32};
33
34static struct tlpm_node *tlpm_add(struct tlpm_node *list,
35 const uint8_t *key,
36 size_t n_bits)
37{
38 struct tlpm_node *node;
39 size_t n;
40
41 /* add new entry with @key/@n_bits to @list and return new head */
42
43 n = (n_bits + 7) / 8;
44 node = malloc(sizeof(*node) + n);
45 assert(node);
46
47 node->next = list;
48 node->n_bits = n_bits;
49 memcpy(node->key, key, n);
50
51 return node;
52}
53
54static void tlpm_clear(struct tlpm_node *list)
55{
56 struct tlpm_node *node;
57
58 /* free all entries in @list */
59
60 while ((node = list)) {
61 list = list->next;
62 free(node);
63 }
64}
65
66static struct tlpm_node *tlpm_match(struct tlpm_node *list,
67 const uint8_t *key,
68 size_t n_bits)
69{
70 struct tlpm_node *best = NULL;
71 size_t i;
72
73 /* Perform longest prefix-match on @key/@n_bits. That is, iterate all
74 * entries and match each prefix against @key. Remember the "best"
75 * entry we find (i.e., the longest prefix that matches) and return it
76 * to the caller when done.
77 */
78
79 for ( ; list; list = list->next) {
80 for (i = 0; i < n_bits && i < list->n_bits; ++i) {
81 if ((key[i / 8] & (1 << (7 - i % 8))) !=
82 (list->key[i / 8] & (1 << (7 - i % 8))))
83 break;
84 }
85
86 if (i >= list->n_bits) {
87 if (!best || i > best->n_bits)
88 best = list;
89 }
90 }
91
92 return best;
93}
94
95static void test_lpm_basic(void)
96{
97 struct tlpm_node *list = NULL, *t1, *t2;
98
99 /* very basic, static tests to verify tlpm works as expected */
100
101 assert(!tlpm_match(list, (uint8_t[]){ 0xff }, 8));
102
103 t1 = list = tlpm_add(list, (uint8_t[]){ 0xff }, 8);
104 assert(t1 == tlpm_match(list, (uint8_t[]){ 0xff }, 8));
105 assert(t1 == tlpm_match(list, (uint8_t[]){ 0xff, 0xff }, 16));
106 assert(t1 == tlpm_match(list, (uint8_t[]){ 0xff, 0x00 }, 16));
107 assert(!tlpm_match(list, (uint8_t[]){ 0x7f }, 8));
108 assert(!tlpm_match(list, (uint8_t[]){ 0xfe }, 8));
109 assert(!tlpm_match(list, (uint8_t[]){ 0xff }, 7));
110
111 t2 = list = tlpm_add(list, (uint8_t[]){ 0xff, 0xff }, 16);
112 assert(t1 == tlpm_match(list, (uint8_t[]){ 0xff }, 8));
113 assert(t2 == tlpm_match(list, (uint8_t[]){ 0xff, 0xff }, 16));
114 assert(t1 == tlpm_match(list, (uint8_t[]){ 0xff, 0xff }, 15));
115 assert(!tlpm_match(list, (uint8_t[]){ 0x7f, 0xff }, 16));
116
117 tlpm_clear(list);
118}
119
120static void test_lpm_order(void)
121{
122 struct tlpm_node *t1, *t2, *l1 = NULL, *l2 = NULL;
123 size_t i, j;
124
125 /* Verify the tlpm implementation works correctly regardless of the
126 * order of entries. Insert a random set of entries into @l1, and copy
127 * the same data in reverse order into @l2. Then verify a lookup of
128 * random keys will yield the same result in both sets.
129 */
130
131 for (i = 0; i < (1 << 12); ++i)
132 l1 = tlpm_add(l1, (uint8_t[]){
133 rand() % 0xff,
134 rand() % 0xff,
135 }, rand() % 16 + 1);
136
137 for (t1 = l1; t1; t1 = t1->next)
138 l2 = tlpm_add(l2, t1->key, t1->n_bits);
139
140 for (i = 0; i < (1 << 8); ++i) {
141 uint8_t key[] = { rand() % 0xff, rand() % 0xff };
142
143 t1 = tlpm_match(l1, key, 16);
144 t2 = tlpm_match(l2, key, 16);
145
146 assert(!t1 == !t2);
147 if (t1) {
148 assert(t1->n_bits == t2->n_bits);
149 for (j = 0; j < t1->n_bits; ++j)
150 assert((t1->key[j / 8] & (1 << (7 - j % 8))) ==
151 (t2->key[j / 8] & (1 << (7 - j % 8))));
152 }
153 }
154
155 tlpm_clear(l1);
156 tlpm_clear(l2);
157}
158
159static void test_lpm_map(int keysize)
160{
161 size_t i, j, n_matches, n_nodes, n_lookups;
162 struct tlpm_node *t, *list = NULL;
163 struct bpf_lpm_trie_key *key;
164 uint8_t *data, *value;
165 int r, map;
166
167 /* Compare behavior of tlpm vs. bpf-lpm. Create a randomized set of
168 * prefixes and insert it into both tlpm and bpf-lpm. Then run some
169 * randomized lookups and verify both maps return the same result.
170 */
171
172 n_matches = 0;
173 n_nodes = 1 << 8;
174 n_lookups = 1 << 16;
175
176 data = alloca(keysize);
177 memset(data, 0, keysize);
178
179 value = alloca(keysize + 1);
180 memset(value, 0, keysize + 1);
181
182 key = alloca(sizeof(*key) + keysize);
183 memset(key, 0, sizeof(*key) + keysize);
184
185 map = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE,
186 sizeof(*key) + keysize,
187 keysize + 1,
188 4096,
189 BPF_F_NO_PREALLOC);
190 assert(map >= 0);
191
192 for (i = 0; i < n_nodes; ++i) {
193 for (j = 0; j < keysize; ++j)
194 value[j] = rand() & 0xff;
195 value[keysize] = rand() % (8 * keysize + 1);
196
197 list = tlpm_add(list, value, value[keysize]);
198
199 key->prefixlen = value[keysize];
200 memcpy(key->data, value, keysize);
201 r = bpf_map_update_elem(map, key, value, 0);
202 assert(!r);
203 }
204
205 for (i = 0; i < n_lookups; ++i) {
206 for (j = 0; j < keysize; ++j)
207 data[j] = rand() & 0xff;
208
209 t = tlpm_match(list, data, 8 * keysize);
210
211 key->prefixlen = 8 * keysize;
212 memcpy(key->data, data, keysize);
213 r = bpf_map_lookup_elem(map, key, value);
214 assert(!r || errno == ENOENT);
215 assert(!t == !!r);
216
217 if (t) {
218 ++n_matches;
219 assert(t->n_bits == value[keysize]);
220 for (j = 0; j < t->n_bits; ++j)
221 assert((t->key[j / 8] & (1 << (7 - j % 8))) ==
222 (value[j / 8] & (1 << (7 - j % 8))));
223 }
224 }
225
226 close(map);
227 tlpm_clear(list);
228
229 /* With 255 random nodes in the map, we are pretty likely to match
230 * something on every lookup. For statistics, use this:
231 *
232 * printf(" nodes: %zu\n"
233 * "lookups: %zu\n"
234 * "matches: %zu\n", n_nodes, n_lookups, n_matches);
235 */
236}
237
238/* Test the implementation with some 'real world' examples */
239
240static void test_lpm_ipaddr(void)
241{
242 struct bpf_lpm_trie_key *key_ipv4;
243 struct bpf_lpm_trie_key *key_ipv6;
244 size_t key_size_ipv4;
245 size_t key_size_ipv6;
246 int map_fd_ipv4;
247 int map_fd_ipv6;
248 __u64 value;
249
250 key_size_ipv4 = sizeof(*key_ipv4) + sizeof(__u32);
251 key_size_ipv6 = sizeof(*key_ipv6) + sizeof(__u32) * 4;
252 key_ipv4 = alloca(key_size_ipv4);
253 key_ipv6 = alloca(key_size_ipv6);
254
255 map_fd_ipv4 = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE,
256 key_size_ipv4, sizeof(value),
257 100, BPF_F_NO_PREALLOC);
258 assert(map_fd_ipv4 >= 0);
259
260 map_fd_ipv6 = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE,
261 key_size_ipv6, sizeof(value),
262 100, BPF_F_NO_PREALLOC);
263 assert(map_fd_ipv6 >= 0);
264
265 /* Fill data some IPv4 and IPv6 address ranges */
266 value = 1;
267 key_ipv4->prefixlen = 16;
268 inet_pton(AF_INET, "192.168.0.0", key_ipv4->data);
269 assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
270
271 value = 2;
272 key_ipv4->prefixlen = 24;
273 inet_pton(AF_INET, "192.168.0.0", key_ipv4->data);
274 assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
275
276 value = 3;
277 key_ipv4->prefixlen = 24;
278 inet_pton(AF_INET, "192.168.128.0", key_ipv4->data);
279 assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
280
281 value = 5;
282 key_ipv4->prefixlen = 24;
283 inet_pton(AF_INET, "192.168.1.0", key_ipv4->data);
284 assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
285
286 value = 4;
287 key_ipv4->prefixlen = 23;
288 inet_pton(AF_INET, "192.168.0.0", key_ipv4->data);
289 assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
290
291 value = 0xdeadbeef;
292 key_ipv6->prefixlen = 64;
293 inet_pton(AF_INET6, "2a00:1450:4001:814::200e", key_ipv6->data);
294 assert(bpf_map_update_elem(map_fd_ipv6, key_ipv6, &value, 0) == 0);
295
296 /* Set tprefixlen to maximum for lookups */
297 key_ipv4->prefixlen = 32;
298 key_ipv6->prefixlen = 128;
299
300 /* Test some lookups that should come back with a value */
301 inet_pton(AF_INET, "192.168.128.23", key_ipv4->data);
302 assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == 0);
303 assert(value == 3);
304
305 inet_pton(AF_INET, "192.168.0.1", key_ipv4->data);
306 assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == 0);
307 assert(value == 2);
308
309 inet_pton(AF_INET6, "2a00:1450:4001:814::", key_ipv6->data);
310 assert(bpf_map_lookup_elem(map_fd_ipv6, key_ipv6, &value) == 0);
311 assert(value == 0xdeadbeef);
312
313 inet_pton(AF_INET6, "2a00:1450:4001:814::1", key_ipv6->data);
314 assert(bpf_map_lookup_elem(map_fd_ipv6, key_ipv6, &value) == 0);
315 assert(value == 0xdeadbeef);
316
317 /* Test some lookups that should not match any entry */
318 inet_pton(AF_INET, "10.0.0.1", key_ipv4->data);
319 assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == -1 &&
320 errno == ENOENT);
321
322 inet_pton(AF_INET, "11.11.11.11", key_ipv4->data);
323 assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == -1 &&
324 errno == ENOENT);
325
326 inet_pton(AF_INET6, "2a00:ffff::", key_ipv6->data);
327 assert(bpf_map_lookup_elem(map_fd_ipv6, key_ipv6, &value) == -1 &&
328 errno == ENOENT);
329
330 close(map_fd_ipv4);
331 close(map_fd_ipv6);
332}
333
334int main(void)
335{
336 struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY };
337 int i, ret;
338
339 /* we want predictable, pseudo random tests */
340 srand(0xf00ba1);
341
342 /* allow unlimited locked memory */
343 ret = setrlimit(RLIMIT_MEMLOCK, &limit);
344 if (ret < 0)
345 perror("Unable to lift memlock rlimit");
346
347 test_lpm_basic();
348 test_lpm_order();
349
350 /* Test with 8, 16, 24, 32, ... 128 bit prefix length */
351 for (i = 1; i <= 16; ++i)
352 test_lpm_map(i);
353
354 test_lpm_ipaddr();
355
356 printf("test_lpm: OK\n");
357 return 0;
358}
diff --git a/tools/testing/selftests/bpf/test_lru_map.c b/tools/testing/selftests/bpf/test_lru_map.c
index 9f7bd1915c21..00b0aff56e2e 100644
--- a/tools/testing/selftests/bpf/test_lru_map.c
+++ b/tools/testing/selftests/bpf/test_lru_map.c
@@ -18,7 +18,7 @@
18#include <sys/wait.h> 18#include <sys/wait.h>
19#include <sys/resource.h> 19#include <sys/resource.h>
20 20
21#include "bpf_sys.h" 21#include <bpf/bpf.h>
22#include "bpf_util.h" 22#include "bpf_util.h"
23 23
24#define LOCAL_FREE_TARGET (128) 24#define LOCAL_FREE_TARGET (128)
@@ -30,11 +30,11 @@ static int create_map(int map_type, int map_flags, unsigned int size)
30{ 30{
31 int map_fd; 31 int map_fd;
32 32
33 map_fd = bpf_map_create(map_type, sizeof(unsigned long long), 33 map_fd = bpf_create_map(map_type, sizeof(unsigned long long),
34 sizeof(unsigned long long), size, map_flags); 34 sizeof(unsigned long long), size, map_flags);
35 35
36 if (map_fd == -1) 36 if (map_fd == -1)
37 perror("bpf_map_create"); 37 perror("bpf_create_map");
38 38
39 return map_fd; 39 return map_fd;
40} 40}
@@ -45,9 +45,9 @@ static int map_subset(int map0, int map1)
45 unsigned long long value0[nr_cpus], value1[nr_cpus]; 45 unsigned long long value0[nr_cpus], value1[nr_cpus];
46 int ret; 46 int ret;
47 47
48 while (!bpf_map_next_key(map1, &next_key, &next_key)) { 48 while (!bpf_map_get_next_key(map1, &next_key, &next_key)) {
49 assert(!bpf_map_lookup(map1, &next_key, value1)); 49 assert(!bpf_map_lookup_elem(map1, &next_key, value1));
50 ret = bpf_map_lookup(map0, &next_key, value0); 50 ret = bpf_map_lookup_elem(map0, &next_key, value0);
51 if (ret) { 51 if (ret) {
52 printf("key:%llu not found from map. %s(%d)\n", 52 printf("key:%llu not found from map. %s(%d)\n",
53 next_key, strerror(errno), errno); 53 next_key, strerror(errno), errno);
@@ -119,52 +119,54 @@ static void test_lru_sanity0(int map_type, int map_flags)
119 /* insert key=1 element */ 119 /* insert key=1 element */
120 120
121 key = 1; 121 key = 1;
122 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 122 assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
123 assert(!bpf_map_update(expected_map_fd, &key, value, BPF_NOEXIST)); 123 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
124 BPF_NOEXIST));
124 125
125 /* BPF_NOEXIST means: add new element if it doesn't exist */ 126 /* BPF_NOEXIST means: add new element if it doesn't exist */
126 assert(bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST) == -1 && 127 assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST) == -1
127 /* key=1 already exists */ 128 /* key=1 already exists */
128 errno == EEXIST); 129 && errno == EEXIST);
129 130
130 assert(bpf_map_update(lru_map_fd, &key, value, -1) == -1 && 131 assert(bpf_map_update_elem(lru_map_fd, &key, value, -1) == -1 &&
131 errno == EINVAL); 132 errno == EINVAL);
132 133
133 /* insert key=2 element */ 134 /* insert key=2 element */
134 135
135 /* check that key=2 is not found */ 136 /* check that key=2 is not found */
136 key = 2; 137 key = 2;
137 assert(bpf_map_lookup(lru_map_fd, &key, value) == -1 && 138 assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1 &&
138 errno == ENOENT); 139 errno == ENOENT);
139 140
140 /* BPF_EXIST means: update existing element */ 141 /* BPF_EXIST means: update existing element */
141 assert(bpf_map_update(lru_map_fd, &key, value, BPF_EXIST) == -1 && 142 assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_EXIST) == -1 &&
142 /* key=2 is not there */ 143 /* key=2 is not there */
143 errno == ENOENT); 144 errno == ENOENT);
144 145
145 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 146 assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
146 147
147 /* insert key=3 element */ 148 /* insert key=3 element */
148 149
149 /* check that key=3 is not found */ 150 /* check that key=3 is not found */
150 key = 3; 151 key = 3;
151 assert(bpf_map_lookup(lru_map_fd, &key, value) == -1 && 152 assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1 &&
152 errno == ENOENT); 153 errno == ENOENT);
153 154
154 /* check that key=1 can be found and mark the ref bit to 155 /* check that key=1 can be found and mark the ref bit to
155 * stop LRU from removing key=1 156 * stop LRU from removing key=1
156 */ 157 */
157 key = 1; 158 key = 1;
158 assert(!bpf_map_lookup(lru_map_fd, &key, value)); 159 assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
159 assert(value[0] == 1234); 160 assert(value[0] == 1234);
160 161
161 key = 3; 162 key = 3;
162 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 163 assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
163 assert(!bpf_map_update(expected_map_fd, &key, value, BPF_NOEXIST)); 164 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
165 BPF_NOEXIST));
164 166
165 /* key=2 has been removed from the LRU */ 167 /* key=2 has been removed from the LRU */
166 key = 2; 168 key = 2;
167 assert(bpf_map_lookup(lru_map_fd, &key, value) == -1); 169 assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1);
168 170
169 assert(map_equal(lru_map_fd, expected_map_fd)); 171 assert(map_equal(lru_map_fd, expected_map_fd));
170 172
@@ -217,14 +219,15 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free)
217 /* Insert 1 to tgt_free (+tgt_free keys) */ 219 /* Insert 1 to tgt_free (+tgt_free keys) */
218 end_key = 1 + tgt_free; 220 end_key = 1 + tgt_free;
219 for (key = 1; key < end_key; key++) 221 for (key = 1; key < end_key; key++)
220 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 222 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
223 BPF_NOEXIST));
221 224
222 /* Lookup 1 to tgt_free/2 */ 225 /* Lookup 1 to tgt_free/2 */
223 end_key = 1 + batch_size; 226 end_key = 1 + batch_size;
224 for (key = 1; key < end_key; key++) { 227 for (key = 1; key < end_key; key++) {
225 assert(!bpf_map_lookup(lru_map_fd, &key, value)); 228 assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
226 assert(!bpf_map_update(expected_map_fd, &key, value, 229 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
227 BPF_NOEXIST)); 230 BPF_NOEXIST));
228 } 231 }
229 232
230 /* Insert 1+tgt_free to 2*tgt_free 233 /* Insert 1+tgt_free to 2*tgt_free
@@ -234,9 +237,10 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free)
234 key = 1 + tgt_free; 237 key = 1 + tgt_free;
235 end_key = key + tgt_free; 238 end_key = key + tgt_free;
236 for (; key < end_key; key++) { 239 for (; key < end_key; key++) {
237 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 240 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
238 assert(!bpf_map_update(expected_map_fd, &key, value, 241 BPF_NOEXIST));
239 BPF_NOEXIST)); 242 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
243 BPF_NOEXIST));
240 } 244 }
241 245
242 assert(map_equal(lru_map_fd, expected_map_fd)); 246 assert(map_equal(lru_map_fd, expected_map_fd));
@@ -301,9 +305,10 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
301 /* Insert 1 to tgt_free (+tgt_free keys) */ 305 /* Insert 1 to tgt_free (+tgt_free keys) */
302 end_key = 1 + tgt_free; 306 end_key = 1 + tgt_free;
303 for (key = 1; key < end_key; key++) 307 for (key = 1; key < end_key; key++)
304 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 308 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
309 BPF_NOEXIST));
305 310
306 /* Any bpf_map_update will require to acquire a new node 311 /* Any bpf_map_update_elem will require to acquire a new node
307 * from LRU first. 312 * from LRU first.
308 * 313 *
309 * The local list is running out of free nodes. 314 * The local list is running out of free nodes.
@@ -316,10 +321,12 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
316 */ 321 */
317 key = 1; 322 key = 1;
318 if (map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { 323 if (map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
319 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 324 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
320 assert(!bpf_map_delete(lru_map_fd, &key)); 325 BPF_NOEXIST));
326 assert(!bpf_map_delete_elem(lru_map_fd, &key));
321 } else { 327 } else {
322 assert(bpf_map_update(lru_map_fd, &key, value, BPF_EXIST)); 328 assert(bpf_map_update_elem(lru_map_fd, &key, value,
329 BPF_EXIST));
323 } 330 }
324 331
325 /* Re-insert 1 to tgt_free/2 again and do a lookup 332 /* Re-insert 1 to tgt_free/2 again and do a lookup
@@ -328,12 +335,13 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
328 end_key = 1 + batch_size; 335 end_key = 1 + batch_size;
329 value[0] = 4321; 336 value[0] = 4321;
330 for (key = 1; key < end_key; key++) { 337 for (key = 1; key < end_key; key++) {
331 assert(bpf_map_lookup(lru_map_fd, &key, value)); 338 assert(bpf_map_lookup_elem(lru_map_fd, &key, value));
332 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 339 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
333 assert(!bpf_map_lookup(lru_map_fd, &key, value)); 340 BPF_NOEXIST));
341 assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
334 assert(value[0] == 4321); 342 assert(value[0] == 4321);
335 assert(!bpf_map_update(expected_map_fd, &key, value, 343 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
336 BPF_NOEXIST)); 344 BPF_NOEXIST));
337 } 345 }
338 346
339 value[0] = 1234; 347 value[0] = 1234;
@@ -344,14 +352,16 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
344 /* These newly added but not referenced keys will be 352 /* These newly added but not referenced keys will be
345 * gone during the next LRU shrink. 353 * gone during the next LRU shrink.
346 */ 354 */
347 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 355 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
356 BPF_NOEXIST));
348 357
349 /* Insert 1+tgt_free*3/2 to tgt_free*5/2 */ 358 /* Insert 1+tgt_free*3/2 to tgt_free*5/2 */
350 end_key = key + tgt_free; 359 end_key = key + tgt_free;
351 for (; key < end_key; key++) { 360 for (; key < end_key; key++) {
352 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 361 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
353 assert(!bpf_map_update(expected_map_fd, &key, value, 362 BPF_NOEXIST));
354 BPF_NOEXIST)); 363 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
364 BPF_NOEXIST));
355 } 365 }
356 366
357 assert(map_equal(lru_map_fd, expected_map_fd)); 367 assert(map_equal(lru_map_fd, expected_map_fd));
@@ -401,14 +411,15 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
401 /* Insert 1 to 2*tgt_free (+2*tgt_free keys) */ 411 /* Insert 1 to 2*tgt_free (+2*tgt_free keys) */
402 end_key = 1 + (2 * tgt_free); 412 end_key = 1 + (2 * tgt_free);
403 for (key = 1; key < end_key; key++) 413 for (key = 1; key < end_key; key++)
404 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 414 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
415 BPF_NOEXIST));
405 416
406 /* Lookup key 1 to tgt_free*3/2 */ 417 /* Lookup key 1 to tgt_free*3/2 */
407 end_key = tgt_free + batch_size; 418 end_key = tgt_free + batch_size;
408 for (key = 1; key < end_key; key++) { 419 for (key = 1; key < end_key; key++) {
409 assert(!bpf_map_lookup(lru_map_fd, &key, value)); 420 assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
410 assert(!bpf_map_update(expected_map_fd, &key, value, 421 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
411 BPF_NOEXIST)); 422 BPF_NOEXIST));
412 } 423 }
413 424
414 /* Add 1+2*tgt_free to tgt_free*5/2 425 /* Add 1+2*tgt_free to tgt_free*5/2
@@ -417,9 +428,10 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
417 key = 2 * tgt_free + 1; 428 key = 2 * tgt_free + 1;
418 end_key = key + batch_size; 429 end_key = key + batch_size;
419 for (; key < end_key; key++) { 430 for (; key < end_key; key++) {
420 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 431 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
421 assert(!bpf_map_update(expected_map_fd, &key, value, 432 BPF_NOEXIST));
422 BPF_NOEXIST)); 433 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
434 BPF_NOEXIST));
423 } 435 }
424 436
425 assert(map_equal(lru_map_fd, expected_map_fd)); 437 assert(map_equal(lru_map_fd, expected_map_fd));
@@ -457,27 +469,29 @@ static void test_lru_sanity4(int map_type, int map_flags, unsigned int tgt_free)
457 value[0] = 1234; 469 value[0] = 1234;
458 470
459 for (key = 1; key <= 2 * tgt_free; key++) 471 for (key = 1; key <= 2 * tgt_free; key++)
460 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 472 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
473 BPF_NOEXIST));
461 474
462 key = 1; 475 key = 1;
463 assert(bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 476 assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
464 477
465 for (key = 1; key <= tgt_free; key++) { 478 for (key = 1; key <= tgt_free; key++) {
466 assert(!bpf_map_lookup(lru_map_fd, &key, value)); 479 assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
467 assert(!bpf_map_update(expected_map_fd, &key, value, 480 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
468 BPF_NOEXIST)); 481 BPF_NOEXIST));
469 } 482 }
470 483
471 for (; key <= 2 * tgt_free; key++) { 484 for (; key <= 2 * tgt_free; key++) {
472 assert(!bpf_map_delete(lru_map_fd, &key)); 485 assert(!bpf_map_delete_elem(lru_map_fd, &key));
473 assert(bpf_map_delete(lru_map_fd, &key)); 486 assert(bpf_map_delete_elem(lru_map_fd, &key));
474 } 487 }
475 488
476 end_key = key + 2 * tgt_free; 489 end_key = key + 2 * tgt_free;
477 for (; key < end_key; key++) { 490 for (; key < end_key; key++) {
478 assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST)); 491 assert(!bpf_map_update_elem(lru_map_fd, &key, value,
479 assert(!bpf_map_update(expected_map_fd, &key, value, 492 BPF_NOEXIST));
480 BPF_NOEXIST)); 493 assert(!bpf_map_update_elem(expected_map_fd, &key, value,
494 BPF_NOEXIST));
481 } 495 }
482 496
483 assert(map_equal(lru_map_fd, expected_map_fd)); 497 assert(map_equal(lru_map_fd, expected_map_fd));
@@ -493,16 +507,16 @@ static void do_test_lru_sanity5(unsigned long long last_key, int map_fd)
493 unsigned long long key, value[nr_cpus]; 507 unsigned long long key, value[nr_cpus];
494 508
495 /* Ensure the last key inserted by previous CPU can be found */ 509 /* Ensure the last key inserted by previous CPU can be found */
496 assert(!bpf_map_lookup(map_fd, &last_key, value)); 510 assert(!bpf_map_lookup_elem(map_fd, &last_key, value));
497 511
498 value[0] = 1234; 512 value[0] = 1234;
499 513
500 key = last_key + 1; 514 key = last_key + 1;
501 assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST)); 515 assert(!bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST));
502 assert(!bpf_map_lookup(map_fd, &key, value)); 516 assert(!bpf_map_lookup_elem(map_fd, &key, value));
503 517
504 /* Cannot find the last key because it was removed by LRU */ 518 /* Cannot find the last key because it was removed by LRU */
505 assert(bpf_map_lookup(map_fd, &last_key, value)); 519 assert(bpf_map_lookup_elem(map_fd, &last_key, value));
506} 520}
507 521
508/* Test map with only one element */ 522/* Test map with only one element */
@@ -523,7 +537,7 @@ static void test_lru_sanity5(int map_type, int map_flags)
523 537
524 value[0] = 1234; 538 value[0] = 1234;
525 key = 0; 539 key = 0;
526 assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST)); 540 assert(!bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST));
527 541
528 while (sched_next_online(0, &next_cpu) != -1) { 542 while (sched_next_online(0, &next_cpu) != -1) {
529 pid_t pid; 543 pid_t pid;
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index eedfef8d2946..cada17ac00b8 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -21,7 +21,7 @@
21 21
22#include <linux/bpf.h> 22#include <linux/bpf.h>
23 23
24#include "bpf_sys.h" 24#include <bpf/bpf.h>
25#include "bpf_util.h" 25#include "bpf_util.h"
26 26
27static int map_flags; 27static int map_flags;
@@ -31,7 +31,7 @@ static void test_hashmap(int task, void *data)
31 long long key, next_key, value; 31 long long key, next_key, value;
32 int fd; 32 int fd;
33 33
34 fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), 34 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
35 2, map_flags); 35 2, map_flags);
36 if (fd < 0) { 36 if (fd < 0) {
37 printf("Failed to create hashmap '%s'!\n", strerror(errno)); 37 printf("Failed to create hashmap '%s'!\n", strerror(errno));
@@ -41,69 +41,70 @@ static void test_hashmap(int task, void *data)
41 key = 1; 41 key = 1;
42 value = 1234; 42 value = 1234;
43 /* Insert key=1 element. */ 43 /* Insert key=1 element. */
44 assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0); 44 assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
45 45
46 value = 0; 46 value = 0;
47 /* BPF_NOEXIST means add new element if it doesn't exist. */ 47 /* BPF_NOEXIST means add new element if it doesn't exist. */
48 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 && 48 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
49 /* key=1 already exists. */ 49 /* key=1 already exists. */
50 errno == EEXIST); 50 errno == EEXIST);
51 51
52 /* -1 is an invalid flag. */ 52 /* -1 is an invalid flag. */
53 assert(bpf_map_update(fd, &key, &value, -1) == -1 && errno == EINVAL); 53 assert(bpf_map_update_elem(fd, &key, &value, -1) == -1 &&
54 errno == EINVAL);
54 55
55 /* Check that key=1 can be found. */ 56 /* Check that key=1 can be found. */
56 assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 1234); 57 assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
57 58
58 key = 2; 59 key = 2;
59 /* Check that key=2 is not found. */ 60 /* Check that key=2 is not found. */
60 assert(bpf_map_lookup(fd, &key, &value) == -1 && errno == ENOENT); 61 assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
61 62
62 /* BPF_EXIST means update existing element. */ 63 /* BPF_EXIST means update existing element. */
63 assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == -1 && 64 assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == -1 &&
64 /* key=2 is not there. */ 65 /* key=2 is not there. */
65 errno == ENOENT); 66 errno == ENOENT);
66 67
67 /* Insert key=2 element. */ 68 /* Insert key=2 element. */
68 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == 0); 69 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
69 70
70 /* key=1 and key=2 were inserted, check that key=0 cannot be 71 /* key=1 and key=2 were inserted, check that key=0 cannot be
71 * inserted due to max_entries limit. 72 * inserted due to max_entries limit.
72 */ 73 */
73 key = 0; 74 key = 0;
74 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 && 75 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
75 errno == E2BIG); 76 errno == E2BIG);
76 77
77 /* Update existing element, though the map is full. */ 78 /* Update existing element, though the map is full. */
78 key = 1; 79 key = 1;
79 assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == 0); 80 assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
80 key = 2; 81 key = 2;
81 assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0); 82 assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
82 key = 1; 83 key = 1;
83 assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0); 84 assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
84 85
85 /* Check that key = 0 doesn't exist. */ 86 /* Check that key = 0 doesn't exist. */
86 key = 0; 87 key = 0;
87 assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT); 88 assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
88 89
89 /* Iterate over two elements. */ 90 /* Iterate over two elements. */
90 assert(bpf_map_next_key(fd, &key, &next_key) == 0 && 91 assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
91 (next_key == 1 || next_key == 2)); 92 (next_key == 1 || next_key == 2));
92 assert(bpf_map_next_key(fd, &next_key, &next_key) == 0 && 93 assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
93 (next_key == 1 || next_key == 2)); 94 (next_key == 1 || next_key == 2));
94 assert(bpf_map_next_key(fd, &next_key, &next_key) == -1 && 95 assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
95 errno == ENOENT); 96 errno == ENOENT);
96 97
97 /* Delete both elements. */ 98 /* Delete both elements. */
98 key = 1; 99 key = 1;
99 assert(bpf_map_delete(fd, &key) == 0); 100 assert(bpf_map_delete_elem(fd, &key) == 0);
100 key = 2; 101 key = 2;
101 assert(bpf_map_delete(fd, &key) == 0); 102 assert(bpf_map_delete_elem(fd, &key) == 0);
102 assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT); 103 assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
103 104
104 key = 0; 105 key = 0;
105 /* Check that map is empty. */ 106 /* Check that map is empty. */
106 assert(bpf_map_next_key(fd, &key, &next_key) == -1 && 107 assert(bpf_map_get_next_key(fd, &key, &next_key) == -1 &&
107 errno == ENOENT); 108 errno == ENOENT);
108 109
109 close(fd); 110 close(fd);
@@ -117,7 +118,7 @@ static void test_hashmap_percpu(int task, void *data)
117 int expected_key_mask = 0; 118 int expected_key_mask = 0;
118 int fd, i; 119 int fd, i;
119 120
120 fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key), 121 fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
121 sizeof(value[0]), 2, map_flags); 122 sizeof(value[0]), 2, map_flags);
122 if (fd < 0) { 123 if (fd < 0) {
123 printf("Failed to create hashmap '%s'!\n", strerror(errno)); 124 printf("Failed to create hashmap '%s'!\n", strerror(errno));
@@ -130,53 +131,54 @@ static void test_hashmap_percpu(int task, void *data)
130 key = 1; 131 key = 1;
131 /* Insert key=1 element. */ 132 /* Insert key=1 element. */
132 assert(!(expected_key_mask & key)); 133 assert(!(expected_key_mask & key));
133 assert(bpf_map_update(fd, &key, value, BPF_ANY) == 0); 134 assert(bpf_map_update_elem(fd, &key, value, BPF_ANY) == 0);
134 expected_key_mask |= key; 135 expected_key_mask |= key;
135 136
136 /* BPF_NOEXIST means add new element if it doesn't exist. */ 137 /* BPF_NOEXIST means add new element if it doesn't exist. */
137 assert(bpf_map_update(fd, &key, value, BPF_NOEXIST) == -1 && 138 assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == -1 &&
138 /* key=1 already exists. */ 139 /* key=1 already exists. */
139 errno == EEXIST); 140 errno == EEXIST);
140 141
141 /* -1 is an invalid flag. */ 142 /* -1 is an invalid flag. */
142 assert(bpf_map_update(fd, &key, value, -1) == -1 && errno == EINVAL); 143 assert(bpf_map_update_elem(fd, &key, value, -1) == -1 &&
144 errno == EINVAL);
143 145
144 /* Check that key=1 can be found. Value could be 0 if the lookup 146 /* Check that key=1 can be found. Value could be 0 if the lookup
145 * was run from a different CPU. 147 * was run from a different CPU.
146 */ 148 */
147 value[0] = 1; 149 value[0] = 1;
148 assert(bpf_map_lookup(fd, &key, value) == 0 && value[0] == 100); 150 assert(bpf_map_lookup_elem(fd, &key, value) == 0 && value[0] == 100);
149 151
150 key = 2; 152 key = 2;
151 /* Check that key=2 is not found. */ 153 /* Check that key=2 is not found. */
152 assert(bpf_map_lookup(fd, &key, value) == -1 && errno == ENOENT); 154 assert(bpf_map_lookup_elem(fd, &key, value) == -1 && errno == ENOENT);
153 155
154 /* BPF_EXIST means update existing element. */ 156 /* BPF_EXIST means update existing element. */
155 assert(bpf_map_update(fd, &key, value, BPF_EXIST) == -1 && 157 assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == -1 &&
156 /* key=2 is not there. */ 158 /* key=2 is not there. */
157 errno == ENOENT); 159 errno == ENOENT);
158 160
159 /* Insert key=2 element. */ 161 /* Insert key=2 element. */
160 assert(!(expected_key_mask & key)); 162 assert(!(expected_key_mask & key));
161 assert(bpf_map_update(fd, &key, value, BPF_NOEXIST) == 0); 163 assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
162 expected_key_mask |= key; 164 expected_key_mask |= key;
163 165
164 /* key=1 and key=2 were inserted, check that key=0 cannot be 166 /* key=1 and key=2 were inserted, check that key=0 cannot be
165 * inserted due to max_entries limit. 167 * inserted due to max_entries limit.
166 */ 168 */
167 key = 0; 169 key = 0;
168 assert(bpf_map_update(fd, &key, value, BPF_NOEXIST) == -1 && 170 assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == -1 &&
169 errno == E2BIG); 171 errno == E2BIG);
170 172
171 /* Check that key = 0 doesn't exist. */ 173 /* Check that key = 0 doesn't exist. */
172 assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT); 174 assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
173 175
174 /* Iterate over two elements. */ 176 /* Iterate over two elements. */
175 while (!bpf_map_next_key(fd, &key, &next_key)) { 177 while (!bpf_map_get_next_key(fd, &key, &next_key)) {
176 assert((expected_key_mask & next_key) == next_key); 178 assert((expected_key_mask & next_key) == next_key);
177 expected_key_mask &= ~next_key; 179 expected_key_mask &= ~next_key;
178 180
179 assert(bpf_map_lookup(fd, &next_key, value) == 0); 181 assert(bpf_map_lookup_elem(fd, &next_key, value) == 0);
180 182
181 for (i = 0; i < nr_cpus; i++) 183 for (i = 0; i < nr_cpus; i++)
182 assert(value[i] == i + 100); 184 assert(value[i] == i + 100);
@@ -187,18 +189,18 @@ static void test_hashmap_percpu(int task, void *data)
187 189
188 /* Update with BPF_EXIST. */ 190 /* Update with BPF_EXIST. */
189 key = 1; 191 key = 1;
190 assert(bpf_map_update(fd, &key, value, BPF_EXIST) == 0); 192 assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == 0);
191 193
192 /* Delete both elements. */ 194 /* Delete both elements. */
193 key = 1; 195 key = 1;
194 assert(bpf_map_delete(fd, &key) == 0); 196 assert(bpf_map_delete_elem(fd, &key) == 0);
195 key = 2; 197 key = 2;
196 assert(bpf_map_delete(fd, &key) == 0); 198 assert(bpf_map_delete_elem(fd, &key) == 0);
197 assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT); 199 assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
198 200
199 key = 0; 201 key = 0;
200 /* Check that map is empty. */ 202 /* Check that map is empty. */
201 assert(bpf_map_next_key(fd, &key, &next_key) == -1 && 203 assert(bpf_map_get_next_key(fd, &key, &next_key) == -1 &&
202 errno == ENOENT); 204 errno == ENOENT);
203 205
204 close(fd); 206 close(fd);
@@ -209,7 +211,7 @@ static void test_arraymap(int task, void *data)
209 int key, next_key, fd; 211 int key, next_key, fd;
210 long long value; 212 long long value;
211 213
212 fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value), 214 fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value),
213 2, 0); 215 2, 0);
214 if (fd < 0) { 216 if (fd < 0) {
215 printf("Failed to create arraymap '%s'!\n", strerror(errno)); 217 printf("Failed to create arraymap '%s'!\n", strerror(errno));
@@ -219,40 +221,40 @@ static void test_arraymap(int task, void *data)
219 key = 1; 221 key = 1;
220 value = 1234; 222 value = 1234;
221 /* Insert key=1 element. */ 223 /* Insert key=1 element. */
222 assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0); 224 assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
223 225
224 value = 0; 226 value = 0;
225 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 && 227 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
226 errno == EEXIST); 228 errno == EEXIST);
227 229
228 /* Check that key=1 can be found. */ 230 /* Check that key=1 can be found. */
229 assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 1234); 231 assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
230 232
231 key = 0; 233 key = 0;
232 /* Check that key=0 is also found and zero initialized. */ 234 /* Check that key=0 is also found and zero initialized. */
233 assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 0); 235 assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
234 236
235 /* key=0 and key=1 were inserted, check that key=2 cannot be inserted 237 /* key=0 and key=1 were inserted, check that key=2 cannot be inserted
236 * due to max_entries limit. 238 * due to max_entries limit.
237 */ 239 */
238 key = 2; 240 key = 2;
239 assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == -1 && 241 assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == -1 &&
240 errno == E2BIG); 242 errno == E2BIG);
241 243
242 /* Check that key = 2 doesn't exist. */ 244 /* Check that key = 2 doesn't exist. */
243 assert(bpf_map_lookup(fd, &key, &value) == -1 && errno == ENOENT); 245 assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
244 246
245 /* Iterate over two elements. */ 247 /* Iterate over two elements. */
246 assert(bpf_map_next_key(fd, &key, &next_key) == 0 && 248 assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
247 next_key == 0); 249 next_key == 0);
248 assert(bpf_map_next_key(fd, &next_key, &next_key) == 0 && 250 assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
249 next_key == 1); 251 next_key == 1);
250 assert(bpf_map_next_key(fd, &next_key, &next_key) == -1 && 252 assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
251 errno == ENOENT); 253 errno == ENOENT);
252 254
253 /* Delete shouldn't succeed. */ 255 /* Delete shouldn't succeed. */
254 key = 1; 256 key = 1;
255 assert(bpf_map_delete(fd, &key) == -1 && errno == EINVAL); 257 assert(bpf_map_delete_elem(fd, &key) == -1 && errno == EINVAL);
256 258
257 close(fd); 259 close(fd);
258} 260}
@@ -263,7 +265,7 @@ static void test_arraymap_percpu(int task, void *data)
263 int key, next_key, fd, i; 265 int key, next_key, fd, i;
264 long values[nr_cpus]; 266 long values[nr_cpus];
265 267
266 fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key), 268 fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
267 sizeof(values[0]), 2, 0); 269 sizeof(values[0]), 2, 0);
268 if (fd < 0) { 270 if (fd < 0) {
269 printf("Failed to create arraymap '%s'!\n", strerror(errno)); 271 printf("Failed to create arraymap '%s'!\n", strerror(errno));
@@ -275,39 +277,39 @@ static void test_arraymap_percpu(int task, void *data)
275 277
276 key = 1; 278 key = 1;
277 /* Insert key=1 element. */ 279 /* Insert key=1 element. */
278 assert(bpf_map_update(fd, &key, values, BPF_ANY) == 0); 280 assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
279 281
280 values[0] = 0; 282 values[0] = 0;
281 assert(bpf_map_update(fd, &key, values, BPF_NOEXIST) == -1 && 283 assert(bpf_map_update_elem(fd, &key, values, BPF_NOEXIST) == -1 &&
282 errno == EEXIST); 284 errno == EEXIST);
283 285
284 /* Check that key=1 can be found. */ 286 /* Check that key=1 can be found. */
285 assert(bpf_map_lookup(fd, &key, values) == 0 && values[0] == 100); 287 assert(bpf_map_lookup_elem(fd, &key, values) == 0 && values[0] == 100);
286 288
287 key = 0; 289 key = 0;
288 /* Check that key=0 is also found and zero initialized. */ 290 /* Check that key=0 is also found and zero initialized. */
289 assert(bpf_map_lookup(fd, &key, values) == 0 && 291 assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
290 values[0] == 0 && values[nr_cpus - 1] == 0); 292 values[0] == 0 && values[nr_cpus - 1] == 0);
291 293
292 /* Check that key=2 cannot be inserted due to max_entries limit. */ 294 /* Check that key=2 cannot be inserted due to max_entries limit. */
293 key = 2; 295 key = 2;
294 assert(bpf_map_update(fd, &key, values, BPF_EXIST) == -1 && 296 assert(bpf_map_update_elem(fd, &key, values, BPF_EXIST) == -1 &&
295 errno == E2BIG); 297 errno == E2BIG);
296 298
297 /* Check that key = 2 doesn't exist. */ 299 /* Check that key = 2 doesn't exist. */
298 assert(bpf_map_lookup(fd, &key, values) == -1 && errno == ENOENT); 300 assert(bpf_map_lookup_elem(fd, &key, values) == -1 && errno == ENOENT);
299 301
300 /* Iterate over two elements. */ 302 /* Iterate over two elements. */
301 assert(bpf_map_next_key(fd, &key, &next_key) == 0 && 303 assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
302 next_key == 0); 304 next_key == 0);
303 assert(bpf_map_next_key(fd, &next_key, &next_key) == 0 && 305 assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
304 next_key == 1); 306 next_key == 1);
305 assert(bpf_map_next_key(fd, &next_key, &next_key) == -1 && 307 assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
306 errno == ENOENT); 308 errno == ENOENT);
307 309
308 /* Delete shouldn't succeed. */ 310 /* Delete shouldn't succeed. */
309 key = 1; 311 key = 1;
310 assert(bpf_map_delete(fd, &key) == -1 && errno == EINVAL); 312 assert(bpf_map_delete_elem(fd, &key) == -1 && errno == EINVAL);
311 313
312 close(fd); 314 close(fd);
313} 315}
@@ -319,7 +321,7 @@ static void test_arraymap_percpu_many_keys(void)
319 long values[nr_cpus]; 321 long values[nr_cpus];
320 int key, fd, i; 322 int key, fd, i;
321 323
322 fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key), 324 fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
323 sizeof(values[0]), nr_keys, 0); 325 sizeof(values[0]), nr_keys, 0);
324 if (fd < 0) { 326 if (fd < 0) {
325 printf("Failed to create per-cpu arraymap '%s'!\n", 327 printf("Failed to create per-cpu arraymap '%s'!\n",
@@ -331,13 +333,13 @@ static void test_arraymap_percpu_many_keys(void)
331 values[i] = i + 10; 333 values[i] = i + 10;
332 334
333 for (key = 0; key < nr_keys; key++) 335 for (key = 0; key < nr_keys; key++)
334 assert(bpf_map_update(fd, &key, values, BPF_ANY) == 0); 336 assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
335 337
336 for (key = 0; key < nr_keys; key++) { 338 for (key = 0; key < nr_keys; key++) {
337 for (i = 0; i < nr_cpus; i++) 339 for (i = 0; i < nr_cpus; i++)
338 values[i] = 0; 340 values[i] = 0;
339 341
340 assert(bpf_map_lookup(fd, &key, values) == 0); 342 assert(bpf_map_lookup_elem(fd, &key, values) == 0);
341 343
342 for (i = 0; i < nr_cpus; i++) 344 for (i = 0; i < nr_cpus; i++)
343 assert(values[i] == i + 10); 345 assert(values[i] == i + 10);
@@ -357,7 +359,7 @@ static void test_map_large(void)
357 } key; 359 } key;
358 int fd, i, value; 360 int fd, i, value;
359 361
360 fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), 362 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
361 MAP_SIZE, map_flags); 363 MAP_SIZE, map_flags);
362 if (fd < 0) { 364 if (fd < 0) {
363 printf("Failed to create large map '%s'!\n", strerror(errno)); 365 printf("Failed to create large map '%s'!\n", strerror(errno));
@@ -368,22 +370,22 @@ static void test_map_large(void)
368 key = (struct bigkey) { .c = i }; 370 key = (struct bigkey) { .c = i };
369 value = i; 371 value = i;
370 372
371 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == 0); 373 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
372 } 374 }
373 375
374 key.c = -1; 376 key.c = -1;
375 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 && 377 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
376 errno == E2BIG); 378 errno == E2BIG);
377 379
378 /* Iterate through all elements. */ 380 /* Iterate through all elements. */
379 for (i = 0; i < MAP_SIZE; i++) 381 for (i = 0; i < MAP_SIZE; i++)
380 assert(bpf_map_next_key(fd, &key, &key) == 0); 382 assert(bpf_map_get_next_key(fd, &key, &key) == 0);
381 assert(bpf_map_next_key(fd, &key, &key) == -1 && errno == ENOENT); 383 assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
382 384
383 key.c = 0; 385 key.c = 0;
384 assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 0); 386 assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
385 key.a = 1; 387 key.a = 1;
386 assert(bpf_map_lookup(fd, &key, &value) == -1 && errno == ENOENT); 388 assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
387 389
388 close(fd); 390 close(fd);
389} 391}
@@ -437,10 +439,12 @@ static void do_work(int fn, void *data)
437 key = value = i; 439 key = value = i;
438 440
439 if (do_update) { 441 if (do_update) {
440 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == 0); 442 assert(bpf_map_update_elem(fd, &key, &value,
441 assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == 0); 443 BPF_NOEXIST) == 0);
444 assert(bpf_map_update_elem(fd, &key, &value,
445 BPF_EXIST) == 0);
442 } else { 446 } else {
443 assert(bpf_map_delete(fd, &key) == 0); 447 assert(bpf_map_delete_elem(fd, &key) == 0);
444 } 448 }
445 } 449 }
446} 450}
@@ -450,7 +454,7 @@ static void test_map_parallel(void)
450 int i, fd, key = 0, value = 0; 454 int i, fd, key = 0, value = 0;
451 int data[2]; 455 int data[2];
452 456
453 fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value), 457 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
454 MAP_SIZE, map_flags); 458 MAP_SIZE, map_flags);
455 if (fd < 0) { 459 if (fd < 0) {
456 printf("Failed to create map for parallel test '%s'!\n", 460 printf("Failed to create map for parallel test '%s'!\n",
@@ -468,20 +472,20 @@ static void test_map_parallel(void)
468 run_parallel(TASKS, do_work, data); 472 run_parallel(TASKS, do_work, data);
469 473
470 /* Check that key=0 is already there. */ 474 /* Check that key=0 is already there. */
471 assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 && 475 assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
472 errno == EEXIST); 476 errno == EEXIST);
473 477
474 /* Check that all elements were inserted. */ 478 /* Check that all elements were inserted. */
475 key = -1; 479 key = -1;
476 for (i = 0; i < MAP_SIZE; i++) 480 for (i = 0; i < MAP_SIZE; i++)
477 assert(bpf_map_next_key(fd, &key, &key) == 0); 481 assert(bpf_map_get_next_key(fd, &key, &key) == 0);
478 assert(bpf_map_next_key(fd, &key, &key) == -1 && errno == ENOENT); 482 assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
479 483
480 /* Another check for all elements */ 484 /* Another check for all elements */
481 for (i = 0; i < MAP_SIZE; i++) { 485 for (i = 0; i < MAP_SIZE; i++) {
482 key = MAP_SIZE - i - 1; 486 key = MAP_SIZE - i - 1;
483 487
484 assert(bpf_map_lookup(fd, &key, &value) == 0 && 488 assert(bpf_map_lookup_elem(fd, &key, &value) == 0 &&
485 value == key); 489 value == key);
486 } 490 }
487 491
@@ -491,7 +495,7 @@ static void test_map_parallel(void)
491 495
492 /* Nothing should be left. */ 496 /* Nothing should be left. */
493 key = -1; 497 key = -1;
494 assert(bpf_map_next_key(fd, &key, &key) == -1 && errno == ENOENT); 498 assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
495} 499}
496 500
497static void run_all_tests(void) 501static void run_all_tests(void)
diff --git a/tools/testing/selftests/bpf/test_tag.c b/tools/testing/selftests/bpf/test_tag.c
new file mode 100644
index 000000000000..de409fc50c35
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_tag.c
@@ -0,0 +1,203 @@
1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <ctype.h>
5#include <time.h>
6#include <errno.h>
7#include <unistd.h>
8#include <string.h>
9#include <sched.h>
10#include <limits.h>
11#include <assert.h>
12
13#include <sys/socket.h>
14#include <sys/resource.h>
15
16#include <linux/filter.h>
17#include <linux/bpf.h>
18#include <linux/if_alg.h>
19
20#include <bpf/bpf.h>
21
22#include "../../../include/linux/filter.h"
23
24static struct bpf_insn prog[BPF_MAXINSNS];
25
26static void bpf_gen_imm_prog(unsigned int insns, int fd_map)
27{
28 int i;
29
30 srand(time(NULL));
31 for (i = 0; i < insns; i++)
32 prog[i] = BPF_ALU64_IMM(BPF_MOV, i % BPF_REG_10, rand());
33 prog[i - 1] = BPF_EXIT_INSN();
34}
35
36static void bpf_gen_map_prog(unsigned int insns, int fd_map)
37{
38 int i, j = 0;
39
40 for (i = 0; i + 1 < insns; i += 2) {
41 struct bpf_insn tmp[] = {
42 BPF_LD_MAP_FD(j++ % BPF_REG_10, fd_map)
43 };
44
45 memcpy(&prog[i], tmp, sizeof(tmp));
46 }
47 if (insns % 2 == 0)
48 prog[insns - 2] = BPF_ALU64_IMM(BPF_MOV, i % BPF_REG_10, 42);
49 prog[insns - 1] = BPF_EXIT_INSN();
50}
51
52static int bpf_try_load_prog(int insns, int fd_map,
53 void (*bpf_filler)(unsigned int insns,
54 int fd_map))
55{
56 int fd_prog;
57
58 bpf_filler(insns, fd_map);
59 fd_prog = bpf_load_program(BPF_PROG_TYPE_SCHED_CLS, prog, insns, "", 0,
60 NULL, 0);
61 assert(fd_prog > 0);
62 if (fd_map > 0)
63 bpf_filler(insns, 0);
64 return fd_prog;
65}
66
67static int __hex2bin(char ch)
68{
69 if ((ch >= '0') && (ch <= '9'))
70 return ch - '0';
71 ch = tolower(ch);
72 if ((ch >= 'a') && (ch <= 'f'))
73 return ch - 'a' + 10;
74 return -1;
75}
76
77static int hex2bin(uint8_t *dst, const char *src, size_t count)
78{
79 while (count--) {
80 int hi = __hex2bin(*src++);
81 int lo = __hex2bin(*src++);
82
83 if ((hi < 0) || (lo < 0))
84 return -1;
85 *dst++ = (hi << 4) | lo;
86 }
87 return 0;
88}
89
90static void tag_from_fdinfo(int fd_prog, uint8_t *tag, uint32_t len)
91{
92 const int prefix_len = sizeof("prog_tag:\t") - 1;
93 char buff[256];
94 int ret = -1;
95 FILE *fp;
96
97 snprintf(buff, sizeof(buff), "/proc/%d/fdinfo/%d", getpid(),
98 fd_prog);
99 fp = fopen(buff, "r");
100 assert(fp);
101
102 while (fgets(buff, sizeof(buff), fp)) {
103 if (strncmp(buff, "prog_tag:\t", prefix_len))
104 continue;
105 ret = hex2bin(tag, buff + prefix_len, len);
106 break;
107 }
108
109 fclose(fp);
110 assert(!ret);
111}
112
113static void tag_from_alg(int insns, uint8_t *tag, uint32_t len)
114{
115 static const struct sockaddr_alg alg = {
116 .salg_family = AF_ALG,
117 .salg_type = "hash",
118 .salg_name = "sha1",
119 };
120 int fd_base, fd_alg, ret;
121 ssize_t size;
122
123 fd_base = socket(AF_ALG, SOCK_SEQPACKET, 0);
124 assert(fd_base > 0);
125
126 ret = bind(fd_base, (struct sockaddr *)&alg, sizeof(alg));
127 assert(!ret);
128
129 fd_alg = accept(fd_base, NULL, 0);
130 assert(fd_alg > 0);
131
132 insns *= sizeof(struct bpf_insn);
133 size = write(fd_alg, prog, insns);
134 assert(size == insns);
135
136 size = read(fd_alg, tag, len);
137 assert(size == len);
138
139 close(fd_alg);
140 close(fd_base);
141}
142
143static void tag_dump(const char *prefix, uint8_t *tag, uint32_t len)
144{
145 int i;
146
147 printf("%s", prefix);
148 for (i = 0; i < len; i++)
149 printf("%02x", tag[i]);
150 printf("\n");
151}
152
153static void tag_exit_report(int insns, int fd_map, uint8_t *ftag,
154 uint8_t *atag, uint32_t len)
155{
156 printf("Program tag mismatch for %d insns%s!\n", insns,
157 fd_map < 0 ? "" : " with map");
158
159 tag_dump(" fdinfo result: ", ftag, len);
160 tag_dump(" af_alg result: ", atag, len);
161 exit(1);
162}
163
164static void do_test(uint32_t *tests, int start_insns, int fd_map,
165 void (*bpf_filler)(unsigned int insns, int fd))
166{
167 int i, fd_prog;
168
169 for (i = start_insns; i <= BPF_MAXINSNS; i++) {
170 uint8_t ftag[8], atag[sizeof(ftag)];
171
172 fd_prog = bpf_try_load_prog(i, fd_map, bpf_filler);
173 tag_from_fdinfo(fd_prog, ftag, sizeof(ftag));
174 tag_from_alg(i, atag, sizeof(atag));
175 if (memcmp(ftag, atag, sizeof(ftag)))
176 tag_exit_report(i, fd_map, ftag, atag, sizeof(ftag));
177
178 close(fd_prog);
179 sched_yield();
180 (*tests)++;
181 }
182}
183
184int main(void)
185{
186 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
187 uint32_t tests = 0;
188 int i, fd_map;
189
190 setrlimit(RLIMIT_MEMLOCK, &rinf);
191 fd_map = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int),
192 sizeof(int), 1, BPF_F_NO_PREALLOC);
193 assert(fd_map > 0);
194
195 for (i = 0; i < 5; i++) {
196 do_test(&tests, 2, -1, bpf_gen_imm_prog);
197 do_test(&tests, 3, fd_map, bpf_gen_map_prog);
198 }
199
200 printf("test_tag: OK (%u tests)\n", tests);
201 close(fd_map);
202 return 0;
203}
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 853d7e43434a..d1555e4240c0 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -8,7 +8,11 @@
8 * License as published by the Free Software Foundation. 8 * License as published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <asm/types.h>
12#include <linux/types.h>
13#include <stdint.h>
11#include <stdio.h> 14#include <stdio.h>
15#include <stdlib.h>
12#include <unistd.h> 16#include <unistd.h>
13#include <errno.h> 17#include <errno.h>
14#include <string.h> 18#include <string.h>
@@ -16,6 +20,7 @@
16#include <stdbool.h> 20#include <stdbool.h>
17#include <sched.h> 21#include <sched.h>
18 22
23#include <sys/capability.h>
19#include <sys/resource.h> 24#include <sys/resource.h>
20 25
21#include <linux/unistd.h> 26#include <linux/unistd.h>
@@ -23,9 +28,9 @@
23#include <linux/bpf_perf_event.h> 28#include <linux/bpf_perf_event.h>
24#include <linux/bpf.h> 29#include <linux/bpf.h>
25 30
26#include "../../../include/linux/filter.h" 31#include <bpf/bpf.h>
27 32
28#include "bpf_sys.h" 33#include "../../../include/linux/filter.h"
29 34
30#ifndef ARRAY_SIZE 35#ifndef ARRAY_SIZE
31# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 36# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -859,17 +864,453 @@ static struct bpf_test tests[] = {
859 .result = REJECT, 864 .result = REJECT,
860 }, 865 },
861 { 866 {
862 "check non-u32 access to cb", 867 "check cb access: byte",
863 .insns = { 868 .insns = {
864 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_1, 869 BPF_MOV64_IMM(BPF_REG_0, 0),
870 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
871 offsetof(struct __sk_buff, cb[0])),
872 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
873 offsetof(struct __sk_buff, cb[0]) + 1),
874 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
875 offsetof(struct __sk_buff, cb[0]) + 2),
876 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
877 offsetof(struct __sk_buff, cb[0]) + 3),
878 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
879 offsetof(struct __sk_buff, cb[1])),
880 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
881 offsetof(struct __sk_buff, cb[1]) + 1),
882 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
883 offsetof(struct __sk_buff, cb[1]) + 2),
884 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
885 offsetof(struct __sk_buff, cb[1]) + 3),
886 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
887 offsetof(struct __sk_buff, cb[2])),
888 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
889 offsetof(struct __sk_buff, cb[2]) + 1),
890 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
891 offsetof(struct __sk_buff, cb[2]) + 2),
892 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
893 offsetof(struct __sk_buff, cb[2]) + 3),
894 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
895 offsetof(struct __sk_buff, cb[3])),
896 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
897 offsetof(struct __sk_buff, cb[3]) + 1),
898 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
899 offsetof(struct __sk_buff, cb[3]) + 2),
900 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
901 offsetof(struct __sk_buff, cb[3]) + 3),
902 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
903 offsetof(struct __sk_buff, cb[4])),
904 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
905 offsetof(struct __sk_buff, cb[4]) + 1),
906 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
907 offsetof(struct __sk_buff, cb[4]) + 2),
908 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
909 offsetof(struct __sk_buff, cb[4]) + 3),
910 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
865 offsetof(struct __sk_buff, cb[0])), 911 offsetof(struct __sk_buff, cb[0])),
912 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
913 offsetof(struct __sk_buff, cb[0]) + 1),
914 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
915 offsetof(struct __sk_buff, cb[0]) + 2),
916 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
917 offsetof(struct __sk_buff, cb[0]) + 3),
918 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
919 offsetof(struct __sk_buff, cb[1])),
920 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
921 offsetof(struct __sk_buff, cb[1]) + 1),
922 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
923 offsetof(struct __sk_buff, cb[1]) + 2),
924 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
925 offsetof(struct __sk_buff, cb[1]) + 3),
926 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
927 offsetof(struct __sk_buff, cb[2])),
928 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
929 offsetof(struct __sk_buff, cb[2]) + 1),
930 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
931 offsetof(struct __sk_buff, cb[2]) + 2),
932 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
933 offsetof(struct __sk_buff, cb[2]) + 3),
934 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
935 offsetof(struct __sk_buff, cb[3])),
936 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
937 offsetof(struct __sk_buff, cb[3]) + 1),
938 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
939 offsetof(struct __sk_buff, cb[3]) + 2),
940 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
941 offsetof(struct __sk_buff, cb[3]) + 3),
942 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
943 offsetof(struct __sk_buff, cb[4])),
944 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
945 offsetof(struct __sk_buff, cb[4]) + 1),
946 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
947 offsetof(struct __sk_buff, cb[4]) + 2),
948 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
949 offsetof(struct __sk_buff, cb[4]) + 3),
950 BPF_EXIT_INSN(),
951 },
952 .result = ACCEPT,
953 },
954 {
955 "check cb access: byte, oob 1",
956 .insns = {
957 BPF_MOV64_IMM(BPF_REG_0, 0),
958 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
959 offsetof(struct __sk_buff, cb[4]) + 4),
960 BPF_EXIT_INSN(),
961 },
962 .errstr = "invalid bpf_context access",
963 .result = REJECT,
964 },
965 {
966 "check cb access: byte, oob 2",
967 .insns = {
968 BPF_MOV64_IMM(BPF_REG_0, 0),
969 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
970 offsetof(struct __sk_buff, cb[0]) - 1),
971 BPF_EXIT_INSN(),
972 },
973 .errstr = "invalid bpf_context access",
974 .result = REJECT,
975 },
976 {
977 "check cb access: byte, oob 3",
978 .insns = {
979 BPF_MOV64_IMM(BPF_REG_0, 0),
980 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
981 offsetof(struct __sk_buff, cb[4]) + 4),
982 BPF_EXIT_INSN(),
983 },
984 .errstr = "invalid bpf_context access",
985 .result = REJECT,
986 },
987 {
988 "check cb access: byte, oob 4",
989 .insns = {
990 BPF_MOV64_IMM(BPF_REG_0, 0),
991 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
992 offsetof(struct __sk_buff, cb[0]) - 1),
993 BPF_EXIT_INSN(),
994 },
995 .errstr = "invalid bpf_context access",
996 .result = REJECT,
997 },
998 {
999 "check cb access: byte, wrong type",
1000 .insns = {
1001 BPF_MOV64_IMM(BPF_REG_0, 0),
1002 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
1003 offsetof(struct __sk_buff, cb[0])),
1004 BPF_EXIT_INSN(),
1005 },
1006 .errstr = "invalid bpf_context access",
1007 .result = REJECT,
1008 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1009 },
1010 {
1011 "check cb access: half",
1012 .insns = {
1013 BPF_MOV64_IMM(BPF_REG_0, 0),
1014 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1015 offsetof(struct __sk_buff, cb[0])),
1016 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1017 offsetof(struct __sk_buff, cb[0]) + 2),
1018 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1019 offsetof(struct __sk_buff, cb[1])),
1020 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1021 offsetof(struct __sk_buff, cb[1]) + 2),
1022 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1023 offsetof(struct __sk_buff, cb[2])),
1024 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1025 offsetof(struct __sk_buff, cb[2]) + 2),
1026 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1027 offsetof(struct __sk_buff, cb[3])),
1028 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1029 offsetof(struct __sk_buff, cb[3]) + 2),
1030 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1031 offsetof(struct __sk_buff, cb[4])),
1032 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1033 offsetof(struct __sk_buff, cb[4]) + 2),
1034 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1035 offsetof(struct __sk_buff, cb[0])),
1036 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1037 offsetof(struct __sk_buff, cb[0]) + 2),
1038 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1039 offsetof(struct __sk_buff, cb[1])),
1040 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1041 offsetof(struct __sk_buff, cb[1]) + 2),
1042 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1043 offsetof(struct __sk_buff, cb[2])),
1044 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1045 offsetof(struct __sk_buff, cb[2]) + 2),
1046 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1047 offsetof(struct __sk_buff, cb[3])),
1048 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1049 offsetof(struct __sk_buff, cb[3]) + 2),
1050 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1051 offsetof(struct __sk_buff, cb[4])),
1052 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1053 offsetof(struct __sk_buff, cb[4]) + 2),
1054 BPF_EXIT_INSN(),
1055 },
1056 .result = ACCEPT,
1057 },
1058 {
1059 "check cb access: half, unaligned",
1060 .insns = {
1061 BPF_MOV64_IMM(BPF_REG_0, 0),
1062 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1063 offsetof(struct __sk_buff, cb[0]) + 1),
1064 BPF_EXIT_INSN(),
1065 },
1066 .errstr = "misaligned access",
1067 .result = REJECT,
1068 },
1069 {
1070 "check cb access: half, oob 1",
1071 .insns = {
1072 BPF_MOV64_IMM(BPF_REG_0, 0),
1073 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1074 offsetof(struct __sk_buff, cb[4]) + 4),
1075 BPF_EXIT_INSN(),
1076 },
1077 .errstr = "invalid bpf_context access",
1078 .result = REJECT,
1079 },
1080 {
1081 "check cb access: half, oob 2",
1082 .insns = {
1083 BPF_MOV64_IMM(BPF_REG_0, 0),
1084 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1085 offsetof(struct __sk_buff, cb[0]) - 2),
1086 BPF_EXIT_INSN(),
1087 },
1088 .errstr = "invalid bpf_context access",
1089 .result = REJECT,
1090 },
1091 {
1092 "check cb access: half, oob 3",
1093 .insns = {
1094 BPF_MOV64_IMM(BPF_REG_0, 0),
1095 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1096 offsetof(struct __sk_buff, cb[4]) + 4),
1097 BPF_EXIT_INSN(),
1098 },
1099 .errstr = "invalid bpf_context access",
1100 .result = REJECT,
1101 },
1102 {
1103 "check cb access: half, oob 4",
1104 .insns = {
1105 BPF_MOV64_IMM(BPF_REG_0, 0),
1106 BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
1107 offsetof(struct __sk_buff, cb[0]) - 2),
1108 BPF_EXIT_INSN(),
1109 },
1110 .errstr = "invalid bpf_context access",
1111 .result = REJECT,
1112 },
1113 {
1114 "check cb access: half, wrong type",
1115 .insns = {
1116 BPF_MOV64_IMM(BPF_REG_0, 0),
1117 BPF_STX_MEM(BPF_H, BPF_REG_1, BPF_REG_0,
1118 offsetof(struct __sk_buff, cb[0])),
1119 BPF_EXIT_INSN(),
1120 },
1121 .errstr = "invalid bpf_context access",
1122 .result = REJECT,
1123 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1124 },
1125 {
1126 "check cb access: word",
1127 .insns = {
1128 BPF_MOV64_IMM(BPF_REG_0, 0),
1129 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1130 offsetof(struct __sk_buff, cb[0])),
1131 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1132 offsetof(struct __sk_buff, cb[1])),
1133 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1134 offsetof(struct __sk_buff, cb[2])),
1135 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1136 offsetof(struct __sk_buff, cb[3])),
1137 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1138 offsetof(struct __sk_buff, cb[4])),
1139 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1140 offsetof(struct __sk_buff, cb[0])),
1141 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1142 offsetof(struct __sk_buff, cb[1])),
1143 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1144 offsetof(struct __sk_buff, cb[2])),
1145 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1146 offsetof(struct __sk_buff, cb[3])),
1147 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1148 offsetof(struct __sk_buff, cb[4])),
1149 BPF_EXIT_INSN(),
1150 },
1151 .result = ACCEPT,
1152 },
1153 {
1154 "check cb access: word, unaligned 1",
1155 .insns = {
1156 BPF_MOV64_IMM(BPF_REG_0, 0),
1157 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1158 offsetof(struct __sk_buff, cb[0]) + 2),
1159 BPF_EXIT_INSN(),
1160 },
1161 .errstr = "misaligned access",
1162 .result = REJECT,
1163 },
1164 {
1165 "check cb access: word, unaligned 2",
1166 .insns = {
1167 BPF_MOV64_IMM(BPF_REG_0, 0),
1168 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1169 offsetof(struct __sk_buff, cb[4]) + 1),
1170 BPF_EXIT_INSN(),
1171 },
1172 .errstr = "misaligned access",
1173 .result = REJECT,
1174 },
1175 {
1176 "check cb access: word, unaligned 3",
1177 .insns = {
1178 BPF_MOV64_IMM(BPF_REG_0, 0),
1179 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1180 offsetof(struct __sk_buff, cb[4]) + 2),
1181 BPF_EXIT_INSN(),
1182 },
1183 .errstr = "misaligned access",
1184 .result = REJECT,
1185 },
1186 {
1187 "check cb access: word, unaligned 4",
1188 .insns = {
1189 BPF_MOV64_IMM(BPF_REG_0, 0),
1190 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1191 offsetof(struct __sk_buff, cb[4]) + 3),
1192 BPF_EXIT_INSN(),
1193 },
1194 .errstr = "misaligned access",
1195 .result = REJECT,
1196 },
1197 {
1198 "check cb access: double",
1199 .insns = {
1200 BPF_MOV64_IMM(BPF_REG_0, 0),
1201 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1202 offsetof(struct __sk_buff, cb[0])),
1203 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1204 offsetof(struct __sk_buff, cb[2])),
1205 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1206 offsetof(struct __sk_buff, cb[0])),
1207 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1208 offsetof(struct __sk_buff, cb[2])),
1209 BPF_EXIT_INSN(),
1210 },
1211 .result = ACCEPT,
1212 },
1213 {
1214 "check cb access: double, unaligned 1",
1215 .insns = {
1216 BPF_MOV64_IMM(BPF_REG_0, 0),
1217 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1218 offsetof(struct __sk_buff, cb[1])),
1219 BPF_EXIT_INSN(),
1220 },
1221 .errstr = "misaligned access",
1222 .result = REJECT,
1223 },
1224 {
1225 "check cb access: double, unaligned 2",
1226 .insns = {
1227 BPF_MOV64_IMM(BPF_REG_0, 0),
1228 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1229 offsetof(struct __sk_buff, cb[3])),
1230 BPF_EXIT_INSN(),
1231 },
1232 .errstr = "misaligned access",
1233 .result = REJECT,
1234 },
1235 {
1236 "check cb access: double, oob 1",
1237 .insns = {
1238 BPF_MOV64_IMM(BPF_REG_0, 0),
1239 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1240 offsetof(struct __sk_buff, cb[4])),
1241 BPF_EXIT_INSN(),
1242 },
1243 .errstr = "invalid bpf_context access",
1244 .result = REJECT,
1245 },
1246 {
1247 "check cb access: double, oob 2",
1248 .insns = {
1249 BPF_MOV64_IMM(BPF_REG_0, 0),
1250 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1251 offsetof(struct __sk_buff, cb[4]) + 8),
1252 BPF_EXIT_INSN(),
1253 },
1254 .errstr = "invalid bpf_context access",
1255 .result = REJECT,
1256 },
1257 {
1258 "check cb access: double, oob 3",
1259 .insns = {
1260 BPF_MOV64_IMM(BPF_REG_0, 0),
1261 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1262 offsetof(struct __sk_buff, cb[0]) - 8),
866 BPF_EXIT_INSN(), 1263 BPF_EXIT_INSN(),
867 }, 1264 },
868 .errstr = "invalid bpf_context access", 1265 .errstr = "invalid bpf_context access",
869 .errstr_unpriv = "R1 leaks addr",
870 .result = REJECT, 1266 .result = REJECT,
871 }, 1267 },
872 { 1268 {
1269 "check cb access: double, oob 4",
1270 .insns = {
1271 BPF_MOV64_IMM(BPF_REG_0, 0),
1272 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1273 offsetof(struct __sk_buff, cb[4])),
1274 BPF_EXIT_INSN(),
1275 },
1276 .errstr = "invalid bpf_context access",
1277 .result = REJECT,
1278 },
1279 {
1280 "check cb access: double, oob 5",
1281 .insns = {
1282 BPF_MOV64_IMM(BPF_REG_0, 0),
1283 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1284 offsetof(struct __sk_buff, cb[4]) + 8),
1285 BPF_EXIT_INSN(),
1286 },
1287 .errstr = "invalid bpf_context access",
1288 .result = REJECT,
1289 },
1290 {
1291 "check cb access: double, oob 6",
1292 .insns = {
1293 BPF_MOV64_IMM(BPF_REG_0, 0),
1294 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1,
1295 offsetof(struct __sk_buff, cb[0]) - 8),
1296 BPF_EXIT_INSN(),
1297 },
1298 .errstr = "invalid bpf_context access",
1299 .result = REJECT,
1300 },
1301 {
1302 "check cb access: double, wrong type",
1303 .insns = {
1304 BPF_MOV64_IMM(BPF_REG_0, 0),
1305 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0,
1306 offsetof(struct __sk_buff, cb[0])),
1307 BPF_EXIT_INSN(),
1308 },
1309 .errstr = "invalid bpf_context access",
1310 .result = REJECT,
1311 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
1312 },
1313 {
873 "check out of range skb->cb access", 1314 "check out of range skb->cb access",
874 .insns = { 1315 .insns = {
875 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 1316 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
@@ -1890,6 +2331,107 @@ static struct bpf_test tests[] = {
1890 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 2331 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1891 }, 2332 },
1892 { 2333 {
2334 "direct packet access: test11 (shift, good access)",
2335 .insns = {
2336 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2337 offsetof(struct __sk_buff, data)),
2338 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2339 offsetof(struct __sk_buff, data_end)),
2340 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2341 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2342 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2343 BPF_MOV64_IMM(BPF_REG_3, 144),
2344 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2346 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 3),
2347 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2348 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2349 BPF_MOV64_IMM(BPF_REG_0, 1),
2350 BPF_EXIT_INSN(),
2351 BPF_MOV64_IMM(BPF_REG_0, 0),
2352 BPF_EXIT_INSN(),
2353 },
2354 .result = ACCEPT,
2355 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2356 },
2357 {
2358 "direct packet access: test12 (and, good access)",
2359 .insns = {
2360 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2361 offsetof(struct __sk_buff, data)),
2362 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2363 offsetof(struct __sk_buff, data_end)),
2364 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2366 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 8),
2367 BPF_MOV64_IMM(BPF_REG_3, 144),
2368 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2369 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2370 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2371 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2372 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2373 BPF_MOV64_IMM(BPF_REG_0, 1),
2374 BPF_EXIT_INSN(),
2375 BPF_MOV64_IMM(BPF_REG_0, 0),
2376 BPF_EXIT_INSN(),
2377 },
2378 .result = ACCEPT,
2379 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2380 },
2381 {
2382 "direct packet access: test13 (branches, good access)",
2383 .insns = {
2384 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2385 offsetof(struct __sk_buff, data)),
2386 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2387 offsetof(struct __sk_buff, data_end)),
2388 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2390 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 13),
2391 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2392 offsetof(struct __sk_buff, mark)),
2393 BPF_MOV64_IMM(BPF_REG_4, 1),
2394 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_4, 2),
2395 BPF_MOV64_IMM(BPF_REG_3, 14),
2396 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
2397 BPF_MOV64_IMM(BPF_REG_3, 24),
2398 BPF_MOV64_REG(BPF_REG_5, BPF_REG_3),
2399 BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 23),
2400 BPF_ALU64_IMM(BPF_AND, BPF_REG_5, 15),
2401 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2402 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2403 BPF_MOV64_IMM(BPF_REG_0, 1),
2404 BPF_EXIT_INSN(),
2405 BPF_MOV64_IMM(BPF_REG_0, 0),
2406 BPF_EXIT_INSN(),
2407 },
2408 .result = ACCEPT,
2409 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2410 },
2411 {
2412 "direct packet access: test14 (pkt_ptr += 0, CONST_IMM, good access)",
2413 .insns = {
2414 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
2415 offsetof(struct __sk_buff, data)),
2416 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
2417 offsetof(struct __sk_buff, data_end)),
2418 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
2419 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 22),
2420 BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 7),
2421 BPF_MOV64_IMM(BPF_REG_5, 12),
2422 BPF_ALU64_IMM(BPF_RSH, BPF_REG_5, 4),
2423 BPF_MOV64_REG(BPF_REG_6, BPF_REG_2),
2424 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_5),
2425 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0),
2426 BPF_MOV64_IMM(BPF_REG_0, 1),
2427 BPF_EXIT_INSN(),
2428 BPF_MOV64_IMM(BPF_REG_0, 0),
2429 BPF_EXIT_INSN(),
2430 },
2431 .result = ACCEPT,
2432 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
2433 },
2434 {
1893 "helper access to packet: test1, valid packet_ptr range", 2435 "helper access to packet: test1, valid packet_ptr range",
1894 .insns = { 2436 .insns = {
1895 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 2437 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
@@ -2905,6 +3447,1012 @@ static struct bpf_test tests[] = {
2905 .result = REJECT, 3447 .result = REJECT,
2906 .errstr = "invalid bpf_context access", 3448 .errstr = "invalid bpf_context access",
2907 }, 3449 },
3450 {
3451 "helper access to map: full range",
3452 .insns = {
3453 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3454 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3455 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3456 BPF_LD_MAP_FD(BPF_REG_1, 0),
3457 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3458 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3459 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3460 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
3461 BPF_MOV64_IMM(BPF_REG_3, 0),
3462 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3463 BPF_EXIT_INSN(),
3464 },
3465 .fixup_map2 = { 3 },
3466 .result = ACCEPT,
3467 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3468 },
3469 {
3470 "helper access to map: partial range",
3471 .insns = {
3472 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3473 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3474 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3475 BPF_LD_MAP_FD(BPF_REG_1, 0),
3476 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3477 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3478 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3479 BPF_MOV64_IMM(BPF_REG_2, 8),
3480 BPF_MOV64_IMM(BPF_REG_3, 0),
3481 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3482 BPF_EXIT_INSN(),
3483 },
3484 .fixup_map2 = { 3 },
3485 .result = ACCEPT,
3486 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3487 },
3488 {
3489 "helper access to map: empty range",
3490 .insns = {
3491 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3492 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3493 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3494 BPF_LD_MAP_FD(BPF_REG_1, 0),
3495 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3496 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3497 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3498 BPF_MOV64_IMM(BPF_REG_2, 0),
3499 BPF_MOV64_IMM(BPF_REG_3, 0),
3500 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3501 BPF_EXIT_INSN(),
3502 },
3503 .fixup_map2 = { 3 },
3504 .errstr = "invalid access to map value, value_size=48 off=0 size=0",
3505 .result = REJECT,
3506 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3507 },
3508 {
3509 "helper access to map: out-of-bound range",
3510 .insns = {
3511 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3513 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3514 BPF_LD_MAP_FD(BPF_REG_1, 0),
3515 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3516 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3517 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3518 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val) + 8),
3519 BPF_MOV64_IMM(BPF_REG_3, 0),
3520 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3521 BPF_EXIT_INSN(),
3522 },
3523 .fixup_map2 = { 3 },
3524 .errstr = "invalid access to map value, value_size=48 off=0 size=56",
3525 .result = REJECT,
3526 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3527 },
3528 {
3529 "helper access to map: negative range",
3530 .insns = {
3531 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3532 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3533 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3534 BPF_LD_MAP_FD(BPF_REG_1, 0),
3535 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3536 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
3537 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3538 BPF_MOV64_IMM(BPF_REG_2, -8),
3539 BPF_MOV64_IMM(BPF_REG_3, 0),
3540 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3541 BPF_EXIT_INSN(),
3542 },
3543 .fixup_map2 = { 3 },
3544 .errstr = "invalid access to map value, value_size=48 off=0 size=-8",
3545 .result = REJECT,
3546 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3547 },
3548 {
3549 "helper access to adjusted map (via const imm): full range",
3550 .insns = {
3551 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3552 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3553 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3554 BPF_LD_MAP_FD(BPF_REG_1, 0),
3555 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3556 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3557 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3558 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3559 offsetof(struct test_val, foo)),
3560 BPF_MOV64_IMM(BPF_REG_2,
3561 sizeof(struct test_val) -
3562 offsetof(struct test_val, foo)),
3563 BPF_MOV64_IMM(BPF_REG_3, 0),
3564 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3565 BPF_EXIT_INSN(),
3566 },
3567 .fixup_map2 = { 3 },
3568 .result = ACCEPT,
3569 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3570 },
3571 {
3572 "helper access to adjusted map (via const imm): partial range",
3573 .insns = {
3574 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3575 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3576 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3577 BPF_LD_MAP_FD(BPF_REG_1, 0),
3578 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3579 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3580 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3582 offsetof(struct test_val, foo)),
3583 BPF_MOV64_IMM(BPF_REG_2, 8),
3584 BPF_MOV64_IMM(BPF_REG_3, 0),
3585 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3586 BPF_EXIT_INSN(),
3587 },
3588 .fixup_map2 = { 3 },
3589 .result = ACCEPT,
3590 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3591 },
3592 {
3593 "helper access to adjusted map (via const imm): empty range",
3594 .insns = {
3595 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3596 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3597 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3598 BPF_LD_MAP_FD(BPF_REG_1, 0),
3599 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3600 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3601 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3602 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3603 offsetof(struct test_val, foo)),
3604 BPF_MOV64_IMM(BPF_REG_2, 0),
3605 BPF_MOV64_IMM(BPF_REG_3, 0),
3606 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3607 BPF_EXIT_INSN(),
3608 },
3609 .fixup_map2 = { 3 },
3610 .errstr = "R1 min value is outside of the array range",
3611 .result = REJECT,
3612 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3613 },
3614 {
3615 "helper access to adjusted map (via const imm): out-of-bound range",
3616 .insns = {
3617 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3618 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3619 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3620 BPF_LD_MAP_FD(BPF_REG_1, 0),
3621 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3622 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3623 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3624 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3625 offsetof(struct test_val, foo)),
3626 BPF_MOV64_IMM(BPF_REG_2,
3627 sizeof(struct test_val) -
3628 offsetof(struct test_val, foo) + 8),
3629 BPF_MOV64_IMM(BPF_REG_3, 0),
3630 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3631 BPF_EXIT_INSN(),
3632 },
3633 .fixup_map2 = { 3 },
3634 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3635 .result = REJECT,
3636 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3637 },
3638 {
3639 "helper access to adjusted map (via const imm): negative range (> adjustment)",
3640 .insns = {
3641 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3642 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3643 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3644 BPF_LD_MAP_FD(BPF_REG_1, 0),
3645 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3646 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3647 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3648 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3649 offsetof(struct test_val, foo)),
3650 BPF_MOV64_IMM(BPF_REG_2, -8),
3651 BPF_MOV64_IMM(BPF_REG_3, 0),
3652 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3653 BPF_EXIT_INSN(),
3654 },
3655 .fixup_map2 = { 3 },
3656 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3657 .result = REJECT,
3658 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3659 },
3660 {
3661 "helper access to adjusted map (via const imm): negative range (< adjustment)",
3662 .insns = {
3663 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3664 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3665 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3666 BPF_LD_MAP_FD(BPF_REG_1, 0),
3667 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3668 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
3669 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3670 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
3671 offsetof(struct test_val, foo)),
3672 BPF_MOV64_IMM(BPF_REG_2, -1),
3673 BPF_MOV64_IMM(BPF_REG_3, 0),
3674 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3675 BPF_EXIT_INSN(),
3676 },
3677 .fixup_map2 = { 3 },
3678 .errstr = "R1 min value is outside of the array range",
3679 .result = REJECT,
3680 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3681 },
3682 {
3683 "helper access to adjusted map (via const reg): full range",
3684 .insns = {
3685 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3686 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3687 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3688 BPF_LD_MAP_FD(BPF_REG_1, 0),
3689 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3690 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3691 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3692 BPF_MOV64_IMM(BPF_REG_3,
3693 offsetof(struct test_val, foo)),
3694 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3695 BPF_MOV64_IMM(BPF_REG_2,
3696 sizeof(struct test_val) -
3697 offsetof(struct test_val, foo)),
3698 BPF_MOV64_IMM(BPF_REG_3, 0),
3699 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3700 BPF_EXIT_INSN(),
3701 },
3702 .fixup_map2 = { 3 },
3703 .result = ACCEPT,
3704 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3705 },
3706 {
3707 "helper access to adjusted map (via const reg): partial range",
3708 .insns = {
3709 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3710 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3711 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3712 BPF_LD_MAP_FD(BPF_REG_1, 0),
3713 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3714 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3715 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3716 BPF_MOV64_IMM(BPF_REG_3,
3717 offsetof(struct test_val, foo)),
3718 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3719 BPF_MOV64_IMM(BPF_REG_2, 8),
3720 BPF_MOV64_IMM(BPF_REG_3, 0),
3721 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3722 BPF_EXIT_INSN(),
3723 },
3724 .fixup_map2 = { 3 },
3725 .result = ACCEPT,
3726 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3727 },
3728 {
3729 "helper access to adjusted map (via const reg): empty range",
3730 .insns = {
3731 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3732 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3733 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3734 BPF_LD_MAP_FD(BPF_REG_1, 0),
3735 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3736 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3737 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3738 BPF_MOV64_IMM(BPF_REG_3, 0),
3739 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3740 BPF_MOV64_IMM(BPF_REG_2, 0),
3741 BPF_MOV64_IMM(BPF_REG_3, 0),
3742 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3743 BPF_EXIT_INSN(),
3744 },
3745 .fixup_map2 = { 3 },
3746 .errstr = "R1 min value is outside of the array range",
3747 .result = REJECT,
3748 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3749 },
3750 {
3751 "helper access to adjusted map (via const reg): out-of-bound range",
3752 .insns = {
3753 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3754 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3755 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3756 BPF_LD_MAP_FD(BPF_REG_1, 0),
3757 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3758 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3759 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3760 BPF_MOV64_IMM(BPF_REG_3,
3761 offsetof(struct test_val, foo)),
3762 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3763 BPF_MOV64_IMM(BPF_REG_2,
3764 sizeof(struct test_val) -
3765 offsetof(struct test_val, foo) + 8),
3766 BPF_MOV64_IMM(BPF_REG_3, 0),
3767 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3768 BPF_EXIT_INSN(),
3769 },
3770 .fixup_map2 = { 3 },
3771 .errstr = "invalid access to map value, value_size=48 off=4 size=52",
3772 .result = REJECT,
3773 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3774 },
3775 {
3776 "helper access to adjusted map (via const reg): negative range (> adjustment)",
3777 .insns = {
3778 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3779 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3780 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3781 BPF_LD_MAP_FD(BPF_REG_1, 0),
3782 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3783 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3784 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3785 BPF_MOV64_IMM(BPF_REG_3,
3786 offsetof(struct test_val, foo)),
3787 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3788 BPF_MOV64_IMM(BPF_REG_2, -8),
3789 BPF_MOV64_IMM(BPF_REG_3, 0),
3790 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3791 BPF_EXIT_INSN(),
3792 },
3793 .fixup_map2 = { 3 },
3794 .errstr = "invalid access to map value, value_size=48 off=4 size=-8",
3795 .result = REJECT,
3796 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3797 },
3798 {
3799 "helper access to adjusted map (via const reg): negative range (< adjustment)",
3800 .insns = {
3801 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3802 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3803 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3804 BPF_LD_MAP_FD(BPF_REG_1, 0),
3805 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3806 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3807 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3808 BPF_MOV64_IMM(BPF_REG_3,
3809 offsetof(struct test_val, foo)),
3810 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3811 BPF_MOV64_IMM(BPF_REG_2, -1),
3812 BPF_MOV64_IMM(BPF_REG_3, 0),
3813 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3814 BPF_EXIT_INSN(),
3815 },
3816 .fixup_map2 = { 3 },
3817 .errstr = "R1 min value is outside of the array range",
3818 .result = REJECT,
3819 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3820 },
3821 {
3822 "helper access to adjusted map (via variable): full range",
3823 .insns = {
3824 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3825 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3826 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3827 BPF_LD_MAP_FD(BPF_REG_1, 0),
3828 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3829 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3830 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3831 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3832 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3833 offsetof(struct test_val, foo), 4),
3834 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3835 BPF_MOV64_IMM(BPF_REG_2,
3836 sizeof(struct test_val) -
3837 offsetof(struct test_val, foo)),
3838 BPF_MOV64_IMM(BPF_REG_3, 0),
3839 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3840 BPF_EXIT_INSN(),
3841 },
3842 .fixup_map2 = { 3 },
3843 .result = ACCEPT,
3844 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3845 },
3846 {
3847 "helper access to adjusted map (via variable): partial range",
3848 .insns = {
3849 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3850 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3851 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3852 BPF_LD_MAP_FD(BPF_REG_1, 0),
3853 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3854 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3855 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3856 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3857 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3858 offsetof(struct test_val, foo), 4),
3859 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3860 BPF_MOV64_IMM(BPF_REG_2, 8),
3861 BPF_MOV64_IMM(BPF_REG_3, 0),
3862 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3863 BPF_EXIT_INSN(),
3864 },
3865 .fixup_map2 = { 3 },
3866 .result = ACCEPT,
3867 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3868 },
3869 {
3870 "helper access to adjusted map (via variable): empty range",
3871 .insns = {
3872 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3873 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3874 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3875 BPF_LD_MAP_FD(BPF_REG_1, 0),
3876 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3877 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3878 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3879 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3880 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3881 offsetof(struct test_val, foo), 4),
3882 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3883 BPF_MOV64_IMM(BPF_REG_2, 0),
3884 BPF_MOV64_IMM(BPF_REG_3, 0),
3885 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3886 BPF_EXIT_INSN(),
3887 },
3888 .fixup_map2 = { 3 },
3889 .errstr = "R1 min value is outside of the array range",
3890 .result = REJECT,
3891 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3892 },
3893 {
3894 "helper access to adjusted map (via variable): no max check",
3895 .insns = {
3896 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3897 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3898 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3899 BPF_LD_MAP_FD(BPF_REG_1, 0),
3900 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3901 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3902 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3903 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3904 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3905 BPF_MOV64_IMM(BPF_REG_2, 0),
3906 BPF_MOV64_IMM(BPF_REG_3, 0),
3907 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3908 BPF_EXIT_INSN(),
3909 },
3910 .fixup_map2 = { 3 },
3911 .errstr = "R1 min value is negative, either use unsigned index or do a if (index >=0) check",
3912 .result = REJECT,
3913 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3914 },
3915 {
3916 "helper access to adjusted map (via variable): wrong max check",
3917 .insns = {
3918 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3919 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3920 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3921 BPF_LD_MAP_FD(BPF_REG_1, 0),
3922 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3923 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3924 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
3925 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
3926 BPF_JMP_IMM(BPF_JGT, BPF_REG_3,
3927 offsetof(struct test_val, foo), 4),
3928 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
3929 BPF_MOV64_IMM(BPF_REG_2,
3930 sizeof(struct test_val) -
3931 offsetof(struct test_val, foo) + 1),
3932 BPF_MOV64_IMM(BPF_REG_3, 0),
3933 BPF_EMIT_CALL(BPF_FUNC_probe_read),
3934 BPF_EXIT_INSN(),
3935 },
3936 .fixup_map2 = { 3 },
3937 .errstr = "invalid access to map value, value_size=48 off=4 size=45",
3938 .result = REJECT,
3939 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
3940 },
3941 {
3942 "map element value is preserved across register spilling",
3943 .insns = {
3944 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3945 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3946 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3947 BPF_LD_MAP_FD(BPF_REG_1, 0),
3948 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3949 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
3950 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3951 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3952 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3953 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3954 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3955 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3956 BPF_EXIT_INSN(),
3957 },
3958 .fixup_map2 = { 3 },
3959 .errstr_unpriv = "R0 leaks addr",
3960 .result = ACCEPT,
3961 .result_unpriv = REJECT,
3962 },
3963 {
3964 "map element value (adjusted) is preserved across register spilling",
3965 .insns = {
3966 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
3967 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
3968 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
3969 BPF_LD_MAP_FD(BPF_REG_1, 0),
3970 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
3971 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
3972 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0,
3973 offsetof(struct test_val, foo)),
3974 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
3975 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3976 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -184),
3977 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
3978 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1, 0),
3979 BPF_ST_MEM(BPF_DW, BPF_REG_3, 0, 42),
3980 BPF_EXIT_INSN(),
3981 },
3982 .fixup_map2 = { 3 },
3983 .errstr_unpriv = "R0 pointer arithmetic prohibited",
3984 .result = ACCEPT,
3985 .result_unpriv = REJECT,
3986 },
3987 {
3988 "helper access to variable memory: stack, bitwise AND + JMP, correct bounds",
3989 .insns = {
3990 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
3991 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
3992 BPF_MOV64_IMM(BPF_REG_0, 0),
3993 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
3994 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
3995 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
3996 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
3997 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
3998 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
3999 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4000 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4001 BPF_MOV64_IMM(BPF_REG_2, 16),
4002 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4003 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4004 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4005 BPF_MOV64_IMM(BPF_REG_4, 0),
4006 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4007 BPF_MOV64_IMM(BPF_REG_3, 0),
4008 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4009 BPF_MOV64_IMM(BPF_REG_0, 0),
4010 BPF_EXIT_INSN(),
4011 },
4012 .result = ACCEPT,
4013 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4014 },
4015 {
4016 "helper access to variable memory: stack, bitwise AND, zero included",
4017 .insns = {
4018 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4019 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4020 BPF_MOV64_IMM(BPF_REG_2, 16),
4021 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4022 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4023 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4024 BPF_MOV64_IMM(BPF_REG_3, 0),
4025 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4026 BPF_EXIT_INSN(),
4027 },
4028 .errstr = "invalid stack type R1 off=-64 access_size=0",
4029 .result = REJECT,
4030 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4031 },
4032 {
4033 "helper access to variable memory: stack, bitwise AND + JMP, wrong max",
4034 .insns = {
4035 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4036 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4037 BPF_MOV64_IMM(BPF_REG_2, 16),
4038 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4039 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4040 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 65),
4041 BPF_MOV64_IMM(BPF_REG_4, 0),
4042 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4043 BPF_MOV64_IMM(BPF_REG_3, 0),
4044 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4045 BPF_MOV64_IMM(BPF_REG_0, 0),
4046 BPF_EXIT_INSN(),
4047 },
4048 .errstr = "invalid stack type R1 off=-64 access_size=65",
4049 .result = REJECT,
4050 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4051 },
4052 {
4053 "helper access to variable memory: stack, JMP, correct bounds",
4054 .insns = {
4055 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4056 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4057 BPF_MOV64_IMM(BPF_REG_0, 0),
4058 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4059 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4060 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4061 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4062 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4063 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4064 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4065 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4066 BPF_MOV64_IMM(BPF_REG_2, 16),
4067 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4068 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4069 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 4),
4070 BPF_MOV64_IMM(BPF_REG_4, 0),
4071 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4072 BPF_MOV64_IMM(BPF_REG_3, 0),
4073 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4074 BPF_MOV64_IMM(BPF_REG_0, 0),
4075 BPF_EXIT_INSN(),
4076 },
4077 .result = ACCEPT,
4078 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4079 },
4080 {
4081 "helper access to variable memory: stack, JMP (signed), correct bounds",
4082 .insns = {
4083 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4084 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4085 BPF_MOV64_IMM(BPF_REG_0, 0),
4086 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4087 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4088 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4089 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4090 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4091 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4092 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4093 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4094 BPF_MOV64_IMM(BPF_REG_2, 16),
4095 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4096 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4097 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 4),
4098 BPF_MOV64_IMM(BPF_REG_4, 0),
4099 BPF_JMP_REG(BPF_JSGE, BPF_REG_4, BPF_REG_2, 2),
4100 BPF_MOV64_IMM(BPF_REG_3, 0),
4101 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4102 BPF_MOV64_IMM(BPF_REG_0, 0),
4103 BPF_EXIT_INSN(),
4104 },
4105 .result = ACCEPT,
4106 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4107 },
4108 {
4109 "helper access to variable memory: stack, JMP, bounds + offset",
4110 .insns = {
4111 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4112 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4113 BPF_MOV64_IMM(BPF_REG_2, 16),
4114 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4115 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4116 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 5),
4117 BPF_MOV64_IMM(BPF_REG_4, 0),
4118 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 3),
4119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4120 BPF_MOV64_IMM(BPF_REG_3, 0),
4121 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4122 BPF_MOV64_IMM(BPF_REG_0, 0),
4123 BPF_EXIT_INSN(),
4124 },
4125 .errstr = "invalid stack type R1 off=-64 access_size=65",
4126 .result = REJECT,
4127 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4128 },
4129 {
4130 "helper access to variable memory: stack, JMP, wrong max",
4131 .insns = {
4132 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4133 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4134 BPF_MOV64_IMM(BPF_REG_2, 16),
4135 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4136 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4137 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 65, 4),
4138 BPF_MOV64_IMM(BPF_REG_4, 0),
4139 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4140 BPF_MOV64_IMM(BPF_REG_3, 0),
4141 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4142 BPF_MOV64_IMM(BPF_REG_0, 0),
4143 BPF_EXIT_INSN(),
4144 },
4145 .errstr = "invalid stack type R1 off=-64 access_size=65",
4146 .result = REJECT,
4147 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4148 },
4149 {
4150 "helper access to variable memory: stack, JMP, no max check",
4151 .insns = {
4152 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4153 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4154 BPF_MOV64_IMM(BPF_REG_2, 16),
4155 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4156 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4157 BPF_MOV64_IMM(BPF_REG_4, 0),
4158 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4159 BPF_MOV64_IMM(BPF_REG_3, 0),
4160 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4161 BPF_MOV64_IMM(BPF_REG_0, 0),
4162 BPF_EXIT_INSN(),
4163 },
4164 .errstr = "R2 unbounded memory access",
4165 .result = REJECT,
4166 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4167 },
4168 {
4169 "helper access to variable memory: stack, JMP, no min check",
4170 .insns = {
4171 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4172 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4173 BPF_MOV64_IMM(BPF_REG_2, 16),
4174 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4175 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4176 BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3),
4177 BPF_MOV64_IMM(BPF_REG_3, 0),
4178 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4179 BPF_MOV64_IMM(BPF_REG_0, 0),
4180 BPF_EXIT_INSN(),
4181 },
4182 .errstr = "invalid stack type R1 off=-64 access_size=0",
4183 .result = REJECT,
4184 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4185 },
4186 {
4187 "helper access to variable memory: stack, JMP (signed), no min check",
4188 .insns = {
4189 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4190 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4191 BPF_MOV64_IMM(BPF_REG_2, 16),
4192 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128),
4193 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128),
4194 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2, 64, 3),
4195 BPF_MOV64_IMM(BPF_REG_3, 0),
4196 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4197 BPF_MOV64_IMM(BPF_REG_0, 0),
4198 BPF_EXIT_INSN(),
4199 },
4200 .errstr = "R2 min value is negative",
4201 .result = REJECT,
4202 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4203 },
4204 {
4205 "helper access to variable memory: map, JMP, correct bounds",
4206 .insns = {
4207 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4209 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4210 BPF_LD_MAP_FD(BPF_REG_1, 0),
4211 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4212 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4213 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4214 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4215 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4216 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4217 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4218 sizeof(struct test_val), 4),
4219 BPF_MOV64_IMM(BPF_REG_4, 0),
4220 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4221 BPF_MOV64_IMM(BPF_REG_3, 0),
4222 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4223 BPF_MOV64_IMM(BPF_REG_0, 0),
4224 BPF_EXIT_INSN(),
4225 },
4226 .fixup_map2 = { 3 },
4227 .result = ACCEPT,
4228 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4229 },
4230 {
4231 "helper access to variable memory: map, JMP, wrong max",
4232 .insns = {
4233 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4235 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4236 BPF_LD_MAP_FD(BPF_REG_1, 0),
4237 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4238 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
4239 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4240 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4241 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4242 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4243 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4244 sizeof(struct test_val) + 1, 4),
4245 BPF_MOV64_IMM(BPF_REG_4, 0),
4246 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4247 BPF_MOV64_IMM(BPF_REG_3, 0),
4248 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4249 BPF_MOV64_IMM(BPF_REG_0, 0),
4250 BPF_EXIT_INSN(),
4251 },
4252 .fixup_map2 = { 3 },
4253 .errstr = "invalid access to map value, value_size=48 off=0 size=49",
4254 .result = REJECT,
4255 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4256 },
4257 {
4258 "helper access to variable memory: map adjusted, JMP, correct bounds",
4259 .insns = {
4260 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4261 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4262 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4263 BPF_LD_MAP_FD(BPF_REG_1, 0),
4264 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4265 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4266 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4267 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4268 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4269 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4270 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4271 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4272 sizeof(struct test_val) - 20, 4),
4273 BPF_MOV64_IMM(BPF_REG_4, 0),
4274 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4275 BPF_MOV64_IMM(BPF_REG_3, 0),
4276 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4277 BPF_MOV64_IMM(BPF_REG_0, 0),
4278 BPF_EXIT_INSN(),
4279 },
4280 .fixup_map2 = { 3 },
4281 .result = ACCEPT,
4282 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4283 },
4284 {
4285 "helper access to variable memory: map adjusted, JMP, wrong max",
4286 .insns = {
4287 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4288 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4289 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
4290 BPF_LD_MAP_FD(BPF_REG_1, 0),
4291 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
4292 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
4293 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
4294 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 20),
4295 BPF_MOV64_IMM(BPF_REG_2, sizeof(struct test_val)),
4296 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4297 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4298 BPF_JMP_IMM(BPF_JSGT, BPF_REG_2,
4299 sizeof(struct test_val) - 19, 4),
4300 BPF_MOV64_IMM(BPF_REG_4, 0),
4301 BPF_JMP_REG(BPF_JGE, BPF_REG_4, BPF_REG_2, 2),
4302 BPF_MOV64_IMM(BPF_REG_3, 0),
4303 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4304 BPF_MOV64_IMM(BPF_REG_0, 0),
4305 BPF_EXIT_INSN(),
4306 },
4307 .fixup_map2 = { 3 },
4308 .errstr = "R1 min value is outside of the array range",
4309 .result = REJECT,
4310 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4311 },
4312 {
4313 "helper access to variable memory: size > 0 not allowed on NULL",
4314 .insns = {
4315 BPF_MOV64_IMM(BPF_REG_1, 0),
4316 BPF_MOV64_IMM(BPF_REG_2, 0),
4317 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4318 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4319 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64),
4320 BPF_MOV64_IMM(BPF_REG_3, 0),
4321 BPF_MOV64_IMM(BPF_REG_4, 0),
4322 BPF_MOV64_IMM(BPF_REG_5, 0),
4323 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4324 BPF_EXIT_INSN(),
4325 },
4326 .errstr = "R1 type=imm expected=fp",
4327 .result = REJECT,
4328 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4329 },
4330 {
4331 "helper access to variable memory: size = 0 not allowed on != NULL",
4332 .insns = {
4333 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4334 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
4335 BPF_MOV64_IMM(BPF_REG_2, 0),
4336 BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, 0),
4337 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 8),
4338 BPF_MOV64_IMM(BPF_REG_3, 0),
4339 BPF_MOV64_IMM(BPF_REG_4, 0),
4340 BPF_MOV64_IMM(BPF_REG_5, 0),
4341 BPF_EMIT_CALL(BPF_FUNC_csum_diff),
4342 BPF_EXIT_INSN(),
4343 },
4344 .errstr = "invalid stack type R1 off=-8 access_size=0",
4345 .result = REJECT,
4346 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
4347 },
4348 {
4349 "helper access to variable memory: 8 bytes leak",
4350 .insns = {
4351 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4352 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4353 BPF_MOV64_IMM(BPF_REG_0, 0),
4354 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4355 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4356 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4357 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4358 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4359 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4360 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4361 BPF_MOV64_IMM(BPF_REG_2, 0),
4362 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128),
4363 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128),
4364 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63),
4365 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
4366 BPF_MOV64_IMM(BPF_REG_3, 0),
4367 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4368 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4369 BPF_EXIT_INSN(),
4370 },
4371 .errstr = "invalid indirect read from stack off -64+32 size 64",
4372 .result = REJECT,
4373 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4374 },
4375 {
4376 "helper access to variable memory: 8 bytes no leak (init memory)",
4377 .insns = {
4378 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
4379 BPF_MOV64_IMM(BPF_REG_0, 0),
4380 BPF_MOV64_IMM(BPF_REG_0, 0),
4381 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64),
4382 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56),
4383 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48),
4384 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40),
4385 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -32),
4386 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24),
4387 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16),
4388 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8),
4389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64),
4390 BPF_MOV64_IMM(BPF_REG_2, 0),
4391 BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 32),
4392 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 32),
4393 BPF_MOV64_IMM(BPF_REG_3, 0),
4394 BPF_EMIT_CALL(BPF_FUNC_probe_read),
4395 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16),
4396 BPF_EXIT_INSN(),
4397 },
4398 .result = ACCEPT,
4399 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4400 },
4401 {
4402 "invalid and of negative number",
4403 .insns = {
4404 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4405 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4406 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4407 BPF_LD_MAP_FD(BPF_REG_1, 0),
4408 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4409 BPF_FUNC_map_lookup_elem),
4410 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
4411 BPF_MOV64_IMM(BPF_REG_1, 6),
4412 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, -4),
4413 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
4414 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
4415 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0,
4416 offsetof(struct test_val, foo)),
4417 BPF_EXIT_INSN(),
4418 },
4419 .fixup_map2 = { 3 },
4420 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4421 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4422 .result = REJECT,
4423 .result_unpriv = REJECT,
4424 },
4425 {
4426 "invalid range check",
4427 .insns = {
4428 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
4429 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
4430 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
4431 BPF_LD_MAP_FD(BPF_REG_1, 0),
4432 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
4433 BPF_FUNC_map_lookup_elem),
4434 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 12),
4435 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
4436 BPF_MOV64_IMM(BPF_REG_9, 1),
4437 BPF_ALU32_IMM(BPF_MOD, BPF_REG_1, 2),
4438 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
4439 BPF_ALU32_REG(BPF_AND, BPF_REG_9, BPF_REG_1),
4440 BPF_ALU32_IMM(BPF_ADD, BPF_REG_9, 1),
4441 BPF_ALU32_IMM(BPF_RSH, BPF_REG_9, 1),
4442 BPF_MOV32_IMM(BPF_REG_3, 1),
4443 BPF_ALU32_REG(BPF_SUB, BPF_REG_3, BPF_REG_9),
4444 BPF_ALU32_IMM(BPF_MUL, BPF_REG_3, 0x10000000),
4445 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3),
4446 BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
4447 BPF_MOV64_REG(BPF_REG_0, 0),
4448 BPF_EXIT_INSN(),
4449 },
4450 .fixup_map2 = { 3 },
4451 .errstr_unpriv = "R0 pointer arithmetic prohibited",
4452 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
4453 .result = REJECT,
4454 .result_unpriv = REJECT,
4455 }
2908}; 4456};
2909 4457
2910static int probe_filter_length(const struct bpf_insn *fp) 4458static int probe_filter_length(const struct bpf_insn *fp)
@@ -2921,7 +4469,7 @@ static int create_map(uint32_t size_value, uint32_t max_elem)
2921{ 4469{
2922 int fd; 4470 int fd;
2923 4471
2924 fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(long long), 4472 fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
2925 size_value, max_elem, BPF_F_NO_PREALLOC); 4473 size_value, max_elem, BPF_F_NO_PREALLOC);
2926 if (fd < 0) 4474 if (fd < 0)
2927 printf("Failed to create hash map '%s'!\n", strerror(errno)); 4475 printf("Failed to create hash map '%s'!\n", strerror(errno));
@@ -2933,7 +4481,7 @@ static int create_prog_array(void)
2933{ 4481{
2934 int fd; 4482 int fd;
2935 4483
2936 fd = bpf_map_create(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int), 4484 fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
2937 sizeof(int), 4, 0); 4485 sizeof(int), 4, 0);
2938 if (fd < 0) 4486 if (fd < 0)
2939 printf("Failed to create prog array '%s'!\n", strerror(errno)); 4487 printf("Failed to create prog array '%s'!\n", strerror(errno));
@@ -2991,9 +4539,9 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
2991 4539
2992 do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3); 4540 do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3);
2993 4541
2994 fd_prog = bpf_prog_load(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER, 4542 fd_prog = bpf_load_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
2995 prog, prog_len * sizeof(struct bpf_insn), 4543 prog, prog_len, "GPL", 0, bpf_vlog,
2996 "GPL", bpf_vlog, sizeof(bpf_vlog)); 4544 sizeof(bpf_vlog));
2997 4545
2998 expected_ret = unpriv && test->result_unpriv != UNDEF ? 4546 expected_ret = unpriv && test->result_unpriv != UNDEF ?
2999 test->result_unpriv : test->result; 4547 test->result_unpriv : test->result;
@@ -3031,6 +4579,57 @@ fail_log:
3031 goto close_fds; 4579 goto close_fds;
3032} 4580}
3033 4581
4582static bool is_admin(void)
4583{
4584 cap_t caps;
4585 cap_flag_value_t sysadmin = CAP_CLEAR;
4586 const cap_value_t cap_val = CAP_SYS_ADMIN;
4587
4588#ifdef CAP_IS_SUPPORTED
4589 if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
4590 perror("cap_get_flag");
4591 return false;
4592 }
4593#endif
4594 caps = cap_get_proc();
4595 if (!caps) {
4596 perror("cap_get_proc");
4597 return false;
4598 }
4599 if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
4600 perror("cap_get_flag");
4601 if (cap_free(caps))
4602 perror("cap_free");
4603 return (sysadmin == CAP_SET);
4604}
4605
4606static int set_admin(bool admin)
4607{
4608 cap_t caps;
4609 const cap_value_t cap_val = CAP_SYS_ADMIN;
4610 int ret = -1;
4611
4612 caps = cap_get_proc();
4613 if (!caps) {
4614 perror("cap_get_proc");
4615 return -1;
4616 }
4617 if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
4618 admin ? CAP_SET : CAP_CLEAR)) {
4619 perror("cap_set_flag");
4620 goto out;
4621 }
4622 if (cap_set_proc(caps)) {
4623 perror("cap_set_proc");
4624 goto out;
4625 }
4626 ret = 0;
4627out:
4628 if (cap_free(caps))
4629 perror("cap_free");
4630 return ret;
4631}
4632
3034static int do_test(bool unpriv, unsigned int from, unsigned int to) 4633static int do_test(bool unpriv, unsigned int from, unsigned int to)
3035{ 4634{
3036 int i, passes = 0, errors = 0; 4635 int i, passes = 0, errors = 0;
@@ -3041,11 +4640,19 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to)
3041 /* Program types that are not supported by non-root we 4640 /* Program types that are not supported by non-root we
3042 * skip right away. 4641 * skip right away.
3043 */ 4642 */
3044 if (unpriv && test->prog_type) 4643 if (!test->prog_type) {
3045 continue; 4644 if (!unpriv)
4645 set_admin(false);
4646 printf("#%d/u %s ", i, test->descr);
4647 do_test_single(test, true, &passes, &errors);
4648 if (!unpriv)
4649 set_admin(true);
4650 }
3046 4651
3047 printf("#%d %s ", i, test->descr); 4652 if (!unpriv) {
3048 do_test_single(test, unpriv, &passes, &errors); 4653 printf("#%d/p %s ", i, test->descr);
4654 do_test_single(test, false, &passes, &errors);
4655 }
3049 } 4656 }
3050 4657
3051 printf("Summary: %d PASSED, %d FAILED\n", passes, errors); 4658 printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
@@ -3057,7 +4664,7 @@ int main(int argc, char **argv)
3057 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY }; 4664 struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
3058 struct rlimit rlim = { 1 << 20, 1 << 20 }; 4665 struct rlimit rlim = { 1 << 20, 1 << 20 };
3059 unsigned int from = 0, to = ARRAY_SIZE(tests); 4666 unsigned int from = 0, to = ARRAY_SIZE(tests);
3060 bool unpriv = geteuid() != 0; 4667 bool unpriv = !is_admin();
3061 4668
3062 if (argc == 3) { 4669 if (argc == 3) {
3063 unsigned int l = atoi(argv[argc - 2]); 4670 unsigned int l = atoi(argv[argc - 2]);
diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile
index 61b79e8df1f4..72aa103e4141 100644
--- a/tools/testing/selftests/breakpoints/Makefile
+++ b/tools/testing/selftests/breakpoints/Makefile
@@ -3,17 +3,13 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
3ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) 3ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
4 4
5ifeq ($(ARCH),x86) 5ifeq ($(ARCH),x86)
6TEST_PROGS := breakpoint_test 6TEST_GEN_PROGS := breakpoint_test
7endif 7endif
8ifeq ($(ARCH),aarch64) 8ifeq ($(ARCH),aarch64)
9TEST_PROGS := breakpoint_test_arm64 9TEST_GEN_PROGS := breakpoint_test_arm64
10endif 10endif
11 11
12TEST_PROGS += step_after_suspend_test 12TEST_GEN_PROGS += step_after_suspend_test
13
14all: $(TEST_PROGS)
15 13
16include ../lib.mk 14include ../lib.mk
17 15
18clean:
19 rm -fr breakpoint_test breakpoint_test_arm64 step_after_suspend_test
diff --git a/tools/testing/selftests/capabilities/Makefile b/tools/testing/selftests/capabilities/Makefile
index 008602aed920..29b8adfdac71 100644
--- a/tools/testing/selftests/capabilities/Makefile
+++ b/tools/testing/selftests/capabilities/Makefile
@@ -1,15 +1,8 @@
1TEST_FILES := validate_cap 1TEST_GEN_FILES := validate_cap
2TEST_PROGS := test_execve 2TEST_GEN_PROGS := test_execve
3
4BINARIES := $(TEST_FILES) $(TEST_PROGS)
5 3
6CFLAGS += -O2 -g -std=gnu99 -Wall 4CFLAGS += -O2 -g -std=gnu99 -Wall
7LDLIBS += -lcap-ng -lrt -ldl 5LDLIBS += -lcap-ng -lrt -ldl
8 6
9all: $(BINARIES)
10
11clean:
12 $(RM) $(BINARIES)
13
14include ../lib.mk 7include ../lib.mk
15 8
diff --git a/tools/testing/selftests/cpufreq/Makefile b/tools/testing/selftests/cpufreq/Makefile
new file mode 100644
index 000000000000..3955cd96f3a2
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/Makefile
@@ -0,0 +1,8 @@
1all:
2
3TEST_PROGS := main.sh
4TEST_FILES := cpu.sh cpufreq.sh governor.sh module.sh special-tests.sh
5
6include ../lib.mk
7
8clean:
diff --git a/tools/testing/selftests/cpufreq/cpu.sh b/tools/testing/selftests/cpufreq/cpu.sh
new file mode 100755
index 000000000000..8e08a83d65f2
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/cpu.sh
@@ -0,0 +1,84 @@
1#!/bin/bash
2#
3# CPU helpers
4
5# protect against multiple inclusion
6if [ $FILE_CPU ]; then
7 return 0
8else
9 FILE_CPU=DONE
10fi
11
12source cpufreq.sh
13
14for_each_cpu()
15{
16 cpus=$(ls $CPUROOT | grep "cpu[0-9].*")
17 for cpu in $cpus; do
18 $@ $cpu
19 done
20}
21
22for_each_non_boot_cpu()
23{
24 cpus=$(ls $CPUROOT | grep "cpu[1-9].*")
25 for cpu in $cpus; do
26 $@ $cpu
27 done
28}
29
30#$1: cpu
31offline_cpu()
32{
33 printf "Offline $1\n"
34 echo 0 > $CPUROOT/$1/online
35}
36
37#$1: cpu
38online_cpu()
39{
40 printf "Online $1\n"
41 echo 1 > $CPUROOT/$1/online
42}
43
44#$1: cpu
45reboot_cpu()
46{
47 offline_cpu $1
48 online_cpu $1
49}
50
51# Reboot CPUs
52# param: number of times we want to run the loop
53reboot_cpus()
54{
55 printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n"
56
57 for i in `seq 1 $1`; do
58 for_each_non_boot_cpu offline_cpu
59 for_each_non_boot_cpu online_cpu
60 printf "\n"
61 done
62
63 printf "\n%s\n\n" "------------------------------------------------"
64}
65
66# Prints warning for all CPUs with missing cpufreq directory
67print_unmanaged_cpus()
68{
69 for_each_cpu cpu_should_have_cpufreq_directory
70}
71
72# Counts CPUs with cpufreq directories
73count_cpufreq_managed_cpus()
74{
75 count=0;
76
77 for cpu in `ls $CPUROOT | grep "cpu[0-9].*"`; do
78 if [ -d $CPUROOT/$cpu/cpufreq ]; then
79 let count=count+1;
80 fi
81 done
82
83 echo $count;
84}
diff --git a/tools/testing/selftests/cpufreq/cpufreq.sh b/tools/testing/selftests/cpufreq/cpufreq.sh
new file mode 100755
index 000000000000..1ed3832030b4
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/cpufreq.sh
@@ -0,0 +1,241 @@
1#!/bin/bash
2
3# protect against multiple inclusion
4if [ $FILE_CPUFREQ ]; then
5 return 0
6else
7 FILE_CPUFREQ=DONE
8fi
9
10source cpu.sh
11
12
13# $1: cpu
14cpu_should_have_cpufreq_directory()
15{
16 if [ ! -d $CPUROOT/$1/cpufreq ]; then
17 printf "Warning: No cpufreq directory present for $1\n"
18 fi
19}
20
21cpu_should_not_have_cpufreq_directory()
22{
23 if [ -d $CPUROOT/$1/cpufreq ]; then
24 printf "Warning: cpufreq directory present for $1\n"
25 fi
26}
27
28for_each_policy()
29{
30 policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
31 for policy in $policies; do
32 $@ $policy
33 done
34}
35
36for_each_policy_concurrent()
37{
38 policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
39 for policy in $policies; do
40 $@ $policy &
41 done
42}
43
44# $1: Path
45read_cpufreq_files_in_dir()
46{
47 local files=`ls $1`
48
49 printf "Printing directory: $1\n\n"
50
51 for file in $files; do
52 if [ -f $1/$file ]; then
53 printf "$file:"
54 cat $1/$file
55 else
56 printf "\n"
57 read_cpufreq_files_in_dir "$1/$file"
58 fi
59 done
60 printf "\n"
61}
62
63
64read_all_cpufreq_files()
65{
66 printf "** Test: Running ${FUNCNAME[0]} **\n\n"
67
68 read_cpufreq_files_in_dir $CPUFREQROOT
69
70 printf "%s\n\n" "------------------------------------------------"
71}
72
73
74# UPDATE CPUFREQ FILES
75
76# $1: directory path
77update_cpufreq_files_in_dir()
78{
79 local files=`ls $1`
80
81 printf "Updating directory: $1\n\n"
82
83 for file in $files; do
84 if [ -f $1/$file ]; then
85 # file is writable ?
86 local wfile=$(ls -l $1/$file | awk '$1 ~ /^.*w.*/ { print $NF; }')
87
88 if [ ! -z $wfile ]; then
89 # scaling_setspeed is a special file and we
90 # should skip updating it
91 if [ $file != "scaling_setspeed" ]; then
92 local val=$(cat $1/$file)
93 printf "Writing $val to: $file\n"
94 echo $val > $1/$file
95 fi
96 fi
97 else
98 printf "\n"
99 update_cpufreq_files_in_dir "$1/$file"
100 fi
101 done
102
103 printf "\n"
104}
105
106# Update all writable files with their existing values
107update_all_cpufreq_files()
108{
109 printf "** Test: Running ${FUNCNAME[0]} **\n\n"
110
111 update_cpufreq_files_in_dir $CPUFREQROOT
112
113 printf "%s\n\n" "------------------------------------------------"
114}
115
116
117# CHANGE CPU FREQUENCIES
118
119# $1: policy
120find_current_freq()
121{
122 cat $CPUFREQROOT/$1/scaling_cur_freq
123}
124
125# $1: policy
126# $2: frequency
127set_cpu_frequency()
128{
129 printf "Change frequency for $1 to $2\n"
130 echo $2 > $CPUFREQROOT/$1/scaling_setspeed
131}
132
133# $1: policy
134test_all_frequencies()
135{
136 local filepath="$CPUFREQROOT/$1"
137
138 backup_governor $1
139
140 local found=$(switch_governor $1 "userspace")
141 if [ $found = 1 ]; then
142 printf "${FUNCNAME[0]}: userspace governor not available for: $1\n"
143 return;
144 fi
145
146 printf "Switched governor for $1 to userspace\n\n"
147
148 local freqs=$(cat $filepath/scaling_available_frequencies)
149 printf "Available frequencies for $1: $freqs\n\n"
150
151 # Set all frequencies one-by-one
152 for freq in $freqs; do
153 set_cpu_frequency $1 $freq
154 done
155
156 printf "\n"
157
158 restore_governor $1
159}
160
161# $1: loop count
162shuffle_frequency_for_all_cpus()
163{
164 printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n"
165
166 for i in `seq 1 $1`; do
167 for_each_policy test_all_frequencies
168 done
169 printf "\n%s\n\n" "------------------------------------------------"
170}
171
172# Basic cpufreq tests
173cpufreq_basic_tests()
174{
175 printf "*** RUNNING CPUFREQ SANITY TESTS ***\n"
176 printf "====================================\n\n"
177
178 count=$(count_cpufreq_managed_cpus)
179 if [ $count = 0 ]; then
180 printf "No cpu is managed by cpufreq core, exiting\n"
181 exit;
182 else
183 printf "CPUFreq manages: $count CPUs\n\n"
184 fi
185
186 # Detect & print which CPUs are not managed by cpufreq
187 print_unmanaged_cpus
188
189 # read/update all cpufreq files
190 read_all_cpufreq_files
191 update_all_cpufreq_files
192
193 # hotplug cpus
194 reboot_cpus 5
195
196 # Test all frequencies
197 shuffle_frequency_for_all_cpus 2
198
199 # Test all governors
200 shuffle_governors_for_all_cpus 1
201}
202
203# Suspend/resume
204# $1: "suspend" or "hibernate", $2: loop count
205do_suspend()
206{
207 printf "** Test: Running ${FUNCNAME[0]}: Trying $1 for $2 loops **\n\n"
208
209 # Is the directory available
210 if [ ! -d $SYSFS/power/ -o ! -f $SYSFS/power/state ]; then
211 printf "$SYSFS/power/state not available\n"
212 return 1
213 fi
214
215 if [ $1 = "suspend" ]; then
216 filename="mem"
217 elif [ $1 = "hibernate" ]; then
218 filename="disk"
219 else
220 printf "$1 is not a valid option\n"
221 return 1
222 fi
223
224 if [ -n $filename ]; then
225 present=$(cat $SYSFS/power/state | grep $filename)
226
227 if [ -z "$present" ]; then
228 printf "Tried to $1 but $filename isn't present in $SYSFS/power/state\n"
229 return 1;
230 fi
231
232 for i in `seq 1 $2`; do
233 printf "Starting $1\n"
234 echo $filename > $SYSFS/power/state
235 printf "Came out of $1\n"
236
237 printf "Do basic tests after finishing $1 to verify cpufreq state\n\n"
238 cpufreq_basic_tests
239 done
240 fi
241}
diff --git a/tools/testing/selftests/cpufreq/governor.sh b/tools/testing/selftests/cpufreq/governor.sh
new file mode 100755
index 000000000000..def645103555
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/governor.sh
@@ -0,0 +1,153 @@
1#!/bin/bash
2#
3# Test governors
4
5# protect against multiple inclusion
6if [ $FILE_GOVERNOR ]; then
7 return 0
8else
9 FILE_GOVERNOR=DONE
10fi
11
12source cpu.sh
13source cpufreq.sh
14
15CUR_GOV=
16CUR_FREQ=
17
18# Find governor's directory path
19# $1: policy, $2: governor
20find_gov_directory()
21{
22 if [ -d $CPUFREQROOT/$2 ]; then
23 printf "$CPUFREQROOT/$2\n"
24 elif [ -d $CPUFREQROOT/$1/$2 ]; then
25 printf "$CPUFREQROOT/$1/$2\n"
26 else
27 printf "INVALID\n"
28 fi
29}
30
31# $1: policy
32find_current_governor()
33{
34 cat $CPUFREQROOT/$1/scaling_governor
35}
36
37# $1: policy
38backup_governor()
39{
40 CUR_GOV=$(find_current_governor $1)
41
42 printf "Governor backup done for $1: $CUR_GOV\n"
43
44 if [ $CUR_GOV == "userspace" ]; then
45 CUR_FREQ=$(find_current_freq $1)
46 printf "Governor frequency backup done for $1: $CUR_FREQ\n"
47 fi
48
49 printf "\n"
50}
51
52# $1: policy
53restore_governor()
54{
55 __switch_governor $1 $CUR_GOV
56
57 printf "Governor restored for $1 to $CUR_GOV\n"
58
59 if [ $CUR_GOV == "userspace" ]; then
60 set_cpu_frequency $1 $CUR_FREQ
61 printf "Governor frequency restored for $1: $CUR_FREQ\n"
62 fi
63
64 printf "\n"
65}
66
67# param:
68# $1: policy, $2: governor
69__switch_governor()
70{
71 echo $2 > $CPUFREQROOT/$1/scaling_governor
72}
73
74# param:
75# $1: cpu, $2: governor
76__switch_governor_for_cpu()
77{
78 echo $2 > $CPUROOT/$1/cpufreq/scaling_governor
79}
80
81# SWITCH GOVERNORS
82
83# $1: cpu, $2: governor
84switch_governor()
85{
86 local filepath=$CPUFREQROOT/$1/scaling_available_governors
87
88 # check if governor is available
89 local found=$(cat $filepath | grep $2 | wc -l)
90 if [ $found = 0 ]; then
91 echo 1;
92 return
93 fi
94
95 __switch_governor $1 $2
96 echo 0;
97}
98
99# $1: policy, $2: governor
100switch_show_governor()
101{
102 cur_gov=find_current_governor
103 if [ $cur_gov == "userspace" ]; then
104 cur_freq=find_current_freq
105 fi
106
107 # switch governor
108 __switch_governor $1 $2
109
110 printf "\nSwitched governor for $1 to $2\n\n"
111
112 if [ $2 == "userspace" -o $2 == "powersave" -o $2 == "performance" ]; then
113 printf "No files to read for $2 governor\n\n"
114 return
115 fi
116
117 # show governor files
118 local govpath=$(find_gov_directory $1 $2)
119 read_cpufreq_files_in_dir $govpath
120}
121
122# $1: function to be called, $2: policy
123call_for_each_governor()
124{
125 local filepath=$CPUFREQROOT/$2/scaling_available_governors
126
127 # Exit if cpu isn't managed by cpufreq core
128 if [ ! -f $filepath ]; then
129 return;
130 fi
131
132 backup_governor $2
133
134 local governors=$(cat $filepath)
135 printf "Available governors for $2: $governors\n"
136
137 for governor in $governors; do
138 $1 $2 $governor
139 done
140
141 restore_governor $2
142}
143
144# $1: loop count
145shuffle_governors_for_all_cpus()
146{
147 printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n"
148
149 for i in `seq 1 $1`; do
150 for_each_policy call_for_each_governor switch_show_governor
151 done
152 printf "%s\n\n" "------------------------------------------------"
153}
diff --git a/tools/testing/selftests/cpufreq/main.sh b/tools/testing/selftests/cpufreq/main.sh
new file mode 100755
index 000000000000..01bac76ac0ec
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/main.sh
@@ -0,0 +1,194 @@
1#!/bin/bash
2
3source cpu.sh
4source cpufreq.sh
5source governor.sh
6source module.sh
7source special-tests.sh
8
9FUNC=basic # do basic tests by default
10OUTFILE=cpufreq_selftest
11SYSFS=
12CPUROOT=
13CPUFREQROOT=
14
15helpme()
16{
17 printf "Usage: $0 [-h] [-todg args]
18 [-h <help>]
19 [-o <output-file-for-dump>]
20 [-t <basic: Basic cpufreq testing
21 suspend: suspend/resume,
22 hibernate: hibernate/resume,
23 modtest: test driver or governor modules. Only to be used with -d or -g options,
24 sptest1: Simple governor switch to produce lockdep.
25 sptest2: Concurrent governor switch to produce lockdep.
26 sptest3: Governor races, shuffle between governors quickly.
27 sptest4: CPU hotplugs with updates to cpufreq files.>]
28 [-d <driver's module name: only with \"-t modtest>\"]
29 [-g <governor's module name: only with \"-t modtest>\"]
30 \n"
31 exit 2
32}
33
34prerequisite()
35{
36 msg="skip all tests:"
37
38 if [ $UID != 0 ]; then
39 echo $msg must be run as root >&2
40 exit 2
41 fi
42
43 taskset -p 01 $$
44
45 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
46
47 if [ ! -d "$SYSFS" ]; then
48 echo $msg sysfs is not mounted >&2
49 exit 2
50 fi
51
52 CPUROOT=$SYSFS/devices/system/cpu
53 CPUFREQROOT="$CPUROOT/cpufreq"
54
55 if ! ls $CPUROOT/cpu* > /dev/null 2>&1; then
56 echo $msg cpus not available in sysfs >&2
57 exit 2
58 fi
59
60 if ! ls $CPUROOT/cpufreq > /dev/null 2>&1; then
61 echo $msg cpufreq directory not available in sysfs >&2
62 exit 2
63 fi
64}
65
66parse_arguments()
67{
68 while getopts ht:o:d:g: arg
69 do
70 case $arg in
71 h) # --help
72 helpme
73 ;;
74
75 t) # --func_type (Function to perform: basic, suspend, hibernate, modtest, sptest1/2/3/4 (default: basic))
76 FUNC=$OPTARG
77 ;;
78
79 o) # --output-file (Output file to store dumps)
80 OUTFILE=$OPTARG
81 ;;
82
83 d) # --driver-mod-name (Name of the driver module)
84 DRIVER_MOD=$OPTARG
85 ;;
86
87 g) # --governor-mod-name (Name of the governor module)
88 GOVERNOR_MOD=$OPTARG
89 ;;
90
91 \?)
92 helpme
93 ;;
94 esac
95 done
96}
97
98do_test()
99{
100 # Check if CPUs are managed by cpufreq or not
101 count=$(count_cpufreq_managed_cpus)
102
103 if [ $count = 0 -a $FUNC != "modtest" ]; then
104 echo "No cpu is managed by cpufreq core, exiting"
105 exit 2;
106 fi
107
108 case "$FUNC" in
109 "basic")
110 cpufreq_basic_tests
111 ;;
112
113 "suspend")
114 do_suspend "suspend" 1
115 ;;
116
117 "hibernate")
118 do_suspend "hibernate" 1
119 ;;
120
121 "modtest")
122 # Do we have modules in place?
123 if [ -z $DRIVER_MOD ] && [ -z $GOVERNOR_MOD ]; then
124 echo "No driver or governor module passed with -d or -g"
125 exit 2;
126 fi
127
128 if [ $DRIVER_MOD ]; then
129 if [ $GOVERNOR_MOD ]; then
130 module_test $DRIVER_MOD $GOVERNOR_MOD
131 else
132 module_driver_test $DRIVER_MOD
133 fi
134 else
135 if [ $count = 0 ]; then
136 echo "No cpu is managed by cpufreq core, exiting"
137 exit 2;
138 fi
139
140 module_governor_test $GOVERNOR_MOD
141 fi
142 ;;
143
144 "sptest1")
145 simple_lockdep
146 ;;
147
148 "sptest2")
149 concurrent_lockdep
150 ;;
151
152 "sptest3")
153 governor_race
154 ;;
155
156 "sptest4")
157 hotplug_with_updates
158 ;;
159
160 *)
161 echo "Invalid [-f] function type"
162 helpme
163 ;;
164 esac
165}
166
167# clear dumps
168# $1: file name
169clear_dumps()
170{
171 echo "" > $1.txt
172 echo "" > $1.dmesg_cpufreq.txt
173 echo "" > $1.dmesg_full.txt
174}
175
176# $1: output file name
177dmesg_dumps()
178{
179 dmesg | grep cpufreq >> $1.dmesg_cpufreq.txt
180
181 # We may need the full logs as well
182 dmesg >> $1.dmesg_full.txt
183}
184
185# Parse arguments
186parse_arguments $@
187
188# Make sure all requirements are met
189prerequisite
190
191# Run requested functions
192clear_dumps $OUTFILE
193do_test >> $OUTFILE.txt
194dmesg_dumps $OUTFILE
diff --git a/tools/testing/selftests/cpufreq/module.sh b/tools/testing/selftests/cpufreq/module.sh
new file mode 100755
index 000000000000..8ff2244a33a1
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/module.sh
@@ -0,0 +1,243 @@
1#!/bin/bash
2#
3# Modules specific tests cases
4
5# protect against multiple inclusion
6if [ $FILE_MODULE ]; then
7 return 0
8else
9 FILE_MODULE=DONE
10fi
11
12source cpu.sh
13source cpufreq.sh
14source governor.sh
15
16# Check basic insmod/rmmod
17# $1: module
18test_basic_insmod_rmmod()
19{
20 printf "** Test: Running ${FUNCNAME[0]} **\n\n"
21
22 printf "Inserting $1 module\n"
23 # insert module
24 insmod $1
25 if [ $? != 0 ]; then
26 printf "Insmod $1 failed\n"
27 exit;
28 fi
29
30 printf "Removing $1 module\n"
31 # remove module
32 rmmod $1
33 if [ $? != 0 ]; then
34 printf "rmmod $1 failed\n"
35 exit;
36 fi
37
38 printf "\n"
39}
40
41# Insert cpufreq driver module and perform basic tests
42# $1: cpufreq-driver module to insert
43# $2: If we want to play with CPUs (1) or not (0)
44module_driver_test_single()
45{
46 printf "** Test: Running ${FUNCNAME[0]} for driver $1 and cpus_hotplug=$2 **\n\n"
47
48 if [ $2 -eq 1 ]; then
49 # offline all non-boot CPUs
50 for_each_non_boot_cpu offline_cpu
51 printf "\n"
52 fi
53
54 # insert module
55 printf "Inserting $1 module\n\n"
56 insmod $1
57 if [ $? != 0 ]; then
58 printf "Insmod $1 failed\n"
59 return;
60 fi
61
62 if [ $2 -eq 1 ]; then
63 # online all non-boot CPUs
64 for_each_non_boot_cpu online_cpu
65 printf "\n"
66 fi
67
68 # run basic tests
69 cpufreq_basic_tests
70
71 # remove module
72 printf "Removing $1 module\n\n"
73 rmmod $1
74 if [ $? != 0 ]; then
75 printf "rmmod $1 failed\n"
76 return;
77 fi
78
79 # There shouldn't be any cpufreq directories now.
80 for_each_cpu cpu_should_not_have_cpufreq_directory
81 printf "\n"
82}
83
84# $1: cpufreq-driver module to insert
85module_driver_test()
86{
87 printf "** Test: Running ${FUNCNAME[0]} **\n\n"
88
89 # check if module is present or not
90 ls $1 > /dev/null
91 if [ $? != 0 ]; then
92 printf "$1: not present in `pwd` folder\n"
93 return;
94 fi
95
96 # test basic module tests
97 test_basic_insmod_rmmod $1
98
99 # Do simple module test
100 module_driver_test_single $1 0
101
102 # Remove CPUs before inserting module and then bring them back
103 module_driver_test_single $1 1
104 printf "\n"
105}
106
107# find governor name based on governor module name
108# $1: governor module name
109find_gov_name()
110{
111 if [ $1 = "cpufreq_ondemand.ko" ]; then
112 printf "ondemand"
113 elif [ $1 = "cpufreq_conservative.ko" ]; then
114 printf "conservative"
115 elif [ $1 = "cpufreq_userspace.ko" ]; then
116 printf "userspace"
117 elif [ $1 = "cpufreq_performance.ko" ]; then
118 printf "performance"
119 elif [ $1 = "cpufreq_powersave.ko" ]; then
120 printf "powersave"
121 elif [ $1 = "cpufreq_schedutil.ko" ]; then
122 printf "schedutil"
123 fi
124}
125
126# $1: governor string, $2: governor module, $3: policy
127# example: module_governor_test_single "ondemand" "cpufreq_ondemand.ko" 2
128module_governor_test_single()
129{
130 printf "** Test: Running ${FUNCNAME[0]} for $3 **\n\n"
131
132 backup_governor $3
133
134 # switch to new governor
135 printf "Switch from $CUR_GOV to $1\n"
136 switch_show_governor $3 $1
137
138 # try removing module, it should fail as governor is used
139 printf "Removing $2 module\n\n"
140 rmmod $2
141 if [ $? = 0 ]; then
142 printf "WARN: rmmod $2 succeeded even if governor is used\n"
143 insmod $2
144 else
145 printf "Pass: unable to remove $2 while it is being used\n\n"
146 fi
147
148 # switch back to old governor
149 printf "Switchback to $CUR_GOV from $1\n"
150 restore_governor $3
151 printf "\n"
152}
153
154# Insert cpufreq governor module and perform basic tests
155# $1: cpufreq-governor module to insert
156module_governor_test()
157{
158 printf "** Test: Running ${FUNCNAME[0]} **\n\n"
159
160 # check if module is present or not
161 ls $1 > /dev/null
162 if [ $? != 0 ]; then
163 printf "$1: not present in `pwd` folder\n"
164 return;
165 fi
166
167 # test basic module tests
168 test_basic_insmod_rmmod $1
169
170 # insert module
171 printf "Inserting $1 module\n\n"
172 insmod $1
173 if [ $? != 0 ]; then
174 printf "Insmod $1 failed\n"
175 return;
176 fi
177
178 # switch to new governor for each cpu
179 for_each_policy module_governor_test_single $(find_gov_name $1) $1
180
181 # remove module
182 printf "Removing $1 module\n\n"
183 rmmod $1
184 if [ $? != 0 ]; then
185 printf "rmmod $1 failed\n"
186 return;
187 fi
188 printf "\n"
189}
190
191# test modules: driver and governor
192# $1: driver module, $2: governor module
193module_test()
194{
195 printf "** Test: Running ${FUNCNAME[0]} **\n\n"
196
197 # check if modules are present or not
198 ls $1 $2 > /dev/null
199 if [ $? != 0 ]; then
200 printf "$1 or $2: is not present in `pwd` folder\n"
201 return;
202 fi
203
204 # TEST1: Insert gov after driver
205 # insert driver module
206 printf "Inserting $1 module\n\n"
207 insmod $1
208 if [ $? != 0 ]; then
209 printf "Insmod $1 failed\n"
210 return;
211 fi
212
213 # run governor tests
214 module_governor_test $2
215
216 # remove driver module
217 printf "Removing $1 module\n\n"
218 rmmod $1
219 if [ $? != 0 ]; then
220 printf "rmmod $1 failed\n"
221 return;
222 fi
223
224 # TEST2: Insert driver after governor
225 # insert governor module
226 printf "Inserting $2 module\n\n"
227 insmod $2
228 if [ $? != 0 ]; then
229 printf "Insmod $2 failed\n"
230 return;
231 fi
232
233 # run governor tests
234 module_driver_test $1
235
236 # remove driver module
237 printf "Removing $2 module\n\n"
238 rmmod $2
239 if [ $? != 0 ]; then
240 printf "rmmod $2 failed\n"
241 return;
242 fi
243}
diff --git a/tools/testing/selftests/cpufreq/special-tests.sh b/tools/testing/selftests/cpufreq/special-tests.sh
new file mode 100755
index 000000000000..58b730f23ef7
--- /dev/null
+++ b/tools/testing/selftests/cpufreq/special-tests.sh
@@ -0,0 +1,115 @@
1#!/bin/bash
2#
3# Special test cases reported by people
4
5# Testcase 1: Reported here: http://marc.info/?l=linux-pm&m=140618592709858&w=2
6
7# protect against multiple inclusion
8if [ $FILE_SPECIAL ]; then
9 return 0
10else
11 FILE_SPECIAL=DONE
12fi
13
14source cpu.sh
15source cpufreq.sh
16source governor.sh
17
18# Test 1
19# $1: policy
20__simple_lockdep()
21{
22 # switch to ondemand
23 __switch_governor $1 "ondemand"
24
25 # cat ondemand files
26 local ondir=$(find_gov_directory $1 "ondemand")
27 if [ -z $ondir ]; then
28 printf "${FUNCNAME[0]}Ondemand directory not created, quit"
29 return
30 fi
31
32 cat $ondir/*
33
34 # switch to conservative
35 __switch_governor $1 "conservative"
36}
37
38simple_lockdep()
39{
40 printf "** Test: Running ${FUNCNAME[0]} **\n"
41
42 for_each_policy __simple_lockdep
43}
44
45# Test 2
46# $1: policy
47__concurrent_lockdep()
48{
49 for i in `seq 0 100`; do
50 __simple_lockdep $1
51 done
52}
53
54concurrent_lockdep()
55{
56 printf "** Test: Running ${FUNCNAME[0]} **\n"
57
58 for_each_policy_concurrent __concurrent_lockdep
59}
60
61# Test 3
62quick_shuffle()
63{
64 # this is called concurrently from governor_race
65 for I in `seq 1000`
66 do
67 echo ondemand | sudo tee $CPUFREQROOT/policy*/scaling_governor &
68 echo userspace | sudo tee $CPUFREQROOT/policy*/scaling_governor &
69 done
70}
71
72governor_race()
73{
74 printf "** Test: Running ${FUNCNAME[0]} **\n"
75
76 # run 8 concurrent instances
77 for I in `seq 8`
78 do
79 quick_shuffle &
80 done
81}
82
83# Test 4
84# $1: cpu
85hotplug_with_updates_cpu()
86{
87 local filepath="$CPUROOT/$1/cpufreq"
88
89 # switch to ondemand
90 __switch_governor_for_cpu $1 "ondemand"
91
92 for i in `seq 1 5000`
93 do
94 reboot_cpu $1
95 done &
96
97 local freqs=$(cat $filepath/scaling_available_frequencies)
98 local oldfreq=$(cat $filepath/scaling_min_freq)
99
100 for j in `seq 1 5000`
101 do
102 # Set all frequencies one-by-one
103 for freq in $freqs; do
104 echo $freq > $filepath/scaling_min_freq
105 done
106 done
107
108 # restore old freq
109 echo $oldfreq > $filepath/scaling_min_freq
110}
111
112hotplug_with_updates()
113{
114 for_each_non_boot_cpu hotplug_with_updates_cpu
115}
diff --git a/tools/testing/selftests/drivers/gpu/drm_mm.sh b/tools/testing/selftests/drivers/gpu/drm_mm.sh
new file mode 100755
index 000000000000..96dd55c92799
--- /dev/null
+++ b/tools/testing/selftests/drivers/gpu/drm_mm.sh
@@ -0,0 +1,15 @@
1#!/bin/sh
2# Runs API tests for struct drm_mm (DRM range manager)
3
4if ! /sbin/modprobe -n -q test-drm_mm; then
5 echo "drivers/gpu/drm_mm: [skip]"
6 exit 77
7fi
8
9if /sbin/modprobe -q test-drm_mm; then
10 /sbin/modprobe -q -r test-drm_mm
11 echo "drivers/gpu/drm_mm: ok"
12else
13 echo "drivers/gpu/drm_mm: [FAIL]"
14 exit 1
15fi
diff --git a/tools/testing/selftests/efivarfs/Makefile b/tools/testing/selftests/efivarfs/Makefile
index 736c3ddfc787..c49dcea69319 100644
--- a/tools/testing/selftests/efivarfs/Makefile
+++ b/tools/testing/selftests/efivarfs/Makefile
@@ -1,13 +1,7 @@
1CFLAGS = -Wall 1CFLAGS = -Wall
2 2
3test_objs = open-unlink create-read 3TEST_GEN_FILES := open-unlink create-read
4
5all: $(test_objs)
6
7TEST_PROGS := efivarfs.sh 4TEST_PROGS := efivarfs.sh
8TEST_FILES := $(test_objs)
9 5
10include ../lib.mk 6include ../lib.mk
11 7
12clean:
13 rm -f $(test_objs)
diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile
index d4300602bf37..2e13035dff7f 100644
--- a/tools/testing/selftests/exec/Makefile
+++ b/tools/testing/selftests/exec/Makefile
@@ -1,27 +1,23 @@
1CFLAGS = -Wall 1CFLAGS = -Wall
2BINARIES = execveat
3DEPS = execveat.symlink execveat.denatured script subdir
4all: $(BINARIES) $(DEPS)
5 2
6subdir: 3TEST_GEN_PROGS := execveat
4TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir
5# Makefile is a run-time dependency, since it's accessed by the execveat test
6TEST_FILES := Makefile
7
8EXTRA_CLEAN := $(OUTPUT)/subdir.moved $(OUTPUT)/execveat.moved $(OUTPUT)/xxxxx*
9
10include ../lib.mk
11
12$(OUTPUT)/subdir:
7 mkdir -p $@ 13 mkdir -p $@
8script: 14$(OUTPUT)/script:
9 echo '#!/bin/sh' > $@ 15 echo '#!/bin/sh' > $@
10 echo 'exit $$*' >> $@ 16 echo 'exit $$*' >> $@
11 chmod +x $@ 17 chmod +x $@
12execveat.symlink: execveat 18$(OUTPUT)/execveat.symlink: $(OUTPUT)/execveat
13 ln -s -f $< $@ 19 cd $(OUTPUT) && ln -s -f $(shell basename $<) $(shell basename $@)
14execveat.denatured: execveat 20$(OUTPUT)/execveat.denatured: $(OUTPUT)/execveat
15 cp $< $@ 21 cp $< $@
16 chmod -x $@ 22 chmod -x $@
17%: %.c
18 $(CC) $(CFLAGS) -o $@ $^
19
20TEST_PROGS := execveat
21# Makefile is a run-time dependency, since it's accessed by the execveat test
22TEST_FILES := $(DEPS) Makefile
23
24include ../lib.mk
25 23
26clean:
27 rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx*
diff --git a/tools/testing/selftests/firmware/Makefile b/tools/testing/selftests/firmware/Makefile
index 9bf82234855b..1894d625af2d 100644
--- a/tools/testing/selftests/firmware/Makefile
+++ b/tools/testing/selftests/firmware/Makefile
@@ -3,7 +3,7 @@
3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
4all: 4all:
5 5
6TEST_PROGS := fw_filesystem.sh fw_userhelper.sh 6TEST_PROGS := fw_filesystem.sh fw_fallback.sh
7 7
8include ../lib.mk 8include ../lib.mk
9 9
diff --git a/tools/testing/selftests/firmware/fw_fallback.sh b/tools/testing/selftests/firmware/fw_fallback.sh
new file mode 100755
index 000000000000..2e4c22d5abf7
--- /dev/null
+++ b/tools/testing/selftests/firmware/fw_fallback.sh
@@ -0,0 +1,224 @@
1#!/bin/sh
2# This validates that the kernel will fall back to using the fallback mechanism
3# to load firmware it can't find on disk itself. We must request a firmware
4# that the kernel won't find, and any installed helper (e.g. udev) also
5# won't find so that we can do the load ourself manually.
6set -e
7
8modprobe test_firmware
9
10DIR=/sys/devices/virtual/misc/test_firmware
11
12# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
13# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
14# as an indicator for CONFIG_FW_LOADER_USER_HELPER.
15HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
16
17if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
18 OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
19else
20 echo "usermode helper disabled so ignoring test"
21 exit 0
22fi
23
24FWPATH=$(mktemp -d)
25FW="$FWPATH/test-firmware.bin"
26
27test_finish()
28{
29 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
30 rm -f "$FW"
31 rmdir "$FWPATH"
32}
33
34load_fw()
35{
36 local name="$1"
37 local file="$2"
38
39 # This will block until our load (below) has finished.
40 echo -n "$name" >"$DIR"/trigger_request &
41
42 # Give kernel a chance to react.
43 local timeout=10
44 while [ ! -e "$DIR"/"$name"/loading ]; do
45 sleep 0.1
46 timeout=$(( $timeout - 1 ))
47 if [ "$timeout" -eq 0 ]; then
48 echo "$0: firmware interface never appeared" >&2
49 exit 1
50 fi
51 done
52
53 echo 1 >"$DIR"/"$name"/loading
54 cat "$file" >"$DIR"/"$name"/data
55 echo 0 >"$DIR"/"$name"/loading
56
57 # Wait for request to finish.
58 wait
59}
60
61load_fw_cancel()
62{
63 local name="$1"
64 local file="$2"
65
66 # This will block until our load (below) has finished.
67 echo -n "$name" >"$DIR"/trigger_request 2>/dev/null &
68
69 # Give kernel a chance to react.
70 local timeout=10
71 while [ ! -e "$DIR"/"$name"/loading ]; do
72 sleep 0.1
73 timeout=$(( $timeout - 1 ))
74 if [ "$timeout" -eq 0 ]; then
75 echo "$0: firmware interface never appeared" >&2
76 exit 1
77 fi
78 done
79
80 echo -1 >"$DIR"/"$name"/loading
81
82 # Wait for request to finish.
83 wait
84}
85
86load_fw_custom()
87{
88 local name="$1"
89 local file="$2"
90
91 echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &
92
93 # Give kernel a chance to react.
94 local timeout=10
95 while [ ! -e "$DIR"/"$name"/loading ]; do
96 sleep 0.1
97 timeout=$(( $timeout - 1 ))
98 if [ "$timeout" -eq 0 ]; then
99 echo "$0: firmware interface never appeared" >&2
100 exit 1
101 fi
102 done
103
104 echo 1 >"$DIR"/"$name"/loading
105 cat "$file" >"$DIR"/"$name"/data
106 echo 0 >"$DIR"/"$name"/loading
107
108 # Wait for request to finish.
109 wait
110}
111
112
113load_fw_custom_cancel()
114{
115 local name="$1"
116 local file="$2"
117
118 echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &
119
120 # Give kernel a chance to react.
121 local timeout=10
122 while [ ! -e "$DIR"/"$name"/loading ]; do
123 sleep 0.1
124 timeout=$(( $timeout - 1 ))
125 if [ "$timeout" -eq 0 ]; then
126 echo "$0: firmware interface never appeared" >&2
127 exit 1
128 fi
129 done
130
131 echo -1 >"$DIR"/"$name"/loading
132
133 # Wait for request to finish.
134 wait
135}
136
137
138trap "test_finish" EXIT
139
140# This is an unlikely real-world firmware content. :)
141echo "ABCD0123" >"$FW"
142NAME=$(basename "$FW")
143
144DEVPATH="$DIR"/"nope-$NAME"/loading
145
146# Test failure when doing nothing (timeout works).
147echo -n 2 >/sys/class/firmware/timeout
148echo -n "nope-$NAME" >"$DIR"/trigger_request 2>/dev/null &
149
150# Give the kernel some time to load the loading file, must be less
151# than the timeout above.
152sleep 1
153if [ ! -f $DEVPATH ]; then
154 echo "$0: fallback mechanism immediately cancelled"
155 echo ""
156 echo "The file never appeared: $DEVPATH"
157 echo ""
158 echo "This might be a distribution udev rule setup by your distribution"
159 echo "to immediately cancel all fallback requests, this must be"
160 echo "removed before running these tests. To confirm look for"
161 echo "a firmware rule like /lib/udev/rules.d/50-firmware.rules"
162 echo "and see if you have something like this:"
163 echo ""
164 echo "SUBSYSTEM==\"firmware\", ACTION==\"add\", ATTR{loading}=\"-1\""
165 echo ""
166 echo "If you do remove this file or comment out this line before"
167 echo "proceeding with these tests."
168 exit 1
169fi
170
171if diff -q "$FW" /dev/test_firmware >/dev/null ; then
172 echo "$0: firmware was not expected to match" >&2
173 exit 1
174else
175 echo "$0: timeout works"
176fi
177
178# Put timeout high enough for us to do work but not so long that failures
179# slow down this test too much.
180echo 4 >/sys/class/firmware/timeout
181
182# Load this script instead of the desired firmware.
183load_fw "$NAME" "$0"
184if diff -q "$FW" /dev/test_firmware >/dev/null ; then
185 echo "$0: firmware was not expected to match" >&2
186 exit 1
187else
188 echo "$0: firmware comparison works"
189fi
190
191# Do a proper load, which should work correctly.
192load_fw "$NAME" "$FW"
193if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
194 echo "$0: firmware was not loaded" >&2
195 exit 1
196else
197 echo "$0: fallback mechanism works"
198fi
199
200load_fw_cancel "nope-$NAME" "$FW"
201if diff -q "$FW" /dev/test_firmware >/dev/null ; then
202 echo "$0: firmware was expected to be cancelled" >&2
203 exit 1
204else
205 echo "$0: cancelling fallback mechanism works"
206fi
207
208load_fw_custom "$NAME" "$FW"
209if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
210 echo "$0: firmware was not loaded" >&2
211 exit 1
212else
213 echo "$0: custom fallback loading mechanism works"
214fi
215
216load_fw_custom_cancel "nope-$NAME" "$FW"
217if diff -q "$FW" /dev/test_firmware >/dev/null ; then
218 echo "$0: firmware was expected to be cancelled" >&2
219 exit 1
220else
221 echo "$0: cancelling custom fallback mechanism works"
222fi
223
224exit 0
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh
index 5c495ad7958a..e35691239350 100755
--- a/tools/testing/selftests/firmware/fw_filesystem.sh
+++ b/tools/testing/selftests/firmware/fw_filesystem.sh
@@ -5,9 +5,24 @@
5# know so we can be sure we're not accidentally testing the user helper. 5# know so we can be sure we're not accidentally testing the user helper.
6set -e 6set -e
7 7
8modprobe test_firmware
9
10DIR=/sys/devices/virtual/misc/test_firmware 8DIR=/sys/devices/virtual/misc/test_firmware
9TEST_DIR=$(dirname $0)
10
11test_modprobe()
12{
13 if [ ! -d $DIR ]; then
14 echo "$0: $DIR not present"
15 echo "You must have the following enabled in your kernel:"
16 cat $TEST_DIR/config
17 exit 1
18 fi
19}
20
21trap "test_modprobe" EXIT
22
23if [ ! -d $DIR ]; then
24 modprobe test_firmware
25fi
11 26
12# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/ 27# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
13# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that 28# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
@@ -48,18 +63,18 @@ echo "ABCD0123" >"$FW"
48 63
49NAME=$(basename "$FW") 64NAME=$(basename "$FW")
50 65
51if printf '\000' >"$DIR"/trigger_request; then 66if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then
52 echo "$0: empty filename should not succeed" >&2 67 echo "$0: empty filename should not succeed" >&2
53 exit 1 68 exit 1
54fi 69fi
55 70
56if printf '\000' >"$DIR"/trigger_async_request; then 71if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
57 echo "$0: empty filename should not succeed (async)" >&2 72 echo "$0: empty filename should not succeed (async)" >&2
58 exit 1 73 exit 1
59fi 74fi
60 75
61# Request a firmware that doesn't exist, it should fail. 76# Request a firmware that doesn't exist, it should fail.
62if echo -n "nope-$NAME" >"$DIR"/trigger_request; then 77if echo -n "nope-$NAME" >"$DIR"/trigger_request 2> /dev/null; then
63 echo "$0: firmware shouldn't have loaded" >&2 78 echo "$0: firmware shouldn't have loaded" >&2
64 exit 1 79 exit 1
65fi 80fi
diff --git a/tools/testing/selftests/firmware/fw_userhelper.sh b/tools/testing/selftests/firmware/fw_userhelper.sh
deleted file mode 100755
index b9983f8e09f6..000000000000
--- a/tools/testing/selftests/firmware/fw_userhelper.sh
+++ /dev/null
@@ -1,99 +0,0 @@
1#!/bin/sh
2# This validates that the kernel will fall back to using the user helper
3# to load firmware it can't find on disk itself. We must request a firmware
4# that the kernel won't find, and any installed helper (e.g. udev) also
5# won't find so that we can do the load ourself manually.
6set -e
7
8modprobe test_firmware
9
10DIR=/sys/devices/virtual/misc/test_firmware
11
12# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
13# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
14# as an indicator for CONFIG_FW_LOADER_USER_HELPER.
15HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
16
17if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
18 OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
19else
20 echo "usermode helper disabled so ignoring test"
21 exit 0
22fi
23
24FWPATH=$(mktemp -d)
25FW="$FWPATH/test-firmware.bin"
26
27test_finish()
28{
29 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
30 rm -f "$FW"
31 rmdir "$FWPATH"
32}
33
34load_fw()
35{
36 local name="$1"
37 local file="$2"
38
39 # This will block until our load (below) has finished.
40 echo -n "$name" >"$DIR"/trigger_request &
41
42 # Give kernel a chance to react.
43 local timeout=10
44 while [ ! -e "$DIR"/"$name"/loading ]; do
45 sleep 0.1
46 timeout=$(( $timeout - 1 ))
47 if [ "$timeout" -eq 0 ]; then
48 echo "$0: firmware interface never appeared" >&2
49 exit 1
50 fi
51 done
52
53 echo 1 >"$DIR"/"$name"/loading
54 cat "$file" >"$DIR"/"$name"/data
55 echo 0 >"$DIR"/"$name"/loading
56
57 # Wait for request to finish.
58 wait
59}
60
61trap "test_finish" EXIT
62
63# This is an unlikely real-world firmware content. :)
64echo "ABCD0123" >"$FW"
65NAME=$(basename "$FW")
66
67# Test failure when doing nothing (timeout works).
68echo 1 >/sys/class/firmware/timeout
69echo -n "$NAME" >"$DIR"/trigger_request
70if diff -q "$FW" /dev/test_firmware >/dev/null ; then
71 echo "$0: firmware was not expected to match" >&2
72 exit 1
73else
74 echo "$0: timeout works"
75fi
76
77# Put timeout high enough for us to do work but not so long that failures
78# slow down this test too much.
79echo 4 >/sys/class/firmware/timeout
80
81# Load this script instead of the desired firmware.
82load_fw "$NAME" "$0"
83if diff -q "$FW" /dev/test_firmware >/dev/null ; then
84 echo "$0: firmware was not expected to match" >&2
85 exit 1
86else
87 echo "$0: firmware comparison works"
88fi
89
90# Do a proper load, which should work correctly.
91load_fw "$NAME" "$FW"
92if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
93 echo "$0: firmware was not loaded" >&2
94 exit 1
95else
96 echo "$0: user helper firmware loading works"
97fi
98
99exit 0
diff --git a/tools/testing/selftests/ftrace/Makefile b/tools/testing/selftests/ftrace/Makefile
index 4e6ed13e7f66..a8a5e21850e7 100644
--- a/tools/testing/selftests/ftrace/Makefile
+++ b/tools/testing/selftests/ftrace/Makefile
@@ -1,9 +1,7 @@
1all: 1all:
2 2
3TEST_PROGS := ftracetest 3TEST_PROGS := ftracetest
4TEST_DIRS := test.d 4TEST_FILES := test.d
5EXTRA_CLEAN := $(OUTPUT)/logs/*
5 6
6include ../lib.mk 7include ../lib.mk
7
8clean:
9 rm -rf logs/*
diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile
index 6a1752956283..653c5cd9e44d 100644
--- a/tools/testing/selftests/futex/Makefile
+++ b/tools/testing/selftests/futex/Makefile
@@ -3,13 +3,18 @@ SUBDIRS := functional
3TEST_PROGS := run.sh 3TEST_PROGS := run.sh
4 4
5.PHONY: all clean 5.PHONY: all clean
6all:
7 for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done
8 6
9include ../lib.mk 7include ../lib.mk
10 8
9all:
10 for DIR in $(SUBDIRS); do \
11 BUILD_TARGET=$$OUTPUT/$$DIR; \
12 mkdir $$BUILD_TARGET -p; \
13 make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
14 done
15
11override define RUN_TESTS 16override define RUN_TESTS
12 ./run.sh 17 @if [ `dirname $(OUTPUT)` = $(PWD) ]; then ./run.sh; fi
13endef 18endef
14 19
15override define INSTALL_RULE 20override define INSTALL_RULE
@@ -17,7 +22,9 @@ override define INSTALL_RULE
17 install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) 22 install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES)
18 23
19 @for SUBDIR in $(SUBDIRS); do \ 24 @for SUBDIR in $(SUBDIRS); do \
20 $(MAKE) -C $$SUBDIR INSTALL_PATH=$(INSTALL_PATH)/$$SUBDIR install; \ 25 BUILD_TARGET=$$OUTPUT/$$SUBDIR; \
26 mkdir $$BUILD_TARGET -p; \
27 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$SUBDIR INSTALL_PATH=$(INSTALL_PATH)/$$SUBDIR install; \
21 done; 28 done;
22endef 29endef
23 30
@@ -26,4 +33,8 @@ override define EMIT_TESTS
26endef 33endef
27 34
28clean: 35clean:
29 for DIR in $(SUBDIRS); do $(MAKE) -C $$DIR $@ ; done 36 for DIR in $(SUBDIRS); do \
37 BUILD_TARGET=$$OUTPUT/$$DIR; \
38 mkdir $$BUILD_TARGET -p; \
39 make OUTPUT=$$BUILD_TARGET -C $$DIR $@;\
40 done
diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile
index 9d6b75ef7b5d..a648e7a6cbc3 100644
--- a/tools/testing/selftests/futex/functional/Makefile
+++ b/tools/testing/selftests/futex/functional/Makefile
@@ -2,8 +2,11 @@ INCLUDES := -I../include -I../../
2CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) 2CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES)
3LDFLAGS := $(LDFLAGS) -pthread -lrt 3LDFLAGS := $(LDFLAGS) -pthread -lrt
4 4
5HEADERS := ../include/futextest.h 5HEADERS := \
6TARGETS := \ 6 ../include/futextest.h \
7 ../include/atomic.h \
8 ../include/logging.h
9TEST_GEN_FILES := \
7 futex_wait_timeout \ 10 futex_wait_timeout \
8 futex_wait_wouldblock \ 11 futex_wait_wouldblock \
9 futex_requeue_pi \ 12 futex_requeue_pi \
@@ -12,14 +15,8 @@ TARGETS := \
12 futex_wait_uninitialized_heap \ 15 futex_wait_uninitialized_heap \
13 futex_wait_private_mapped_file 16 futex_wait_private_mapped_file
14 17
15TEST_PROGS := $(TARGETS) run.sh 18TEST_PROGS := run.sh
16
17.PHONY: all clean
18all: $(TARGETS)
19
20$(TARGETS): $(HEADERS)
21 19
22include ../../lib.mk 20include ../../lib.mk
23 21
24clean: 22$(TEST_GEN_FILES): $(HEADERS)
25 rm -f $(TARGETS)
diff --git a/tools/testing/selftests/futex/include/logging.h b/tools/testing/selftests/futex/include/logging.h
index 014aa01197af..e14469103f07 100644
--- a/tools/testing/selftests/futex/include/logging.h
+++ b/tools/testing/selftests/futex/include/logging.h
@@ -21,6 +21,7 @@
21#ifndef _LOGGING_H 21#ifndef _LOGGING_H
22#define _LOGGING_H 22#define _LOGGING_H
23 23
24#include <stdio.h>
24#include <string.h> 25#include <string.h>
25#include <unistd.h> 26#include <unistd.h>
26#include <linux/futex.h> 27#include <linux/futex.h>
diff --git a/tools/testing/selftests/gpio/.gitignore b/tools/testing/selftests/gpio/.gitignore
new file mode 100644
index 000000000000..7d14f743d1a4
--- /dev/null
+++ b/tools/testing/selftests/gpio/.gitignore
@@ -0,0 +1 @@
gpio-mockup-chardev
diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile
index f5f1a28715ff..19678e90efb2 100644
--- a/tools/testing/selftests/intel_pstate/Makefile
+++ b/tools/testing/selftests/intel_pstate/Makefile
@@ -1,15 +1,10 @@
1CC := $(CROSS_COMPILE)gcc
2CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE 1CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE
3LDFLAGS := $(LDFLAGS) -lm 2LDFLAGS := $(LDFLAGS) -lm
4 3
5TARGETS := msr aperf 4TEST_GEN_FILES := msr aperf
6 5
7TEST_PROGS := $(TARGETS) run.sh 6TEST_PROGS := run.sh
8 7
9.PHONY: all clean 8include ../lib.mk
10all: $(TARGETS)
11 9
12$(TARGETS): $(HEADERS) 10$(TEST_GEN_FILES): $(HEADERS)
13
14clean:
15 rm -f $(TARGETS)
diff --git a/tools/testing/selftests/intel_pstate/aperf.c b/tools/testing/selftests/intel_pstate/aperf.c
index 6046e183f4ad..cd72f3dc83e9 100644
--- a/tools/testing/selftests/intel_pstate/aperf.c
+++ b/tools/testing/selftests/intel_pstate/aperf.c
@@ -14,7 +14,7 @@ void usage(char *name) {
14} 14}
15 15
16int main(int argc, char **argv) { 16int main(int argc, char **argv) {
17 int i, cpu, fd; 17 unsigned int i, cpu, fd;
18 char msr_file_name[64]; 18 char msr_file_name[64];
19 long long tsc, old_tsc, new_tsc; 19 long long tsc, old_tsc, new_tsc;
20 long long aperf, old_aperf, new_aperf; 20 long long aperf, old_aperf, new_aperf;
diff --git a/tools/testing/selftests/ipc/.gitignore b/tools/testing/selftests/ipc/.gitignore
index 84b66a3c1f74..9af04c9353c0 100644
--- a/tools/testing/selftests/ipc/.gitignore
+++ b/tools/testing/selftests/ipc/.gitignore
@@ -1 +1,2 @@
1msgque_test 1msgque_test
2msgque
diff --git a/tools/testing/selftests/ipc/Makefile b/tools/testing/selftests/ipc/Makefile
index 25d2e702c68a..30ef4c7f53ea 100644
--- a/tools/testing/selftests/ipc/Makefile
+++ b/tools/testing/selftests/ipc/Makefile
@@ -11,12 +11,7 @@ endif
11 11
12CFLAGS += -I../../../../usr/include/ 12CFLAGS += -I../../../../usr/include/
13 13
14all: 14TEST_GEN_PROGS := msgque
15 $(CC) $(CFLAGS) msgque.c -o msgque_test
16
17TEST_PROGS := msgque_test
18 15
19include ../lib.mk 16include ../lib.mk
20 17
21clean:
22 rm -fr ./msgque_test
diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile
index 2ae7450a9a89..47aa9887f9d4 100644
--- a/tools/testing/selftests/kcmp/Makefile
+++ b/tools/testing/selftests/kcmp/Makefile
@@ -1,10 +1,8 @@
1CFLAGS += -I../../../../usr/include/ 1CFLAGS += -I../../../../usr/include/
2 2
3all: kcmp_test 3TEST_GEN_PROGS := kcmp_test
4 4
5TEST_PROGS := kcmp_test 5EXTRA_CLEAN := $(OUTPUT)/kcmp-test-file
6 6
7include ../lib.mk 7include ../lib.mk
8 8
9clean:
10 $(RM) kcmp_test kcmp-test-file
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
index 50a93f5f13d6..775c589ac3c0 100644
--- a/tools/testing/selftests/lib.mk
+++ b/tools/testing/selftests/lib.mk
@@ -2,9 +2,19 @@
2# Makefile can operate with or without the kbuild infrastructure. 2# Makefile can operate with or without the kbuild infrastructure.
3CC := $(CROSS_COMPILE)gcc 3CC := $(CROSS_COMPILE)gcc
4 4
5ifeq (0,$(MAKELEVEL))
6OUTPUT := $(shell pwd)
7endif
8
9TEST_GEN_PROGS := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_PROGS))
10TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
11
12all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
13
5define RUN_TESTS 14define RUN_TESTS
6 @for TEST in $(TEST_PROGS); do \ 15 @for TEST in $(TEST_GEN_PROGS) $(TEST_PROGS); do \
7 (./$$TEST && echo "selftests: $$TEST [PASS]") || echo "selftests: $$TEST [FAIL]"; \ 16 BASENAME_TEST=`basename $$TEST`; \
17 cd `dirname $$TEST`; (./$$BASENAME_TEST && echo "selftests: $$BASENAME_TEST [PASS]") || echo "selftests: $$BASENAME_TEST [FAIL]"; cd -;\
8 done; 18 done;
9endef 19endef
10 20
@@ -14,8 +24,13 @@ run_tests: all
14define INSTALL_RULE 24define INSTALL_RULE
15 @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ 25 @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \
16 mkdir -p ${INSTALL_PATH}; \ 26 mkdir -p ${INSTALL_PATH}; \
17 echo "rsync -a $(TEST_DIRS) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/"; \ 27 echo "rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/"; \
18 rsync -a $(TEST_DIRS) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/; \ 28 rsync -a $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(INSTALL_PATH)/; \
29 fi
30 @if [ "X$(TEST_GEN_PROGS)$(TEST_GEN_PROGS_EXTENDED)$(TEST_GEN_FILES)" != "X" ]; then \
31 mkdir -p ${INSTALL_PATH}; \
32 echo "rsync -a $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/"; \
33 rsync -a $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(INSTALL_PATH)/; \
19 fi 34 fi
20endef 35endef
21 36
@@ -27,12 +42,25 @@ else
27endif 42endif
28 43
29define EMIT_TESTS 44define EMIT_TESTS
30 @for TEST in $(TEST_PROGS); do \ 45 @for TEST in $(TEST_GEN_PROGS) $(TEST_PROGS); do \
31 echo "(./$$TEST && echo \"selftests: $$TEST [PASS]\") || echo \"selftests: $$TEST [FAIL]\""; \ 46 BASENAME_TEST=`basename $$TEST`; \
47 echo "(./$$BASENAME_TEST && echo \"selftests: $$BASENAME_TEST [PASS]\") || echo \"selftests: $$BASENAME_TEST [FAIL]\""; \
32 done; 48 done;
33endef 49endef
34 50
35emit_tests: 51emit_tests:
36 $(EMIT_TESTS) 52 $(EMIT_TESTS)
37 53
54clean:
55 $(RM) -r $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(EXTRA_CLEAN)
56
57$(OUTPUT)/%:%.c
58 $(LINK.c) $^ $(LDLIBS) -o $@
59
60$(OUTPUT)/%.o:%.S
61 $(COMPILE.S) $^ -o $@
62
63$(OUTPUT)/%:%.S
64 $(LINK.S) $^ $(LDLIBS) -o $@
65
38.PHONY: run_tests all clean install emit_tests 66.PHONY: run_tests all clean install emit_tests
diff --git a/tools/testing/selftests/lib/prime_numbers.sh b/tools/testing/selftests/lib/prime_numbers.sh
new file mode 100755
index 000000000000..da4cbcd766f5
--- /dev/null
+++ b/tools/testing/selftests/lib/prime_numbers.sh
@@ -0,0 +1,15 @@
1#!/bin/sh
2# Checks fast/slow prime_number generation for inconsistencies
3
4if ! /sbin/modprobe -q -r prime_numbers; then
5 echo "prime_numbers: [SKIP]"
6 exit 77
7fi
8
9if /sbin/modprobe -q prime_numbers selftest=65536; then
10 /sbin/modprobe -q -r prime_numbers
11 echo "prime_numbers: ok"
12else
13 echo "prime_numbers: [FAIL]"
14 exit 1
15fi
diff --git a/tools/testing/selftests/membarrier/Makefile b/tools/testing/selftests/membarrier/Makefile
index a1a97085847d..02845532b059 100644
--- a/tools/testing/selftests/membarrier/Makefile
+++ b/tools/testing/selftests/membarrier/Makefile
@@ -1,10 +1,6 @@
1CFLAGS += -g -I../../../../usr/include/ 1CFLAGS += -g -I../../../../usr/include/
2 2
3TEST_PROGS := membarrier_test 3TEST_GEN_PROGS := membarrier_test
4
5all: $(TEST_PROGS)
6 4
7include ../lib.mk 5include ../lib.mk
8 6
9clean:
10 $(RM) $(TEST_PROGS)
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile
index fd396ac811b6..79891d033de1 100644
--- a/tools/testing/selftests/memfd/Makefile
+++ b/tools/testing/selftests/memfd/Makefile
@@ -1,22 +1,13 @@
1CC = $(CROSS_COMPILE)gcc
2CFLAGS += -D_FILE_OFFSET_BITS=64 1CFLAGS += -D_FILE_OFFSET_BITS=64
3CFLAGS += -I../../../../include/uapi/ 2CFLAGS += -I../../../../include/uapi/
4CFLAGS += -I../../../../include/ 3CFLAGS += -I../../../../include/
5CFLAGS += -I../../../../usr/include/ 4CFLAGS += -I../../../../usr/include/
6 5
7TEST_PROGS := memfd_test 6TEST_PROGS := run_fuse_test.sh
8 7TEST_GEN_FILES := memfd_test fuse_mnt fuse_test
9all: $(TEST_PROGS)
10
11include ../lib.mk
12
13build_fuse: fuse_mnt fuse_test
14 8
15fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) 9fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
16fuse_mnt: LDFLAGS += $(shell pkg-config fuse --libs) 10fuse_mnt: LDFLAGS += $(shell pkg-config fuse --libs)
17 11
18run_fuse: build_fuse 12include ../lib.mk
19 @./run_fuse_test.sh || echo "fuse_test: [FAIL]"
20 13
21clean:
22 $(RM) memfd_test fuse_test
diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile
index 5e35c9c50b72..9093d7ffe87f 100644
--- a/tools/testing/selftests/mount/Makefile
+++ b/tools/testing/selftests/mount/Makefile
@@ -1,14 +1,11 @@
1# Makefile for mount selftests. 1# Makefile for mount selftests.
2CFLAGS = -Wall \ 2CFLAGS = -Wall \
3 -O2 3 -O2
4all: unprivileged-remount-test
5 4
6unprivileged-remount-test: unprivileged-remount-test.c 5TEST_GEN_PROGS := unprivileged-remount-test
7 $(CC) $(CFLAGS) unprivileged-remount-test.c -o unprivileged-remount-test
8 6
9include ../lib.mk 7include ../lib.mk
10 8
11TEST_PROGS := unprivileged-remount-test
12override RUN_TESTS := if [ -f /proc/self/uid_map ] ; \ 9override RUN_TESTS := if [ -f /proc/self/uid_map ] ; \
13 then \ 10 then \
14 ./unprivileged-remount-test ; \ 11 ./unprivileged-remount-test ; \
@@ -17,5 +14,3 @@ override RUN_TESTS := if [ -f /proc/self/uid_map ] ; \
17 fi 14 fi
18override EMIT_TESTS := echo "$(RUN_TESTS)" 15override EMIT_TESTS := echo "$(RUN_TESTS)"
19 16
20clean:
21 rm -f unprivileged-remount-test
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile
index eebac29acbd9..79a664aeb8d7 100644
--- a/tools/testing/selftests/mqueue/Makefile
+++ b/tools/testing/selftests/mqueue/Makefile
@@ -1,8 +1,6 @@
1CFLAGS += -O2 1CFLAGS += -O2
2LDLIBS = -lrt -lpthread -lpopt 2LDLIBS = -lrt -lpthread -lpopt
3TEST_PROGS := mq_open_tests mq_perf_tests 3TEST_GEN_PROGS := mq_open_tests mq_perf_tests
4
5all: $(TEST_PROGS)
6 4
7include ../lib.mk 5include ../lib.mk
8 6
@@ -16,5 +14,3 @@ override define EMIT_TESTS
16 echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\"" 14 echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\""
17endef 15endef
18 16
19clean:
20 rm -f mq_open_tests mq_perf_tests
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index e24e4c82542e..fbfe5d0d5c2e 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -3,20 +3,13 @@
3CFLAGS = -Wall -Wl,--no-as-needed -O2 -g 3CFLAGS = -Wall -Wl,--no-as-needed -O2 -g
4CFLAGS += -I../../../../usr/include/ 4CFLAGS += -I../../../../usr/include/
5 5
6NET_PROGS = socket
7NET_PROGS += psock_fanout psock_tpacket
8NET_PROGS += reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
9NET_PROGS += reuseport_dualstack
10
11all: $(NET_PROGS)
12reuseport_bpf_numa: LDFLAGS += -lnuma 6reuseport_bpf_numa: LDFLAGS += -lnuma
13%: %.c
14 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
15 7
16TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh 8TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh
17TEST_FILES := $(NET_PROGS) 9TEST_GEN_FILES = socket
10TEST_GEN_FILES += psock_fanout psock_tpacket
11TEST_GEN_FILES += reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
12TEST_GEN_FILES += reuseport_dualstack
18 13
19include ../lib.mk 14include ../lib.mk
20 15
21clean:
22 $(RM) $(NET_PROGS)
diff --git a/tools/testing/selftests/net/psock_lib.h b/tools/testing/selftests/net/psock_lib.h
index 24bc7ec1be7d..a77da88bf946 100644
--- a/tools/testing/selftests/net/psock_lib.h
+++ b/tools/testing/selftests/net/psock_lib.h
@@ -40,14 +40,39 @@
40 40
41static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum) 41static __maybe_unused void sock_setfilter(int fd, int lvl, int optnum)
42{ 42{
43 /* the filter below checks for all of the following conditions that
44 * are based on the contents of create_payload()
45 * ether type 0x800 and
46 * ip proto udp and
47 * skb->len == DATA_LEN and
48 * udp[38] == 'a' or udp[38] == 'b'
49 * It can be generated from the following bpf_asm input:
50 * ldh [12]
51 * jne #0x800, drop ; ETH_P_IP
52 * ldb [23]
53 * jneq #17, drop ; IPPROTO_UDP
54 * ld len ; ld skb->len
55 * jlt #100, drop ; DATA_LEN
56 * ldb [80]
57 * jeq #97, pass ; DATA_CHAR
58 * jne #98, drop ; DATA_CHAR_1
59 * pass:
60 * ret #-1
61 * drop:
62 * ret #0
63 */
43 struct sock_filter bpf_filter[] = { 64 struct sock_filter bpf_filter[] = {
44 { 0x80, 0, 0, 0x00000000 }, /* LD pktlen */ 65 { 0x28, 0, 0, 0x0000000c },
45 { 0x35, 0, 4, DATA_LEN }, /* JGE DATA_LEN [f goto nomatch]*/ 66 { 0x15, 0, 8, 0x00000800 },
46 { 0x30, 0, 0, 0x00000050 }, /* LD ip[80] */ 67 { 0x30, 0, 0, 0x00000017 },
47 { 0x15, 1, 0, DATA_CHAR }, /* JEQ DATA_CHAR [t goto match]*/ 68 { 0x15, 0, 6, 0x00000011 },
48 { 0x15, 0, 1, DATA_CHAR_1}, /* JEQ DATA_CHAR_1 [t goto match]*/ 69 { 0x80, 0, 0, 0000000000 },
49 { 0x06, 0, 0, 0x00000060 }, /* RET match */ 70 { 0x35, 0, 4, 0x00000064 },
50 { 0x06, 0, 0, 0x00000000 }, /* RET no match */ 71 { 0x30, 0, 0, 0x00000050 },
72 { 0x15, 1, 0, 0x00000061 },
73 { 0x15, 0, 1, 0x00000062 },
74 { 0x06, 0, 0, 0xffffffff },
75 { 0x06, 0, 0, 0000000000 },
51 }; 76 };
52 struct sock_fprog bpf_prog; 77 struct sock_fprog bpf_prog;
53 78
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c
index 24adf709bd9d..7f6cd9fdacf3 100644
--- a/tools/testing/selftests/net/psock_tpacket.c
+++ b/tools/testing/selftests/net/psock_tpacket.c
@@ -110,7 +110,7 @@ static unsigned int total_packets, total_bytes;
110 110
111static int pfsocket(int ver) 111static int pfsocket(int ver)
112{ 112{
113 int ret, sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 113 int ret, sock = socket(PF_PACKET, SOCK_RAW, 0);
114 if (sock == -1) { 114 if (sock == -1) {
115 perror("socket"); 115 perror("socket");
116 exit(1); 116 exit(1);
@@ -239,7 +239,6 @@ static void walk_v1_v2_rx(int sock, struct ring *ring)
239 bug_on(ring->type != PACKET_RX_RING); 239 bug_on(ring->type != PACKET_RX_RING);
240 240
241 pair_udp_open(udp_sock, PORT_BASE); 241 pair_udp_open(udp_sock, PORT_BASE);
242 pair_udp_setfilter(sock);
243 242
244 memset(&pfd, 0, sizeof(pfd)); 243 memset(&pfd, 0, sizeof(pfd));
245 pfd.fd = sock; 244 pfd.fd = sock;
@@ -311,20 +310,33 @@ static inline void __v2_tx_user_ready(struct tpacket2_hdr *hdr)
311 __sync_synchronize(); 310 __sync_synchronize();
312} 311}
313 312
314static inline int __v1_v2_tx_kernel_ready(void *base, int version) 313static inline int __v3_tx_kernel_ready(struct tpacket3_hdr *hdr)
314{
315 return !(hdr->tp_status & (TP_STATUS_SEND_REQUEST | TP_STATUS_SENDING));
316}
317
318static inline void __v3_tx_user_ready(struct tpacket3_hdr *hdr)
319{
320 hdr->tp_status = TP_STATUS_SEND_REQUEST;
321 __sync_synchronize();
322}
323
324static inline int __tx_kernel_ready(void *base, int version)
315{ 325{
316 switch (version) { 326 switch (version) {
317 case TPACKET_V1: 327 case TPACKET_V1:
318 return __v1_tx_kernel_ready(base); 328 return __v1_tx_kernel_ready(base);
319 case TPACKET_V2: 329 case TPACKET_V2:
320 return __v2_tx_kernel_ready(base); 330 return __v2_tx_kernel_ready(base);
331 case TPACKET_V3:
332 return __v3_tx_kernel_ready(base);
321 default: 333 default:
322 bug_on(1); 334 bug_on(1);
323 return 0; 335 return 0;
324 } 336 }
325} 337}
326 338
327static inline void __v1_v2_tx_user_ready(void *base, int version) 339static inline void __tx_user_ready(void *base, int version)
328{ 340{
329 switch (version) { 341 switch (version) {
330 case TPACKET_V1: 342 case TPACKET_V1:
@@ -333,6 +345,9 @@ static inline void __v1_v2_tx_user_ready(void *base, int version)
333 case TPACKET_V2: 345 case TPACKET_V2:
334 __v2_tx_user_ready(base); 346 __v2_tx_user_ready(base);
335 break; 347 break;
348 case TPACKET_V3:
349 __v3_tx_user_ready(base);
350 break;
336 } 351 }
337} 352}
338 353
@@ -348,7 +363,22 @@ static void __v1_v2_set_packet_loss_discard(int sock)
348 } 363 }
349} 364}
350 365
351static void walk_v1_v2_tx(int sock, struct ring *ring) 366static inline void *get_next_frame(struct ring *ring, int n)
367{
368 uint8_t *f0 = ring->rd[0].iov_base;
369
370 switch (ring->version) {
371 case TPACKET_V1:
372 case TPACKET_V2:
373 return ring->rd[n].iov_base;
374 case TPACKET_V3:
375 return f0 + (n * ring->req3.tp_frame_size);
376 default:
377 bug_on(1);
378 }
379}
380
381static void walk_tx(int sock, struct ring *ring)
352{ 382{
353 struct pollfd pfd; 383 struct pollfd pfd;
354 int rcv_sock, ret; 384 int rcv_sock, ret;
@@ -360,9 +390,19 @@ static void walk_v1_v2_tx(int sock, struct ring *ring)
360 .sll_family = PF_PACKET, 390 .sll_family = PF_PACKET,
361 .sll_halen = ETH_ALEN, 391 .sll_halen = ETH_ALEN,
362 }; 392 };
393 int nframes;
394
395 /* TPACKET_V{1,2} sets up the ring->rd* related variables based
396 * on frames (e.g., rd_num is tp_frame_nr) whereas V3 sets these
397 * up based on blocks (e.g, rd_num is tp_block_nr)
398 */
399 if (ring->version <= TPACKET_V2)
400 nframes = ring->rd_num;
401 else
402 nframes = ring->req3.tp_frame_nr;
363 403
364 bug_on(ring->type != PACKET_TX_RING); 404 bug_on(ring->type != PACKET_TX_RING);
365 bug_on(ring->rd_num < NUM_PACKETS); 405 bug_on(nframes < NUM_PACKETS);
366 406
367 rcv_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 407 rcv_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
368 if (rcv_sock == -1) { 408 if (rcv_sock == -1) {
@@ -388,10 +428,11 @@ static void walk_v1_v2_tx(int sock, struct ring *ring)
388 create_payload(packet, &packet_len); 428 create_payload(packet, &packet_len);
389 429
390 while (total_packets > 0) { 430 while (total_packets > 0) {
391 while (__v1_v2_tx_kernel_ready(ring->rd[frame_num].iov_base, 431 void *next = get_next_frame(ring, frame_num);
392 ring->version) && 432
433 while (__tx_kernel_ready(next, ring->version) &&
393 total_packets > 0) { 434 total_packets > 0) {
394 ppd.raw = ring->rd[frame_num].iov_base; 435 ppd.raw = next;
395 436
396 switch (ring->version) { 437 switch (ring->version) {
397 case TPACKET_V1: 438 case TPACKET_V1:
@@ -413,14 +454,27 @@ static void walk_v1_v2_tx(int sock, struct ring *ring)
413 packet_len); 454 packet_len);
414 total_bytes += ppd.v2->tp_h.tp_snaplen; 455 total_bytes += ppd.v2->tp_h.tp_snaplen;
415 break; 456 break;
457 case TPACKET_V3: {
458 struct tpacket3_hdr *tx = next;
459
460 tx->tp_snaplen = packet_len;
461 tx->tp_len = packet_len;
462 tx->tp_next_offset = 0;
463
464 memcpy((uint8_t *)tx + TPACKET3_HDRLEN -
465 sizeof(struct sockaddr_ll), packet,
466 packet_len);
467 total_bytes += tx->tp_snaplen;
468 break;
469 }
416 } 470 }
417 471
418 status_bar_update(); 472 status_bar_update();
419 total_packets--; 473 total_packets--;
420 474
421 __v1_v2_tx_user_ready(ppd.raw, ring->version); 475 __tx_user_ready(next, ring->version);
422 476
423 frame_num = (frame_num + 1) % ring->rd_num; 477 frame_num = (frame_num + 1) % nframes;
424 } 478 }
425 479
426 poll(&pfd, 1, 1); 480 poll(&pfd, 1, 1);
@@ -460,7 +514,7 @@ static void walk_v1_v2(int sock, struct ring *ring)
460 if (ring->type == PACKET_RX_RING) 514 if (ring->type == PACKET_RX_RING)
461 walk_v1_v2_rx(sock, ring); 515 walk_v1_v2_rx(sock, ring);
462 else 516 else
463 walk_v1_v2_tx(sock, ring); 517 walk_tx(sock, ring);
464} 518}
465 519
466static uint64_t __v3_prev_block_seq_num = 0; 520static uint64_t __v3_prev_block_seq_num = 0;
@@ -546,7 +600,6 @@ static void walk_v3_rx(int sock, struct ring *ring)
546 bug_on(ring->type != PACKET_RX_RING); 600 bug_on(ring->type != PACKET_RX_RING);
547 601
548 pair_udp_open(udp_sock, PORT_BASE); 602 pair_udp_open(udp_sock, PORT_BASE);
549 pair_udp_setfilter(sock);
550 603
551 memset(&pfd, 0, sizeof(pfd)); 604 memset(&pfd, 0, sizeof(pfd));
552 pfd.fd = sock; 605 pfd.fd = sock;
@@ -583,7 +636,7 @@ static void walk_v3(int sock, struct ring *ring)
583 if (ring->type == PACKET_RX_RING) 636 if (ring->type == PACKET_RX_RING)
584 walk_v3_rx(sock, ring); 637 walk_v3_rx(sock, ring);
585 else 638 else
586 bug_on(1); 639 walk_tx(sock, ring);
587} 640}
588 641
589static void __v1_v2_fill(struct ring *ring, unsigned int blocks) 642static void __v1_v2_fill(struct ring *ring, unsigned int blocks)
@@ -602,12 +655,13 @@ static void __v1_v2_fill(struct ring *ring, unsigned int blocks)
602 ring->flen = ring->req.tp_frame_size; 655 ring->flen = ring->req.tp_frame_size;
603} 656}
604 657
605static void __v3_fill(struct ring *ring, unsigned int blocks) 658static void __v3_fill(struct ring *ring, unsigned int blocks, int type)
606{ 659{
607 ring->req3.tp_retire_blk_tov = 64; 660 if (type == PACKET_RX_RING) {
608 ring->req3.tp_sizeof_priv = 0; 661 ring->req3.tp_retire_blk_tov = 64;
609 ring->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH; 662 ring->req3.tp_sizeof_priv = 0;
610 663 ring->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
664 }
611 ring->req3.tp_block_size = getpagesize() << 2; 665 ring->req3.tp_block_size = getpagesize() << 2;
612 ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7; 666 ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7;
613 ring->req3.tp_block_nr = blocks; 667 ring->req3.tp_block_nr = blocks;
@@ -641,7 +695,7 @@ static void setup_ring(int sock, struct ring *ring, int version, int type)
641 break; 695 break;
642 696
643 case TPACKET_V3: 697 case TPACKET_V3:
644 __v3_fill(ring, blocks); 698 __v3_fill(ring, blocks, type);
645 ret = setsockopt(sock, SOL_PACKET, type, &ring->req3, 699 ret = setsockopt(sock, SOL_PACKET, type, &ring->req3,
646 sizeof(ring->req3)); 700 sizeof(ring->req3));
647 break; 701 break;
@@ -685,6 +739,8 @@ static void bind_ring(int sock, struct ring *ring)
685{ 739{
686 int ret; 740 int ret;
687 741
742 pair_udp_setfilter(sock);
743
688 ring->ll.sll_family = PF_PACKET; 744 ring->ll.sll_family = PF_PACKET;
689 ring->ll.sll_protocol = htons(ETH_P_ALL); 745 ring->ll.sll_protocol = htons(ETH_P_ALL);
690 ring->ll.sll_ifindex = if_nametoindex("lo"); 746 ring->ll.sll_ifindex = if_nametoindex("lo");
@@ -796,6 +852,7 @@ int main(void)
796 ret |= test_tpacket(TPACKET_V2, PACKET_TX_RING); 852 ret |= test_tpacket(TPACKET_V2, PACKET_TX_RING);
797 853
798 ret |= test_tpacket(TPACKET_V3, PACKET_RX_RING); 854 ret |= test_tpacket(TPACKET_V3, PACKET_RX_RING);
855 ret |= test_tpacket(TPACKET_V3, PACKET_TX_RING);
799 856
800 if (ret) 857 if (ret)
801 return 1; 858 return 1;
diff --git a/tools/testing/selftests/nsfs/Makefile b/tools/testing/selftests/nsfs/Makefile
index 2306054a901a..9ff7c7f80625 100644
--- a/tools/testing/selftests/nsfs/Makefile
+++ b/tools/testing/selftests/nsfs/Makefile
@@ -1,12 +1,5 @@
1TEST_PROGS := owner pidns 1TEST_GEN_PROGS := owner pidns
2 2
3CFLAGS := -Wall -Werror 3CFLAGS := -Wall -Werror
4 4
5all: owner pidns
6owner: owner.c
7pidns: pidns.c
8
9clean:
10 $(RM) owner pidns
11
12include ../lib.mk 5include ../lib.mk
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index c2c4211ba58b..1c5d0575802e 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -34,31 +34,35 @@ endif
34all: $(SUB_DIRS) 34all: $(SUB_DIRS)
35 35
36$(SUB_DIRS): 36$(SUB_DIRS):
37 $(MAKE) -k -C $@ all 37 BUILD_TARGET=$$OUTPUT/$@; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $@ all
38 38
39include ../lib.mk 39include ../lib.mk
40 40
41override define RUN_TESTS 41override define RUN_TESTS
42 @for TARGET in $(SUB_DIRS); do \ 42 @for TARGET in $(SUB_DIRS); do \
43 $(MAKE) -C $$TARGET run_tests; \ 43 BUILD_TARGET=$$OUTPUT/$$TARGET; \
44 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\
44 done; 45 done;
45endef 46endef
46 47
47override define INSTALL_RULE 48override define INSTALL_RULE
48 @for TARGET in $(SUB_DIRS); do \ 49 @for TARGET in $(SUB_DIRS); do \
49 $(MAKE) -C $$TARGET install; \ 50 BUILD_TARGET=$$OUTPUT/$$TARGET; \
51 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\
50 done; 52 done;
51endef 53endef
52 54
53override define EMIT_TESTS 55override define EMIT_TESTS
54 @for TARGET in $(SUB_DIRS); do \ 56 @for TARGET in $(SUB_DIRS); do \
55 $(MAKE) -s -C $$TARGET emit_tests; \ 57 BUILD_TARGET=$$OUTPUT/$$TARGET; \
58 $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\
56 done; 59 done;
57endef 60endef
58 61
59clean: 62clean:
60 @for TARGET in $(SUB_DIRS); do \ 63 @for TARGET in $(SUB_DIRS); do \
61 $(MAKE) -C $$TARGET clean; \ 64 BUILD_TARGET=$$OUTPUT/$$TARGET; \
65 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \
62 done; 66 done;
63 rm -f tags 67 rm -f tags
64 68
diff --git a/tools/testing/selftests/powerpc/alignment/Makefile b/tools/testing/selftests/powerpc/alignment/Makefile
index ad6a4e49da91..16b22004e75f 100644
--- a/tools/testing/selftests/powerpc/alignment/Makefile
+++ b/tools/testing/selftests/powerpc/alignment/Makefile
@@ -1,10 +1,5 @@
1TEST_PROGS := copy_unaligned copy_first_unaligned paste_unaligned paste_last_unaligned 1TEST_GEN_PROGS := copy_unaligned copy_first_unaligned paste_unaligned paste_last_unaligned
2
3all: $(TEST_PROGS)
4
5$(TEST_PROGS): ../harness.c ../utils.c copy_paste_unaligned_common.c
6 2
7include ../../lib.mk 3include ../../lib.mk
8 4
9clean: 5$(TEST_GEN_PROGS): ../harness.c ../utils.c copy_paste_unaligned_common.c
10 rm -f $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/benchmarks/Makefile b/tools/testing/selftests/powerpc/benchmarks/Makefile
index 545077f98f72..fb96a89bd953 100644
--- a/tools/testing/selftests/powerpc/benchmarks/Makefile
+++ b/tools/testing/selftests/powerpc/benchmarks/Makefile
@@ -1,16 +1,11 @@
1TEST_PROGS := gettimeofday context_switch mmap_bench futex_bench null_syscall 1TEST_GEN_PROGS := gettimeofday context_switch mmap_bench futex_bench null_syscall
2 2
3CFLAGS += -O2 3CFLAGS += -O2
4 4
5all: $(TEST_PROGS)
6
7$(TEST_PROGS): ../harness.c
8
9context_switch: ../utils.c
10context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec
11context_switch: LDLIBS += -lpthread
12
13include ../../lib.mk 5include ../../lib.mk
14 6
15clean: 7$(TEST_GEN_PROGS): ../harness.c
16 rm -f $(TEST_PROGS) *.o 8
9$(OUTPUT)/context_switch: ../utils.c
10$(OUTPUT)/context_switch: CFLAGS += -maltivec -mvsx -mabi=altivec
11$(OUTPUT)/context_switch: LDLIBS += -lpthread
diff --git a/tools/testing/selftests/powerpc/context_switch/Makefile b/tools/testing/selftests/powerpc/context_switch/Makefile
index e164d1466466..e9351bb4285d 100644
--- a/tools/testing/selftests/powerpc/context_switch/Makefile
+++ b/tools/testing/selftests/powerpc/context_switch/Makefile
@@ -1,10 +1,5 @@
1TEST_PROGS := cp_abort 1TEST_GEN_PROGS := cp_abort
2
3all: $(TEST_PROGS)
4
5$(TEST_PROGS): ../harness.c ../utils.c
6 2
7include ../../lib.mk 3include ../../lib.mk
8 4
9clean: 5$(TEST_GEN_PROGS): ../harness.c ../utils.c
10 rm -f $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile
index 384843ea0d40..681ab19d0a84 100644
--- a/tools/testing/selftests/powerpc/copyloops/Makefile
+++ b/tools/testing/selftests/powerpc/copyloops/Makefile
@@ -7,19 +7,14 @@ CFLAGS += -maltivec
7# Use our CFLAGS for the implicit .S rule 7# Use our CFLAGS for the implicit .S rule
8ASFLAGS = $(CFLAGS) 8ASFLAGS = $(CFLAGS)
9 9
10TEST_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 10TEST_GEN_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7
11EXTRA_SOURCES := validate.c ../harness.c 11EXTRA_SOURCES := validate.c ../harness.c
12 12
13all: $(TEST_PROGS)
14
15copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base
16copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7
17memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy
18memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7
19
20$(TEST_PROGS): $(EXTRA_SOURCES)
21
22include ../../lib.mk 13include ../../lib.mk
23 14
24clean: 15$(OUTPUT)/copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base
25 rm -f $(TEST_PROGS) *.o 16$(OUTPUT)/copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7
17$(OUTPUT)/memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy
18$(OUTPUT)/memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7
19
20$(TEST_GEN_PROGS): $(EXTRA_SOURCES)
diff --git a/tools/testing/selftests/powerpc/dscr/Makefile b/tools/testing/selftests/powerpc/dscr/Makefile
index 49327ee84e3a..c5639deb8887 100644
--- a/tools/testing/selftests/powerpc/dscr/Makefile
+++ b/tools/testing/selftests/powerpc/dscr/Makefile
@@ -1,14 +1,9 @@
1TEST_PROGS := dscr_default_test dscr_explicit_test dscr_user_test \ 1TEST_GEN_PROGS := dscr_default_test dscr_explicit_test dscr_user_test \
2 dscr_inherit_test dscr_inherit_exec_test dscr_sysfs_test \ 2 dscr_inherit_test dscr_inherit_exec_test dscr_sysfs_test \
3 dscr_sysfs_thread_test 3 dscr_sysfs_thread_test
4 4
5dscr_default_test: LDLIBS += -lpthread
6
7all: $(TEST_PROGS)
8
9$(TEST_PROGS): ../harness.c
10
11include ../../lib.mk 5include ../../lib.mk
12 6
13clean: 7$(OUTPUT)/dscr_default_test: LDLIBS += -lpthread
14 rm -f $(TEST_PROGS) *.o 8
9$(TEST_GEN_PROGS): ../harness.c
diff --git a/tools/testing/selftests/powerpc/harness.c b/tools/testing/selftests/powerpc/harness.c
index 248a820048df..66d31de60b9a 100644
--- a/tools/testing/selftests/powerpc/harness.c
+++ b/tools/testing/selftests/powerpc/harness.c
@@ -114,9 +114,11 @@ int test_harness(int (test_function)(void), char *name)
114 114
115 rc = run_test(test_function, name); 115 rc = run_test(test_function, name);
116 116
117 if (rc == MAGIC_SKIP_RETURN_VALUE) 117 if (rc == MAGIC_SKIP_RETURN_VALUE) {
118 test_skip(name); 118 test_skip(name);
119 else 119 /* so that skipped test is not marked as failed */
120 rc = 0;
121 } else
120 test_finish(name, rc); 122 test_finish(name, rc);
121 123
122 return rc; 124 return rc;
diff --git a/tools/testing/selftests/powerpc/include/vsx_asm.h b/tools/testing/selftests/powerpc/include/vsx_asm.h
index d828bfb6ef2d..54064ced9e95 100644
--- a/tools/testing/selftests/powerpc/include/vsx_asm.h
+++ b/tools/testing/selftests/powerpc/include/vsx_asm.h
@@ -16,56 +16,56 @@
16 */ 16 */
17FUNC_START(load_vsx) 17FUNC_START(load_vsx)
18 li r5,0 18 li r5,0
19 lxvx vs20,r5,r3 19 lxvd2x vs20,r5,r3
20 addi r5,r5,16 20 addi r5,r5,16
21 lxvx vs21,r5,r3 21 lxvd2x vs21,r5,r3
22 addi r5,r5,16 22 addi r5,r5,16
23 lxvx vs22,r5,r3 23 lxvd2x vs22,r5,r3
24 addi r5,r5,16 24 addi r5,r5,16
25 lxvx vs23,r5,r3 25 lxvd2x vs23,r5,r3
26 addi r5,r5,16 26 addi r5,r5,16
27 lxvx vs24,r5,r3 27 lxvd2x vs24,r5,r3
28 addi r5,r5,16 28 addi r5,r5,16
29 lxvx vs25,r5,r3 29 lxvd2x vs25,r5,r3
30 addi r5,r5,16 30 addi r5,r5,16
31 lxvx vs26,r5,r3 31 lxvd2x vs26,r5,r3
32 addi r5,r5,16 32 addi r5,r5,16
33 lxvx vs27,r5,r3 33 lxvd2x vs27,r5,r3
34 addi r5,r5,16 34 addi r5,r5,16
35 lxvx vs28,r5,r3 35 lxvd2x vs28,r5,r3
36 addi r5,r5,16 36 addi r5,r5,16
37 lxvx vs29,r5,r3 37 lxvd2x vs29,r5,r3
38 addi r5,r5,16 38 addi r5,r5,16
39 lxvx vs30,r5,r3 39 lxvd2x vs30,r5,r3
40 addi r5,r5,16 40 addi r5,r5,16
41 lxvx vs31,r5,r3 41 lxvd2x vs31,r5,r3
42 blr 42 blr
43FUNC_END(load_vsx) 43FUNC_END(load_vsx)
44 44
45FUNC_START(store_vsx) 45FUNC_START(store_vsx)
46 li r5,0 46 li r5,0
47 stxvx vs20,r5,r3 47 stxvd2x vs20,r5,r3
48 addi r5,r5,16 48 addi r5,r5,16
49 stxvx vs21,r5,r3 49 stxvd2x vs21,r5,r3
50 addi r5,r5,16 50 addi r5,r5,16
51 stxvx vs22,r5,r3 51 stxvd2x vs22,r5,r3
52 addi r5,r5,16 52 addi r5,r5,16
53 stxvx vs23,r5,r3 53 stxvd2x vs23,r5,r3
54 addi r5,r5,16 54 addi r5,r5,16
55 stxvx vs24,r5,r3 55 stxvd2x vs24,r5,r3
56 addi r5,r5,16 56 addi r5,r5,16
57 stxvx vs25,r5,r3 57 stxvd2x vs25,r5,r3
58 addi r5,r5,16 58 addi r5,r5,16
59 stxvx vs26,r5,r3 59 stxvd2x vs26,r5,r3
60 addi r5,r5,16 60 addi r5,r5,16
61 stxvx vs27,r5,r3 61 stxvd2x vs27,r5,r3
62 addi r5,r5,16 62 addi r5,r5,16
63 stxvx vs28,r5,r3 63 stxvd2x vs28,r5,r3
64 addi r5,r5,16 64 addi r5,r5,16
65 stxvx vs29,r5,r3 65 stxvd2x vs29,r5,r3
66 addi r5,r5,16 66 addi r5,r5,16
67 stxvx vs30,r5,r3 67 stxvd2x vs30,r5,r3
68 addi r5,r5,16 68 addi r5,r5,16
69 stxvx vs31,r5,r3 69 stxvd2x vs31,r5,r3
70 blr 70 blr
71FUNC_END(store_vsx) 71FUNC_END(store_vsx)
diff --git a/tools/testing/selftests/powerpc/math/Makefile b/tools/testing/selftests/powerpc/math/Makefile
index a505b66d408a..fa8bae920c91 100644
--- a/tools/testing/selftests/powerpc/math/Makefile
+++ b/tools/testing/selftests/powerpc/math/Makefile
@@ -1,22 +1,17 @@
1TEST_PROGS := fpu_syscall fpu_preempt fpu_signal vmx_syscall vmx_preempt vmx_signal vsx_preempt 1TEST_GEN_PROGS := fpu_syscall fpu_preempt fpu_signal vmx_syscall vmx_preempt vmx_signal vsx_preempt
2 2
3all: $(TEST_PROGS) 3include ../../lib.mk
4
5$(TEST_PROGS): ../harness.c
6$(TEST_PROGS): CFLAGS += -O2 -g -pthread -m64 -maltivec
7
8fpu_syscall: fpu_asm.S
9fpu_preempt: fpu_asm.S
10fpu_signal: fpu_asm.S
11 4
12vmx_syscall: vmx_asm.S 5$(TEST_GEN_PROGS): ../harness.c
13vmx_preempt: vmx_asm.S 6$(TEST_GEN_PROGS): CFLAGS += -O2 -g -pthread -m64 -maltivec
14vmx_signal: vmx_asm.S
15 7
16vsx_preempt: CFLAGS += -mvsx 8$(OUTPUT)/fpu_syscall: fpu_asm.S
17vsx_preempt: vsx_asm.S 9$(OUTPUT)/fpu_preempt: fpu_asm.S
10$(OUTPUT)/fpu_signal: fpu_asm.S
18 11
19include ../../lib.mk 12$(OUTPUT)/vmx_syscall: vmx_asm.S
13$(OUTPUT)/vmx_preempt: vmx_asm.S
14$(OUTPUT)/vmx_signal: vmx_asm.S
20 15
21clean: 16$(OUTPUT)/vsx_preempt: CFLAGS += -mvsx
22 rm -f $(TEST_PROGS) *.o 17$(OUTPUT)/vsx_preempt: vsx_asm.S
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
index 3bdb96eae558..1cffe54dccfb 100644
--- a/tools/testing/selftests/powerpc/mm/Makefile
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -1,19 +1,15 @@
1noarg: 1noarg:
2 $(MAKE) -C ../ 2 $(MAKE) -C ../
3 3
4TEST_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao 4TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao
5TEST_FILES := tempfile 5TEST_GEN_FILES := tempfile
6 6
7all: $(TEST_PROGS) $(TEST_FILES) 7include ../../lib.mk
8
9$(TEST_PROGS): ../harness.c
10 8
11prot_sao: ../utils.c 9$(TEST_GEN_PROGS): ../harness.c
12 10
13include ../../lib.mk 11$(OUTPUT)/prot_sao: ../utils.c
14 12
15tempfile: 13$(OUTPUT)/tempfile:
16 dd if=/dev/zero of=tempfile bs=64k count=1 14 dd if=/dev/zero of=$@ bs=64k count=1
17 15
18clean:
19 rm -f $(TEST_PROGS) tempfile
diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile
index ac41a7177f2e..e4e55d1d3e0f 100644
--- a/tools/testing/selftests/powerpc/pmu/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/Makefile
@@ -1,44 +1,44 @@
1noarg: 1noarg:
2 $(MAKE) -C ../ 2 $(MAKE) -C ../
3 3
4TEST_PROGS := count_instructions l3_bank_test per_event_excludes 4TEST_GEN_PROGS := count_instructions l3_bank_test per_event_excludes
5EXTRA_SOURCES := ../harness.c event.c lib.c ../utils.c 5EXTRA_SOURCES := ../harness.c event.c lib.c ../utils.c
6 6
7all: $(TEST_PROGS) ebb 7include ../../lib.mk
8
9all: $(TEST_GEN_PROGS) ebb
8 10
9$(TEST_PROGS): $(EXTRA_SOURCES) 11$(TEST_GEN_PROGS): $(EXTRA_SOURCES)
10 12
11# loop.S can only be built 64-bit 13# loop.S can only be built 64-bit
12count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES) 14$(OUTPUT)/count_instructions: loop.S count_instructions.c $(EXTRA_SOURCES)
13 $(CC) $(CFLAGS) -m64 -o $@ $^ 15 $(CC) $(CFLAGS) -m64 -o $@ $^
14 16
15per_event_excludes: ../utils.c 17$(OUTPUT)/per_event_excludes: ../utils.c
16
17include ../../lib.mk
18 18
19DEFAULT_RUN_TESTS := $(RUN_TESTS) 19DEFAULT_RUN_TESTS := $(RUN_TESTS)
20override define RUN_TESTS 20override define RUN_TESTS
21 $(DEFAULT_RUN_TESTS) 21 $(DEFAULT_RUN_TESTS)
22 $(MAKE) -C ebb run_tests 22 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests
23endef 23endef
24 24
25DEFAULT_EMIT_TESTS := $(EMIT_TESTS) 25DEFAULT_EMIT_TESTS := $(EMIT_TESTS)
26override define EMIT_TESTS 26override define EMIT_TESTS
27 $(DEFAULT_EMIT_TESTS) 27 $(DEFAULT_EMIT_TESTS)
28 $(MAKE) -s -C ebb emit_tests 28 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests
29endef 29endef
30 30
31DEFAULT_INSTALL_RULE := $(INSTALL_RULE) 31DEFAULT_INSTALL_RULE := $(INSTALL_RULE)
32override define INSTALL_RULE 32override define INSTALL_RULE
33 $(DEFAULT_INSTALL_RULE) 33 $(DEFAULT_INSTALL_RULE)
34 $(MAKE) -C ebb install 34 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install
35endef 35endef
36 36
37clean: 37clean:
38 rm -f $(TEST_PROGS) loop.o 38 $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o
39 $(MAKE) -C ebb clean 39 TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean
40 40
41ebb: 41ebb:
42 $(MAKE) -k -C $@ all 42 TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all
43 43
44.PHONY: all run_tests clean ebb 44.PHONY: all run_tests clean ebb
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
index 8d2279c4bb4b..6001fb0a377a 100644
--- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile
+++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile
@@ -4,7 +4,7 @@ noarg:
4# The EBB handler is 64-bit code and everything links against it 4# The EBB handler is 64-bit code and everything links against it
5CFLAGS += -m64 5CFLAGS += -m64
6 6
7TEST_PROGS := reg_access_test event_attributes_test cycles_test \ 7TEST_GEN_PROGS := reg_access_test event_attributes_test cycles_test \
8 cycles_with_freeze_test pmc56_overflow_test \ 8 cycles_with_freeze_test pmc56_overflow_test \
9 ebb_vs_cpu_event_test cpu_event_vs_ebb_test \ 9 ebb_vs_cpu_event_test cpu_event_vs_ebb_test \
10 cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \ 10 cpu_event_pinned_vs_ebb_test task_event_vs_ebb_test \
@@ -16,16 +16,11 @@ TEST_PROGS := reg_access_test event_attributes_test cycles_test \
16 lost_exception_test no_handler_test \ 16 lost_exception_test no_handler_test \
17 cycles_with_mmcr2_test 17 cycles_with_mmcr2_test
18 18
19all: $(TEST_PROGS) 19include ../../../lib.mk
20 20
21$(TEST_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c \ 21$(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c \
22 ebb.c ebb_handler.S trace.c busy_loop.S 22 ebb.c ebb_handler.S trace.c busy_loop.S
23 23
24instruction_count_test: ../loop.S 24$(OUTPUT)/instruction_count_test: ../loop.S
25
26lost_exception_test: ../lib.c
27
28include ../../../lib.mk
29 25
30clean: 26$(OUTPUT)/lost_exception_test: ../lib.c
31 rm -f $(TEST_PROGS)
diff --git a/tools/testing/selftests/powerpc/primitives/Makefile b/tools/testing/selftests/powerpc/primitives/Makefile
index b68c6221d3d1..175366db7be8 100644
--- a/tools/testing/selftests/powerpc/primitives/Makefile
+++ b/tools/testing/selftests/powerpc/primitives/Makefile
@@ -1,12 +1,7 @@
1CFLAGS += -I$(CURDIR) 1CFLAGS += -I$(CURDIR)
2 2
3TEST_PROGS := load_unaligned_zeropad 3TEST_GEN_PROGS := load_unaligned_zeropad
4
5all: $(TEST_PROGS)
6
7$(TEST_PROGS): ../harness.c
8 4
9include ../../lib.mk 5include ../../lib.mk
10 6
11clean: 7$(TEST_GEN_PROGS): ../harness.c
12 rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile
index 2a728f4d2873..557b9379f3bb 100644
--- a/tools/testing/selftests/powerpc/stringloops/Makefile
+++ b/tools/testing/selftests/powerpc/stringloops/Makefile
@@ -2,14 +2,9 @@
2CFLAGS += -m64 2CFLAGS += -m64
3CFLAGS += -I$(CURDIR) 3CFLAGS += -I$(CURDIR)
4 4
5TEST_PROGS := memcmp 5TEST_GEN_PROGS := memcmp
6EXTRA_SOURCES := memcmp_64.S ../harness.c 6EXTRA_SOURCES := memcmp_64.S ../harness.c
7 7
8all: $(TEST_PROGS)
9
10$(TEST_PROGS): $(EXTRA_SOURCES)
11
12include ../../lib.mk 8include ../../lib.mk
13 9
14clean: 10$(TEST_GEN_PROGS): $(EXTRA_SOURCES)
15 rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/switch_endian/Makefile b/tools/testing/selftests/powerpc/switch_endian/Makefile
index e21d10674e54..b92c2a132c4f 100644
--- a/tools/testing/selftests/powerpc/switch_endian/Makefile
+++ b/tools/testing/selftests/powerpc/switch_endian/Makefile
@@ -1,18 +1,15 @@
1TEST_PROGS := switch_endian_test 1TEST_GEN_PROGS := switch_endian_test
2 2
3ASFLAGS += -O2 -Wall -g -nostdlib -m64 3ASFLAGS += -O2 -Wall -g -nostdlib -m64
4 4
5all: $(TEST_PROGS) 5EXTRA_CLEAN = $(OUTPUT)/*.o $(OUTPUT)/check-reversed.S
6 6
7switch_endian_test: check-reversed.S 7include ../../lib.mk
8
9$(OUTPUT)/switch_endian_test: $(OUTPUT)/check-reversed.S
8 10
9check-reversed.o: check.o 11$(OUTPUT)/check-reversed.o: $(OUTPUT)/check.o
10 $(CROSS_COMPILE)objcopy -j .text --reverse-bytes=4 -O binary $< $@ 12 $(CROSS_COMPILE)objcopy -j .text --reverse-bytes=4 -O binary $< $@
11 13
12check-reversed.S: check-reversed.o 14$(OUTPUT)/check-reversed.S: $(OUTPUT)/check-reversed.o
13 hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@ 15 hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@
14
15include ../../lib.mk
16
17clean:
18 rm -f $(TEST_PROGS) *.o check-reversed.S
diff --git a/tools/testing/selftests/powerpc/syscalls/Makefile b/tools/testing/selftests/powerpc/syscalls/Makefile
index b35c7945bec5..da22ca7c38c1 100644
--- a/tools/testing/selftests/powerpc/syscalls/Makefile
+++ b/tools/testing/selftests/powerpc/syscalls/Makefile
@@ -1,12 +1,7 @@
1TEST_PROGS := ipc_unmuxed 1TEST_GEN_PROGS := ipc_unmuxed
2 2
3CFLAGS += -I../../../../../usr/include 3CFLAGS += -I../../../../../usr/include
4 4
5all: $(TEST_PROGS)
6
7$(TEST_PROGS): ../harness.c
8
9include ../../lib.mk 5include ../../lib.mk
10 6
11clean: 7$(TEST_GEN_PROGS): ../harness.c
12 rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index c6c53c82fdd6..5576ee6a51f2 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -1,23 +1,19 @@
1SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu \ 1SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu \
2 tm-signal-context-chk-vmx tm-signal-context-chk-vsx 2 tm-signal-context-chk-vmx tm-signal-context-chk-vsx
3 3
4TEST_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \ 4TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
5 tm-vmxcopy tm-fork tm-tar tm-tmspr $(SIGNAL_CONTEXT_CHK_TESTS) 5 tm-vmxcopy tm-fork tm-tar tm-tmspr $(SIGNAL_CONTEXT_CHK_TESTS)
6 6
7all: $(TEST_PROGS) 7include ../../lib.mk
8 8
9$(TEST_PROGS): ../harness.c ../utils.c 9$(TEST_GEN_PROGS): ../harness.c ../utils.c
10 10
11CFLAGS += -mhtm 11CFLAGS += -mhtm
12 12
13tm-syscall: tm-syscall-asm.S 13$(OUTPUT)/tm-syscall: tm-syscall-asm.S
14tm-syscall: CFLAGS += -I../../../../../usr/include 14$(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include
15tm-tmspr: CFLAGS += -pthread 15$(OUTPUT)/tm-tmspr: CFLAGS += -pthread
16 16
17SIGNAL_CONTEXT_CHK_TESTS := $(patsubst %,$(OUTPUT)/%,$(SIGNAL_CONTEXT_CHK_TESTS))
17$(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S 18$(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S
18$(SIGNAL_CONTEXT_CHK_TESTS): CFLAGS += -mhtm -m64 -mvsx 19$(SIGNAL_CONTEXT_CHK_TESTS): CFLAGS += -mhtm -m64 -mvsx
19
20include ../../lib.mk
21
22clean:
23 rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/vphn/Makefile b/tools/testing/selftests/powerpc/vphn/Makefile
index a485f2e286ae..f8ced26748f8 100644
--- a/tools/testing/selftests/powerpc/vphn/Makefile
+++ b/tools/testing/selftests/powerpc/vphn/Makefile
@@ -1,12 +1,8 @@
1TEST_PROGS := test-vphn 1TEST_GEN_PROGS := test-vphn
2 2
3CFLAGS += -m64 3CFLAGS += -m64
4 4
5all: $(TEST_PROGS)
6
7$(TEST_PROGS): ../harness.c
8
9include ../../lib.mk 5include ../../lib.mk
10 6
11clean: 7$(TEST_GEN_PROGS): ../harness.c
12 rm -f $(TEST_PROGS) 8
diff --git a/tools/testing/selftests/pstore/Makefile b/tools/testing/selftests/pstore/Makefile
index bd7abe24ea08..c5f2440ba1f7 100644
--- a/tools/testing/selftests/pstore/Makefile
+++ b/tools/testing/selftests/pstore/Makefile
@@ -5,11 +5,9 @@ all:
5 5
6TEST_PROGS := pstore_tests pstore_post_reboot_tests 6TEST_PROGS := pstore_tests pstore_post_reboot_tests
7TEST_FILES := common_tests pstore_crash_test 7TEST_FILES := common_tests pstore_crash_test
8EXTRA_CLEAN := logs/* *uuid
8 9
9include ../lib.mk 10include ../lib.mk
10 11
11run_crash: 12run_crash:
12 @sh pstore_crash_test || { echo "pstore_crash_test: [FAIL]"; exit 1; } 13 @sh pstore_crash_test || { echo "pstore_crash_test: [FAIL]"; exit 1; }
13
14clean:
15 rm -rf logs/* *uuid
diff --git a/tools/testing/selftests/ptrace/Makefile b/tools/testing/selftests/ptrace/Makefile
index 453927fea90c..8a2bc5562179 100644
--- a/tools/testing/selftests/ptrace/Makefile
+++ b/tools/testing/selftests/ptrace/Makefile
@@ -1,11 +1,5 @@
1CFLAGS += -iquote../../../../include/uapi -Wall 1CFLAGS += -iquote../../../../include/uapi -Wall
2peeksiginfo: peeksiginfo.c
3 2
4all: peeksiginfo 3TEST_GEN_PROGS := peeksiginfo
5
6clean:
7 rm -f peeksiginfo
8
9TEST_PROGS := peeksiginfo
10 4
11include ../lib.mk 5include ../lib.mk
diff --git a/tools/testing/selftests/seccomp/Makefile b/tools/testing/selftests/seccomp/Makefile
index 8401e87e34e1..5fa6fd2246b1 100644
--- a/tools/testing/selftests/seccomp/Makefile
+++ b/tools/testing/selftests/seccomp/Makefile
@@ -1,10 +1,6 @@
1TEST_PROGS := seccomp_bpf 1TEST_GEN_PROGS := seccomp_bpf
2CFLAGS += -Wl,-no-as-needed -Wall 2CFLAGS += -Wl,-no-as-needed -Wall
3LDFLAGS += -lpthread 3LDFLAGS += -lpthread
4 4
5all: $(TEST_PROGS)
6
7include ../lib.mk 5include ../lib.mk
8 6
9clean:
10 $(RM) $(TEST_PROGS)
diff --git a/tools/testing/selftests/sigaltstack/Makefile b/tools/testing/selftests/sigaltstack/Makefile
index 56af56eda6fa..f68fbf80d8be 100644
--- a/tools/testing/selftests/sigaltstack/Makefile
+++ b/tools/testing/selftests/sigaltstack/Makefile
@@ -1,8 +1,5 @@
1CFLAGS = -Wall 1CFLAGS = -Wall
2BINARIES = sas 2TEST_GEN_PROGS = sas
3all: $(BINARIES)
4 3
5include ../lib.mk 4include ../lib.mk
6 5
7clean:
8 rm -rf $(BINARIES)
diff --git a/tools/testing/selftests/sigaltstack/sas.c b/tools/testing/selftests/sigaltstack/sas.c
index 1bb01258e559..ccd07343d418 100644
--- a/tools/testing/selftests/sigaltstack/sas.c
+++ b/tools/testing/selftests/sigaltstack/sas.c
@@ -57,7 +57,7 @@ void my_usr1(int sig, siginfo_t *si, void *u)
57 exit(EXIT_FAILURE); 57 exit(EXIT_FAILURE);
58 } 58 }
59 if (stk.ss_flags != SS_DISABLE) 59 if (stk.ss_flags != SS_DISABLE)
60 printf("[FAIL]\tss_flags=%i, should be SS_DISABLE\n", 60 printf("[FAIL]\tss_flags=%x, should be SS_DISABLE\n",
61 stk.ss_flags); 61 stk.ss_flags);
62 else 62 else
63 printf("[OK]\tsigaltstack is disabled in sighandler\n"); 63 printf("[OK]\tsigaltstack is disabled in sighandler\n");
@@ -122,7 +122,8 @@ int main(void)
122 if (stk.ss_flags == SS_DISABLE) { 122 if (stk.ss_flags == SS_DISABLE) {
123 printf("[OK]\tInitial sigaltstack state was SS_DISABLE\n"); 123 printf("[OK]\tInitial sigaltstack state was SS_DISABLE\n");
124 } else { 124 } else {
125 printf("[FAIL]\tInitial sigaltstack state was %i; should have been SS_DISABLE\n", stk.ss_flags); 125 printf("[FAIL]\tInitial sigaltstack state was %x; "
126 "should have been SS_DISABLE\n", stk.ss_flags);
126 return EXIT_FAILURE; 127 return EXIT_FAILURE;
127 } 128 }
128 129
@@ -165,7 +166,7 @@ int main(void)
165 exit(EXIT_FAILURE); 166 exit(EXIT_FAILURE);
166 } 167 }
167 if (stk.ss_flags != SS_AUTODISARM) { 168 if (stk.ss_flags != SS_AUTODISARM) {
168 printf("[FAIL]\tss_flags=%i, should be SS_AUTODISARM\n", 169 printf("[FAIL]\tss_flags=%x, should be SS_AUTODISARM\n",
169 stk.ss_flags); 170 stk.ss_flags);
170 exit(EXIT_FAILURE); 171 exit(EXIT_FAILURE);
171 } 172 }
diff --git a/tools/testing/selftests/size/Makefile b/tools/testing/selftests/size/Makefile
index bbd0b5398b61..4685b3e421fc 100644
--- a/tools/testing/selftests/size/Makefile
+++ b/tools/testing/selftests/size/Makefile
@@ -1,11 +1,5 @@
1all: get_size 1CFLAGS := -static -ffreestanding -nostartfiles -s
2 2
3get_size: get_size.c 3TEST_GEN_PROGS := get_size
4 $(CC) -static -ffreestanding -nostartfiles -s $< -o $@
5
6TEST_PROGS := get_size
7 4
8include ../lib.mk 5include ../lib.mk
9
10clean:
11 $(RM) get_size
diff --git a/tools/testing/selftests/splice/Makefile b/tools/testing/selftests/splice/Makefile
new file mode 100644
index 000000000000..de51f439d4a6
--- /dev/null
+++ b/tools/testing/selftests/splice/Makefile
@@ -0,0 +1,8 @@
1TEST_PROGS := default_file_splice_read.sh
2EXTRA := default_file_splice_read
3all: $(TEST_PROGS) $(EXTRA)
4
5include ../lib.mk
6
7clean:
8 rm -fr $(TEST_PROGS) $(EXTRA)
diff --git a/tools/testing/selftests/splice/default_file_splice_read.c b/tools/testing/selftests/splice/default_file_splice_read.c
new file mode 100644
index 000000000000..01dd6091554c
--- /dev/null
+++ b/tools/testing/selftests/splice/default_file_splice_read.c
@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3
4int main(int argc, char **argv)
5{
6 splice(0, 0, 1, 0, 1<<30, 0);
7 return 0;
8}
diff --git a/tools/testing/selftests/splice/default_file_splice_read.sh b/tools/testing/selftests/splice/default_file_splice_read.sh
new file mode 100755
index 000000000000..1ea2adeabc94
--- /dev/null
+++ b/tools/testing/selftests/splice/default_file_splice_read.sh
@@ -0,0 +1,7 @@
1#!/bin/sh
2n=`./default_file_splice_read </dev/null | wc -c`
3
4test "$n" = 0 && exit 0
5
6echo "default_file_splice_read broken: leaked $n"
7exit 1
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 1d5556869137..b90e50c36f9f 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -1,20 +1,16 @@
1CC = $(CROSS_COMPILE)gcc
2BUILD_FLAGS = -DKTEST 1BUILD_FLAGS = -DKTEST
3CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) 2CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS)
4LDFLAGS += -lrt -lpthread 3LDFLAGS += -lrt -lpthread
5 4
6# these are all "safe" tests that don't modify 5# these are all "safe" tests that don't modify
7# system time or require escalated privledges 6# system time or require escalated privledges
8TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ 7TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
9 inconsistency-check raw_skew threadtest rtctest 8 inconsistency-check raw_skew threadtest rtctest
10 9
11TEST_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ 10TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
12 skew_consistency clocksource-switch leap-a-day \ 11 skew_consistency clocksource-switch leap-a-day \
13 leapcrash set-tai set-2038 set-tz 12 leapcrash set-tai set-2038 set-tz
14 13
15bins = $(TEST_PROGS) $(TEST_PROGS_EXTENDED)
16
17all: ${bins}
18 14
19include ../lib.mk 15include ../lib.mk
20 16
@@ -34,5 +30,3 @@ run_destructive_tests: run_tests
34 ./set-tai 30 ./set-tai
35 ./set-2038 31 ./set-2038
36 32
37clean:
38 rm -f ${bins}
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
index bbab7f4664ac..41642ba5e318 100644
--- a/tools/testing/selftests/vm/Makefile
+++ b/tools/testing/selftests/vm/Makefile
@@ -1,33 +1,37 @@
1# Makefile for vm selftests 1# Makefile for vm selftests
2 2
3CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) 3ifndef OUTPUT
4BINARIES = compaction_test 4 OUTPUT := $(shell pwd)
5BINARIES += hugepage-mmap 5endif
6BINARIES += hugepage-shm
7BINARIES += map_hugetlb
8BINARIES += mlock2-tests
9BINARIES += on-fault-limit
10BINARIES += thuge-gen
11BINARIES += transhuge-stress
12BINARIES += userfaultfd
13BINARIES += mlock-random-test
14
15all: $(BINARIES)
16%: %.c
17 $(CC) $(CFLAGS) -o $@ $^ -lrt
18userfaultfd: userfaultfd.c ../../../../usr/include/linux/kernel.h
19 $(CC) $(CFLAGS) -O2 -o $@ $< -lpthread
20
21mlock-random-test: mlock-random-test.c
22 $(CC) $(CFLAGS) -o $@ $< -lcap
23 6
24../../../../usr/include/linux/kernel.h: 7CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS)
25 make -C ../../../.. headers_install 8LDLIBS = -lrt
9TEST_GEN_FILES = compaction_test
10TEST_GEN_FILES += hugepage-mmap
11TEST_GEN_FILES += hugepage-shm
12TEST_GEN_FILES += map_hugetlb
13TEST_GEN_FILES += mlock2-tests
14TEST_GEN_FILES += on-fault-limit
15TEST_GEN_FILES += thuge-gen
16TEST_GEN_FILES += transhuge-stress
17TEST_GEN_FILES += userfaultfd
18TEST_GEN_FILES += userfaultfd_hugetlb
19TEST_GEN_FILES += userfaultfd_shmem
20TEST_GEN_FILES += mlock-random-test
26 21
27TEST_PROGS := run_vmtests 22TEST_PROGS := run_vmtests
28TEST_FILES := $(BINARIES)
29 23
30include ../lib.mk 24include ../lib.mk
31 25
32clean: 26$(OUTPUT)/userfaultfd: LDLIBS += -lpthread ../../../../usr/include/linux/kernel.h
33 $(RM) $(BINARIES) 27
28$(OUTPUT)/userfaultfd_hugetlb: userfaultfd.c ../../../../usr/include/linux/kernel.h
29 $(CC) $(CFLAGS) -DHUGETLB_TEST -O2 -o $@ $< -lpthread
30
31$(OUTPUT)/userfaultfd_shmem: userfaultfd.c ../../../../usr/include/linux/kernel.h
32 $(CC) $(CFLAGS) -DSHMEM_TEST -O2 -o $@ $< -lpthread
33
34$(OUTPUT)/mlock-random-test: LDLIBS += -lcap
35
36../../../../usr/include/linux/kernel.h:
37 make -C ../../../.. headers_install
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests
index e11968b3677e..c92f6cf31d0a 100755
--- a/tools/testing/selftests/vm/run_vmtests
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -103,6 +103,30 @@ else
103 echo "[PASS]" 103 echo "[PASS]"
104fi 104fi
105 105
106echo "----------------------------"
107echo "running userfaultfd_hugetlb"
108echo "----------------------------"
109# 258MB total huge pages == 128MB src and 128MB dst
110./userfaultfd_hugetlb 128 32 $mnt/ufd_test_file
111if [ $? -ne 0 ]; then
112 echo "[FAIL]"
113 exitcode=1
114else
115 echo "[PASS]"
116fi
117rm -f $mnt/ufd_test_file
118
119echo "----------------------------"
120echo "running userfaultfd_shmem"
121echo "----------------------------"
122./userfaultfd_shmem 128 32
123if [ $? -ne 0 ]; then
124 echo "[FAIL]"
125 exitcode=1
126else
127 echo "[PASS]"
128fi
129
106#cleanup 130#cleanup
107umount $mnt 131umount $mnt
108rm -rf $mnt 132rm -rf $mnt
diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
index d77ed41b2094..e9449c801888 100644
--- a/tools/testing/selftests/vm/userfaultfd.c
+++ b/tools/testing/selftests/vm/userfaultfd.c
@@ -63,6 +63,7 @@
63#include <sys/mman.h> 63#include <sys/mman.h>
64#include <sys/syscall.h> 64#include <sys/syscall.h>
65#include <sys/ioctl.h> 65#include <sys/ioctl.h>
66#include <sys/wait.h>
66#include <pthread.h> 67#include <pthread.h>
67#include <linux/userfaultfd.h> 68#include <linux/userfaultfd.h>
68 69
@@ -76,8 +77,12 @@ static unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size;
76#define BOUNCE_POLL (1<<3) 77#define BOUNCE_POLL (1<<3)
77static int bounces; 78static int bounces;
78 79
80#ifdef HUGETLB_TEST
81static int huge_fd;
82static char *huge_fd_off0;
83#endif
79static unsigned long long *count_verify; 84static unsigned long long *count_verify;
80static int uffd, finished, *pipefd; 85static int uffd, uffd_flags, finished, *pipefd;
81static char *area_src, *area_dst; 86static char *area_src, *area_dst;
82static char *zeropage; 87static char *zeropage;
83pthread_attr_t attr; 88pthread_attr_t attr;
@@ -97,6 +102,102 @@ pthread_attr_t attr;
97 ~(unsigned long)(sizeof(unsigned long long) \ 102 ~(unsigned long)(sizeof(unsigned long long) \
98 - 1))) 103 - 1)))
99 104
105#if !defined(HUGETLB_TEST) && !defined(SHMEM_TEST)
106
107/* Anonymous memory */
108#define EXPECTED_IOCTLS ((1 << _UFFDIO_WAKE) | \
109 (1 << _UFFDIO_COPY) | \
110 (1 << _UFFDIO_ZEROPAGE))
111
112static int release_pages(char *rel_area)
113{
114 int ret = 0;
115
116 if (madvise(rel_area, nr_pages * page_size, MADV_DONTNEED)) {
117 perror("madvise");
118 ret = 1;
119 }
120
121 return ret;
122}
123
124static void allocate_area(void **alloc_area)
125{
126 if (posix_memalign(alloc_area, page_size, nr_pages * page_size)) {
127 fprintf(stderr, "out of memory\n");
128 *alloc_area = NULL;
129 }
130}
131
132#else /* HUGETLB_TEST or SHMEM_TEST */
133
134#define EXPECTED_IOCTLS UFFD_API_RANGE_IOCTLS_BASIC
135
136#ifdef HUGETLB_TEST
137
138/* HugeTLB memory */
139static int release_pages(char *rel_area)
140{
141 int ret = 0;
142
143 if (fallocate(huge_fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
144 rel_area == huge_fd_off0 ? 0 :
145 nr_pages * page_size,
146 nr_pages * page_size)) {
147 perror("fallocate");
148 ret = 1;
149 }
150
151 return ret;
152}
153
154
155static void allocate_area(void **alloc_area)
156{
157 *alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
158 MAP_PRIVATE | MAP_HUGETLB, huge_fd,
159 *alloc_area == area_src ? 0 :
160 nr_pages * page_size);
161 if (*alloc_area == MAP_FAILED) {
162 fprintf(stderr, "mmap of hugetlbfs file failed\n");
163 *alloc_area = NULL;
164 }
165
166 if (*alloc_area == area_src)
167 huge_fd_off0 = *alloc_area;
168}
169
170#elif defined(SHMEM_TEST)
171
172/* Shared memory */
173static int release_pages(char *rel_area)
174{
175 int ret = 0;
176
177 if (madvise(rel_area, nr_pages * page_size, MADV_REMOVE)) {
178 perror("madvise");
179 ret = 1;
180 }
181
182 return ret;
183}
184
185static void allocate_area(void **alloc_area)
186{
187 *alloc_area = mmap(NULL, nr_pages * page_size, PROT_READ | PROT_WRITE,
188 MAP_ANONYMOUS | MAP_SHARED, -1, 0);
189 if (*alloc_area == MAP_FAILED) {
190 fprintf(stderr, "shared memory mmap failed\n");
191 *alloc_area = NULL;
192 }
193}
194
195#else /* SHMEM_TEST */
196#error "Undefined test type"
197#endif /* HUGETLB_TEST */
198
199#endif /* !defined(HUGETLB_TEST) && !defined(SHMEM_TEST) */
200
100static int my_bcmp(char *str1, char *str2, size_t n) 201static int my_bcmp(char *str1, char *str2, size_t n)
101{ 202{
102 unsigned long i; 203 unsigned long i;
@@ -217,7 +318,7 @@ static void *locking_thread(void *arg)
217 return NULL; 318 return NULL;
218} 319}
219 320
220static int copy_page(unsigned long offset) 321static int copy_page(int ufd, unsigned long offset)
221{ 322{
222 struct uffdio_copy uffdio_copy; 323 struct uffdio_copy uffdio_copy;
223 324
@@ -229,7 +330,7 @@ static int copy_page(unsigned long offset)
229 uffdio_copy.len = page_size; 330 uffdio_copy.len = page_size;
230 uffdio_copy.mode = 0; 331 uffdio_copy.mode = 0;
231 uffdio_copy.copy = 0; 332 uffdio_copy.copy = 0;
232 if (ioctl(uffd, UFFDIO_COPY, &uffdio_copy)) { 333 if (ioctl(ufd, UFFDIO_COPY, &uffdio_copy)) {
233 /* real retval in ufdio_copy.copy */ 334 /* real retval in ufdio_copy.copy */
234 if (uffdio_copy.copy != -EEXIST) 335 if (uffdio_copy.copy != -EEXIST)
235 fprintf(stderr, "UFFDIO_COPY error %Ld\n", 336 fprintf(stderr, "UFFDIO_COPY error %Ld\n",
@@ -247,6 +348,7 @@ static void *uffd_poll_thread(void *arg)
247 unsigned long cpu = (unsigned long) arg; 348 unsigned long cpu = (unsigned long) arg;
248 struct pollfd pollfd[2]; 349 struct pollfd pollfd[2];
249 struct uffd_msg msg; 350 struct uffd_msg msg;
351 struct uffdio_register uffd_reg;
250 int ret; 352 int ret;
251 unsigned long offset; 353 unsigned long offset;
252 char tmp_chr; 354 char tmp_chr;
@@ -278,16 +380,35 @@ static void *uffd_poll_thread(void *arg)
278 continue; 380 continue;
279 perror("nonblocking read error"), exit(1); 381 perror("nonblocking read error"), exit(1);
280 } 382 }
281 if (msg.event != UFFD_EVENT_PAGEFAULT) 383 switch (msg.event) {
384 default:
282 fprintf(stderr, "unexpected msg event %u\n", 385 fprintf(stderr, "unexpected msg event %u\n",
283 msg.event), exit(1); 386 msg.event), exit(1);
284 if (msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE) 387 break;
285 fprintf(stderr, "unexpected write fault\n"), exit(1); 388 case UFFD_EVENT_PAGEFAULT:
286 offset = (char *)(unsigned long)msg.arg.pagefault.address - 389 if (msg.arg.pagefault.flags & UFFD_PAGEFAULT_FLAG_WRITE)
287 area_dst; 390 fprintf(stderr, "unexpected write fault\n"), exit(1);
288 offset &= ~(page_size-1); 391 offset = (char *)(unsigned long)msg.arg.pagefault.address -
289 if (copy_page(offset)) 392 area_dst;
290 userfaults++; 393 offset &= ~(page_size-1);
394 if (copy_page(uffd, offset))
395 userfaults++;
396 break;
397 case UFFD_EVENT_FORK:
398 uffd = msg.arg.fork.ufd;
399 pollfd[0].fd = uffd;
400 break;
401 case UFFD_EVENT_REMOVE:
402 uffd_reg.range.start = msg.arg.remove.start;
403 uffd_reg.range.len = msg.arg.remove.end -
404 msg.arg.remove.start;
405 if (ioctl(uffd, UFFDIO_UNREGISTER, &uffd_reg.range))
406 fprintf(stderr, "remove failure\n"), exit(1);
407 break;
408 case UFFD_EVENT_REMAP:
409 area_dst = (char *)(unsigned long)msg.arg.remap.to;
410 break;
411 }
291 } 412 }
292 return (void *)userfaults; 413 return (void *)userfaults;
293} 414}
@@ -324,7 +445,7 @@ static void *uffd_read_thread(void *arg)
324 offset = (char *)(unsigned long)msg.arg.pagefault.address - 445 offset = (char *)(unsigned long)msg.arg.pagefault.address -
325 area_dst; 446 area_dst;
326 offset &= ~(page_size-1); 447 offset &= ~(page_size-1);
327 if (copy_page(offset)) 448 if (copy_page(uffd, offset))
328 (*this_cpu_userfaults)++; 449 (*this_cpu_userfaults)++;
329 } 450 }
330 return (void *)NULL; 451 return (void *)NULL;
@@ -338,7 +459,7 @@ static void *background_thread(void *arg)
338 for (page_nr = cpu * nr_pages_per_cpu; 459 for (page_nr = cpu * nr_pages_per_cpu;
339 page_nr < (cpu+1) * nr_pages_per_cpu; 460 page_nr < (cpu+1) * nr_pages_per_cpu;
340 page_nr++) 461 page_nr++)
341 copy_page(page_nr * page_size); 462 copy_page(uffd, page_nr * page_size);
342 463
343 return NULL; 464 return NULL;
344} 465}
@@ -384,10 +505,8 @@ static int stress(unsigned long *userfaults)
384 * UFFDIO_COPY without writing zero pages into area_dst 505 * UFFDIO_COPY without writing zero pages into area_dst
385 * because the background threads already completed). 506 * because the background threads already completed).
386 */ 507 */
387 if (madvise(area_src, nr_pages * page_size, MADV_DONTNEED)) { 508 if (release_pages(area_src))
388 perror("madvise");
389 return 1; 509 return 1;
390 }
391 510
392 for (cpu = 0; cpu < nr_cpus; cpu++) { 511 for (cpu = 0; cpu < nr_cpus; cpu++) {
393 char c; 512 char c;
@@ -414,27 +533,9 @@ static int stress(unsigned long *userfaults)
414 return 0; 533 return 0;
415} 534}
416 535
417static int userfaultfd_stress(void) 536static int userfaultfd_open(int features)
418{ 537{
419 void *area;
420 char *tmp_area;
421 unsigned long nr;
422 struct uffdio_register uffdio_register;
423 struct uffdio_api uffdio_api; 538 struct uffdio_api uffdio_api;
424 unsigned long cpu;
425 int uffd_flags, err;
426 unsigned long userfaults[nr_cpus];
427
428 if (posix_memalign(&area, page_size, nr_pages * page_size)) {
429 fprintf(stderr, "out of memory\n");
430 return 1;
431 }
432 area_src = area;
433 if (posix_memalign(&area, page_size, nr_pages * page_size)) {
434 fprintf(stderr, "out of memory\n");
435 return 1;
436 }
437 area_dst = area;
438 539
439 uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); 540 uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
440 if (uffd < 0) { 541 if (uffd < 0) {
@@ -445,7 +546,7 @@ static int userfaultfd_stress(void)
445 uffd_flags = fcntl(uffd, F_GETFD, NULL); 546 uffd_flags = fcntl(uffd, F_GETFD, NULL);
446 547
447 uffdio_api.api = UFFD_API; 548 uffdio_api.api = UFFD_API;
448 uffdio_api.features = 0; 549 uffdio_api.features = features;
449 if (ioctl(uffd, UFFDIO_API, &uffdio_api)) { 550 if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
450 fprintf(stderr, "UFFDIO_API\n"); 551 fprintf(stderr, "UFFDIO_API\n");
451 return 1; 552 return 1;
@@ -455,6 +556,233 @@ static int userfaultfd_stress(void)
455 return 1; 556 return 1;
456 } 557 }
457 558
559 return 0;
560}
561
562/*
563 * For non-cooperative userfaultfd test we fork() a process that will
564 * generate pagefaults, will mremap the area monitored by the
565 * userfaultfd and at last this process will release the monitored
566 * area.
567 * For the anonymous and shared memory the area is divided into two
568 * parts, the first part is accessed before mremap, and the second
569 * part is accessed after mremap. Since hugetlbfs does not support
570 * mremap, the entire monitored area is accessed in a single pass for
571 * HUGETLB_TEST.
572 * The release of the pages currently generates event for shmem and
573 * anonymous memory (UFFD_EVENT_REMOVE), hence it is not checked
574 * for hugetlb.
575 */
576static int faulting_process(void)
577{
578 unsigned long nr;
579 unsigned long long count;
580
581#ifndef HUGETLB_TEST
582 unsigned long split_nr_pages = (nr_pages + 1) / 2;
583#else
584 unsigned long split_nr_pages = nr_pages;
585#endif
586
587 for (nr = 0; nr < split_nr_pages; nr++) {
588 count = *area_count(area_dst, nr);
589 if (count != count_verify[nr]) {
590 fprintf(stderr,
591 "nr %lu memory corruption %Lu %Lu\n",
592 nr, count,
593 count_verify[nr]), exit(1);
594 }
595 }
596
597#ifndef HUGETLB_TEST
598 area_dst = mremap(area_dst, nr_pages * page_size, nr_pages * page_size,
599 MREMAP_MAYMOVE | MREMAP_FIXED, area_src);
600 if (area_dst == MAP_FAILED)
601 perror("mremap"), exit(1);
602
603 for (; nr < nr_pages; nr++) {
604 count = *area_count(area_dst, nr);
605 if (count != count_verify[nr]) {
606 fprintf(stderr,
607 "nr %lu memory corruption %Lu %Lu\n",
608 nr, count,
609 count_verify[nr]), exit(1);
610 }
611 }
612
613 if (release_pages(area_dst))
614 return 1;
615
616 for (nr = 0; nr < nr_pages; nr++) {
617 if (my_bcmp(area_dst + nr * page_size, zeropage, page_size))
618 fprintf(stderr, "nr %lu is not zero\n", nr), exit(1);
619 }
620
621#endif /* HUGETLB_TEST */
622
623 return 0;
624}
625
626static int uffdio_zeropage(int ufd, unsigned long offset)
627{
628 struct uffdio_zeropage uffdio_zeropage;
629 int ret;
630 unsigned long has_zeropage = EXPECTED_IOCTLS & (1 << _UFFDIO_ZEROPAGE);
631
632 if (offset >= nr_pages * page_size)
633 fprintf(stderr, "unexpected offset %lu\n",
634 offset), exit(1);
635 uffdio_zeropage.range.start = (unsigned long) area_dst + offset;
636 uffdio_zeropage.range.len = page_size;
637 uffdio_zeropage.mode = 0;
638 ret = ioctl(ufd, UFFDIO_ZEROPAGE, &uffdio_zeropage);
639 if (ret) {
640 /* real retval in ufdio_zeropage.zeropage */
641 if (has_zeropage) {
642 if (uffdio_zeropage.zeropage == -EEXIST)
643 fprintf(stderr, "UFFDIO_ZEROPAGE -EEXIST\n"),
644 exit(1);
645 else
646 fprintf(stderr, "UFFDIO_ZEROPAGE error %Ld\n",
647 uffdio_zeropage.zeropage), exit(1);
648 } else {
649 if (uffdio_zeropage.zeropage != -EINVAL)
650 fprintf(stderr,
651 "UFFDIO_ZEROPAGE not -EINVAL %Ld\n",
652 uffdio_zeropage.zeropage), exit(1);
653 }
654 } else if (has_zeropage) {
655 if (uffdio_zeropage.zeropage != page_size) {
656 fprintf(stderr, "UFFDIO_ZEROPAGE unexpected %Ld\n",
657 uffdio_zeropage.zeropage), exit(1);
658 } else
659 return 1;
660 } else {
661 fprintf(stderr,
662 "UFFDIO_ZEROPAGE succeeded %Ld\n",
663 uffdio_zeropage.zeropage), exit(1);
664 }
665
666 return 0;
667}
668
669/* exercise UFFDIO_ZEROPAGE */
670static int userfaultfd_zeropage_test(void)
671{
672 struct uffdio_register uffdio_register;
673 unsigned long expected_ioctls;
674
675 printf("testing UFFDIO_ZEROPAGE: ");
676 fflush(stdout);
677
678 if (release_pages(area_dst))
679 return 1;
680
681 if (userfaultfd_open(0) < 0)
682 return 1;
683 uffdio_register.range.start = (unsigned long) area_dst;
684 uffdio_register.range.len = nr_pages * page_size;
685 uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
686 if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
687 fprintf(stderr, "register failure\n"), exit(1);
688
689 expected_ioctls = EXPECTED_IOCTLS;
690 if ((uffdio_register.ioctls & expected_ioctls) !=
691 expected_ioctls)
692 fprintf(stderr,
693 "unexpected missing ioctl for anon memory\n"),
694 exit(1);
695
696 if (uffdio_zeropage(uffd, 0)) {
697 if (my_bcmp(area_dst, zeropage, page_size))
698 fprintf(stderr, "zeropage is not zero\n"), exit(1);
699 }
700
701 close(uffd);
702 printf("done.\n");
703 return 0;
704}
705
706static int userfaultfd_events_test(void)
707{
708 struct uffdio_register uffdio_register;
709 unsigned long expected_ioctls;
710 unsigned long userfaults;
711 pthread_t uffd_mon;
712 int err, features;
713 pid_t pid;
714 char c;
715
716 printf("testing events (fork, remap, remove): ");
717 fflush(stdout);
718
719 if (release_pages(area_dst))
720 return 1;
721
722 features = UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP |
723 UFFD_FEATURE_EVENT_REMOVE;
724 if (userfaultfd_open(features) < 0)
725 return 1;
726 fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
727
728 uffdio_register.range.start = (unsigned long) area_dst;
729 uffdio_register.range.len = nr_pages * page_size;
730 uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
731 if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
732 fprintf(stderr, "register failure\n"), exit(1);
733
734 expected_ioctls = EXPECTED_IOCTLS;
735 if ((uffdio_register.ioctls & expected_ioctls) !=
736 expected_ioctls)
737 fprintf(stderr,
738 "unexpected missing ioctl for anon memory\n"),
739 exit(1);
740
741 if (pthread_create(&uffd_mon, &attr, uffd_poll_thread, NULL))
742 perror("uffd_poll_thread create"), exit(1);
743
744 pid = fork();
745 if (pid < 0)
746 perror("fork"), exit(1);
747
748 if (!pid)
749 return faulting_process();
750
751 waitpid(pid, &err, 0);
752 if (err)
753 fprintf(stderr, "faulting process failed\n"), exit(1);
754
755 if (write(pipefd[1], &c, sizeof(c)) != sizeof(c))
756 perror("pipe write"), exit(1);
757 if (pthread_join(uffd_mon, (void **)&userfaults))
758 return 1;
759
760 close(uffd);
761 printf("userfaults: %ld\n", userfaults);
762
763 return userfaults != nr_pages;
764}
765
766static int userfaultfd_stress(void)
767{
768 void *area;
769 char *tmp_area;
770 unsigned long nr;
771 struct uffdio_register uffdio_register;
772 unsigned long cpu;
773 int err;
774 unsigned long userfaults[nr_cpus];
775
776 allocate_area((void **)&area_src);
777 if (!area_src)
778 return 1;
779 allocate_area((void **)&area_dst);
780 if (!area_dst)
781 return 1;
782
783 if (userfaultfd_open(0) < 0)
784 return 1;
785
458 count_verify = malloc(nr_pages * sizeof(unsigned long long)); 786 count_verify = malloc(nr_pages * sizeof(unsigned long long));
459 if (!count_verify) { 787 if (!count_verify) {
460 perror("count_verify"); 788 perror("count_verify");
@@ -528,9 +856,7 @@ static int userfaultfd_stress(void)
528 fprintf(stderr, "register failure\n"); 856 fprintf(stderr, "register failure\n");
529 return 1; 857 return 1;
530 } 858 }
531 expected_ioctls = (1 << _UFFDIO_WAKE) | 859 expected_ioctls = EXPECTED_IOCTLS;
532 (1 << _UFFDIO_COPY) |
533 (1 << _UFFDIO_ZEROPAGE);
534 if ((uffdio_register.ioctls & expected_ioctls) != 860 if ((uffdio_register.ioctls & expected_ioctls) !=
535 expected_ioctls) { 861 expected_ioctls) {
536 fprintf(stderr, 862 fprintf(stderr,
@@ -562,10 +888,8 @@ static int userfaultfd_stress(void)
562 * MADV_DONTNEED only after the UFFDIO_REGISTER, so it's 888 * MADV_DONTNEED only after the UFFDIO_REGISTER, so it's
563 * required to MADV_DONTNEED here. 889 * required to MADV_DONTNEED here.
564 */ 890 */
565 if (madvise(area_dst, nr_pages * page_size, MADV_DONTNEED)) { 891 if (release_pages(area_dst))
566 perror("madvise 2");
567 return 1; 892 return 1;
568 }
569 893
570 /* bounce pass */ 894 /* bounce pass */
571 if (stress(userfaults)) 895 if (stress(userfaults))
@@ -603,9 +927,15 @@ static int userfaultfd_stress(void)
603 printf("\n"); 927 printf("\n");
604 } 928 }
605 929
606 return err; 930 if (err)
931 return err;
932
933 close(uffd);
934 return userfaultfd_zeropage_test() || userfaultfd_events_test();
607} 935}
608 936
937#ifndef HUGETLB_TEST
938
609int main(int argc, char **argv) 939int main(int argc, char **argv)
610{ 940{
611 if (argc < 3) 941 if (argc < 3)
@@ -632,6 +962,74 @@ int main(int argc, char **argv)
632 return userfaultfd_stress(); 962 return userfaultfd_stress();
633} 963}
634 964
965#else /* HUGETLB_TEST */
966
967/*
968 * Copied from mlock2-tests.c
969 */
970unsigned long default_huge_page_size(void)
971{
972 unsigned long hps = 0;
973 char *line = NULL;
974 size_t linelen = 0;
975 FILE *f = fopen("/proc/meminfo", "r");
976
977 if (!f)
978 return 0;
979 while (getline(&line, &linelen, f) > 0) {
980 if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
981 hps <<= 10;
982 break;
983 }
984 }
985
986 free(line);
987 fclose(f);
988 return hps;
989}
990
991int main(int argc, char **argv)
992{
993 if (argc < 4)
994 fprintf(stderr, "Usage: <MiB> <bounces> <hugetlbfs_file>\n"),
995 exit(1);
996 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
997 page_size = default_huge_page_size();
998 if (!page_size)
999 fprintf(stderr, "Unable to determine huge page size\n"),
1000 exit(2);
1001 if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) * 2
1002 > page_size)
1003 fprintf(stderr, "Impossible to run this test\n"), exit(2);
1004 nr_pages_per_cpu = atol(argv[1]) * 1024*1024 / page_size /
1005 nr_cpus;
1006 if (!nr_pages_per_cpu) {
1007 fprintf(stderr, "invalid MiB\n");
1008 fprintf(stderr, "Usage: <MiB> <bounces>\n"), exit(1);
1009 }
1010 bounces = atoi(argv[2]);
1011 if (bounces <= 0) {
1012 fprintf(stderr, "invalid bounces\n");
1013 fprintf(stderr, "Usage: <MiB> <bounces>\n"), exit(1);
1014 }
1015 nr_pages = nr_pages_per_cpu * nr_cpus;
1016 huge_fd = open(argv[3], O_CREAT | O_RDWR, 0755);
1017 if (huge_fd < 0) {
1018 fprintf(stderr, "Open of %s failed", argv[3]);
1019 perror("open");
1020 exit(1);
1021 }
1022 if (ftruncate(huge_fd, 0)) {
1023 fprintf(stderr, "ftruncate %s to size 0 failed", argv[3]);
1024 perror("ftruncate");
1025 exit(1);
1026 }
1027 printf("nr_pages: %lu, nr_pages_per_cpu: %lu\n",
1028 nr_pages, nr_pages_per_cpu);
1029 return userfaultfd_stress();
1030}
1031
1032#endif
635#else /* __NR_userfaultfd */ 1033#else /* __NR_userfaultfd */
636 1034
637#warning "missing __NR_userfaultfd definition" 1035#warning "missing __NR_userfaultfd definition"
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 83d8b1c6cb0e..38e0a9ca5d71 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -5,7 +5,7 @@ include ../lib.mk
5.PHONY: all all_32 all_64 warn_32bit_failure clean 5.PHONY: all all_32 all_64 warn_32bit_failure clean
6 6
7TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ 7TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \
8 check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test \ 8 check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \
9 protection_keys test_vdso 9 protection_keys test_vdso
10TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ 10TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
11 test_FCMOV test_FCOMI test_FISTTP \ 11 test_FCMOV test_FCOMI test_FISTTP \
@@ -17,6 +17,9 @@ TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
17BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) 17BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
18BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64) 18BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64)
19 19
20BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32))
21BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64))
22
20CFLAGS := -O2 -g -std=gnu99 -pthread -Wall 23CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
21 24
22UNAME_M := $(shell uname -m) 25UNAME_M := $(shell uname -m)
@@ -40,10 +43,10 @@ all_64: $(BINARIES_64)
40clean: 43clean:
41 $(RM) $(BINARIES_32) $(BINARIES_64) 44 $(RM) $(BINARIES_32) $(BINARIES_64)
42 45
43$(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c 46$(BINARIES_32): $(OUTPUT)/%_32: %.c
44 $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm 47 $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm
45 48
46$(TARGETS_C_64BIT_ALL:%=%_64): %_64: %.c 49$(BINARIES_64): $(OUTPUT)/%_64: %.c
47 $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl 50 $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
48 51
49# x86_64 users should be encouraged to install 32-bit libraries 52# x86_64 users should be encouraged to install 32-bit libraries
@@ -65,12 +68,12 @@ warn_32bit_failure:
65endif 68endif
66 69
67# Some tests have additional dependencies. 70# Some tests have additional dependencies.
68sysret_ss_attrs_64: thunks.S 71$(OUTPUT)/sysret_ss_attrs_64: thunks.S
69ptrace_syscall_32: raw_syscall_helper_32.S 72$(OUTPUT)/ptrace_syscall_32: raw_syscall_helper_32.S
70test_syscall_vdso_32: thunks_32.S 73$(OUTPUT)/test_syscall_vdso_32: thunks_32.S
71 74
72# check_initial_reg_state is special: it needs a custom entry, and it 75# check_initial_reg_state is special: it needs a custom entry, and it
73# needs to be static so that its interpreter doesn't destroy its initial 76# needs to be static so that its interpreter doesn't destroy its initial
74# state. 77# state.
75check_initial_reg_state_32: CFLAGS += -Wl,-ereal_start -static 78$(OUTPUT)/check_initial_reg_state_32: CFLAGS += -Wl,-ereal_start -static
76check_initial_reg_state_64: CFLAGS += -Wl,-ereal_start -static 79$(OUTPUT)/check_initial_reg_state_64: CFLAGS += -Wl,-ereal_start -static
diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c
index 5b2b4b3c634c..b4967d875236 100644
--- a/tools/testing/selftests/x86/fsgsbase.c
+++ b/tools/testing/selftests/x86/fsgsbase.c
@@ -245,7 +245,7 @@ void do_unexpected_base(void)
245 long ret; 245 long ret;
246 asm volatile ("int $0x80" 246 asm volatile ("int $0x80"
247 : "=a" (ret) : "a" (243), "b" (low_desc) 247 : "=a" (ret) : "a" (243), "b" (low_desc)
248 : "flags"); 248 : "r8", "r9", "r10", "r11");
249 memcpy(&desc, low_desc, sizeof(desc)); 249 memcpy(&desc, low_desc, sizeof(desc));
250 munmap(low_desc, sizeof(desc)); 250 munmap(low_desc, sizeof(desc));
251 251
diff --git a/tools/testing/selftests/x86/ioperm.c b/tools/testing/selftests/x86/ioperm.c
new file mode 100644
index 000000000000..b77313ba2ab1
--- /dev/null
+++ b/tools/testing/selftests/x86/ioperm.c
@@ -0,0 +1,170 @@
1/*
2 * ioperm.c - Test case for ioperm(2)
3 * Copyright (c) 2015 Andrew Lutomirski
4 */
5
6#define _GNU_SOURCE
7#include <err.h>
8#include <stdio.h>
9#include <stdint.h>
10#include <signal.h>
11#include <setjmp.h>
12#include <stdlib.h>
13#include <string.h>
14#include <errno.h>
15#include <unistd.h>
16#include <sys/types.h>
17#include <sys/wait.h>
18#include <stdbool.h>
19#include <sched.h>
20#include <sys/io.h>
21
22static int nerrs = 0;
23
24static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
25 int flags)
26{
27 struct sigaction sa;
28 memset(&sa, 0, sizeof(sa));
29 sa.sa_sigaction = handler;
30 sa.sa_flags = SA_SIGINFO | flags;
31 sigemptyset(&sa.sa_mask);
32 if (sigaction(sig, &sa, 0))
33 err(1, "sigaction");
34
35}
36
37static void clearhandler(int sig)
38{
39 struct sigaction sa;
40 memset(&sa, 0, sizeof(sa));
41 sa.sa_handler = SIG_DFL;
42 sigemptyset(&sa.sa_mask);
43 if (sigaction(sig, &sa, 0))
44 err(1, "sigaction");
45}
46
47static jmp_buf jmpbuf;
48
49static void sigsegv(int sig, siginfo_t *si, void *ctx_void)
50{
51 siglongjmp(jmpbuf, 1);
52}
53
54static bool try_outb(unsigned short port)
55{
56 sethandler(SIGSEGV, sigsegv, SA_RESETHAND);
57 if (sigsetjmp(jmpbuf, 1) != 0) {
58 return false;
59 } else {
60 asm volatile ("outb %%al, %w[port]"
61 : : [port] "Nd" (port), "a" (0));
62 return true;
63 }
64 clearhandler(SIGSEGV);
65}
66
67static void expect_ok(unsigned short port)
68{
69 if (!try_outb(port)) {
70 printf("[FAIL]\toutb to 0x%02hx failed\n", port);
71 exit(1);
72 }
73
74 printf("[OK]\toutb to 0x%02hx worked\n", port);
75}
76
77static void expect_gp(unsigned short port)
78{
79 if (try_outb(port)) {
80 printf("[FAIL]\toutb to 0x%02hx worked\n", port);
81 exit(1);
82 }
83
84 printf("[OK]\toutb to 0x%02hx failed\n", port);
85}
86
87int main(void)
88{
89 cpu_set_t cpuset;
90 CPU_ZERO(&cpuset);
91 CPU_SET(0, &cpuset);
92 if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
93 err(1, "sched_setaffinity to CPU 0");
94
95 expect_gp(0x80);
96 expect_gp(0xed);
97
98 /*
99 * Probe for ioperm support. Note that clearing ioperm bits
100 * works even as nonroot.
101 */
102 printf("[RUN]\tenable 0x80\n");
103 if (ioperm(0x80, 1, 1) != 0) {
104 printf("[OK]\tioperm(0x80, 1, 1) failed (%d) -- try running as root\n",
105 errno);
106 return 0;
107 }
108 expect_ok(0x80);
109 expect_gp(0xed);
110
111 printf("[RUN]\tdisable 0x80\n");
112 if (ioperm(0x80, 1, 0) != 0) {
113 printf("[FAIL]\tioperm(0x80, 1, 0) failed (%d)", errno);
114 return 1;
115 }
116 expect_gp(0x80);
117 expect_gp(0xed);
118
119 /* Make sure that fork() preserves ioperm. */
120 if (ioperm(0x80, 1, 1) != 0) {
121 printf("[FAIL]\tioperm(0x80, 1, 0) failed (%d)", errno);
122 return 1;
123 }
124
125 pid_t child = fork();
126 if (child == -1)
127 err(1, "fork");
128
129 if (child == 0) {
130 printf("[RUN]\tchild: check that we inherited permissions\n");
131 expect_ok(0x80);
132 expect_gp(0xed);
133 return 0;
134 } else {
135 int status;
136 if (waitpid(child, &status, 0) != child ||
137 !WIFEXITED(status)) {
138 printf("[FAIL]\tChild died\n");
139 nerrs++;
140 } else if (WEXITSTATUS(status) != 0) {
141 printf("[FAIL]\tChild failed\n");
142 nerrs++;
143 } else {
144 printf("[OK]\tChild succeeded\n");
145 }
146 }
147
148 /* Test the capability checks. */
149
150 printf("\tDrop privileges\n");
151 if (setresuid(1, 1, 1) != 0) {
152 printf("[WARN]\tDropping privileges failed\n");
153 return 0;
154 }
155
156 printf("[RUN]\tdisable 0x80\n");
157 if (ioperm(0x80, 1, 0) != 0) {
158 printf("[FAIL]\tioperm(0x80, 1, 0) failed (%d)", errno);
159 return 1;
160 }
161 printf("[OK]\tit worked\n");
162
163 printf("[RUN]\tenable 0x80 again\n");
164 if (ioperm(0x80, 1, 1) == 0) {
165 printf("[FAIL]\tit succeeded but should have failed.\n");
166 return 1;
167 }
168 printf("[OK]\tit failed\n");
169 return 0;
170}
diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index 4af47079cf04..f6121612e769 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -45,6 +45,12 @@
45#define AR_DB (1 << 22) 45#define AR_DB (1 << 22)
46#define AR_G (1 << 23) 46#define AR_G (1 << 23)
47 47
48#ifdef __x86_64__
49# define INT80_CLOBBERS "r8", "r9", "r10", "r11"
50#else
51# define INT80_CLOBBERS
52#endif
53
48static int nerrs; 54static int nerrs;
49 55
50/* Points to an array of 1024 ints, each holding its own index. */ 56/* Points to an array of 1024 ints, each holding its own index. */
@@ -588,7 +594,7 @@ static int invoke_set_thread_area(void)
588 asm volatile ("int $0x80" 594 asm volatile ("int $0x80"
589 : "=a" (ret), "+m" (low_user_desc) : 595 : "=a" (ret), "+m" (low_user_desc) :
590 "a" (243), "b" (low_user_desc) 596 "a" (243), "b" (low_user_desc)
591 : "flags"); 597 : INT80_CLOBBERS);
592 return ret; 598 return ret;
593} 599}
594 600
@@ -657,7 +663,7 @@ static void test_gdt_invalidation(void)
657 "+a" (eax) 663 "+a" (eax)
658 : "m" (low_user_desc_clear), 664 : "m" (low_user_desc_clear),
659 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear) 665 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
660 : "flags"); 666 : INT80_CLOBBERS);
661 667
662 if (sel != 0) { 668 if (sel != 0) {
663 result = "FAIL"; 669 result = "FAIL";
@@ -688,7 +694,7 @@ static void test_gdt_invalidation(void)
688 "+a" (eax) 694 "+a" (eax)
689 : "m" (low_user_desc_clear), 695 : "m" (low_user_desc_clear),
690 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear) 696 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
691 : "flags"); 697 : INT80_CLOBBERS);
692 698
693 if (sel != 0) { 699 if (sel != 0) {
694 result = "FAIL"; 700 result = "FAIL";
@@ -721,7 +727,7 @@ static void test_gdt_invalidation(void)
721 "+a" (eax) 727 "+a" (eax)
722 : "m" (low_user_desc_clear), 728 : "m" (low_user_desc_clear),
723 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear) 729 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
724 : "flags"); 730 : INT80_CLOBBERS);
725 731
726#ifdef __x86_64__ 732#ifdef __x86_64__
727 syscall(SYS_arch_prctl, ARCH_GET_FS, &new_base); 733 syscall(SYS_arch_prctl, ARCH_GET_FS, &new_base);
@@ -774,7 +780,7 @@ static void test_gdt_invalidation(void)
774 "+a" (eax) 780 "+a" (eax)
775 : "m" (low_user_desc_clear), 781 : "m" (low_user_desc_clear),
776 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear) 782 [arg1] "r" ((unsigned int)(unsigned long)low_user_desc_clear)
777 : "flags"); 783 : INT80_CLOBBERS);
778 784
779#ifdef __x86_64__ 785#ifdef __x86_64__
780 syscall(SYS_arch_prctl, ARCH_GET_GS, &new_base); 786 syscall(SYS_arch_prctl, ARCH_GET_GS, &new_base);
diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c
index df9e0a0cdf29..3237bc010e1c 100644
--- a/tools/testing/selftests/x86/protection_keys.c
+++ b/tools/testing/selftests/x86/protection_keys.c
@@ -192,7 +192,7 @@ void lots_o_noops_around_write(int *write_to_me)
192#define SYS_pkey_alloc 381 192#define SYS_pkey_alloc 381
193#define SYS_pkey_free 382 193#define SYS_pkey_free 382
194#define REG_IP_IDX REG_EIP 194#define REG_IP_IDX REG_EIP
195#define si_pkey_offset 0x18 195#define si_pkey_offset 0x14
196#else 196#else
197#define SYS_mprotect_key 329 197#define SYS_mprotect_key 329
198#define SYS_pkey_alloc 330 198#define SYS_pkey_alloc 330
@@ -462,7 +462,7 @@ void pkey_disable_set(int pkey, int flags)
462 unsigned long syscall_flags = 0; 462 unsigned long syscall_flags = 0;
463 int ret; 463 int ret;
464 int pkey_rights; 464 int pkey_rights;
465 u32 orig_pkru; 465 u32 orig_pkru = rdpkru();
466 466
467 dprintf1("START->%s(%d, 0x%x)\n", __func__, 467 dprintf1("START->%s(%d, 0x%x)\n", __func__,
468 pkey, flags); 468 pkey, flags);
@@ -812,8 +812,6 @@ void setup_hugetlbfs(void)
812{ 812{
813 int err; 813 int err;
814 int fd; 814 int fd;
815 int validated_nr_pages;
816 int i;
817 char buf[] = "123"; 815 char buf[] = "123";
818 816
819 if (geteuid() != 0) { 817 if (geteuid() != 0) {
@@ -1116,11 +1114,6 @@ void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
1116 err = sys_pkey_free(i); 1114 err = sys_pkey_free(i);
1117 pkey_assert(err); 1115 pkey_assert(err);
1118 1116
1119 /* not enforced when pkey_get() is not a syscall
1120 err = pkey_get(i, 0);
1121 pkey_assert(err < 0);
1122 */
1123
1124 err = sys_pkey_free(i); 1117 err = sys_pkey_free(i);
1125 pkey_assert(err); 1118 pkey_assert(err);
1126 1119
@@ -1133,14 +1126,8 @@ void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
1133void test_pkey_syscalls_bad_args(int *ptr, u16 pkey) 1126void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
1134{ 1127{
1135 int err; 1128 int err;
1136 int bad_flag = (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE) + 1;
1137 int bad_pkey = NR_PKEYS+99; 1129 int bad_pkey = NR_PKEYS+99;
1138 1130
1139 /* not enforced when pkey_get() is not a syscall
1140 err = pkey_get(bad_pkey, bad_flag);
1141 pkey_assert(err < 0);
1142 */
1143
1144 /* pass a known-invalid pkey in: */ 1131 /* pass a known-invalid pkey in: */
1145 err = sys_mprotect_pkey(ptr, PAGE_SIZE, PROT_READ, bad_pkey); 1132 err = sys_mprotect_pkey(ptr, PAGE_SIZE, PROT_READ, bad_pkey);
1146 pkey_assert(err); 1133 pkey_assert(err);
@@ -1149,8 +1136,6 @@ void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
1149/* Assumes that all pkeys other than 'pkey' are unallocated */ 1136/* Assumes that all pkeys other than 'pkey' are unallocated */
1150void test_pkey_alloc_exhaust(int *ptr, u16 pkey) 1137void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
1151{ 1138{
1152 unsigned long flags;
1153 unsigned long init_val;
1154 int err; 1139 int err;
1155 int allocated_pkeys[NR_PKEYS] = {0}; 1140 int allocated_pkeys[NR_PKEYS] = {0};
1156 int nr_allocated_pkeys = 0; 1141 int nr_allocated_pkeys = 0;
diff --git a/tools/testing/selftests/x86/ptrace_syscall.c b/tools/testing/selftests/x86/ptrace_syscall.c
index b037ce9cf116..eaea92439708 100644
--- a/tools/testing/selftests/x86/ptrace_syscall.c
+++ b/tools/testing/selftests/x86/ptrace_syscall.c
@@ -58,7 +58,8 @@ static void do_full_int80(struct syscall_args32 *args)
58 asm volatile ("int $0x80" 58 asm volatile ("int $0x80"
59 : "+a" (args->nr), 59 : "+a" (args->nr),
60 "+b" (args->arg0), "+c" (args->arg1), "+d" (args->arg2), 60 "+b" (args->arg0), "+c" (args->arg1), "+d" (args->arg2),
61 "+S" (args->arg3), "+D" (args->arg4), "+r" (bp)); 61 "+S" (args->arg3), "+D" (args->arg4), "+r" (bp)
62 : : "r8", "r9", "r10", "r11");
62 args->arg5 = bp; 63 args->arg5 = bp;
63#else 64#else
64 sys32_helper(args, int80_and_ret); 65 sys32_helper(args, int80_and_ret);
diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c
index 50c26358e8b7..a48da95c18fd 100644
--- a/tools/testing/selftests/x86/single_step_syscall.c
+++ b/tools/testing/selftests/x86/single_step_syscall.c
@@ -56,9 +56,11 @@ static volatile sig_atomic_t sig_traps;
56#ifdef __x86_64__ 56#ifdef __x86_64__
57# define REG_IP REG_RIP 57# define REG_IP REG_RIP
58# define WIDTH "q" 58# define WIDTH "q"
59# define INT80_CLOBBERS "r8", "r9", "r10", "r11"
59#else 60#else
60# define REG_IP REG_EIP 61# define REG_IP REG_EIP
61# define WIDTH "l" 62# define WIDTH "l"
63# define INT80_CLOBBERS
62#endif 64#endif
63 65
64static unsigned long get_eflags(void) 66static unsigned long get_eflags(void)
@@ -140,7 +142,8 @@ int main()
140 142
141 printf("[RUN]\tSet TF and check int80\n"); 143 printf("[RUN]\tSet TF and check int80\n");
142 set_eflags(get_eflags() | X86_EFLAGS_TF); 144 set_eflags(get_eflags() | X86_EFLAGS_TF);
143 asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid)); 145 asm volatile ("int $0x80" : "=a" (tmp) : "a" (SYS_getpid)
146 : INT80_CLOBBERS);
144 check_result(); 147 check_result();
145 148
146 /* 149 /*
diff --git a/tools/testing/selftests/zram/Makefile b/tools/testing/selftests/zram/Makefile
index 29d80346e3eb..c3a87e5f9d36 100644
--- a/tools/testing/selftests/zram/Makefile
+++ b/tools/testing/selftests/zram/Makefile
@@ -2,8 +2,7 @@ all:
2 2
3TEST_PROGS := zram.sh 3TEST_PROGS := zram.sh
4TEST_FILES := zram01.sh zram02.sh zram_lib.sh 4TEST_FILES := zram01.sh zram02.sh zram_lib.sh
5EXTRA_CLEAN := err.log
5 6
6include ../lib.mk 7include ../lib.mk
7 8
8clean:
9 $(RM) err.log
diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c
index 88d5e71be044..95dd14648ba5 100644
--- a/tools/usb/ffs-test.c
+++ b/tools/usb/ffs-test.c
@@ -22,7 +22,7 @@
22/* $(CROSS_COMPILE)cc -Wall -Wextra -g -o ffs-test ffs-test.c -lpthread */ 22/* $(CROSS_COMPILE)cc -Wall -Wextra -g -o ffs-test ffs-test.c -lpthread */
23 23
24 24
25#define _BSD_SOURCE /* for endian.h */ 25#define _DEFAULT_SOURCE /* for endian.h */
26 26
27#include <endian.h> 27#include <endian.h>
28#include <errno.h> 28#include <errno.h>
@@ -110,16 +110,25 @@ static const struct {
110 struct usb_functionfs_descs_head_v2 header; 110 struct usb_functionfs_descs_head_v2 header;
111 __le32 fs_count; 111 __le32 fs_count;
112 __le32 hs_count; 112 __le32 hs_count;
113 __le32 ss_count;
113 struct { 114 struct {
114 struct usb_interface_descriptor intf; 115 struct usb_interface_descriptor intf;
115 struct usb_endpoint_descriptor_no_audio sink; 116 struct usb_endpoint_descriptor_no_audio sink;
116 struct usb_endpoint_descriptor_no_audio source; 117 struct usb_endpoint_descriptor_no_audio source;
117 } __attribute__((packed)) fs_descs, hs_descs; 118 } __attribute__((packed)) fs_descs, hs_descs;
119 struct {
120 struct usb_interface_descriptor intf;
121 struct usb_endpoint_descriptor_no_audio sink;
122 struct usb_ss_ep_comp_descriptor sink_comp;
123 struct usb_endpoint_descriptor_no_audio source;
124 struct usb_ss_ep_comp_descriptor source_comp;
125 } ss_descs;
118} __attribute__((packed)) descriptors = { 126} __attribute__((packed)) descriptors = {
119 .header = { 127 .header = {
120 .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), 128 .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
121 .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC | 129 .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC |
122 FUNCTIONFS_HAS_HS_DESC), 130 FUNCTIONFS_HAS_HS_DESC |
131 FUNCTIONFS_HAS_SS_DESC),
123 .length = cpu_to_le32(sizeof descriptors), 132 .length = cpu_to_le32(sizeof descriptors),
124 }, 133 },
125 .fs_count = cpu_to_le32(3), 134 .fs_count = cpu_to_le32(3),
@@ -171,6 +180,45 @@ static const struct {
171 .bInterval = 1, /* NAK every 1 uframe */ 180 .bInterval = 1, /* NAK every 1 uframe */
172 }, 181 },
173 }, 182 },
183 .ss_count = cpu_to_le32(5),
184 .ss_descs = {
185 .intf = {
186 .bLength = sizeof descriptors.fs_descs.intf,
187 .bDescriptorType = USB_DT_INTERFACE,
188 .bNumEndpoints = 2,
189 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
190 .iInterface = 1,
191 },
192 .sink = {
193 .bLength = sizeof descriptors.hs_descs.sink,
194 .bDescriptorType = USB_DT_ENDPOINT,
195 .bEndpointAddress = 1 | USB_DIR_IN,
196 .bmAttributes = USB_ENDPOINT_XFER_BULK,
197 .wMaxPacketSize = cpu_to_le16(1024),
198 },
199 .sink_comp = {
200 .bLength = USB_DT_SS_EP_COMP_SIZE,
201 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
202 .bMaxBurst = 0,
203 .bmAttributes = 0,
204 .wBytesPerInterval = 0,
205 },
206 .source = {
207 .bLength = sizeof descriptors.hs_descs.source,
208 .bDescriptorType = USB_DT_ENDPOINT,
209 .bEndpointAddress = 2 | USB_DIR_OUT,
210 .bmAttributes = USB_ENDPOINT_XFER_BULK,
211 .wMaxPacketSize = cpu_to_le16(1024),
212 .bInterval = 1, /* NAK every 1 uframe */
213 },
214 .source_comp = {
215 .bLength = USB_DT_SS_EP_COMP_SIZE,
216 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
217 .bMaxBurst = 0,
218 .bmAttributes = 0,
219 .wBytesPerInterval = 0,
220 },
221 },
174}; 222};
175 223
176static size_t descs_to_legacy(void **legacy, const void *descriptors_v2) 224static size_t descs_to_legacy(void **legacy, const void *descriptors_v2)
diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README
index 831f49fea3ce..5eb2b6c7722b 100644
--- a/tools/usb/usbip/README
+++ b/tools/usb/usbip/README
@@ -4,10 +4,33 @@
4# Copyright (C) 2011 matt mooney <mfm@muteddisk.com> 4# Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
5# 2005-2008 Takahiro Hirofuchi 5# 2005-2008 Takahiro Hirofuchi
6 6
7[Overview]
8USB/IP protocol allows to pass USB device from server to client over the
9network. Server is a machine which provides (shares) a USB device. Client is
10a machine which uses USB device provided by server over the network.
11The USB device may be either physical device connected to a server or
12software entity created on a server using USB gadget subsystem.
13Whole project consists of four parts:
14
15 - usbip-vhci
16 A client side kernel module which provides a virtual USB Host Controller
17 and allows to import a USB device from a remote machine.
18
19 - usbip-host (stub driver)
20 A server side module which provides a USB device driver which can be
21 bound to a physical USB device to make it exportable.
22
23 - usbip-vudc
24 A server side module which provides a virtual USB Device Controller and allows
25 to export a USB device created using USB Gadget Subsystem.
26
27 - usbip-utils
28 A set of userspace tools used to handle connection and management.
29 Used on both sides.
7 30
8[Requirements] 31[Requirements]
9 - USB/IP device drivers 32 - USB/IP device drivers
10 Found in the staging directory of the Linux kernel. 33 Found in the drivers/usb/usbip/ directory of the Linux kernel tree.
11 34
12 - libudev >= 2.0 35 - libudev >= 2.0
13 libudev library 36 libudev library
@@ -36,6 +59,10 @@
36 59
37 60
38[Usage] 61[Usage]
62On a server side there are two entities which can be shared.
63First of them is physical usb device connected to the machine.
64To make it available below steps should be executed:
65
39 server:# (Physically attach your USB device.) 66 server:# (Physically attach your USB device.)
40 67
41 server:# insmod usbip-core.ko 68 server:# insmod usbip-core.ko
@@ -52,6 +79,30 @@
52 - The USB device 1-2 is now exportable to other hosts! 79 - The USB device 1-2 is now exportable to other hosts!
53 - Use `usbip unbind --busid 1-2' to stop exporting the device. 80 - Use `usbip unbind --busid 1-2' to stop exporting the device.
54 81
82Second of shareable entities is USB Gadget created using USB Gadget Subsystem
83on a server machine. To make it available below steps should be executed:
84
85 server:# (Create your USB gadget)
86 - Currently the most preferable way of creating a new USB gadget
87 is ConfigFS Composite Gadget. Please refer to its documentation
88 for details.
89 - See vudc_server_example.sh for a short example of USB gadget creation
90
91 server:# insmod usbip-core.ko
92 server:# insmod usbip-vudc.ko
93 - To create more than one instance of vudc use num module param
94
95 server:# (Bind gadget to one of available vudc)
96 - Assign your new gadget to USB/IP UDC
97 - Using ConfigFS interface you may do this simply by:
98 server:# cd /sys/kernel/config/usb_gadget/<gadget_name>
99 server:# echo "usbip-vudc.0" > UDC
100
101 server:# usbipd -D --device
102 - Start usbip daemon.
103
104To attach new device to client machine below commands should be used:
105
55 client:# insmod usbip-core.ko 106 client:# insmod usbip-core.ko
56 client:# insmod vhci-hcd.ko 107 client:# insmod vhci-hcd.ko
57 108
@@ -60,6 +111,8 @@
60 111
61 client:# usbip attach --remote <host> --busid 1-2 112 client:# usbip attach --remote <host> --busid 1-2
62 - Connect the remote USB device. 113 - Connect the remote USB device.
114 - When using vudc on a server side busid is really vudc instance name.
115 For example: usbip-vudc.0
63 116
64 client:# usbip port 117 client:# usbip port
65 - Show virtual port status. 118 - Show virtual port status.
@@ -192,6 +245,8 @@ Detach the imported device:
192 - http://usbip.wiki.sourceforge.net/how-to-debug-usbip 245 - http://usbip.wiki.sourceforge.net/how-to-debug-usbip
193 - usbip-host.ko must be bound to the target device. 246 - usbip-host.ko must be bound to the target device.
194 - See /proc/bus/usb/devices and find "Driver=..." lines of the device. 247 - See /proc/bus/usb/devices and find "Driver=..." lines of the device.
248 - Target USB gadget must be bound to vudc
249 (using USB gadget susbsys, not usbip bind command)
195 - Shutdown firewall. 250 - Shutdown firewall.
196 - usbip now uses TCP port 3240. 251 - usbip now uses TCP port 3240.
197 - Disable SELinux. 252 - Disable SELinux.
diff --git a/tools/usb/usbip/vudc/vudc_server_example.sh b/tools/usb/usbip/vudc/vudc_server_example.sh
new file mode 100755
index 000000000000..2736be64f203
--- /dev/null
+++ b/tools/usb/usbip/vudc/vudc_server_example.sh
@@ -0,0 +1,107 @@
1#!/bin/bash
2
3################################################################################
4# This is free and unencumbered software released into the public domain.
5#
6# Anyone is free to copy, modify, publish, use, compile, sell, or
7# distribute this software, either in source code form or as a compiled
8# binary, for any purpose, commercial or non-commercial, and by any
9# means.
10#
11# In jurisdictions that recognize copyright laws, the author or authors
12# of this software dedicate any and all copyright interest in the
13# software to the public domain. We make this dedication for the benefit
14# of the public at large and to the detriment of our heirs and
15# successors. We intend this dedication to be an overt act of
16# relinquishment in perpetuity of all present and future rights to this
17# software under copyright law.
18#
19# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25# OTHER DEALINGS IN THE SOFTWARE.
26#
27# For more information, please refer to <http://unlicense.org/>
28################################################################################
29
30################################################################################
31# This is a sample script which shows how to use vUDC with ConfigFS gadgets
32################################################################################
33
34# Stop script on error
35set -e
36
37################################################################################
38# Create your USB gadget
39# You may use bare ConfigFS interface (as below)
40# or libusbgx or gt toool
41# Instead of ConfigFS gadgets you may use any of legacy gadgets.
42################################################################################
43CONFIGFS_MOUNT_POINT="/sys/kernel/config"
44GADGET_NAME="g1"
45ID_VENDOR="0x1d6b"
46ID_PRODUCT="0x0104"
47
48cd ${CONFIGFS_MOUNT_POINT}/usb_gadget
49# Create a new USB gadget
50mkdir ${GADGET_NAME}
51cd ${GADGET_NAME}
52
53# This gadget contains one function - ACM (serial port over USB)
54FUNC_DIR="functions/acm.ser0"
55mkdir ${FUNC_DIR}
56
57# Just one configuration
58mkdir configs/c.1
59ln -s ${FUNC_DIR} configs/c.1
60
61# Set our gadget identity
62echo ${ID_VENDOR} > idVendor
63echo ${ID_PRODUCT} > idProduct
64
65################################################################################
66# Load vudc-module if vudc is not available
67# You may change value of num param to get more than one vUDC instance
68################################################################################
69[[ -d /sys/class/udc/usbip-vudc.0 ]] || modprobe usbip-vudc num=1
70
71################################################################################
72# Bind gadget to our vUDC
73# By default we bind to first one but you may change this if you would like
74# to use more than one instance
75################################################################################
76echo "usbip-vudc.0" > UDC
77
78################################################################################
79# Let's now run our usbip daemon in a USB device mode
80################################################################################
81usbipd --device &
82
83################################################################################
84# Now your USB gadget is available using USB/IP protocol.
85# To prepare your client, you should ensure that usbip-vhci module is inside
86# your kernel. If it's not then you can load it:
87#
88# $ modprobe usbip-vhci
89#
90# To check availability of your gadget you may try to list devices exported
91# on a remote server:
92#
93# $ modprobe usbip-vhci
94# $ usbip list -r $SERVER_IP
95# Exportable USB devices
96# ======================
97# usbipd: info: request 0x8005(6): complete
98# - 127.0.0.1
99# usbip-vudc.0: Linux Foundation : unknown product (1d6b:0104)
100# : /sys/devices/platform/usbip-vudc.0
101# : (Defined at Interface level) (00/00/00)
102#
103# To attach this device to your client you may use:
104#
105# $ usbip attach -r $SERVER_IP -d usbip-vudc.0
106#
107################################################################################
diff --git a/tools/vm/Makefile b/tools/vm/Makefile
index 93aadaf7ff63..006029456988 100644
--- a/tools/vm/Makefile
+++ b/tools/vm/Makefile
@@ -9,6 +9,8 @@ CC = $(CROSS_COMPILE)gcc
9CFLAGS = -Wall -Wextra -I../lib/ 9CFLAGS = -Wall -Wextra -I../lib/
10LDFLAGS = $(LIBS) 10LDFLAGS = $(LIBS)
11 11
12all: $(TARGETS)
13
12$(TARGETS): $(LIBS) 14$(TARGETS): $(LIBS)
13 15
14$(LIBS): 16$(LIBS):
@@ -20,3 +22,9 @@ $(LIBS):
20clean: 22clean:
21 $(RM) page-types slabinfo page_owner_sort 23 $(RM) page-types slabinfo page_owner_sort
22 make -C $(LIB_DIR) clean 24 make -C $(LIB_DIR) clean
25
26sbindir ?= /usr/sbin
27
28install: all
29 install -d $(DESTDIR)$(sbindir)
30 install -m 755 -p $(TARGETS) $(DESTDIR)$(sbindir)