diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-16 16:13:03 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-16 16:21:29 -0400 |
commit | 0a3173a5f09bc58a3638ecfd0a80bdbae55e123c (patch) | |
tree | d6c0bc84863cca54dfbde3b7463e5d49c82af9f1 /tools | |
parent | 92f4e77c85918eab5e5803d7e28ab89a7e6bd3a2 (diff) | |
parent | 5c60a7389d795e001c8748b458eb76e3a5b6008c (diff) |
Merge branch 'linus/master' into rdma.git for-next
rdma.git merge resolution for the 4.19 merge window
Conflicts:
drivers/infiniband/core/rdma_core.c
- Use the rdma code and revise with the new spelling for
atomic_fetch_add_unless
drivers/nvme/host/rdma.c
- Replace max_sge with max_send_sge in new blk code
drivers/nvme/target/rdma.c
- Use the blk code and revise to use NULL for ib_post_recv when
appropriate
- Replace max_sge with max_recv_sge in new blk code
net/rds/ib_send.c
- Use the net code and revise to use NULL for ib_post_recv when
appropriate
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'tools')
229 files changed, 15362 insertions, 718 deletions
diff --git a/tools/arch/arm64/include/uapi/asm/unistd.h b/tools/arch/arm64/include/uapi/asm/unistd.h new file mode 100644 index 000000000000..5072cbd15c82 --- /dev/null +++ b/tools/arch/arm64/include/uapi/asm/unistd.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
2 | /* | ||
3 | * Copyright (C) 2012 ARM Ltd. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #define __ARCH_WANT_RENAMEAT | ||
19 | |||
20 | #include <asm-generic/unistd.h> | ||
diff --git a/tools/arch/parisc/include/uapi/asm/errno.h b/tools/arch/parisc/include/uapi/asm/errno.h index fc0df353ff0d..87245c584784 100644 --- a/tools/arch/parisc/include/uapi/asm/errno.h +++ b/tools/arch/parisc/include/uapi/asm/errno.h | |||
@@ -113,7 +113,6 @@ | |||
113 | #define ELOOP 249 /* Too many symbolic links encountered */ | 113 | #define ELOOP 249 /* Too many symbolic links encountered */ |
114 | #define ENOSYS 251 /* Function not implemented */ | 114 | #define ENOSYS 251 /* Function not implemented */ |
115 | 115 | ||
116 | #define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */ | ||
117 | #define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ | 116 | #define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ |
118 | #define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */ | 117 | #define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */ |
119 | 118 | ||
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 5701f5cecd31..64aaa3f5f36c 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h | |||
@@ -219,6 +219,7 @@ | |||
219 | #define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ | 219 | #define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ |
220 | #define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ | 220 | #define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ |
221 | #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ | 221 | #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ |
222 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */ | ||
222 | 223 | ||
223 | /* Virtualization flags: Linux defined, word 8 */ | 224 | /* Virtualization flags: Linux defined, word 8 */ |
224 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | 225 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ |
@@ -341,6 +342,7 @@ | |||
341 | #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ | 342 | #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ |
342 | #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ | 343 | #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ |
343 | #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ | 344 | #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ |
345 | #define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */ | ||
344 | #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ | 346 | #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ |
345 | #define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ | 347 | #define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ |
346 | 348 | ||
@@ -373,5 +375,6 @@ | |||
373 | #define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ | 375 | #define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ |
374 | #define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ | 376 | #define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ |
375 | #define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ | 377 | #define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ |
378 | #define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */ | ||
376 | 379 | ||
377 | #endif /* _ASM_X86_CPUFEATURES_H */ | 380 | #endif /* _ASM_X86_CPUFEATURES_H */ |
diff --git a/tools/bpf/.gitignore b/tools/bpf/.gitignore new file mode 100644 index 000000000000..dfe2bd5a4b95 --- /dev/null +++ b/tools/bpf/.gitignore | |||
@@ -0,0 +1,5 @@ | |||
1 | FEATURE-DUMP.bpf | ||
2 | bpf_asm | ||
3 | bpf_dbg | ||
4 | bpf_exp.yacc.* | ||
5 | bpf_jit_disasm | ||
diff --git a/tools/bpf/Makefile.helpers b/tools/bpf/Makefile.helpers new file mode 100644 index 000000000000..c34fea77f39f --- /dev/null +++ b/tools/bpf/Makefile.helpers | |||
@@ -0,0 +1,59 @@ | |||
1 | ifndef allow-override | ||
2 | include ../scripts/Makefile.include | ||
3 | include ../scripts/utilities.mak | ||
4 | else | ||
5 | # Assume Makefile.helpers is being run from bpftool/Documentation | ||
6 | # subdirectory. Go up two more directories to fetch bpf.h header and | ||
7 | # associated script. | ||
8 | UP2DIR := ../../ | ||
9 | endif | ||
10 | |||
11 | INSTALL ?= install | ||
12 | RM ?= rm -f | ||
13 | RMDIR ?= rmdir --ignore-fail-on-non-empty | ||
14 | |||
15 | ifeq ($(V),1) | ||
16 | Q = | ||
17 | else | ||
18 | Q = @ | ||
19 | endif | ||
20 | |||
21 | prefix ?= /usr/local | ||
22 | mandir ?= $(prefix)/man | ||
23 | man7dir = $(mandir)/man7 | ||
24 | |||
25 | HELPERS_RST = bpf-helpers.rst | ||
26 | MAN7_RST = $(HELPERS_RST) | ||
27 | |||
28 | _DOC_MAN7 = $(patsubst %.rst,%.7,$(MAN7_RST)) | ||
29 | DOC_MAN7 = $(addprefix $(OUTPUT),$(_DOC_MAN7)) | ||
30 | |||
31 | helpers: man7 | ||
32 | man7: $(DOC_MAN7) | ||
33 | |||
34 | RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null) | ||
35 | |||
36 | $(OUTPUT)$(HELPERS_RST): $(UP2DIR)../../include/uapi/linux/bpf.h | ||
37 | $(QUIET_GEN)$(UP2DIR)../../scripts/bpf_helpers_doc.py --filename $< > $@ | ||
38 | |||
39 | $(OUTPUT)%.7: $(OUTPUT)%.rst | ||
40 | ifndef RST2MAN_DEP | ||
41 | $(error "rst2man not found, but required to generate man pages") | ||
42 | endif | ||
43 | $(QUIET_GEN)rst2man $< > $@ | ||
44 | |||
45 | helpers-clean: | ||
46 | $(call QUIET_CLEAN, eBPF_helpers-manpage) | ||
47 | $(Q)$(RM) $(DOC_MAN7) $(OUTPUT)$(HELPERS_RST) | ||
48 | |||
49 | helpers-install: helpers | ||
50 | $(call QUIET_INSTALL, eBPF_helpers-manpage) | ||
51 | $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(man7dir) | ||
52 | $(Q)$(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) | ||
53 | |||
54 | helpers-uninstall: | ||
55 | $(call QUIET_UNINST, eBPF_helpers-manpage) | ||
56 | $(Q)$(RM) $(addprefix $(DESTDIR)$(man7dir)/,$(_DOC_MAN7)) | ||
57 | $(Q)$(RMDIR) $(DESTDIR)$(man7dir) | ||
58 | |||
59 | .PHONY: helpers helpers-clean helpers-install helpers-uninstall | ||
diff --git a/tools/bpf/bpftool/.gitignore b/tools/bpf/bpftool/.gitignore index d7e678c2d396..67167e44b726 100644 --- a/tools/bpf/bpftool/.gitignore +++ b/tools/bpf/bpftool/.gitignore | |||
@@ -1,3 +1,5 @@ | |||
1 | *.d | 1 | *.d |
2 | bpftool | 2 | bpftool |
3 | bpftool*.8 | ||
4 | bpf-helpers.* | ||
3 | FEATURE-DUMP.bpftool | 5 | FEATURE-DUMP.bpftool |
diff --git a/tools/bpf/bpftool/Documentation/Makefile b/tools/bpf/bpftool/Documentation/Makefile index a9d47c1558bb..f7663a3e60c9 100644 --- a/tools/bpf/bpftool/Documentation/Makefile +++ b/tools/bpf/bpftool/Documentation/Makefile | |||
@@ -15,12 +15,15 @@ prefix ?= /usr/local | |||
15 | mandir ?= $(prefix)/man | 15 | mandir ?= $(prefix)/man |
16 | man8dir = $(mandir)/man8 | 16 | man8dir = $(mandir)/man8 |
17 | 17 | ||
18 | MAN8_RST = $(wildcard *.rst) | 18 | # Load targets for building eBPF helpers man page. |
19 | include ../../Makefile.helpers | ||
20 | |||
21 | MAN8_RST = $(filter-out $(HELPERS_RST),$(wildcard *.rst)) | ||
19 | 22 | ||
20 | _DOC_MAN8 = $(patsubst %.rst,%.8,$(MAN8_RST)) | 23 | _DOC_MAN8 = $(patsubst %.rst,%.8,$(MAN8_RST)) |
21 | DOC_MAN8 = $(addprefix $(OUTPUT),$(_DOC_MAN8)) | 24 | DOC_MAN8 = $(addprefix $(OUTPUT),$(_DOC_MAN8)) |
22 | 25 | ||
23 | man: man8 | 26 | man: man8 helpers |
24 | man8: $(DOC_MAN8) | 27 | man8: $(DOC_MAN8) |
25 | 28 | ||
26 | RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null) | 29 | RST2MAN_DEP := $(shell command -v rst2man 2>/dev/null) |
@@ -31,16 +34,16 @@ ifndef RST2MAN_DEP | |||
31 | endif | 34 | endif |
32 | $(QUIET_GEN)rst2man $< > $@ | 35 | $(QUIET_GEN)rst2man $< > $@ |
33 | 36 | ||
34 | clean: | 37 | clean: helpers-clean |
35 | $(call QUIET_CLEAN, Documentation) | 38 | $(call QUIET_CLEAN, Documentation) |
36 | $(Q)$(RM) $(DOC_MAN8) | 39 | $(Q)$(RM) $(DOC_MAN8) |
37 | 40 | ||
38 | install: man | 41 | install: man helpers-install |
39 | $(call QUIET_INSTALL, Documentation-man) | 42 | $(call QUIET_INSTALL, Documentation-man) |
40 | $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(man8dir) | 43 | $(Q)$(INSTALL) -d -m 755 $(DESTDIR)$(man8dir) |
41 | $(Q)$(INSTALL) -m 644 $(DOC_MAN8) $(DESTDIR)$(man8dir) | 44 | $(Q)$(INSTALL) -m 644 $(DOC_MAN8) $(DESTDIR)$(man8dir) |
42 | 45 | ||
43 | uninstall: | 46 | uninstall: helpers-uninstall |
44 | $(call QUIET_UNINST, Documentation-man) | 47 | $(call QUIET_UNINST, Documentation-man) |
45 | $(Q)$(RM) $(addprefix $(DESTDIR)$(man8dir)/,$(_DOC_MAN8)) | 48 | $(Q)$(RM) $(addprefix $(DESTDIR)$(man8dir)/,$(_DOC_MAN8)) |
46 | $(Q)$(RMDIR) $(DESTDIR)$(man8dir) | 49 | $(Q)$(RMDIR) $(DESTDIR)$(man8dir) |
diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst index 7b0e6d453e92..edbe81534c6d 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst | |||
@@ -15,12 +15,13 @@ SYNOPSIS | |||
15 | *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } | 15 | *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } |
16 | 16 | ||
17 | *COMMANDS* := | 17 | *COMMANDS* := |
18 | { **show** | **list** | **attach** | **detach** | **help** } | 18 | { **show** | **list** | **tree** | **attach** | **detach** | **help** } |
19 | 19 | ||
20 | MAP COMMANDS | 20 | MAP COMMANDS |
21 | ============= | 21 | ============= |
22 | 22 | ||
23 | | **bpftool** **cgroup { show | list }** *CGROUP* | 23 | | **bpftool** **cgroup { show | list }** *CGROUP* |
24 | | **bpftool** **cgroup tree** [*CGROUP_ROOT*] | ||
24 | | **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] | 25 | | **bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] |
25 | | **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* | 26 | | **bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG* |
26 | | **bpftool** **cgroup help** | 27 | | **bpftool** **cgroup help** |
@@ -39,6 +40,15 @@ DESCRIPTION | |||
39 | Output will start with program ID followed by attach type, | 40 | Output will start with program ID followed by attach type, |
40 | attach flags and program name. | 41 | attach flags and program name. |
41 | 42 | ||
43 | **bpftool cgroup tree** [*CGROUP_ROOT*] | ||
44 | Iterate over all cgroups in *CGROUP_ROOT* and list all | ||
45 | attached programs. If *CGROUP_ROOT* is not specified, | ||
46 | bpftool uses cgroup v2 mountpoint. | ||
47 | |||
48 | The output is similar to the output of cgroup show/list | ||
49 | commands: it starts with absolute cgroup path, followed by | ||
50 | program ID, attach type, attach flags and program name. | ||
51 | |||
42 | **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] | 52 | **bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*] |
43 | Attach program *PROG* to the cgroup *CGROUP* with attach type | 53 | Attach program *PROG* to the cgroup *CGROUP* with attach type |
44 | *ATTACH_TYPE* and optional *ATTACH_FLAGS*. | 54 | *ATTACH_TYPE* and optional *ATTACH_FLAGS*. |
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index 43d34a5c3ec5..64156a16d530 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst | |||
@@ -24,10 +24,20 @@ MAP COMMANDS | |||
24 | | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}] | 24 | | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}] |
25 | | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | 25 | | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] |
26 | | **bpftool** **prog pin** *PROG* *FILE* | 26 | | **bpftool** **prog pin** *PROG* *FILE* |
27 | | **bpftool** **prog load** *OBJ* *FILE* | 27 | | **bpftool** **prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] |
28 | | **bpftool** **prog help** | 28 | | **bpftool** **prog help** |
29 | | | 29 | | |
30 | | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } | ||
30 | | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } | 31 | | *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* } |
32 | | *TYPE* := { | ||
33 | | **socket** | **kprobe** | **kretprobe** | **classifier** | **action** | | ||
34 | | **tracepoint** | **raw_tracepoint** | **xdp** | **perf_event** | **cgroup/skb** | | ||
35 | | **cgroup/sock** | **cgroup/dev** | **lwt_in** | **lwt_out** | **lwt_xmit** | | ||
36 | | **lwt_seg6local** | **sockops** | **sk_skb** | **sk_msg** | **lirc_mode2** | | ||
37 | | **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** | | ||
38 | | **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6** | ||
39 | | } | ||
40 | |||
31 | 41 | ||
32 | DESCRIPTION | 42 | DESCRIPTION |
33 | =========== | 43 | =========== |
@@ -64,8 +74,19 @@ DESCRIPTION | |||
64 | 74 | ||
65 | Note: *FILE* must be located in *bpffs* mount. | 75 | Note: *FILE* must be located in *bpffs* mount. |
66 | 76 | ||
67 | **bpftool prog load** *OBJ* *FILE* | 77 | **bpftool prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] |
68 | Load bpf program from binary *OBJ* and pin as *FILE*. | 78 | Load bpf program from binary *OBJ* and pin as *FILE*. |
79 | **type** is optional, if not specified program type will be | ||
80 | inferred from section names. | ||
81 | By default bpftool will create new maps as declared in the ELF | ||
82 | object being loaded. **map** parameter allows for the reuse | ||
83 | of existing maps. It can be specified multiple times, each | ||
84 | time for a different map. *IDX* refers to index of the map | ||
85 | to be replaced in the ELF file counting from 0, while *NAME* | ||
86 | allows to replace a map by name. *MAP* specifies the map to | ||
87 | use, referring to it by **id** or through a **pinned** file. | ||
88 | If **dev** *NAME* is specified program will be loaded onto | ||
89 | given networking device (offload). | ||
69 | 90 | ||
70 | Note: *FILE* must be located in *bpffs* mount. | 91 | Note: *FILE* must be located in *bpffs* mount. |
71 | 92 | ||
@@ -159,6 +180,14 @@ EXAMPLES | |||
159 | mov %rbx,0x0(%rbp) | 180 | mov %rbx,0x0(%rbp) |
160 | 48 89 5d 00 | 181 | 48 89 5d 00 |
161 | 182 | ||
183 | | | ||
184 | | **# bpftool prog load xdp1_kern.o /sys/fs/bpf/xdp1 type xdp map name rxcnt id 7** | ||
185 | | **# bpftool prog show pinned /sys/fs/bpf/xdp1** | ||
186 | | 9: xdp name xdp_prog1 tag 539ec6ce11b52f98 gpl | ||
187 | | loaded_at 2018-06-25T16:17:31-0700 uid 0 | ||
188 | | xlated 488B jited 336B memlock 4096B map_ids 7 | ||
189 | | **# rm /sys/fs/bpf/xdp1** | ||
190 | | | ||
162 | 191 | ||
163 | SEE ALSO | 192 | SEE ALSO |
164 | ======== | 193 | ======== |
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index 892dbf095bff..74288a2197ab 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile | |||
@@ -23,10 +23,10 @@ endif | |||
23 | 23 | ||
24 | LIBBPF = $(BPF_PATH)libbpf.a | 24 | LIBBPF = $(BPF_PATH)libbpf.a |
25 | 25 | ||
26 | BPFTOOL_VERSION=$(shell make --no-print-directory -sC ../../.. kernelversion) | 26 | BPFTOOL_VERSION := $(shell make --no-print-directory -sC ../../.. kernelversion) |
27 | 27 | ||
28 | $(LIBBPF): FORCE | 28 | $(LIBBPF): FORCE |
29 | $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT) | 29 | $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a |
30 | 30 | ||
31 | $(LIBBPF)-clean: | 31 | $(LIBBPF)-clean: |
32 | $(call QUIET_CLEAN, libbpf) | 32 | $(call QUIET_CLEAN, libbpf) |
@@ -52,7 +52,7 @@ INSTALL ?= install | |||
52 | RM ?= rm -f | 52 | RM ?= rm -f |
53 | 53 | ||
54 | FEATURE_USER = .bpftool | 54 | FEATURE_USER = .bpftool |
55 | FEATURE_TESTS = libbfd disassembler-four-args | 55 | FEATURE_TESTS = libbfd disassembler-four-args reallocarray |
56 | FEATURE_DISPLAY = libbfd disassembler-four-args | 56 | FEATURE_DISPLAY = libbfd disassembler-four-args |
57 | 57 | ||
58 | check_feat := 1 | 58 | check_feat := 1 |
@@ -75,6 +75,10 @@ ifeq ($(feature-disassembler-four-args), 1) | |||
75 | CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE | 75 | CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE |
76 | endif | 76 | endif |
77 | 77 | ||
78 | ifeq ($(feature-reallocarray), 0) | ||
79 | CFLAGS += -DCOMPAT_NEED_REALLOCARRAY | ||
80 | endif | ||
81 | |||
78 | include $(wildcard $(OUTPUT)*.d) | 82 | include $(wildcard $(OUTPUT)*.d) |
79 | 83 | ||
80 | all: $(OUTPUT)bpftool | 84 | all: $(OUTPUT)bpftool |
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 1e1083321643..598066c40191 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool | |||
@@ -99,6 +99,35 @@ _bpftool_get_prog_tags() | |||
99 | command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) ) | 99 | command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) ) |
100 | } | 100 | } |
101 | 101 | ||
102 | _bpftool_get_obj_map_names() | ||
103 | { | ||
104 | local obj | ||
105 | |||
106 | obj=$1 | ||
107 | |||
108 | maps=$(objdump -j maps -t $obj 2>/dev/null | \ | ||
109 | command awk '/g . maps/ {print $NF}') | ||
110 | |||
111 | COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) ) | ||
112 | } | ||
113 | |||
114 | _bpftool_get_obj_map_idxs() | ||
115 | { | ||
116 | local obj | ||
117 | |||
118 | obj=$1 | ||
119 | |||
120 | nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps') | ||
121 | |||
122 | COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) ) | ||
123 | } | ||
124 | |||
125 | _sysfs_get_netdevs() | ||
126 | { | ||
127 | COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \ | ||
128 | "$cur" ) ) | ||
129 | } | ||
130 | |||
102 | # For bpftool map update: retrieve type of the map to update. | 131 | # For bpftool map update: retrieve type of the map to update. |
103 | _bpftool_map_update_map_type() | 132 | _bpftool_map_update_map_type() |
104 | { | 133 | { |
@@ -153,6 +182,13 @@ _bpftool() | |||
153 | local cur prev words objword | 182 | local cur prev words objword |
154 | _init_completion || return | 183 | _init_completion || return |
155 | 184 | ||
185 | # Deal with options | ||
186 | if [[ ${words[cword]} == -* ]]; then | ||
187 | local c='--version --json --pretty --bpffs' | ||
188 | COMPREPLY=( $( compgen -W "$c" -- "$cur" ) ) | ||
189 | return 0 | ||
190 | fi | ||
191 | |||
156 | # Deal with simplest keywords | 192 | # Deal with simplest keywords |
157 | case $prev in | 193 | case $prev in |
158 | help|hex|opcodes|visual) | 194 | help|hex|opcodes|visual) |
@@ -172,20 +208,23 @@ _bpftool() | |||
172 | ;; | 208 | ;; |
173 | esac | 209 | esac |
174 | 210 | ||
175 | # Search for object and command | 211 | # Remove all options so completions don't have to deal with them. |
176 | local object command cmdword | 212 | local i |
177 | for (( cmdword=1; cmdword < ${#words[@]}-1; cmdword++ )); do | 213 | for (( i=1; i < ${#words[@]}; )); do |
178 | [[ -n $object ]] && command=${words[cmdword]} && break | 214 | if [[ ${words[i]::1} == - ]]; then |
179 | [[ ${words[cmdword]} != -* ]] && object=${words[cmdword]} | 215 | words=( "${words[@]:0:i}" "${words[@]:i+1}" ) |
216 | [[ $i -le $cword ]] && cword=$(( cword - 1 )) | ||
217 | else | ||
218 | i=$(( ++i )) | ||
219 | fi | ||
180 | done | 220 | done |
221 | cur=${words[cword]} | ||
222 | prev=${words[cword - 1]} | ||
223 | |||
224 | local object=${words[1]} command=${words[2]} | ||
181 | 225 | ||
182 | if [[ -z $object ]]; then | 226 | if [[ -z $object || $cword -eq 1 ]]; then |
183 | case $cur in | 227 | case $cur in |
184 | -*) | ||
185 | local c='--version --json --pretty' | ||
186 | COMPREPLY=( $( compgen -W "$c" -- "$cur" ) ) | ||
187 | return 0 | ||
188 | ;; | ||
189 | *) | 228 | *) |
190 | COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \ | 229 | COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \ |
191 | command sed \ | 230 | command sed \ |
@@ -204,12 +243,14 @@ _bpftool() | |||
204 | # Completion depends on object and command in use | 243 | # Completion depends on object and command in use |
205 | case $object in | 244 | case $object in |
206 | prog) | 245 | prog) |
207 | case $prev in | 246 | if [[ $command != "load" ]]; then |
208 | id) | 247 | case $prev in |
209 | _bpftool_get_prog_ids | 248 | id) |
210 | return 0 | 249 | _bpftool_get_prog_ids |
211 | ;; | 250 | return 0 |
212 | esac | 251 | ;; |
252 | esac | ||
253 | fi | ||
213 | 254 | ||
214 | local PROG_TYPE='id pinned tag' | 255 | local PROG_TYPE='id pinned tag' |
215 | case $command in | 256 | case $command in |
@@ -252,8 +293,57 @@ _bpftool() | |||
252 | return 0 | 293 | return 0 |
253 | ;; | 294 | ;; |
254 | load) | 295 | load) |
255 | _filedir | 296 | local obj |
256 | return 0 | 297 | |
298 | if [[ ${#words[@]} -lt 6 ]]; then | ||
299 | _filedir | ||
300 | return 0 | ||
301 | fi | ||
302 | |||
303 | obj=${words[3]} | ||
304 | |||
305 | if [[ ${words[-4]} == "map" ]]; then | ||
306 | COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) ) | ||
307 | return 0 | ||
308 | fi | ||
309 | if [[ ${words[-3]} == "map" ]]; then | ||
310 | if [[ ${words[-2]} == "idx" ]]; then | ||
311 | _bpftool_get_obj_map_idxs $obj | ||
312 | elif [[ ${words[-2]} == "name" ]]; then | ||
313 | _bpftool_get_obj_map_names $obj | ||
314 | fi | ||
315 | return 0 | ||
316 | fi | ||
317 | if [[ ${words[-2]} == "map" ]]; then | ||
318 | COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) ) | ||
319 | return 0 | ||
320 | fi | ||
321 | |||
322 | case $prev in | ||
323 | type) | ||
324 | COMPREPLY=( $( compgen -W "socket kprobe kretprobe classifier action tracepoint raw_tracepoint xdp perf_event cgroup/skb cgroup/sock cgroup/dev lwt_in lwt_out lwt_xmit lwt_seg6local sockops sk_skb sk_msg lirc_mode2 cgroup/bind4 cgroup/bind6 cgroup/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6 cgroup/post_bind4 cgroup/post_bind6" -- \ | ||
325 | "$cur" ) ) | ||
326 | return 0 | ||
327 | ;; | ||
328 | id) | ||
329 | _bpftool_get_map_ids | ||
330 | return 0 | ||
331 | ;; | ||
332 | pinned) | ||
333 | _filedir | ||
334 | return 0 | ||
335 | ;; | ||
336 | dev) | ||
337 | _sysfs_get_netdevs | ||
338 | return 0 | ||
339 | ;; | ||
340 | *) | ||
341 | COMPREPLY=( $( compgen -W "map" -- "$cur" ) ) | ||
342 | _bpftool_once_attr 'type' | ||
343 | _bpftool_once_attr 'dev' | ||
344 | return 0 | ||
345 | ;; | ||
346 | esac | ||
257 | ;; | 347 | ;; |
258 | *) | 348 | *) |
259 | [[ $prev == $object ]] && \ | 349 | [[ $prev == $object ]] && \ |
@@ -404,6 +494,10 @@ _bpftool() | |||
404 | _filedir | 494 | _filedir |
405 | return 0 | 495 | return 0 |
406 | ;; | 496 | ;; |
497 | tree) | ||
498 | _filedir | ||
499 | return 0 | ||
500 | ;; | ||
407 | attach|detach) | 501 | attach|detach) |
408 | local ATTACH_TYPES='ingress egress sock_create sock_ops \ | 502 | local ATTACH_TYPES='ingress egress sock_create sock_ops \ |
409 | device bind4 bind6 post_bind4 post_bind6 connect4 \ | 503 | device bind4 bind6 post_bind4 post_bind6 connect4 \ |
@@ -445,7 +539,7 @@ _bpftool() | |||
445 | *) | 539 | *) |
446 | [[ $prev == $object ]] && \ | 540 | [[ $prev == $object ]] && \ |
447 | COMPREPLY=( $( compgen -W 'help attach detach \ | 541 | COMPREPLY=( $( compgen -W 'help attach detach \ |
448 | show list' -- "$cur" ) ) | 542 | show list tree' -- "$cur" ) ) |
449 | ;; | 543 | ;; |
450 | esac | 544 | esac |
451 | ;; | 545 | ;; |
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c new file mode 100644 index 000000000000..55bc512a1831 --- /dev/null +++ b/tools/bpf/bpftool/btf_dumper.c | |||
@@ -0,0 +1,251 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* Copyright (c) 2018 Facebook */ | ||
3 | |||
4 | #include <ctype.h> | ||
5 | #include <stdio.h> /* for (FILE *) used by json_writer */ | ||
6 | #include <string.h> | ||
7 | #include <asm/byteorder.h> | ||
8 | #include <linux/bitops.h> | ||
9 | #include <linux/btf.h> | ||
10 | #include <linux/err.h> | ||
11 | |||
12 | #include "btf.h" | ||
13 | #include "json_writer.h" | ||
14 | #include "main.h" | ||
15 | |||
16 | #define BITS_PER_BYTE_MASK (BITS_PER_BYTE - 1) | ||
17 | #define BITS_PER_BYTE_MASKED(bits) ((bits) & BITS_PER_BYTE_MASK) | ||
18 | #define BITS_ROUNDDOWN_BYTES(bits) ((bits) >> 3) | ||
19 | #define BITS_ROUNDUP_BYTES(bits) \ | ||
20 | (BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits)) | ||
21 | |||
22 | static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id, | ||
23 | __u8 bit_offset, const void *data); | ||
24 | |||
25 | static void btf_dumper_ptr(const void *data, json_writer_t *jw, | ||
26 | bool is_plain_text) | ||
27 | { | ||
28 | if (is_plain_text) | ||
29 | jsonw_printf(jw, "%p", *(unsigned long *)data); | ||
30 | else | ||
31 | jsonw_printf(jw, "%u", *(unsigned long *)data); | ||
32 | } | ||
33 | |||
34 | static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id, | ||
35 | const void *data) | ||
36 | { | ||
37 | int actual_type_id; | ||
38 | |||
39 | actual_type_id = btf__resolve_type(d->btf, type_id); | ||
40 | if (actual_type_id < 0) | ||
41 | return actual_type_id; | ||
42 | |||
43 | return btf_dumper_do_type(d, actual_type_id, 0, data); | ||
44 | } | ||
45 | |||
46 | static void btf_dumper_enum(const void *data, json_writer_t *jw) | ||
47 | { | ||
48 | jsonw_printf(jw, "%d", *(int *)data); | ||
49 | } | ||
50 | |||
51 | static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id, | ||
52 | const void *data) | ||
53 | { | ||
54 | const struct btf_type *t = btf__type_by_id(d->btf, type_id); | ||
55 | struct btf_array *arr = (struct btf_array *)(t + 1); | ||
56 | long long elem_size; | ||
57 | int ret = 0; | ||
58 | __u32 i; | ||
59 | |||
60 | elem_size = btf__resolve_size(d->btf, arr->type); | ||
61 | if (elem_size < 0) | ||
62 | return elem_size; | ||
63 | |||
64 | jsonw_start_array(d->jw); | ||
65 | for (i = 0; i < arr->nelems; i++) { | ||
66 | ret = btf_dumper_do_type(d, arr->type, 0, | ||
67 | data + i * elem_size); | ||
68 | if (ret) | ||
69 | break; | ||
70 | } | ||
71 | |||
72 | jsonw_end_array(d->jw); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset, | ||
77 | const void *data, json_writer_t *jw, | ||
78 | bool is_plain_text) | ||
79 | { | ||
80 | int left_shift_bits, right_shift_bits; | ||
81 | int nr_bits = BTF_INT_BITS(int_type); | ||
82 | int total_bits_offset; | ||
83 | int bytes_to_copy; | ||
84 | int bits_to_copy; | ||
85 | __u64 print_num; | ||
86 | |||
87 | total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type); | ||
88 | data += BITS_ROUNDDOWN_BYTES(total_bits_offset); | ||
89 | bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset); | ||
90 | bits_to_copy = bit_offset + nr_bits; | ||
91 | bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy); | ||
92 | |||
93 | print_num = 0; | ||
94 | memcpy(&print_num, data, bytes_to_copy); | ||
95 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
96 | left_shift_bits = bit_offset; | ||
97 | #elif defined(__LITTLE_ENDIAN_BITFIELD) | ||
98 | left_shift_bits = 64 - bits_to_copy; | ||
99 | #else | ||
100 | #error neither big nor little endian | ||
101 | #endif | ||
102 | right_shift_bits = 64 - nr_bits; | ||
103 | |||
104 | print_num <<= left_shift_bits; | ||
105 | print_num >>= right_shift_bits; | ||
106 | if (is_plain_text) | ||
107 | jsonw_printf(jw, "0x%llx", print_num); | ||
108 | else | ||
109 | jsonw_printf(jw, "%llu", print_num); | ||
110 | } | ||
111 | |||
112 | static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, | ||
113 | const void *data, json_writer_t *jw, | ||
114 | bool is_plain_text) | ||
115 | { | ||
116 | __u32 *int_type; | ||
117 | __u32 nr_bits; | ||
118 | |||
119 | int_type = (__u32 *)(t + 1); | ||
120 | nr_bits = BTF_INT_BITS(*int_type); | ||
121 | /* if this is bit field */ | ||
122 | if (bit_offset || BTF_INT_OFFSET(*int_type) || | ||
123 | BITS_PER_BYTE_MASKED(nr_bits)) { | ||
124 | btf_dumper_int_bits(*int_type, bit_offset, data, jw, | ||
125 | is_plain_text); | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | switch (BTF_INT_ENCODING(*int_type)) { | ||
130 | case 0: | ||
131 | if (BTF_INT_BITS(*int_type) == 64) | ||
132 | jsonw_printf(jw, "%lu", *(__u64 *)data); | ||
133 | else if (BTF_INT_BITS(*int_type) == 32) | ||
134 | jsonw_printf(jw, "%u", *(__u32 *)data); | ||
135 | else if (BTF_INT_BITS(*int_type) == 16) | ||
136 | jsonw_printf(jw, "%hu", *(__u16 *)data); | ||
137 | else if (BTF_INT_BITS(*int_type) == 8) | ||
138 | jsonw_printf(jw, "%hhu", *(__u8 *)data); | ||
139 | else | ||
140 | btf_dumper_int_bits(*int_type, bit_offset, data, jw, | ||
141 | is_plain_text); | ||
142 | break; | ||
143 | case BTF_INT_SIGNED: | ||
144 | if (BTF_INT_BITS(*int_type) == 64) | ||
145 | jsonw_printf(jw, "%ld", *(long long *)data); | ||
146 | else if (BTF_INT_BITS(*int_type) == 32) | ||
147 | jsonw_printf(jw, "%d", *(int *)data); | ||
148 | else if (BTF_INT_BITS(*int_type) == 16) | ||
149 | jsonw_printf(jw, "%hd", *(short *)data); | ||
150 | else if (BTF_INT_BITS(*int_type) == 8) | ||
151 | jsonw_printf(jw, "%hhd", *(char *)data); | ||
152 | else | ||
153 | btf_dumper_int_bits(*int_type, bit_offset, data, jw, | ||
154 | is_plain_text); | ||
155 | break; | ||
156 | case BTF_INT_CHAR: | ||
157 | if (isprint(*(char *)data)) | ||
158 | jsonw_printf(jw, "\"%c\"", *(char *)data); | ||
159 | else | ||
160 | if (is_plain_text) | ||
161 | jsonw_printf(jw, "0x%hhx", *(char *)data); | ||
162 | else | ||
163 | jsonw_printf(jw, "\"\\u00%02hhx\"", | ||
164 | *(char *)data); | ||
165 | break; | ||
166 | case BTF_INT_BOOL: | ||
167 | jsonw_bool(jw, *(int *)data); | ||
168 | break; | ||
169 | default: | ||
170 | /* shouldn't happen */ | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | |||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id, | ||
178 | const void *data) | ||
179 | { | ||
180 | const struct btf_type *t; | ||
181 | struct btf_member *m; | ||
182 | const void *data_off; | ||
183 | int ret = 0; | ||
184 | int i, vlen; | ||
185 | |||
186 | t = btf__type_by_id(d->btf, type_id); | ||
187 | if (!t) | ||
188 | return -EINVAL; | ||
189 | |||
190 | vlen = BTF_INFO_VLEN(t->info); | ||
191 | jsonw_start_object(d->jw); | ||
192 | m = (struct btf_member *)(t + 1); | ||
193 | |||
194 | for (i = 0; i < vlen; i++) { | ||
195 | data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset); | ||
196 | jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off)); | ||
197 | ret = btf_dumper_do_type(d, m[i].type, | ||
198 | BITS_PER_BYTE_MASKED(m[i].offset), | ||
199 | data_off); | ||
200 | if (ret) | ||
201 | break; | ||
202 | } | ||
203 | |||
204 | jsonw_end_object(d->jw); | ||
205 | |||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id, | ||
210 | __u8 bit_offset, const void *data) | ||
211 | { | ||
212 | const struct btf_type *t = btf__type_by_id(d->btf, type_id); | ||
213 | |||
214 | switch (BTF_INFO_KIND(t->info)) { | ||
215 | case BTF_KIND_INT: | ||
216 | return btf_dumper_int(t, bit_offset, data, d->jw, | ||
217 | d->is_plain_text); | ||
218 | case BTF_KIND_STRUCT: | ||
219 | case BTF_KIND_UNION: | ||
220 | return btf_dumper_struct(d, type_id, data); | ||
221 | case BTF_KIND_ARRAY: | ||
222 | return btf_dumper_array(d, type_id, data); | ||
223 | case BTF_KIND_ENUM: | ||
224 | btf_dumper_enum(data, d->jw); | ||
225 | return 0; | ||
226 | case BTF_KIND_PTR: | ||
227 | btf_dumper_ptr(data, d->jw, d->is_plain_text); | ||
228 | return 0; | ||
229 | case BTF_KIND_UNKN: | ||
230 | jsonw_printf(d->jw, "(unknown)"); | ||
231 | return 0; | ||
232 | case BTF_KIND_FWD: | ||
233 | /* map key or value can't be forward */ | ||
234 | jsonw_printf(d->jw, "(fwd-kind-invalid)"); | ||
235 | return -EINVAL; | ||
236 | case BTF_KIND_TYPEDEF: | ||
237 | case BTF_KIND_VOLATILE: | ||
238 | case BTF_KIND_CONST: | ||
239 | case BTF_KIND_RESTRICT: | ||
240 | return btf_dumper_modifier(d, type_id, data); | ||
241 | default: | ||
242 | jsonw_printf(d->jw, "(unsupported-kind"); | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | int btf_dumper_type(const struct btf_dumper *d, __u32 type_id, | ||
248 | const void *data) | ||
249 | { | ||
250 | return btf_dumper_do_type(d, type_id, 0, data); | ||
251 | } | ||
diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c index 16bee011e16c..ee7a9765c6b3 100644 --- a/tools/bpf/bpftool/cgroup.c +++ b/tools/bpf/bpftool/cgroup.c | |||
@@ -2,7 +2,12 @@ | |||
2 | // Copyright (C) 2017 Facebook | 2 | // Copyright (C) 2017 Facebook |
3 | // Author: Roman Gushchin <guro@fb.com> | 3 | // Author: Roman Gushchin <guro@fb.com> |
4 | 4 | ||
5 | #define _XOPEN_SOURCE 500 | ||
6 | #include <errno.h> | ||
5 | #include <fcntl.h> | 7 | #include <fcntl.h> |
8 | #include <ftw.h> | ||
9 | #include <mntent.h> | ||
10 | #include <stdio.h> | ||
6 | #include <stdlib.h> | 11 | #include <stdlib.h> |
7 | #include <string.h> | 12 | #include <string.h> |
8 | #include <sys/stat.h> | 13 | #include <sys/stat.h> |
@@ -53,7 +58,8 @@ static enum bpf_attach_type parse_attach_type(const char *str) | |||
53 | } | 58 | } |
54 | 59 | ||
55 | static int show_bpf_prog(int id, const char *attach_type_str, | 60 | static int show_bpf_prog(int id, const char *attach_type_str, |
56 | const char *attach_flags_str) | 61 | const char *attach_flags_str, |
62 | int level) | ||
57 | { | 63 | { |
58 | struct bpf_prog_info info = {}; | 64 | struct bpf_prog_info info = {}; |
59 | __u32 info_len = sizeof(info); | 65 | __u32 info_len = sizeof(info); |
@@ -78,7 +84,8 @@ static int show_bpf_prog(int id, const char *attach_type_str, | |||
78 | jsonw_string_field(json_wtr, "name", info.name); | 84 | jsonw_string_field(json_wtr, "name", info.name); |
79 | jsonw_end_object(json_wtr); | 85 | jsonw_end_object(json_wtr); |
80 | } else { | 86 | } else { |
81 | printf("%-8u %-15s %-15s %-15s\n", info.id, | 87 | printf("%s%-8u %-15s %-15s %-15s\n", level ? " " : "", |
88 | info.id, | ||
82 | attach_type_str, | 89 | attach_type_str, |
83 | attach_flags_str, | 90 | attach_flags_str, |
84 | info.name); | 91 | info.name); |
@@ -88,7 +95,20 @@ static int show_bpf_prog(int id, const char *attach_type_str, | |||
88 | return 0; | 95 | return 0; |
89 | } | 96 | } |
90 | 97 | ||
91 | static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) | 98 | static int count_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) |
99 | { | ||
100 | __u32 prog_cnt = 0; | ||
101 | int ret; | ||
102 | |||
103 | ret = bpf_prog_query(cgroup_fd, type, 0, NULL, NULL, &prog_cnt); | ||
104 | if (ret) | ||
105 | return -1; | ||
106 | |||
107 | return prog_cnt; | ||
108 | } | ||
109 | |||
110 | static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type, | ||
111 | int level) | ||
92 | { | 112 | { |
93 | __u32 prog_ids[1024] = {0}; | 113 | __u32 prog_ids[1024] = {0}; |
94 | char *attach_flags_str; | 114 | char *attach_flags_str; |
@@ -123,7 +143,7 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type) | |||
123 | 143 | ||
124 | for (iter = 0; iter < prog_cnt; iter++) | 144 | for (iter = 0; iter < prog_cnt; iter++) |
125 | show_bpf_prog(prog_ids[iter], attach_type_strings[type], | 145 | show_bpf_prog(prog_ids[iter], attach_type_strings[type], |
126 | attach_flags_str); | 146 | attach_flags_str, level); |
127 | 147 | ||
128 | return 0; | 148 | return 0; |
129 | } | 149 | } |
@@ -161,7 +181,7 @@ static int do_show(int argc, char **argv) | |||
161 | * If we were able to get the show for at least one | 181 | * If we were able to get the show for at least one |
162 | * attach type, let's return 0. | 182 | * attach type, let's return 0. |
163 | */ | 183 | */ |
164 | if (show_attached_bpf_progs(cgroup_fd, type) == 0) | 184 | if (show_attached_bpf_progs(cgroup_fd, type, 0) == 0) |
165 | ret = 0; | 185 | ret = 0; |
166 | } | 186 | } |
167 | 187 | ||
@@ -173,6 +193,143 @@ exit: | |||
173 | return ret; | 193 | return ret; |
174 | } | 194 | } |
175 | 195 | ||
196 | /* | ||
197 | * To distinguish nftw() errors and do_show_tree_fn() errors | ||
198 | * and avoid duplicating error messages, let's return -2 | ||
199 | * from do_show_tree_fn() in case of error. | ||
200 | */ | ||
201 | #define NFTW_ERR -1 | ||
202 | #define SHOW_TREE_FN_ERR -2 | ||
203 | static int do_show_tree_fn(const char *fpath, const struct stat *sb, | ||
204 | int typeflag, struct FTW *ftw) | ||
205 | { | ||
206 | enum bpf_attach_type type; | ||
207 | bool skip = true; | ||
208 | int cgroup_fd; | ||
209 | |||
210 | if (typeflag != FTW_D) | ||
211 | return 0; | ||
212 | |||
213 | cgroup_fd = open(fpath, O_RDONLY); | ||
214 | if (cgroup_fd < 0) { | ||
215 | p_err("can't open cgroup %s: %s", fpath, strerror(errno)); | ||
216 | return SHOW_TREE_FN_ERR; | ||
217 | } | ||
218 | |||
219 | for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) { | ||
220 | int count = count_attached_bpf_progs(cgroup_fd, type); | ||
221 | |||
222 | if (count < 0 && errno != EINVAL) { | ||
223 | p_err("can't query bpf programs attached to %s: %s", | ||
224 | fpath, strerror(errno)); | ||
225 | close(cgroup_fd); | ||
226 | return SHOW_TREE_FN_ERR; | ||
227 | } | ||
228 | if (count > 0) { | ||
229 | skip = false; | ||
230 | break; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | if (skip) { | ||
235 | close(cgroup_fd); | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | if (json_output) { | ||
240 | jsonw_start_object(json_wtr); | ||
241 | jsonw_string_field(json_wtr, "cgroup", fpath); | ||
242 | jsonw_name(json_wtr, "programs"); | ||
243 | jsonw_start_array(json_wtr); | ||
244 | } else { | ||
245 | printf("%s\n", fpath); | ||
246 | } | ||
247 | |||
248 | for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) | ||
249 | show_attached_bpf_progs(cgroup_fd, type, ftw->level); | ||
250 | |||
251 | if (json_output) { | ||
252 | jsonw_end_array(json_wtr); | ||
253 | jsonw_end_object(json_wtr); | ||
254 | } | ||
255 | |||
256 | close(cgroup_fd); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static char *find_cgroup_root(void) | ||
262 | { | ||
263 | struct mntent *mnt; | ||
264 | FILE *f; | ||
265 | |||
266 | f = fopen("/proc/mounts", "r"); | ||
267 | if (f == NULL) | ||
268 | return NULL; | ||
269 | |||
270 | while ((mnt = getmntent(f))) { | ||
271 | if (strcmp(mnt->mnt_type, "cgroup2") == 0) { | ||
272 | fclose(f); | ||
273 | return strdup(mnt->mnt_dir); | ||
274 | } | ||
275 | } | ||
276 | |||
277 | fclose(f); | ||
278 | return NULL; | ||
279 | } | ||
280 | |||
281 | static int do_show_tree(int argc, char **argv) | ||
282 | { | ||
283 | char *cgroup_root; | ||
284 | int ret; | ||
285 | |||
286 | switch (argc) { | ||
287 | case 0: | ||
288 | cgroup_root = find_cgroup_root(); | ||
289 | if (!cgroup_root) { | ||
290 | p_err("cgroup v2 isn't mounted"); | ||
291 | return -1; | ||
292 | } | ||
293 | break; | ||
294 | case 1: | ||
295 | cgroup_root = argv[0]; | ||
296 | break; | ||
297 | default: | ||
298 | p_err("too many parameters for cgroup tree"); | ||
299 | return -1; | ||
300 | } | ||
301 | |||
302 | |||
303 | if (json_output) | ||
304 | jsonw_start_array(json_wtr); | ||
305 | else | ||
306 | printf("%s\n" | ||
307 | "%-8s %-15s %-15s %-15s\n", | ||
308 | "CgroupPath", | ||
309 | "ID", "AttachType", "AttachFlags", "Name"); | ||
310 | |||
311 | switch (nftw(cgroup_root, do_show_tree_fn, 1024, FTW_MOUNT)) { | ||
312 | case NFTW_ERR: | ||
313 | p_err("can't iterate over %s: %s", cgroup_root, | ||
314 | strerror(errno)); | ||
315 | ret = -1; | ||
316 | break; | ||
317 | case SHOW_TREE_FN_ERR: | ||
318 | ret = -1; | ||
319 | break; | ||
320 | default: | ||
321 | ret = 0; | ||
322 | } | ||
323 | |||
324 | if (json_output) | ||
325 | jsonw_end_array(json_wtr); | ||
326 | |||
327 | if (argc == 0) | ||
328 | free(cgroup_root); | ||
329 | |||
330 | return ret; | ||
331 | } | ||
332 | |||
176 | static int do_attach(int argc, char **argv) | 333 | static int do_attach(int argc, char **argv) |
177 | { | 334 | { |
178 | enum bpf_attach_type attach_type; | 335 | enum bpf_attach_type attach_type; |
@@ -289,6 +446,7 @@ static int do_help(int argc, char **argv) | |||
289 | 446 | ||
290 | fprintf(stderr, | 447 | fprintf(stderr, |
291 | "Usage: %s %s { show | list } CGROUP\n" | 448 | "Usage: %s %s { show | list } CGROUP\n" |
449 | " %s %s tree [CGROUP_ROOT]\n" | ||
292 | " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n" | 450 | " %s %s attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]\n" |
293 | " %s %s detach CGROUP ATTACH_TYPE PROG\n" | 451 | " %s %s detach CGROUP ATTACH_TYPE PROG\n" |
294 | " %s %s help\n" | 452 | " %s %s help\n" |
@@ -298,6 +456,7 @@ static int do_help(int argc, char **argv) | |||
298 | " " HELP_SPEC_PROGRAM "\n" | 456 | " " HELP_SPEC_PROGRAM "\n" |
299 | " " HELP_SPEC_OPTIONS "\n" | 457 | " " HELP_SPEC_OPTIONS "\n" |
300 | "", | 458 | "", |
459 | bin_name, argv[-2], | ||
301 | bin_name, argv[-2], bin_name, argv[-2], | 460 | bin_name, argv[-2], bin_name, argv[-2], |
302 | bin_name, argv[-2], bin_name, argv[-2]); | 461 | bin_name, argv[-2], bin_name, argv[-2]); |
303 | 462 | ||
@@ -307,6 +466,7 @@ static int do_help(int argc, char **argv) | |||
307 | static const struct cmd cmds[] = { | 466 | static const struct cmd cmds[] = { |
308 | { "show", do_show }, | 467 | { "show", do_show }, |
309 | { "list", do_show }, | 468 | { "list", do_show }, |
469 | { "tree", do_show_tree }, | ||
310 | { "attach", do_attach }, | 470 | { "attach", do_attach }, |
311 | { "detach", do_detach }, | 471 | { "detach", do_detach }, |
312 | { "help", do_help }, | 472 | { "help", do_help }, |
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 3f140eff039f..b3a0709ea7ed 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c | |||
@@ -31,8 +31,6 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* Author: Jakub Kicinski <kubakici@wp.pl> */ | ||
35 | |||
36 | #include <ctype.h> | 34 | #include <ctype.h> |
37 | #include <errno.h> | 35 | #include <errno.h> |
38 | #include <fcntl.h> | 36 | #include <fcntl.h> |
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index eea7f14355f3..d15a62be6cf0 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2017 Netronome Systems, Inc. | 2 | * Copyright (C) 2017-2018 Netronome Systems, Inc. |
3 | * | 3 | * |
4 | * This software is dual licensed under the GNU General License Version 2, | 4 | * This software is dual licensed under the GNU General License Version 2, |
5 | * June 1991 as shown in the file COPYING in the top-level directory of this | 5 | * June 1991 as shown in the file COPYING in the top-level directory of this |
@@ -31,8 +31,6 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* Author: Jakub Kicinski <kubakici@wp.pl> */ | ||
35 | |||
36 | #include <bfd.h> | 34 | #include <bfd.h> |
37 | #include <ctype.h> | 35 | #include <ctype.h> |
38 | #include <errno.h> | 36 | #include <errno.h> |
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 63fdb310b9a4..238e734d75b3 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h | |||
@@ -31,8 +31,6 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* Author: Jakub Kicinski <kubakici@wp.pl> */ | ||
35 | |||
36 | #ifndef __BPF_TOOL_H | 34 | #ifndef __BPF_TOOL_H |
37 | #define __BPF_TOOL_H | 35 | #define __BPF_TOOL_H |
38 | 36 | ||
@@ -44,6 +42,7 @@ | |||
44 | #include <linux/compiler.h> | 42 | #include <linux/compiler.h> |
45 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
46 | #include <linux/hashtable.h> | 44 | #include <linux/hashtable.h> |
45 | #include <tools/libc_compat.h> | ||
47 | 46 | ||
48 | #include "json_writer.h" | 47 | #include "json_writer.h" |
49 | 48 | ||
@@ -52,6 +51,21 @@ | |||
52 | #define NEXT_ARG() ({ argc--; argv++; if (argc < 0) usage(); }) | 51 | #define NEXT_ARG() ({ argc--; argv++; if (argc < 0) usage(); }) |
53 | #define NEXT_ARGP() ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); }) | 52 | #define NEXT_ARGP() ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); }) |
54 | #define BAD_ARG() ({ p_err("what is '%s'?", *argv); -1; }) | 53 | #define BAD_ARG() ({ p_err("what is '%s'?", *argv); -1; }) |
54 | #define GET_ARG() ({ argc--; *argv++; }) | ||
55 | #define REQ_ARGS(cnt) \ | ||
56 | ({ \ | ||
57 | int _cnt = (cnt); \ | ||
58 | bool _res; \ | ||
59 | \ | ||
60 | if (argc < _cnt) { \ | ||
61 | p_err("'%s' needs at least %d arguments, %d found", \ | ||
62 | argv[-1], _cnt, argc); \ | ||
63 | _res = false; \ | ||
64 | } else { \ | ||
65 | _res = true; \ | ||
66 | } \ | ||
67 | _res; \ | ||
68 | }) | ||
55 | 69 | ||
56 | #define ERR_MAX_LEN 1024 | 70 | #define ERR_MAX_LEN 1024 |
57 | 71 | ||
@@ -61,6 +75,8 @@ | |||
61 | "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }" | 75 | "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }" |
62 | #define HELP_SPEC_OPTIONS \ | 76 | #define HELP_SPEC_OPTIONS \ |
63 | "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} }" | 77 | "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} }" |
78 | #define HELP_SPEC_MAP \ | ||
79 | "MAP := { id MAP_ID | pinned FILE }" | ||
64 | 80 | ||
65 | enum bpf_obj_type { | 81 | enum bpf_obj_type { |
66 | BPF_OBJ_UNKNOWN, | 82 | BPF_OBJ_UNKNOWN, |
@@ -122,6 +138,7 @@ int do_cgroup(int argc, char **arg); | |||
122 | int do_perf(int argc, char **arg); | 138 | int do_perf(int argc, char **arg); |
123 | 139 | ||
124 | int prog_parse_fd(int *argc, char ***argv); | 140 | int prog_parse_fd(int *argc, char ***argv); |
141 | int map_parse_fd(int *argc, char ***argv); | ||
125 | int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len); | 142 | int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len); |
126 | 143 | ||
127 | void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes, | 144 | void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes, |
@@ -133,4 +150,19 @@ unsigned int get_page_size(void); | |||
133 | unsigned int get_possible_cpus(void); | 150 | unsigned int get_possible_cpus(void); |
134 | const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino); | 151 | const char *ifindex_to_bfd_name_ns(__u32 ifindex, __u64 ns_dev, __u64 ns_ino); |
135 | 152 | ||
153 | struct btf_dumper { | ||
154 | const struct btf *btf; | ||
155 | json_writer_t *jw; | ||
156 | bool is_plain_text; | ||
157 | }; | ||
158 | |||
159 | /* btf_dumper_type - print data along with type information | ||
160 | * @d: an instance containing context for dumping types | ||
161 | * @type_id: index in btf->types array. this points to the type to be dumped | ||
162 | * @data: pointer the actual data, i.e. the values to be printed | ||
163 | * | ||
164 | * Returns zero on success and negative error code otherwise | ||
165 | */ | ||
166 | int btf_dumper_type(const struct btf_dumper *d, __u32 type_id, | ||
167 | const void *data); | ||
136 | #endif | 168 | #endif |
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index f74a8bcbda87..b2ec20e562bd 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c | |||
@@ -31,11 +31,10 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* Author: Jakub Kicinski <kubakici@wp.pl> */ | ||
35 | |||
36 | #include <assert.h> | 34 | #include <assert.h> |
37 | #include <errno.h> | 35 | #include <errno.h> |
38 | #include <fcntl.h> | 36 | #include <fcntl.h> |
37 | #include <linux/err.h> | ||
39 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
40 | #include <stdbool.h> | 39 | #include <stdbool.h> |
41 | #include <stdio.h> | 40 | #include <stdio.h> |
@@ -47,6 +46,8 @@ | |||
47 | 46 | ||
48 | #include <bpf.h> | 47 | #include <bpf.h> |
49 | 48 | ||
49 | #include "btf.h" | ||
50 | #include "json_writer.h" | ||
50 | #include "main.h" | 51 | #include "main.h" |
51 | 52 | ||
52 | static const char * const map_type_name[] = { | 53 | static const char * const map_type_name[] = { |
@@ -68,6 +69,7 @@ static const char * const map_type_name[] = { | |||
68 | [BPF_MAP_TYPE_SOCKMAP] = "sockmap", | 69 | [BPF_MAP_TYPE_SOCKMAP] = "sockmap", |
69 | [BPF_MAP_TYPE_CPUMAP] = "cpumap", | 70 | [BPF_MAP_TYPE_CPUMAP] = "cpumap", |
70 | [BPF_MAP_TYPE_SOCKHASH] = "sockhash", | 71 | [BPF_MAP_TYPE_SOCKHASH] = "sockhash", |
72 | [BPF_MAP_TYPE_CGROUP_STORAGE] = "cgroup_storage", | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | static bool map_is_per_cpu(__u32 type) | 75 | static bool map_is_per_cpu(__u32 type) |
@@ -97,7 +99,7 @@ static void *alloc_value(struct bpf_map_info *info) | |||
97 | return malloc(info->value_size); | 99 | return malloc(info->value_size); |
98 | } | 100 | } |
99 | 101 | ||
100 | static int map_parse_fd(int *argc, char ***argv) | 102 | int map_parse_fd(int *argc, char ***argv) |
101 | { | 103 | { |
102 | int fd; | 104 | int fd; |
103 | 105 | ||
@@ -152,8 +154,109 @@ int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len) | |||
152 | return fd; | 154 | return fd; |
153 | } | 155 | } |
154 | 156 | ||
157 | static int do_dump_btf(const struct btf_dumper *d, | ||
158 | struct bpf_map_info *map_info, void *key, | ||
159 | void *value) | ||
160 | { | ||
161 | int ret; | ||
162 | |||
163 | /* start of key-value pair */ | ||
164 | jsonw_start_object(d->jw); | ||
165 | |||
166 | jsonw_name(d->jw, "key"); | ||
167 | |||
168 | ret = btf_dumper_type(d, map_info->btf_key_type_id, key); | ||
169 | if (ret) | ||
170 | goto err_end_obj; | ||
171 | |||
172 | jsonw_name(d->jw, "value"); | ||
173 | |||
174 | ret = btf_dumper_type(d, map_info->btf_value_type_id, value); | ||
175 | |||
176 | err_end_obj: | ||
177 | /* end of key-value pair */ | ||
178 | jsonw_end_object(d->jw); | ||
179 | |||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | static int get_btf(struct bpf_map_info *map_info, struct btf **btf) | ||
184 | { | ||
185 | struct bpf_btf_info btf_info = { 0 }; | ||
186 | __u32 len = sizeof(btf_info); | ||
187 | __u32 last_size; | ||
188 | int btf_fd; | ||
189 | void *ptr; | ||
190 | int err; | ||
191 | |||
192 | err = 0; | ||
193 | *btf = NULL; | ||
194 | btf_fd = bpf_btf_get_fd_by_id(map_info->btf_id); | ||
195 | if (btf_fd < 0) | ||
196 | return 0; | ||
197 | |||
198 | /* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so | ||
199 | * let's start with a sane default - 4KiB here - and resize it only if | ||
200 | * bpf_obj_get_info_by_fd() needs a bigger buffer. | ||
201 | */ | ||
202 | btf_info.btf_size = 4096; | ||
203 | last_size = btf_info.btf_size; | ||
204 | ptr = malloc(last_size); | ||
205 | if (!ptr) { | ||
206 | err = -ENOMEM; | ||
207 | goto exit_free; | ||
208 | } | ||
209 | |||
210 | bzero(ptr, last_size); | ||
211 | btf_info.btf = ptr_to_u64(ptr); | ||
212 | err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len); | ||
213 | |||
214 | if (!err && btf_info.btf_size > last_size) { | ||
215 | void *temp_ptr; | ||
216 | |||
217 | last_size = btf_info.btf_size; | ||
218 | temp_ptr = realloc(ptr, last_size); | ||
219 | if (!temp_ptr) { | ||
220 | err = -ENOMEM; | ||
221 | goto exit_free; | ||
222 | } | ||
223 | ptr = temp_ptr; | ||
224 | bzero(ptr, last_size); | ||
225 | btf_info.btf = ptr_to_u64(ptr); | ||
226 | err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len); | ||
227 | } | ||
228 | |||
229 | if (err || btf_info.btf_size > last_size) { | ||
230 | err = errno; | ||
231 | goto exit_free; | ||
232 | } | ||
233 | |||
234 | *btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL); | ||
235 | if (IS_ERR(*btf)) { | ||
236 | err = PTR_ERR(*btf); | ||
237 | *btf = NULL; | ||
238 | } | ||
239 | |||
240 | exit_free: | ||
241 | close(btf_fd); | ||
242 | free(ptr); | ||
243 | |||
244 | return err; | ||
245 | } | ||
246 | |||
247 | static json_writer_t *get_btf_writer(void) | ||
248 | { | ||
249 | json_writer_t *jw = jsonw_new(stdout); | ||
250 | |||
251 | if (!jw) | ||
252 | return NULL; | ||
253 | jsonw_pretty(jw, true); | ||
254 | |||
255 | return jw; | ||
256 | } | ||
257 | |||
155 | static void print_entry_json(struct bpf_map_info *info, unsigned char *key, | 258 | static void print_entry_json(struct bpf_map_info *info, unsigned char *key, |
156 | unsigned char *value) | 259 | unsigned char *value, struct btf *btf) |
157 | { | 260 | { |
158 | jsonw_start_object(json_wtr); | 261 | jsonw_start_object(json_wtr); |
159 | 262 | ||
@@ -162,6 +265,16 @@ static void print_entry_json(struct bpf_map_info *info, unsigned char *key, | |||
162 | print_hex_data_json(key, info->key_size); | 265 | print_hex_data_json(key, info->key_size); |
163 | jsonw_name(json_wtr, "value"); | 266 | jsonw_name(json_wtr, "value"); |
164 | print_hex_data_json(value, info->value_size); | 267 | print_hex_data_json(value, info->value_size); |
268 | if (btf) { | ||
269 | struct btf_dumper d = { | ||
270 | .btf = btf, | ||
271 | .jw = json_wtr, | ||
272 | .is_plain_text = false, | ||
273 | }; | ||
274 | |||
275 | jsonw_name(json_wtr, "formatted"); | ||
276 | do_dump_btf(&d, info, key, value); | ||
277 | } | ||
165 | } else { | 278 | } else { |
166 | unsigned int i, n, step; | 279 | unsigned int i, n, step; |
167 | 280 | ||
@@ -514,10 +627,12 @@ static int do_show(int argc, char **argv) | |||
514 | 627 | ||
515 | static int do_dump(int argc, char **argv) | 628 | static int do_dump(int argc, char **argv) |
516 | { | 629 | { |
630 | struct bpf_map_info info = {}; | ||
517 | void *key, *value, *prev_key; | 631 | void *key, *value, *prev_key; |
518 | unsigned int num_elems = 0; | 632 | unsigned int num_elems = 0; |
519 | struct bpf_map_info info = {}; | ||
520 | __u32 len = sizeof(info); | 633 | __u32 len = sizeof(info); |
634 | json_writer_t *btf_wtr; | ||
635 | struct btf *btf = NULL; | ||
521 | int err; | 636 | int err; |
522 | int fd; | 637 | int fd; |
523 | 638 | ||
@@ -543,8 +658,27 @@ static int do_dump(int argc, char **argv) | |||
543 | } | 658 | } |
544 | 659 | ||
545 | prev_key = NULL; | 660 | prev_key = NULL; |
661 | |||
662 | err = get_btf(&info, &btf); | ||
663 | if (err) { | ||
664 | p_err("failed to get btf"); | ||
665 | goto exit_free; | ||
666 | } | ||
667 | |||
546 | if (json_output) | 668 | if (json_output) |
547 | jsonw_start_array(json_wtr); | 669 | jsonw_start_array(json_wtr); |
670 | else | ||
671 | if (btf) { | ||
672 | btf_wtr = get_btf_writer(); | ||
673 | if (!btf_wtr) { | ||
674 | p_info("failed to create json writer for btf. falling back to plain output"); | ||
675 | btf__free(btf); | ||
676 | btf = NULL; | ||
677 | } else { | ||
678 | jsonw_start_array(btf_wtr); | ||
679 | } | ||
680 | } | ||
681 | |||
548 | while (true) { | 682 | while (true) { |
549 | err = bpf_map_get_next_key(fd, prev_key, key); | 683 | err = bpf_map_get_next_key(fd, prev_key, key); |
550 | if (err) { | 684 | if (err) { |
@@ -555,9 +689,19 @@ static int do_dump(int argc, char **argv) | |||
555 | 689 | ||
556 | if (!bpf_map_lookup_elem(fd, key, value)) { | 690 | if (!bpf_map_lookup_elem(fd, key, value)) { |
557 | if (json_output) | 691 | if (json_output) |
558 | print_entry_json(&info, key, value); | 692 | print_entry_json(&info, key, value, btf); |
559 | else | 693 | else |
560 | print_entry_plain(&info, key, value); | 694 | if (btf) { |
695 | struct btf_dumper d = { | ||
696 | .btf = btf, | ||
697 | .jw = btf_wtr, | ||
698 | .is_plain_text = true, | ||
699 | }; | ||
700 | |||
701 | do_dump_btf(&d, &info, key, value); | ||
702 | } else { | ||
703 | print_entry_plain(&info, key, value); | ||
704 | } | ||
561 | } else { | 705 | } else { |
562 | if (json_output) { | 706 | if (json_output) { |
563 | jsonw_name(json_wtr, "key"); | 707 | jsonw_name(json_wtr, "key"); |
@@ -580,14 +724,19 @@ static int do_dump(int argc, char **argv) | |||
580 | 724 | ||
581 | if (json_output) | 725 | if (json_output) |
582 | jsonw_end_array(json_wtr); | 726 | jsonw_end_array(json_wtr); |
583 | else | 727 | else if (btf) { |
728 | jsonw_end_array(btf_wtr); | ||
729 | jsonw_destroy(&btf_wtr); | ||
730 | } else { | ||
584 | printf("Found %u element%s\n", num_elems, | 731 | printf("Found %u element%s\n", num_elems, |
585 | num_elems != 1 ? "s" : ""); | 732 | num_elems != 1 ? "s" : ""); |
733 | } | ||
586 | 734 | ||
587 | exit_free: | 735 | exit_free: |
588 | free(key); | 736 | free(key); |
589 | free(value); | 737 | free(value); |
590 | close(fd); | 738 | close(fd); |
739 | btf__free(btf); | ||
591 | 740 | ||
592 | return err; | 741 | return err; |
593 | } | 742 | } |
@@ -643,6 +792,8 @@ static int do_lookup(int argc, char **argv) | |||
643 | { | 792 | { |
644 | struct bpf_map_info info = {}; | 793 | struct bpf_map_info info = {}; |
645 | __u32 len = sizeof(info); | 794 | __u32 len = sizeof(info); |
795 | json_writer_t *btf_wtr; | ||
796 | struct btf *btf = NULL; | ||
646 | void *key, *value; | 797 | void *key, *value; |
647 | int err; | 798 | int err; |
648 | int fd; | 799 | int fd; |
@@ -667,27 +818,60 @@ static int do_lookup(int argc, char **argv) | |||
667 | goto exit_free; | 818 | goto exit_free; |
668 | 819 | ||
669 | err = bpf_map_lookup_elem(fd, key, value); | 820 | err = bpf_map_lookup_elem(fd, key, value); |
670 | if (!err) { | 821 | if (err) { |
671 | if (json_output) | 822 | if (errno == ENOENT) { |
672 | print_entry_json(&info, key, value); | 823 | if (json_output) { |
673 | else | 824 | jsonw_null(json_wtr); |
825 | } else { | ||
826 | printf("key:\n"); | ||
827 | fprint_hex(stdout, key, info.key_size, " "); | ||
828 | printf("\n\nNot found\n"); | ||
829 | } | ||
830 | } else { | ||
831 | p_err("lookup failed: %s", strerror(errno)); | ||
832 | } | ||
833 | |||
834 | goto exit_free; | ||
835 | } | ||
836 | |||
837 | /* here means bpf_map_lookup_elem() succeeded */ | ||
838 | err = get_btf(&info, &btf); | ||
839 | if (err) { | ||
840 | p_err("failed to get btf"); | ||
841 | goto exit_free; | ||
842 | } | ||
843 | |||
844 | if (json_output) { | ||
845 | print_entry_json(&info, key, value, btf); | ||
846 | } else if (btf) { | ||
847 | /* if here json_wtr wouldn't have been initialised, | ||
848 | * so let's create separate writer for btf | ||
849 | */ | ||
850 | btf_wtr = get_btf_writer(); | ||
851 | if (!btf_wtr) { | ||
852 | p_info("failed to create json writer for btf. falling back to plain output"); | ||
853 | btf__free(btf); | ||
854 | btf = NULL; | ||
674 | print_entry_plain(&info, key, value); | 855 | print_entry_plain(&info, key, value); |
675 | } else if (errno == ENOENT) { | ||
676 | if (json_output) { | ||
677 | jsonw_null(json_wtr); | ||
678 | } else { | 856 | } else { |
679 | printf("key:\n"); | 857 | struct btf_dumper d = { |
680 | fprint_hex(stdout, key, info.key_size, " "); | 858 | .btf = btf, |
681 | printf("\n\nNot found\n"); | 859 | .jw = btf_wtr, |
860 | .is_plain_text = true, | ||
861 | }; | ||
862 | |||
863 | do_dump_btf(&d, &info, key, value); | ||
864 | jsonw_destroy(&btf_wtr); | ||
682 | } | 865 | } |
683 | } else { | 866 | } else { |
684 | p_err("lookup failed: %s", strerror(errno)); | 867 | print_entry_plain(&info, key, value); |
685 | } | 868 | } |
686 | 869 | ||
687 | exit_free: | 870 | exit_free: |
688 | free(key); | 871 | free(key); |
689 | free(value); | 872 | free(value); |
690 | close(fd); | 873 | close(fd); |
874 | btf__free(btf); | ||
691 | 875 | ||
692 | return err; | 876 | return err; |
693 | } | 877 | } |
@@ -830,7 +1014,7 @@ static int do_help(int argc, char **argv) | |||
830 | " %s %s event_pipe MAP [cpu N index M]\n" | 1014 | " %s %s event_pipe MAP [cpu N index M]\n" |
831 | " %s %s help\n" | 1015 | " %s %s help\n" |
832 | "\n" | 1016 | "\n" |
833 | " MAP := { id MAP_ID | pinned FILE }\n" | 1017 | " " HELP_SPEC_MAP "\n" |
834 | " DATA := { [hex] BYTES }\n" | 1018 | " DATA := { [hex] BYTES }\n" |
835 | " " HELP_SPEC_PROGRAM "\n" | 1019 | " " HELP_SPEC_PROGRAM "\n" |
836 | " VALUE := { DATA | MAP | PROG }\n" | 1020 | " VALUE := { DATA | MAP | PROG }\n" |
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 959aa53ab678..dce960d22106 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2017 Netronome Systems, Inc. | 2 | * Copyright (C) 2017-2018 Netronome Systems, Inc. |
3 | * | 3 | * |
4 | * This software is dual licensed under the GNU General License Version 2, | 4 | * This software is dual licensed under the GNU General License Version 2, |
5 | * June 1991 as shown in the file COPYING in the top-level directory of this | 5 | * June 1991 as shown in the file COPYING in the top-level directory of this |
@@ -31,8 +31,7 @@ | |||
31 | * SOFTWARE. | 31 | * SOFTWARE. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* Author: Jakub Kicinski <kubakici@wp.pl> */ | 34 | #define _GNU_SOURCE |
35 | |||
36 | #include <errno.h> | 35 | #include <errno.h> |
37 | #include <fcntl.h> | 36 | #include <fcntl.h> |
38 | #include <stdarg.h> | 37 | #include <stdarg.h> |
@@ -41,9 +40,12 @@ | |||
41 | #include <string.h> | 40 | #include <string.h> |
42 | #include <time.h> | 41 | #include <time.h> |
43 | #include <unistd.h> | 42 | #include <unistd.h> |
43 | #include <net/if.h> | ||
44 | #include <sys/types.h> | 44 | #include <sys/types.h> |
45 | #include <sys/stat.h> | 45 | #include <sys/stat.h> |
46 | 46 | ||
47 | #include <linux/err.h> | ||
48 | |||
47 | #include <bpf.h> | 49 | #include <bpf.h> |
48 | #include <libbpf.h> | 50 | #include <libbpf.h> |
49 | 51 | ||
@@ -681,31 +683,247 @@ static int do_pin(int argc, char **argv) | |||
681 | return err; | 683 | return err; |
682 | } | 684 | } |
683 | 685 | ||
686 | struct map_replace { | ||
687 | int idx; | ||
688 | int fd; | ||
689 | char *name; | ||
690 | }; | ||
691 | |||
692 | int map_replace_compar(const void *p1, const void *p2) | ||
693 | { | ||
694 | const struct map_replace *a = p1, *b = p2; | ||
695 | |||
696 | return a->idx - b->idx; | ||
697 | } | ||
698 | |||
684 | static int do_load(int argc, char **argv) | 699 | static int do_load(int argc, char **argv) |
685 | { | 700 | { |
701 | enum bpf_attach_type expected_attach_type; | ||
702 | struct bpf_object_open_attr attr = { | ||
703 | .prog_type = BPF_PROG_TYPE_UNSPEC, | ||
704 | }; | ||
705 | struct map_replace *map_replace = NULL; | ||
706 | unsigned int old_map_fds = 0; | ||
707 | struct bpf_program *prog; | ||
686 | struct bpf_object *obj; | 708 | struct bpf_object *obj; |
687 | int prog_fd; | 709 | struct bpf_map *map; |
688 | 710 | const char *pinfile; | |
689 | if (argc != 2) | 711 | unsigned int i, j; |
690 | usage(); | 712 | __u32 ifindex = 0; |
713 | int idx, err; | ||
691 | 714 | ||
692 | if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) { | 715 | if (!REQ_ARGS(2)) |
693 | p_err("failed to load program"); | ||
694 | return -1; | 716 | return -1; |
717 | attr.file = GET_ARG(); | ||
718 | pinfile = GET_ARG(); | ||
719 | |||
720 | while (argc) { | ||
721 | if (is_prefix(*argv, "type")) { | ||
722 | char *type; | ||
723 | |||
724 | NEXT_ARG(); | ||
725 | |||
726 | if (attr.prog_type != BPF_PROG_TYPE_UNSPEC) { | ||
727 | p_err("program type already specified"); | ||
728 | goto err_free_reuse_maps; | ||
729 | } | ||
730 | if (!REQ_ARGS(1)) | ||
731 | goto err_free_reuse_maps; | ||
732 | |||
733 | /* Put a '/' at the end of type to appease libbpf */ | ||
734 | type = malloc(strlen(*argv) + 2); | ||
735 | if (!type) { | ||
736 | p_err("mem alloc failed"); | ||
737 | goto err_free_reuse_maps; | ||
738 | } | ||
739 | *type = 0; | ||
740 | strcat(type, *argv); | ||
741 | strcat(type, "/"); | ||
742 | |||
743 | err = libbpf_prog_type_by_name(type, &attr.prog_type, | ||
744 | &expected_attach_type); | ||
745 | free(type); | ||
746 | if (err < 0) { | ||
747 | p_err("unknown program type '%s'", *argv); | ||
748 | goto err_free_reuse_maps; | ||
749 | } | ||
750 | NEXT_ARG(); | ||
751 | } else if (is_prefix(*argv, "map")) { | ||
752 | char *endptr, *name; | ||
753 | int fd; | ||
754 | |||
755 | NEXT_ARG(); | ||
756 | |||
757 | if (!REQ_ARGS(4)) | ||
758 | goto err_free_reuse_maps; | ||
759 | |||
760 | if (is_prefix(*argv, "idx")) { | ||
761 | NEXT_ARG(); | ||
762 | |||
763 | idx = strtoul(*argv, &endptr, 0); | ||
764 | if (*endptr) { | ||
765 | p_err("can't parse %s as IDX", *argv); | ||
766 | goto err_free_reuse_maps; | ||
767 | } | ||
768 | name = NULL; | ||
769 | } else if (is_prefix(*argv, "name")) { | ||
770 | NEXT_ARG(); | ||
771 | |||
772 | name = *argv; | ||
773 | idx = -1; | ||
774 | } else { | ||
775 | p_err("expected 'idx' or 'name', got: '%s'?", | ||
776 | *argv); | ||
777 | goto err_free_reuse_maps; | ||
778 | } | ||
779 | NEXT_ARG(); | ||
780 | |||
781 | fd = map_parse_fd(&argc, &argv); | ||
782 | if (fd < 0) | ||
783 | goto err_free_reuse_maps; | ||
784 | |||
785 | map_replace = reallocarray(map_replace, old_map_fds + 1, | ||
786 | sizeof(*map_replace)); | ||
787 | if (!map_replace) { | ||
788 | p_err("mem alloc failed"); | ||
789 | goto err_free_reuse_maps; | ||
790 | } | ||
791 | map_replace[old_map_fds].idx = idx; | ||
792 | map_replace[old_map_fds].name = name; | ||
793 | map_replace[old_map_fds].fd = fd; | ||
794 | old_map_fds++; | ||
795 | } else if (is_prefix(*argv, "dev")) { | ||
796 | NEXT_ARG(); | ||
797 | |||
798 | if (ifindex) { | ||
799 | p_err("offload device already specified"); | ||
800 | goto err_free_reuse_maps; | ||
801 | } | ||
802 | if (!REQ_ARGS(1)) | ||
803 | goto err_free_reuse_maps; | ||
804 | |||
805 | ifindex = if_nametoindex(*argv); | ||
806 | if (!ifindex) { | ||
807 | p_err("unrecognized netdevice '%s': %s", | ||
808 | *argv, strerror(errno)); | ||
809 | goto err_free_reuse_maps; | ||
810 | } | ||
811 | NEXT_ARG(); | ||
812 | } else { | ||
813 | p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?", | ||
814 | *argv); | ||
815 | goto err_free_reuse_maps; | ||
816 | } | ||
817 | } | ||
818 | |||
819 | obj = bpf_object__open_xattr(&attr); | ||
820 | if (IS_ERR_OR_NULL(obj)) { | ||
821 | p_err("failed to open object file"); | ||
822 | goto err_free_reuse_maps; | ||
823 | } | ||
824 | |||
825 | prog = bpf_program__next(NULL, obj); | ||
826 | if (!prog) { | ||
827 | p_err("object file doesn't contain any bpf program"); | ||
828 | goto err_close_obj; | ||
829 | } | ||
830 | |||
831 | bpf_program__set_ifindex(prog, ifindex); | ||
832 | if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { | ||
833 | const char *sec_name = bpf_program__title(prog, false); | ||
834 | |||
835 | err = libbpf_prog_type_by_name(sec_name, &attr.prog_type, | ||
836 | &expected_attach_type); | ||
837 | if (err < 0) { | ||
838 | p_err("failed to guess program type based on section name %s\n", | ||
839 | sec_name); | ||
840 | goto err_close_obj; | ||
841 | } | ||
842 | } | ||
843 | bpf_program__set_type(prog, attr.prog_type); | ||
844 | bpf_program__set_expected_attach_type(prog, expected_attach_type); | ||
845 | |||
846 | qsort(map_replace, old_map_fds, sizeof(*map_replace), | ||
847 | map_replace_compar); | ||
848 | |||
849 | /* After the sort maps by name will be first on the list, because they | ||
850 | * have idx == -1. Resolve them. | ||
851 | */ | ||
852 | j = 0; | ||
853 | while (j < old_map_fds && map_replace[j].name) { | ||
854 | i = 0; | ||
855 | bpf_map__for_each(map, obj) { | ||
856 | if (!strcmp(bpf_map__name(map), map_replace[j].name)) { | ||
857 | map_replace[j].idx = i; | ||
858 | break; | ||
859 | } | ||
860 | i++; | ||
861 | } | ||
862 | if (map_replace[j].idx == -1) { | ||
863 | p_err("unable to find map '%s'", map_replace[j].name); | ||
864 | goto err_close_obj; | ||
865 | } | ||
866 | j++; | ||
867 | } | ||
868 | /* Resort if any names were resolved */ | ||
869 | if (j) | ||
870 | qsort(map_replace, old_map_fds, sizeof(*map_replace), | ||
871 | map_replace_compar); | ||
872 | |||
873 | /* Set ifindex and name reuse */ | ||
874 | j = 0; | ||
875 | idx = 0; | ||
876 | bpf_map__for_each(map, obj) { | ||
877 | if (!bpf_map__is_offload_neutral(map)) | ||
878 | bpf_map__set_ifindex(map, ifindex); | ||
879 | |||
880 | if (j < old_map_fds && idx == map_replace[j].idx) { | ||
881 | err = bpf_map__reuse_fd(map, map_replace[j++].fd); | ||
882 | if (err) { | ||
883 | p_err("unable to set up map reuse: %d", err); | ||
884 | goto err_close_obj; | ||
885 | } | ||
886 | |||
887 | /* Next reuse wants to apply to the same map */ | ||
888 | if (j < old_map_fds && map_replace[j].idx == idx) { | ||
889 | p_err("replacement for map idx %d specified more than once", | ||
890 | idx); | ||
891 | goto err_close_obj; | ||
892 | } | ||
893 | } | ||
894 | |||
895 | idx++; | ||
896 | } | ||
897 | if (j < old_map_fds) { | ||
898 | p_err("map idx '%d' not used", map_replace[j].idx); | ||
899 | goto err_close_obj; | ||
900 | } | ||
901 | |||
902 | err = bpf_object__load(obj); | ||
903 | if (err) { | ||
904 | p_err("failed to load object file"); | ||
905 | goto err_close_obj; | ||
695 | } | 906 | } |
696 | 907 | ||
697 | if (do_pin_fd(prog_fd, argv[1])) | 908 | if (do_pin_fd(bpf_program__fd(prog), pinfile)) |
698 | goto err_close_obj; | 909 | goto err_close_obj; |
699 | 910 | ||
700 | if (json_output) | 911 | if (json_output) |
701 | jsonw_null(json_wtr); | 912 | jsonw_null(json_wtr); |
702 | 913 | ||
703 | bpf_object__close(obj); | 914 | bpf_object__close(obj); |
915 | for (i = 0; i < old_map_fds; i++) | ||
916 | close(map_replace[i].fd); | ||
917 | free(map_replace); | ||
704 | 918 | ||
705 | return 0; | 919 | return 0; |
706 | 920 | ||
707 | err_close_obj: | 921 | err_close_obj: |
708 | bpf_object__close(obj); | 922 | bpf_object__close(obj); |
923 | err_free_reuse_maps: | ||
924 | for (i = 0; i < old_map_fds; i++) | ||
925 | close(map_replace[i].fd); | ||
926 | free(map_replace); | ||
709 | return -1; | 927 | return -1; |
710 | } | 928 | } |
711 | 929 | ||
@@ -721,10 +939,19 @@ static int do_help(int argc, char **argv) | |||
721 | " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" | 939 | " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" |
722 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" | 940 | " %s %s dump jited PROG [{ file FILE | opcodes }]\n" |
723 | " %s %s pin PROG FILE\n" | 941 | " %s %s pin PROG FILE\n" |
724 | " %s %s load OBJ FILE\n" | 942 | " %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n" |
943 | " [map { idx IDX | name NAME } MAP]\n" | ||
725 | " %s %s help\n" | 944 | " %s %s help\n" |
726 | "\n" | 945 | "\n" |
946 | " " HELP_SPEC_MAP "\n" | ||
727 | " " HELP_SPEC_PROGRAM "\n" | 947 | " " HELP_SPEC_PROGRAM "\n" |
948 | " TYPE := { socket | kprobe | kretprobe | classifier | action |\n" | ||
949 | " tracepoint | raw_tracepoint | xdp | perf_event | cgroup/skb |\n" | ||
950 | " cgroup/sock | cgroup/dev | lwt_in | lwt_out | lwt_xmit |\n" | ||
951 | " lwt_seg6local | sockops | sk_skb | sk_msg | lirc_mode2 |\n" | ||
952 | " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" | ||
953 | " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" | ||
954 | " cgroup/sendmsg4 | cgroup/sendmsg6 }\n" | ||
728 | " " HELP_SPEC_OPTIONS "\n" | 955 | " " HELP_SPEC_OPTIONS "\n" |
729 | "", | 956 | "", |
730 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], | 957 | bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], |
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c index b97f1da60dd1..3284759df98a 100644 --- a/tools/bpf/bpftool/xlated_dumper.c +++ b/tools/bpf/bpftool/xlated_dumper.c | |||
@@ -35,6 +35,7 @@ | |||
35 | * POSSIBILITY OF SUCH DAMAGE. | 35 | * POSSIBILITY OF SUCH DAMAGE. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #define _GNU_SOURCE | ||
38 | #include <stdarg.h> | 39 | #include <stdarg.h> |
39 | #include <stdio.h> | 40 | #include <stdio.h> |
40 | #include <stdlib.h> | 41 | #include <stdlib.h> |
@@ -66,9 +67,8 @@ void kernel_syms_load(struct dump_data *dd) | |||
66 | while (!feof(fp)) { | 67 | while (!feof(fp)) { |
67 | if (!fgets(buff, sizeof(buff), fp)) | 68 | if (!fgets(buff, sizeof(buff), fp)) |
68 | break; | 69 | break; |
69 | tmp = realloc(dd->sym_mapping, | 70 | tmp = reallocarray(dd->sym_mapping, dd->sym_count + 1, |
70 | (dd->sym_count + 1) * | 71 | sizeof(*dd->sym_mapping)); |
71 | sizeof(*dd->sym_mapping)); | ||
72 | if (!tmp) { | 72 | if (!tmp) { |
73 | out: | 73 | out: |
74 | free(dd->sym_mapping); | 74 | free(dd->sym_mapping); |
diff --git a/tools/build/Build.include b/tools/build/Build.include index 950c1504ca37..9ec01f4454f9 100644 --- a/tools/build/Build.include +++ b/tools/build/Build.include | |||
@@ -98,4 +98,4 @@ cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXX | |||
98 | ### | 98 | ### |
99 | ## HOSTCC C flags | 99 | ## HOSTCC C flags |
100 | 100 | ||
101 | host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(HOSTCFLAGS) -D"BUILD_STR(s)=\#s" $(HOSTCFLAGS_$(basetarget).o) $(HOSTCFLAGS_$(obj)) | 101 | host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(KBUILD_HOSTCFLAGS) -D"BUILD_STR(s)=\#s" $(HOSTCFLAGS_$(basetarget).o) $(HOSTCFLAGS_$(obj)) |
diff --git a/tools/build/Makefile b/tools/build/Makefile index 5edf65e684ab..727050c40f09 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile | |||
@@ -43,7 +43,7 @@ $(OUTPUT)fixdep-in.o: FORCE | |||
43 | $(Q)$(MAKE) $(build)=fixdep | 43 | $(Q)$(MAKE) $(build)=fixdep |
44 | 44 | ||
45 | $(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o | 45 | $(OUTPUT)fixdep: $(OUTPUT)fixdep-in.o |
46 | $(QUIET_LINK)$(HOSTCC) $(HOSTLDFLAGS) -o $@ $< | 46 | $(QUIET_LINK)$(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ $< |
47 | 47 | ||
48 | FORCE: | 48 | FORCE: |
49 | 49 | ||
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 5b6dda3b1ca8..f216b2f5c3d7 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature | |||
@@ -57,6 +57,7 @@ FEATURE_TESTS_BASIC := \ | |||
57 | libunwind-aarch64 \ | 57 | libunwind-aarch64 \ |
58 | pthread-attr-setaffinity-np \ | 58 | pthread-attr-setaffinity-np \ |
59 | pthread-barrier \ | 59 | pthread-barrier \ |
60 | reallocarray \ | ||
60 | stackprotector-all \ | 61 | stackprotector-all \ |
61 | timerfd \ | 62 | timerfd \ |
62 | libdw-dwarf-unwind \ | 63 | libdw-dwarf-unwind \ |
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index dac9563b5470..0516259be70f 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile | |||
@@ -14,6 +14,7 @@ FILES= \ | |||
14 | test-libaudit.bin \ | 14 | test-libaudit.bin \ |
15 | test-libbfd.bin \ | 15 | test-libbfd.bin \ |
16 | test-disassembler-four-args.bin \ | 16 | test-disassembler-four-args.bin \ |
17 | test-reallocarray.bin \ | ||
17 | test-liberty.bin \ | 18 | test-liberty.bin \ |
18 | test-liberty-z.bin \ | 19 | test-liberty-z.bin \ |
19 | test-cplus-demangle.bin \ | 20 | test-cplus-demangle.bin \ |
@@ -204,6 +205,9 @@ $(OUTPUT)test-libbfd.bin: | |||
204 | $(OUTPUT)test-disassembler-four-args.bin: | 205 | $(OUTPUT)test-disassembler-four-args.bin: |
205 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lopcodes | 206 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lopcodes |
206 | 207 | ||
208 | $(OUTPUT)test-reallocarray.bin: | ||
209 | $(BUILD) | ||
210 | |||
207 | $(OUTPUT)test-liberty.bin: | 211 | $(OUTPUT)test-liberty.bin: |
208 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty | 212 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty |
209 | 213 | ||
diff --git a/tools/build/feature/test-reallocarray.c b/tools/build/feature/test-reallocarray.c new file mode 100644 index 000000000000..8170de35150d --- /dev/null +++ b/tools/build/feature/test-reallocarray.c | |||
@@ -0,0 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #define _GNU_SOURCE | ||
3 | #include <stdlib.h> | ||
4 | |||
5 | int main(void) | ||
6 | { | ||
7 | return !!reallocarray(NULL, 1, 1); | ||
8 | } | ||
diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h index 70fe61295733..0d35f18006a1 100644 --- a/tools/include/linux/compiler-gcc.h +++ b/tools/include/linux/compiler-gcc.h | |||
@@ -36,3 +36,7 @@ | |||
36 | #endif | 36 | #endif |
37 | #define __printf(a, b) __attribute__((format(printf, a, b))) | 37 | #define __printf(a, b) __attribute__((format(printf, a, b))) |
38 | #define __scanf(a, b) __attribute__((format(scanf, a, b))) | 38 | #define __scanf(a, b) __attribute__((format(scanf, a, b))) |
39 | |||
40 | #if GCC_VERSION >= 50100 | ||
41 | #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 | ||
42 | #endif | ||
diff --git a/tools/include/linux/overflow.h b/tools/include/linux/overflow.h new file mode 100644 index 000000000000..8712ff70995f --- /dev/null +++ b/tools/include/linux/overflow.h | |||
@@ -0,0 +1,278 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 OR MIT */ | ||
2 | #ifndef __LINUX_OVERFLOW_H | ||
3 | #define __LINUX_OVERFLOW_H | ||
4 | |||
5 | #include <linux/compiler.h> | ||
6 | |||
7 | /* | ||
8 | * In the fallback code below, we need to compute the minimum and | ||
9 | * maximum values representable in a given type. These macros may also | ||
10 | * be useful elsewhere, so we provide them outside the | ||
11 | * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block. | ||
12 | * | ||
13 | * It would seem more obvious to do something like | ||
14 | * | ||
15 | * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0) | ||
16 | * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0) | ||
17 | * | ||
18 | * Unfortunately, the middle expressions, strictly speaking, have | ||
19 | * undefined behaviour, and at least some versions of gcc warn about | ||
20 | * the type_max expression (but not if -fsanitize=undefined is in | ||
21 | * effect; in that case, the warning is deferred to runtime...). | ||
22 | * | ||
23 | * The slightly excessive casting in type_min is to make sure the | ||
24 | * macros also produce sensible values for the exotic type _Bool. [The | ||
25 | * overflow checkers only almost work for _Bool, but that's | ||
26 | * a-feature-not-a-bug, since people shouldn't be doing arithmetic on | ||
27 | * _Bools. Besides, the gcc builtins don't allow _Bool* as third | ||
28 | * argument.] | ||
29 | * | ||
30 | * Idea stolen from | ||
31 | * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html - | ||
32 | * credit to Christian Biere. | ||
33 | */ | ||
34 | #define is_signed_type(type) (((type)(-1)) < (type)1) | ||
35 | #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) | ||
36 | #define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) | ||
37 | #define type_min(T) ((T)((T)-type_max(T)-(T)1)) | ||
38 | |||
39 | |||
40 | #ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW | ||
41 | /* | ||
42 | * For simplicity and code hygiene, the fallback code below insists on | ||
43 | * a, b and *d having the same type (similar to the min() and max() | ||
44 | * macros), whereas gcc's type-generic overflow checkers accept | ||
45 | * different types. Hence we don't just make check_add_overflow an | ||
46 | * alias for __builtin_add_overflow, but add type checks similar to | ||
47 | * below. | ||
48 | */ | ||
49 | #define check_add_overflow(a, b, d) ({ \ | ||
50 | typeof(a) __a = (a); \ | ||
51 | typeof(b) __b = (b); \ | ||
52 | typeof(d) __d = (d); \ | ||
53 | (void) (&__a == &__b); \ | ||
54 | (void) (&__a == __d); \ | ||
55 | __builtin_add_overflow(__a, __b, __d); \ | ||
56 | }) | ||
57 | |||
58 | #define check_sub_overflow(a, b, d) ({ \ | ||
59 | typeof(a) __a = (a); \ | ||
60 | typeof(b) __b = (b); \ | ||
61 | typeof(d) __d = (d); \ | ||
62 | (void) (&__a == &__b); \ | ||
63 | (void) (&__a == __d); \ | ||
64 | __builtin_sub_overflow(__a, __b, __d); \ | ||
65 | }) | ||
66 | |||
67 | #define check_mul_overflow(a, b, d) ({ \ | ||
68 | typeof(a) __a = (a); \ | ||
69 | typeof(b) __b = (b); \ | ||
70 | typeof(d) __d = (d); \ | ||
71 | (void) (&__a == &__b); \ | ||
72 | (void) (&__a == __d); \ | ||
73 | __builtin_mul_overflow(__a, __b, __d); \ | ||
74 | }) | ||
75 | |||
76 | #else | ||
77 | |||
78 | |||
79 | /* Checking for unsigned overflow is relatively easy without causing UB. */ | ||
80 | #define __unsigned_add_overflow(a, b, d) ({ \ | ||
81 | typeof(a) __a = (a); \ | ||
82 | typeof(b) __b = (b); \ | ||
83 | typeof(d) __d = (d); \ | ||
84 | (void) (&__a == &__b); \ | ||
85 | (void) (&__a == __d); \ | ||
86 | *__d = __a + __b; \ | ||
87 | *__d < __a; \ | ||
88 | }) | ||
89 | #define __unsigned_sub_overflow(a, b, d) ({ \ | ||
90 | typeof(a) __a = (a); \ | ||
91 | typeof(b) __b = (b); \ | ||
92 | typeof(d) __d = (d); \ | ||
93 | (void) (&__a == &__b); \ | ||
94 | (void) (&__a == __d); \ | ||
95 | *__d = __a - __b; \ | ||
96 | __a < __b; \ | ||
97 | }) | ||
98 | /* | ||
99 | * If one of a or b is a compile-time constant, this avoids a division. | ||
100 | */ | ||
101 | #define __unsigned_mul_overflow(a, b, d) ({ \ | ||
102 | typeof(a) __a = (a); \ | ||
103 | typeof(b) __b = (b); \ | ||
104 | typeof(d) __d = (d); \ | ||
105 | (void) (&__a == &__b); \ | ||
106 | (void) (&__a == __d); \ | ||
107 | *__d = __a * __b; \ | ||
108 | __builtin_constant_p(__b) ? \ | ||
109 | __b > 0 && __a > type_max(typeof(__a)) / __b : \ | ||
110 | __a > 0 && __b > type_max(typeof(__b)) / __a; \ | ||
111 | }) | ||
112 | |||
113 | /* | ||
114 | * For signed types, detecting overflow is much harder, especially if | ||
115 | * we want to avoid UB. But the interface of these macros is such that | ||
116 | * we must provide a result in *d, and in fact we must produce the | ||
117 | * result promised by gcc's builtins, which is simply the possibly | ||
118 | * wrapped-around value. Fortunately, we can just formally do the | ||
119 | * operations in the widest relevant unsigned type (u64) and then | ||
120 | * truncate the result - gcc is smart enough to generate the same code | ||
121 | * with and without the (u64) casts. | ||
122 | */ | ||
123 | |||
124 | /* | ||
125 | * Adding two signed integers can overflow only if they have the same | ||
126 | * sign, and overflow has happened iff the result has the opposite | ||
127 | * sign. | ||
128 | */ | ||
129 | #define __signed_add_overflow(a, b, d) ({ \ | ||
130 | typeof(a) __a = (a); \ | ||
131 | typeof(b) __b = (b); \ | ||
132 | typeof(d) __d = (d); \ | ||
133 | (void) (&__a == &__b); \ | ||
134 | (void) (&__a == __d); \ | ||
135 | *__d = (u64)__a + (u64)__b; \ | ||
136 | (((~(__a ^ __b)) & (*__d ^ __a)) \ | ||
137 | & type_min(typeof(__a))) != 0; \ | ||
138 | }) | ||
139 | |||
140 | /* | ||
141 | * Subtraction is similar, except that overflow can now happen only | ||
142 | * when the signs are opposite. In this case, overflow has happened if | ||
143 | * the result has the opposite sign of a. | ||
144 | */ | ||
145 | #define __signed_sub_overflow(a, b, d) ({ \ | ||
146 | typeof(a) __a = (a); \ | ||
147 | typeof(b) __b = (b); \ | ||
148 | typeof(d) __d = (d); \ | ||
149 | (void) (&__a == &__b); \ | ||
150 | (void) (&__a == __d); \ | ||
151 | *__d = (u64)__a - (u64)__b; \ | ||
152 | ((((__a ^ __b)) & (*__d ^ __a)) \ | ||
153 | & type_min(typeof(__a))) != 0; \ | ||
154 | }) | ||
155 | |||
156 | /* | ||
157 | * Signed multiplication is rather hard. gcc always follows C99, so | ||
158 | * division is truncated towards 0. This means that we can write the | ||
159 | * overflow check like this: | ||
160 | * | ||
161 | * (a > 0 && (b > MAX/a || b < MIN/a)) || | ||
162 | * (a < -1 && (b > MIN/a || b < MAX/a) || | ||
163 | * (a == -1 && b == MIN) | ||
164 | * | ||
165 | * The redundant casts of -1 are to silence an annoying -Wtype-limits | ||
166 | * (included in -Wextra) warning: When the type is u8 or u16, the | ||
167 | * __b_c_e in check_mul_overflow obviously selects | ||
168 | * __unsigned_mul_overflow, but unfortunately gcc still parses this | ||
169 | * code and warns about the limited range of __b. | ||
170 | */ | ||
171 | |||
172 | #define __signed_mul_overflow(a, b, d) ({ \ | ||
173 | typeof(a) __a = (a); \ | ||
174 | typeof(b) __b = (b); \ | ||
175 | typeof(d) __d = (d); \ | ||
176 | typeof(a) __tmax = type_max(typeof(a)); \ | ||
177 | typeof(a) __tmin = type_min(typeof(a)); \ | ||
178 | (void) (&__a == &__b); \ | ||
179 | (void) (&__a == __d); \ | ||
180 | *__d = (u64)__a * (u64)__b; \ | ||
181 | (__b > 0 && (__a > __tmax/__b || __a < __tmin/__b)) || \ | ||
182 | (__b < (typeof(__b))-1 && (__a > __tmin/__b || __a < __tmax/__b)) || \ | ||
183 | (__b == (typeof(__b))-1 && __a == __tmin); \ | ||
184 | }) | ||
185 | |||
186 | |||
187 | #define check_add_overflow(a, b, d) \ | ||
188 | __builtin_choose_expr(is_signed_type(typeof(a)), \ | ||
189 | __signed_add_overflow(a, b, d), \ | ||
190 | __unsigned_add_overflow(a, b, d)) | ||
191 | |||
192 | #define check_sub_overflow(a, b, d) \ | ||
193 | __builtin_choose_expr(is_signed_type(typeof(a)), \ | ||
194 | __signed_sub_overflow(a, b, d), \ | ||
195 | __unsigned_sub_overflow(a, b, d)) | ||
196 | |||
197 | #define check_mul_overflow(a, b, d) \ | ||
198 | __builtin_choose_expr(is_signed_type(typeof(a)), \ | ||
199 | __signed_mul_overflow(a, b, d), \ | ||
200 | __unsigned_mul_overflow(a, b, d)) | ||
201 | |||
202 | |||
203 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ | ||
204 | |||
205 | /** | ||
206 | * array_size() - Calculate size of 2-dimensional array. | ||
207 | * | ||
208 | * @a: dimension one | ||
209 | * @b: dimension two | ||
210 | * | ||
211 | * Calculates size of 2-dimensional array: @a * @b. | ||
212 | * | ||
213 | * Returns: number of bytes needed to represent the array or SIZE_MAX on | ||
214 | * overflow. | ||
215 | */ | ||
216 | static inline __must_check size_t array_size(size_t a, size_t b) | ||
217 | { | ||
218 | size_t bytes; | ||
219 | |||
220 | if (check_mul_overflow(a, b, &bytes)) | ||
221 | return SIZE_MAX; | ||
222 | |||
223 | return bytes; | ||
224 | } | ||
225 | |||
226 | /** | ||
227 | * array3_size() - Calculate size of 3-dimensional array. | ||
228 | * | ||
229 | * @a: dimension one | ||
230 | * @b: dimension two | ||
231 | * @c: dimension three | ||
232 | * | ||
233 | * Calculates size of 3-dimensional array: @a * @b * @c. | ||
234 | * | ||
235 | * Returns: number of bytes needed to represent the array or SIZE_MAX on | ||
236 | * overflow. | ||
237 | */ | ||
238 | static inline __must_check size_t array3_size(size_t a, size_t b, size_t c) | ||
239 | { | ||
240 | size_t bytes; | ||
241 | |||
242 | if (check_mul_overflow(a, b, &bytes)) | ||
243 | return SIZE_MAX; | ||
244 | if (check_mul_overflow(bytes, c, &bytes)) | ||
245 | return SIZE_MAX; | ||
246 | |||
247 | return bytes; | ||
248 | } | ||
249 | |||
250 | static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c) | ||
251 | { | ||
252 | size_t bytes; | ||
253 | |||
254 | if (check_mul_overflow(n, size, &bytes)) | ||
255 | return SIZE_MAX; | ||
256 | if (check_add_overflow(bytes, c, &bytes)) | ||
257 | return SIZE_MAX; | ||
258 | |||
259 | return bytes; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * struct_size() - Calculate size of structure with trailing array. | ||
264 | * @p: Pointer to the structure. | ||
265 | * @member: Name of the array member. | ||
266 | * @n: Number of elements in the array. | ||
267 | * | ||
268 | * Calculates size of memory needed for structure @p followed by an | ||
269 | * array of @n @member elements. | ||
270 | * | ||
271 | * Return: number of bytes needed or SIZE_MAX on overflow. | ||
272 | */ | ||
273 | #define struct_size(p, member, n) \ | ||
274 | __ab_c_size(n, \ | ||
275 | sizeof(*(p)->member) + __must_be_array((p)->member),\ | ||
276 | sizeof(*(p))) | ||
277 | |||
278 | #endif /* __LINUX_OVERFLOW_H */ | ||
diff --git a/tools/include/tools/libc_compat.h b/tools/include/tools/libc_compat.h new file mode 100644 index 000000000000..664ced8cb1b0 --- /dev/null +++ b/tools/include/tools/libc_compat.h | |||
@@ -0,0 +1,20 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* Copyright (C) 2018 Netronome Systems, Inc. */ | ||
3 | |||
4 | #ifndef __TOOLS_LIBC_COMPAT_H | ||
5 | #define __TOOLS_LIBC_COMPAT_H | ||
6 | |||
7 | #include <stdlib.h> | ||
8 | #include <linux/overflow.h> | ||
9 | |||
10 | #ifdef COMPAT_NEED_REALLOCARRAY | ||
11 | static inline void *reallocarray(void *ptr, size_t nmemb, size_t size) | ||
12 | { | ||
13 | size_t bytes; | ||
14 | |||
15 | if (unlikely(check_mul_overflow(nmemb, size, &bytes))) | ||
16 | return NULL; | ||
17 | return realloc(ptr, bytes); | ||
18 | } | ||
19 | #endif | ||
20 | #endif | ||
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h new file mode 100644 index 000000000000..42990676a55e --- /dev/null +++ b/tools/include/uapi/asm-generic/unistd.h | |||
@@ -0,0 +1,783 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
2 | #include <asm/bitsperlong.h> | ||
3 | |||
4 | /* | ||
5 | * This file contains the system call numbers, based on the | ||
6 | * layout of the x86-64 architecture, which embeds the | ||
7 | * pointer to the syscall in the table. | ||
8 | * | ||
9 | * As a basic principle, no duplication of functionality | ||
10 | * should be added, e.g. we don't use lseek when llseek | ||
11 | * is present. New architectures should use this file | ||
12 | * and implement the less feature-full calls in user space. | ||
13 | */ | ||
14 | |||
15 | #ifndef __SYSCALL | ||
16 | #define __SYSCALL(x, y) | ||
17 | #endif | ||
18 | |||
19 | #if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT) | ||
20 | #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32) | ||
21 | #else | ||
22 | #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64) | ||
23 | #endif | ||
24 | |||
25 | #ifdef __SYSCALL_COMPAT | ||
26 | #define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp) | ||
27 | #define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp) | ||
28 | #else | ||
29 | #define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys) | ||
30 | #define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64) | ||
31 | #endif | ||
32 | |||
33 | #define __NR_io_setup 0 | ||
34 | __SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup) | ||
35 | #define __NR_io_destroy 1 | ||
36 | __SYSCALL(__NR_io_destroy, sys_io_destroy) | ||
37 | #define __NR_io_submit 2 | ||
38 | __SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit) | ||
39 | #define __NR_io_cancel 3 | ||
40 | __SYSCALL(__NR_io_cancel, sys_io_cancel) | ||
41 | #define __NR_io_getevents 4 | ||
42 | __SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents) | ||
43 | |||
44 | /* fs/xattr.c */ | ||
45 | #define __NR_setxattr 5 | ||
46 | __SYSCALL(__NR_setxattr, sys_setxattr) | ||
47 | #define __NR_lsetxattr 6 | ||
48 | __SYSCALL(__NR_lsetxattr, sys_lsetxattr) | ||
49 | #define __NR_fsetxattr 7 | ||
50 | __SYSCALL(__NR_fsetxattr, sys_fsetxattr) | ||
51 | #define __NR_getxattr 8 | ||
52 | __SYSCALL(__NR_getxattr, sys_getxattr) | ||
53 | #define __NR_lgetxattr 9 | ||
54 | __SYSCALL(__NR_lgetxattr, sys_lgetxattr) | ||
55 | #define __NR_fgetxattr 10 | ||
56 | __SYSCALL(__NR_fgetxattr, sys_fgetxattr) | ||
57 | #define __NR_listxattr 11 | ||
58 | __SYSCALL(__NR_listxattr, sys_listxattr) | ||
59 | #define __NR_llistxattr 12 | ||
60 | __SYSCALL(__NR_llistxattr, sys_llistxattr) | ||
61 | #define __NR_flistxattr 13 | ||
62 | __SYSCALL(__NR_flistxattr, sys_flistxattr) | ||
63 | #define __NR_removexattr 14 | ||
64 | __SYSCALL(__NR_removexattr, sys_removexattr) | ||
65 | #define __NR_lremovexattr 15 | ||
66 | __SYSCALL(__NR_lremovexattr, sys_lremovexattr) | ||
67 | #define __NR_fremovexattr 16 | ||
68 | __SYSCALL(__NR_fremovexattr, sys_fremovexattr) | ||
69 | |||
70 | /* fs/dcache.c */ | ||
71 | #define __NR_getcwd 17 | ||
72 | __SYSCALL(__NR_getcwd, sys_getcwd) | ||
73 | |||
74 | /* fs/cookies.c */ | ||
75 | #define __NR_lookup_dcookie 18 | ||
76 | __SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie) | ||
77 | |||
78 | /* fs/eventfd.c */ | ||
79 | #define __NR_eventfd2 19 | ||
80 | __SYSCALL(__NR_eventfd2, sys_eventfd2) | ||
81 | |||
82 | /* fs/eventpoll.c */ | ||
83 | #define __NR_epoll_create1 20 | ||
84 | __SYSCALL(__NR_epoll_create1, sys_epoll_create1) | ||
85 | #define __NR_epoll_ctl 21 | ||
86 | __SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) | ||
87 | #define __NR_epoll_pwait 22 | ||
88 | __SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait) | ||
89 | |||
90 | /* fs/fcntl.c */ | ||
91 | #define __NR_dup 23 | ||
92 | __SYSCALL(__NR_dup, sys_dup) | ||
93 | #define __NR_dup3 24 | ||
94 | __SYSCALL(__NR_dup3, sys_dup3) | ||
95 | #define __NR3264_fcntl 25 | ||
96 | __SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64) | ||
97 | |||
98 | /* fs/inotify_user.c */ | ||
99 | #define __NR_inotify_init1 26 | ||
100 | __SYSCALL(__NR_inotify_init1, sys_inotify_init1) | ||
101 | #define __NR_inotify_add_watch 27 | ||
102 | __SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch) | ||
103 | #define __NR_inotify_rm_watch 28 | ||
104 | __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch) | ||
105 | |||
106 | /* fs/ioctl.c */ | ||
107 | #define __NR_ioctl 29 | ||
108 | __SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl) | ||
109 | |||
110 | /* fs/ioprio.c */ | ||
111 | #define __NR_ioprio_set 30 | ||
112 | __SYSCALL(__NR_ioprio_set, sys_ioprio_set) | ||
113 | #define __NR_ioprio_get 31 | ||
114 | __SYSCALL(__NR_ioprio_get, sys_ioprio_get) | ||
115 | |||
116 | /* fs/locks.c */ | ||
117 | #define __NR_flock 32 | ||
118 | __SYSCALL(__NR_flock, sys_flock) | ||
119 | |||
120 | /* fs/namei.c */ | ||
121 | #define __NR_mknodat 33 | ||
122 | __SYSCALL(__NR_mknodat, sys_mknodat) | ||
123 | #define __NR_mkdirat 34 | ||
124 | __SYSCALL(__NR_mkdirat, sys_mkdirat) | ||
125 | #define __NR_unlinkat 35 | ||
126 | __SYSCALL(__NR_unlinkat, sys_unlinkat) | ||
127 | #define __NR_symlinkat 36 | ||
128 | __SYSCALL(__NR_symlinkat, sys_symlinkat) | ||
129 | #define __NR_linkat 37 | ||
130 | __SYSCALL(__NR_linkat, sys_linkat) | ||
131 | #ifdef __ARCH_WANT_RENAMEAT | ||
132 | /* renameat is superseded with flags by renameat2 */ | ||
133 | #define __NR_renameat 38 | ||
134 | __SYSCALL(__NR_renameat, sys_renameat) | ||
135 | #endif /* __ARCH_WANT_RENAMEAT */ | ||
136 | |||
137 | /* fs/namespace.c */ | ||
138 | #define __NR_umount2 39 | ||
139 | __SYSCALL(__NR_umount2, sys_umount) | ||
140 | #define __NR_mount 40 | ||
141 | __SC_COMP(__NR_mount, sys_mount, compat_sys_mount) | ||
142 | #define __NR_pivot_root 41 | ||
143 | __SYSCALL(__NR_pivot_root, sys_pivot_root) | ||
144 | |||
145 | /* fs/nfsctl.c */ | ||
146 | #define __NR_nfsservctl 42 | ||
147 | __SYSCALL(__NR_nfsservctl, sys_ni_syscall) | ||
148 | |||
149 | /* fs/open.c */ | ||
150 | #define __NR3264_statfs 43 | ||
151 | __SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \ | ||
152 | compat_sys_statfs64) | ||
153 | #define __NR3264_fstatfs 44 | ||
154 | __SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \ | ||
155 | compat_sys_fstatfs64) | ||
156 | #define __NR3264_truncate 45 | ||
157 | __SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \ | ||
158 | compat_sys_truncate64) | ||
159 | #define __NR3264_ftruncate 46 | ||
160 | __SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \ | ||
161 | compat_sys_ftruncate64) | ||
162 | |||
163 | #define __NR_fallocate 47 | ||
164 | __SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate) | ||
165 | #define __NR_faccessat 48 | ||
166 | __SYSCALL(__NR_faccessat, sys_faccessat) | ||
167 | #define __NR_chdir 49 | ||
168 | __SYSCALL(__NR_chdir, sys_chdir) | ||
169 | #define __NR_fchdir 50 | ||
170 | __SYSCALL(__NR_fchdir, sys_fchdir) | ||
171 | #define __NR_chroot 51 | ||
172 | __SYSCALL(__NR_chroot, sys_chroot) | ||
173 | #define __NR_fchmod 52 | ||
174 | __SYSCALL(__NR_fchmod, sys_fchmod) | ||
175 | #define __NR_fchmodat 53 | ||
176 | __SYSCALL(__NR_fchmodat, sys_fchmodat) | ||
177 | #define __NR_fchownat 54 | ||
178 | __SYSCALL(__NR_fchownat, sys_fchownat) | ||
179 | #define __NR_fchown 55 | ||
180 | __SYSCALL(__NR_fchown, sys_fchown) | ||
181 | #define __NR_openat 56 | ||
182 | __SC_COMP(__NR_openat, sys_openat, compat_sys_openat) | ||
183 | #define __NR_close 57 | ||
184 | __SYSCALL(__NR_close, sys_close) | ||
185 | #define __NR_vhangup 58 | ||
186 | __SYSCALL(__NR_vhangup, sys_vhangup) | ||
187 | |||
188 | /* fs/pipe.c */ | ||
189 | #define __NR_pipe2 59 | ||
190 | __SYSCALL(__NR_pipe2, sys_pipe2) | ||
191 | |||
192 | /* fs/quota.c */ | ||
193 | #define __NR_quotactl 60 | ||
194 | __SYSCALL(__NR_quotactl, sys_quotactl) | ||
195 | |||
196 | /* fs/readdir.c */ | ||
197 | #define __NR_getdents64 61 | ||
198 | __SYSCALL(__NR_getdents64, sys_getdents64) | ||
199 | |||
200 | /* fs/read_write.c */ | ||
201 | #define __NR3264_lseek 62 | ||
202 | __SC_3264(__NR3264_lseek, sys_llseek, sys_lseek) | ||
203 | #define __NR_read 63 | ||
204 | __SYSCALL(__NR_read, sys_read) | ||
205 | #define __NR_write 64 | ||
206 | __SYSCALL(__NR_write, sys_write) | ||
207 | #define __NR_readv 65 | ||
208 | __SC_COMP(__NR_readv, sys_readv, compat_sys_readv) | ||
209 | #define __NR_writev 66 | ||
210 | __SC_COMP(__NR_writev, sys_writev, compat_sys_writev) | ||
211 | #define __NR_pread64 67 | ||
212 | __SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64) | ||
213 | #define __NR_pwrite64 68 | ||
214 | __SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64) | ||
215 | #define __NR_preadv 69 | ||
216 | __SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv) | ||
217 | #define __NR_pwritev 70 | ||
218 | __SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev) | ||
219 | |||
220 | /* fs/sendfile.c */ | ||
221 | #define __NR3264_sendfile 71 | ||
222 | __SYSCALL(__NR3264_sendfile, sys_sendfile64) | ||
223 | |||
224 | /* fs/select.c */ | ||
225 | #define __NR_pselect6 72 | ||
226 | __SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6) | ||
227 | #define __NR_ppoll 73 | ||
228 | __SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll) | ||
229 | |||
230 | /* fs/signalfd.c */ | ||
231 | #define __NR_signalfd4 74 | ||
232 | __SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4) | ||
233 | |||
234 | /* fs/splice.c */ | ||
235 | #define __NR_vmsplice 75 | ||
236 | __SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice) | ||
237 | #define __NR_splice 76 | ||
238 | __SYSCALL(__NR_splice, sys_splice) | ||
239 | #define __NR_tee 77 | ||
240 | __SYSCALL(__NR_tee, sys_tee) | ||
241 | |||
242 | /* fs/stat.c */ | ||
243 | #define __NR_readlinkat 78 | ||
244 | __SYSCALL(__NR_readlinkat, sys_readlinkat) | ||
245 | #define __NR3264_fstatat 79 | ||
246 | __SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat) | ||
247 | #define __NR3264_fstat 80 | ||
248 | __SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat) | ||
249 | |||
250 | /* fs/sync.c */ | ||
251 | #define __NR_sync 81 | ||
252 | __SYSCALL(__NR_sync, sys_sync) | ||
253 | #define __NR_fsync 82 | ||
254 | __SYSCALL(__NR_fsync, sys_fsync) | ||
255 | #define __NR_fdatasync 83 | ||
256 | __SYSCALL(__NR_fdatasync, sys_fdatasync) | ||
257 | #ifdef __ARCH_WANT_SYNC_FILE_RANGE2 | ||
258 | #define __NR_sync_file_range2 84 | ||
259 | __SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \ | ||
260 | compat_sys_sync_file_range2) | ||
261 | #else | ||
262 | #define __NR_sync_file_range 84 | ||
263 | __SC_COMP(__NR_sync_file_range, sys_sync_file_range, \ | ||
264 | compat_sys_sync_file_range) | ||
265 | #endif | ||
266 | |||
267 | /* fs/timerfd.c */ | ||
268 | #define __NR_timerfd_create 85 | ||
269 | __SYSCALL(__NR_timerfd_create, sys_timerfd_create) | ||
270 | #define __NR_timerfd_settime 86 | ||
271 | __SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \ | ||
272 | compat_sys_timerfd_settime) | ||
273 | #define __NR_timerfd_gettime 87 | ||
274 | __SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \ | ||
275 | compat_sys_timerfd_gettime) | ||
276 | |||
277 | /* fs/utimes.c */ | ||
278 | #define __NR_utimensat 88 | ||
279 | __SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat) | ||
280 | |||
281 | /* kernel/acct.c */ | ||
282 | #define __NR_acct 89 | ||
283 | __SYSCALL(__NR_acct, sys_acct) | ||
284 | |||
285 | /* kernel/capability.c */ | ||
286 | #define __NR_capget 90 | ||
287 | __SYSCALL(__NR_capget, sys_capget) | ||
288 | #define __NR_capset 91 | ||
289 | __SYSCALL(__NR_capset, sys_capset) | ||
290 | |||
291 | /* kernel/exec_domain.c */ | ||
292 | #define __NR_personality 92 | ||
293 | __SYSCALL(__NR_personality, sys_personality) | ||
294 | |||
295 | /* kernel/exit.c */ | ||
296 | #define __NR_exit 93 | ||
297 | __SYSCALL(__NR_exit, sys_exit) | ||
298 | #define __NR_exit_group 94 | ||
299 | __SYSCALL(__NR_exit_group, sys_exit_group) | ||
300 | #define __NR_waitid 95 | ||
301 | __SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid) | ||
302 | |||
303 | /* kernel/fork.c */ | ||
304 | #define __NR_set_tid_address 96 | ||
305 | __SYSCALL(__NR_set_tid_address, sys_set_tid_address) | ||
306 | #define __NR_unshare 97 | ||
307 | __SYSCALL(__NR_unshare, sys_unshare) | ||
308 | |||
309 | /* kernel/futex.c */ | ||
310 | #define __NR_futex 98 | ||
311 | __SC_COMP(__NR_futex, sys_futex, compat_sys_futex) | ||
312 | #define __NR_set_robust_list 99 | ||
313 | __SC_COMP(__NR_set_robust_list, sys_set_robust_list, \ | ||
314 | compat_sys_set_robust_list) | ||
315 | #define __NR_get_robust_list 100 | ||
316 | __SC_COMP(__NR_get_robust_list, sys_get_robust_list, \ | ||
317 | compat_sys_get_robust_list) | ||
318 | |||
319 | /* kernel/hrtimer.c */ | ||
320 | #define __NR_nanosleep 101 | ||
321 | __SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep) | ||
322 | |||
323 | /* kernel/itimer.c */ | ||
324 | #define __NR_getitimer 102 | ||
325 | __SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer) | ||
326 | #define __NR_setitimer 103 | ||
327 | __SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer) | ||
328 | |||
329 | /* kernel/kexec.c */ | ||
330 | #define __NR_kexec_load 104 | ||
331 | __SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load) | ||
332 | |||
333 | /* kernel/module.c */ | ||
334 | #define __NR_init_module 105 | ||
335 | __SYSCALL(__NR_init_module, sys_init_module) | ||
336 | #define __NR_delete_module 106 | ||
337 | __SYSCALL(__NR_delete_module, sys_delete_module) | ||
338 | |||
339 | /* kernel/posix-timers.c */ | ||
340 | #define __NR_timer_create 107 | ||
341 | __SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create) | ||
342 | #define __NR_timer_gettime 108 | ||
343 | __SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime) | ||
344 | #define __NR_timer_getoverrun 109 | ||
345 | __SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun) | ||
346 | #define __NR_timer_settime 110 | ||
347 | __SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime) | ||
348 | #define __NR_timer_delete 111 | ||
349 | __SYSCALL(__NR_timer_delete, sys_timer_delete) | ||
350 | #define __NR_clock_settime 112 | ||
351 | __SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime) | ||
352 | #define __NR_clock_gettime 113 | ||
353 | __SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime) | ||
354 | #define __NR_clock_getres 114 | ||
355 | __SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres) | ||
356 | #define __NR_clock_nanosleep 115 | ||
357 | __SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \ | ||
358 | compat_sys_clock_nanosleep) | ||
359 | |||
360 | /* kernel/printk.c */ | ||
361 | #define __NR_syslog 116 | ||
362 | __SYSCALL(__NR_syslog, sys_syslog) | ||
363 | |||
364 | /* kernel/ptrace.c */ | ||
365 | #define __NR_ptrace 117 | ||
366 | __SYSCALL(__NR_ptrace, sys_ptrace) | ||
367 | |||
368 | /* kernel/sched/core.c */ | ||
369 | #define __NR_sched_setparam 118 | ||
370 | __SYSCALL(__NR_sched_setparam, sys_sched_setparam) | ||
371 | #define __NR_sched_setscheduler 119 | ||
372 | __SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler) | ||
373 | #define __NR_sched_getscheduler 120 | ||
374 | __SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler) | ||
375 | #define __NR_sched_getparam 121 | ||
376 | __SYSCALL(__NR_sched_getparam, sys_sched_getparam) | ||
377 | #define __NR_sched_setaffinity 122 | ||
378 | __SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \ | ||
379 | compat_sys_sched_setaffinity) | ||
380 | #define __NR_sched_getaffinity 123 | ||
381 | __SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \ | ||
382 | compat_sys_sched_getaffinity) | ||
383 | #define __NR_sched_yield 124 | ||
384 | __SYSCALL(__NR_sched_yield, sys_sched_yield) | ||
385 | #define __NR_sched_get_priority_max 125 | ||
386 | __SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max) | ||
387 | #define __NR_sched_get_priority_min 126 | ||
388 | __SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min) | ||
389 | #define __NR_sched_rr_get_interval 127 | ||
390 | __SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \ | ||
391 | compat_sys_sched_rr_get_interval) | ||
392 | |||
393 | /* kernel/signal.c */ | ||
394 | #define __NR_restart_syscall 128 | ||
395 | __SYSCALL(__NR_restart_syscall, sys_restart_syscall) | ||
396 | #define __NR_kill 129 | ||
397 | __SYSCALL(__NR_kill, sys_kill) | ||
398 | #define __NR_tkill 130 | ||
399 | __SYSCALL(__NR_tkill, sys_tkill) | ||
400 | #define __NR_tgkill 131 | ||
401 | __SYSCALL(__NR_tgkill, sys_tgkill) | ||
402 | #define __NR_sigaltstack 132 | ||
403 | __SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack) | ||
404 | #define __NR_rt_sigsuspend 133 | ||
405 | __SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend) | ||
406 | #define __NR_rt_sigaction 134 | ||
407 | __SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction) | ||
408 | #define __NR_rt_sigprocmask 135 | ||
409 | __SC_COMP(__NR_rt_sigprocmask, sys_rt_sigprocmask, compat_sys_rt_sigprocmask) | ||
410 | #define __NR_rt_sigpending 136 | ||
411 | __SC_COMP(__NR_rt_sigpending, sys_rt_sigpending, compat_sys_rt_sigpending) | ||
412 | #define __NR_rt_sigtimedwait 137 | ||
413 | __SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \ | ||
414 | compat_sys_rt_sigtimedwait) | ||
415 | #define __NR_rt_sigqueueinfo 138 | ||
416 | __SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \ | ||
417 | compat_sys_rt_sigqueueinfo) | ||
418 | #define __NR_rt_sigreturn 139 | ||
419 | __SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn) | ||
420 | |||
421 | /* kernel/sys.c */ | ||
422 | #define __NR_setpriority 140 | ||
423 | __SYSCALL(__NR_setpriority, sys_setpriority) | ||
424 | #define __NR_getpriority 141 | ||
425 | __SYSCALL(__NR_getpriority, sys_getpriority) | ||
426 | #define __NR_reboot 142 | ||
427 | __SYSCALL(__NR_reboot, sys_reboot) | ||
428 | #define __NR_setregid 143 | ||
429 | __SYSCALL(__NR_setregid, sys_setregid) | ||
430 | #define __NR_setgid 144 | ||
431 | __SYSCALL(__NR_setgid, sys_setgid) | ||
432 | #define __NR_setreuid 145 | ||
433 | __SYSCALL(__NR_setreuid, sys_setreuid) | ||
434 | #define __NR_setuid 146 | ||
435 | __SYSCALL(__NR_setuid, sys_setuid) | ||
436 | #define __NR_setresuid 147 | ||
437 | __SYSCALL(__NR_setresuid, sys_setresuid) | ||
438 | #define __NR_getresuid 148 | ||
439 | __SYSCALL(__NR_getresuid, sys_getresuid) | ||
440 | #define __NR_setresgid 149 | ||
441 | __SYSCALL(__NR_setresgid, sys_setresgid) | ||
442 | #define __NR_getresgid 150 | ||
443 | __SYSCALL(__NR_getresgid, sys_getresgid) | ||
444 | #define __NR_setfsuid 151 | ||
445 | __SYSCALL(__NR_setfsuid, sys_setfsuid) | ||
446 | #define __NR_setfsgid 152 | ||
447 | __SYSCALL(__NR_setfsgid, sys_setfsgid) | ||
448 | #define __NR_times 153 | ||
449 | __SC_COMP(__NR_times, sys_times, compat_sys_times) | ||
450 | #define __NR_setpgid 154 | ||
451 | __SYSCALL(__NR_setpgid, sys_setpgid) | ||
452 | #define __NR_getpgid 155 | ||
453 | __SYSCALL(__NR_getpgid, sys_getpgid) | ||
454 | #define __NR_getsid 156 | ||
455 | __SYSCALL(__NR_getsid, sys_getsid) | ||
456 | #define __NR_setsid 157 | ||
457 | __SYSCALL(__NR_setsid, sys_setsid) | ||
458 | #define __NR_getgroups 158 | ||
459 | __SYSCALL(__NR_getgroups, sys_getgroups) | ||
460 | #define __NR_setgroups 159 | ||
461 | __SYSCALL(__NR_setgroups, sys_setgroups) | ||
462 | #define __NR_uname 160 | ||
463 | __SYSCALL(__NR_uname, sys_newuname) | ||
464 | #define __NR_sethostname 161 | ||
465 | __SYSCALL(__NR_sethostname, sys_sethostname) | ||
466 | #define __NR_setdomainname 162 | ||
467 | __SYSCALL(__NR_setdomainname, sys_setdomainname) | ||
468 | #define __NR_getrlimit 163 | ||
469 | __SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit) | ||
470 | #define __NR_setrlimit 164 | ||
471 | __SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit) | ||
472 | #define __NR_getrusage 165 | ||
473 | __SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage) | ||
474 | #define __NR_umask 166 | ||
475 | __SYSCALL(__NR_umask, sys_umask) | ||
476 | #define __NR_prctl 167 | ||
477 | __SYSCALL(__NR_prctl, sys_prctl) | ||
478 | #define __NR_getcpu 168 | ||
479 | __SYSCALL(__NR_getcpu, sys_getcpu) | ||
480 | |||
481 | /* kernel/time.c */ | ||
482 | #define __NR_gettimeofday 169 | ||
483 | __SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday) | ||
484 | #define __NR_settimeofday 170 | ||
485 | __SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday) | ||
486 | #define __NR_adjtimex 171 | ||
487 | __SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex) | ||
488 | |||
489 | /* kernel/timer.c */ | ||
490 | #define __NR_getpid 172 | ||
491 | __SYSCALL(__NR_getpid, sys_getpid) | ||
492 | #define __NR_getppid 173 | ||
493 | __SYSCALL(__NR_getppid, sys_getppid) | ||
494 | #define __NR_getuid 174 | ||
495 | __SYSCALL(__NR_getuid, sys_getuid) | ||
496 | #define __NR_geteuid 175 | ||
497 | __SYSCALL(__NR_geteuid, sys_geteuid) | ||
498 | #define __NR_getgid 176 | ||
499 | __SYSCALL(__NR_getgid, sys_getgid) | ||
500 | #define __NR_getegid 177 | ||
501 | __SYSCALL(__NR_getegid, sys_getegid) | ||
502 | #define __NR_gettid 178 | ||
503 | __SYSCALL(__NR_gettid, sys_gettid) | ||
504 | #define __NR_sysinfo 179 | ||
505 | __SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo) | ||
506 | |||
507 | /* ipc/mqueue.c */ | ||
508 | #define __NR_mq_open 180 | ||
509 | __SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open) | ||
510 | #define __NR_mq_unlink 181 | ||
511 | __SYSCALL(__NR_mq_unlink, sys_mq_unlink) | ||
512 | #define __NR_mq_timedsend 182 | ||
513 | __SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend) | ||
514 | #define __NR_mq_timedreceive 183 | ||
515 | __SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \ | ||
516 | compat_sys_mq_timedreceive) | ||
517 | #define __NR_mq_notify 184 | ||
518 | __SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify) | ||
519 | #define __NR_mq_getsetattr 185 | ||
520 | __SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr) | ||
521 | |||
522 | /* ipc/msg.c */ | ||
523 | #define __NR_msgget 186 | ||
524 | __SYSCALL(__NR_msgget, sys_msgget) | ||
525 | #define __NR_msgctl 187 | ||
526 | __SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl) | ||
527 | #define __NR_msgrcv 188 | ||
528 | __SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv) | ||
529 | #define __NR_msgsnd 189 | ||
530 | __SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd) | ||
531 | |||
532 | /* ipc/sem.c */ | ||
533 | #define __NR_semget 190 | ||
534 | __SYSCALL(__NR_semget, sys_semget) | ||
535 | #define __NR_semctl 191 | ||
536 | __SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl) | ||
537 | #define __NR_semtimedop 192 | ||
538 | __SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop) | ||
539 | #define __NR_semop 193 | ||
540 | __SYSCALL(__NR_semop, sys_semop) | ||
541 | |||
542 | /* ipc/shm.c */ | ||
543 | #define __NR_shmget 194 | ||
544 | __SYSCALL(__NR_shmget, sys_shmget) | ||
545 | #define __NR_shmctl 195 | ||
546 | __SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl) | ||
547 | #define __NR_shmat 196 | ||
548 | __SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat) | ||
549 | #define __NR_shmdt 197 | ||
550 | __SYSCALL(__NR_shmdt, sys_shmdt) | ||
551 | |||
552 | /* net/socket.c */ | ||
553 | #define __NR_socket 198 | ||
554 | __SYSCALL(__NR_socket, sys_socket) | ||
555 | #define __NR_socketpair 199 | ||
556 | __SYSCALL(__NR_socketpair, sys_socketpair) | ||
557 | #define __NR_bind 200 | ||
558 | __SYSCALL(__NR_bind, sys_bind) | ||
559 | #define __NR_listen 201 | ||
560 | __SYSCALL(__NR_listen, sys_listen) | ||
561 | #define __NR_accept 202 | ||
562 | __SYSCALL(__NR_accept, sys_accept) | ||
563 | #define __NR_connect 203 | ||
564 | __SYSCALL(__NR_connect, sys_connect) | ||
565 | #define __NR_getsockname 204 | ||
566 | __SYSCALL(__NR_getsockname, sys_getsockname) | ||
567 | #define __NR_getpeername 205 | ||
568 | __SYSCALL(__NR_getpeername, sys_getpeername) | ||
569 | #define __NR_sendto 206 | ||
570 | __SYSCALL(__NR_sendto, sys_sendto) | ||
571 | #define __NR_recvfrom 207 | ||
572 | __SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom) | ||
573 | #define __NR_setsockopt 208 | ||
574 | __SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt) | ||
575 | #define __NR_getsockopt 209 | ||
576 | __SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt) | ||
577 | #define __NR_shutdown 210 | ||
578 | __SYSCALL(__NR_shutdown, sys_shutdown) | ||
579 | #define __NR_sendmsg 211 | ||
580 | __SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg) | ||
581 | #define __NR_recvmsg 212 | ||
582 | __SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg) | ||
583 | |||
584 | /* mm/filemap.c */ | ||
585 | #define __NR_readahead 213 | ||
586 | __SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead) | ||
587 | |||
588 | /* mm/nommu.c, also with MMU */ | ||
589 | #define __NR_brk 214 | ||
590 | __SYSCALL(__NR_brk, sys_brk) | ||
591 | #define __NR_munmap 215 | ||
592 | __SYSCALL(__NR_munmap, sys_munmap) | ||
593 | #define __NR_mremap 216 | ||
594 | __SYSCALL(__NR_mremap, sys_mremap) | ||
595 | |||
596 | /* security/keys/keyctl.c */ | ||
597 | #define __NR_add_key 217 | ||
598 | __SYSCALL(__NR_add_key, sys_add_key) | ||
599 | #define __NR_request_key 218 | ||
600 | __SYSCALL(__NR_request_key, sys_request_key) | ||
601 | #define __NR_keyctl 219 | ||
602 | __SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl) | ||
603 | |||
604 | /* arch/example/kernel/sys_example.c */ | ||
605 | #define __NR_clone 220 | ||
606 | __SYSCALL(__NR_clone, sys_clone) | ||
607 | #define __NR_execve 221 | ||
608 | __SC_COMP(__NR_execve, sys_execve, compat_sys_execve) | ||
609 | |||
610 | #define __NR3264_mmap 222 | ||
611 | __SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap) | ||
612 | /* mm/fadvise.c */ | ||
613 | #define __NR3264_fadvise64 223 | ||
614 | __SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64) | ||
615 | |||
616 | /* mm/, CONFIG_MMU only */ | ||
617 | #ifndef __ARCH_NOMMU | ||
618 | #define __NR_swapon 224 | ||
619 | __SYSCALL(__NR_swapon, sys_swapon) | ||
620 | #define __NR_swapoff 225 | ||
621 | __SYSCALL(__NR_swapoff, sys_swapoff) | ||
622 | #define __NR_mprotect 226 | ||
623 | __SYSCALL(__NR_mprotect, sys_mprotect) | ||
624 | #define __NR_msync 227 | ||
625 | __SYSCALL(__NR_msync, sys_msync) | ||
626 | #define __NR_mlock 228 | ||
627 | __SYSCALL(__NR_mlock, sys_mlock) | ||
628 | #define __NR_munlock 229 | ||
629 | __SYSCALL(__NR_munlock, sys_munlock) | ||
630 | #define __NR_mlockall 230 | ||
631 | __SYSCALL(__NR_mlockall, sys_mlockall) | ||
632 | #define __NR_munlockall 231 | ||
633 | __SYSCALL(__NR_munlockall, sys_munlockall) | ||
634 | #define __NR_mincore 232 | ||
635 | __SYSCALL(__NR_mincore, sys_mincore) | ||
636 | #define __NR_madvise 233 | ||
637 | __SYSCALL(__NR_madvise, sys_madvise) | ||
638 | #define __NR_remap_file_pages 234 | ||
639 | __SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) | ||
640 | #define __NR_mbind 235 | ||
641 | __SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind) | ||
642 | #define __NR_get_mempolicy 236 | ||
643 | __SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy) | ||
644 | #define __NR_set_mempolicy 237 | ||
645 | __SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy) | ||
646 | #define __NR_migrate_pages 238 | ||
647 | __SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages) | ||
648 | #define __NR_move_pages 239 | ||
649 | __SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages) | ||
650 | #endif | ||
651 | |||
652 | #define __NR_rt_tgsigqueueinfo 240 | ||
653 | __SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \ | ||
654 | compat_sys_rt_tgsigqueueinfo) | ||
655 | #define __NR_perf_event_open 241 | ||
656 | __SYSCALL(__NR_perf_event_open, sys_perf_event_open) | ||
657 | #define __NR_accept4 242 | ||
658 | __SYSCALL(__NR_accept4, sys_accept4) | ||
659 | #define __NR_recvmmsg 243 | ||
660 | __SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg) | ||
661 | |||
662 | /* | ||
663 | * Architectures may provide up to 16 syscalls of their own | ||
664 | * starting with this value. | ||
665 | */ | ||
666 | #define __NR_arch_specific_syscall 244 | ||
667 | |||
668 | #define __NR_wait4 260 | ||
669 | __SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4) | ||
670 | #define __NR_prlimit64 261 | ||
671 | __SYSCALL(__NR_prlimit64, sys_prlimit64) | ||
672 | #define __NR_fanotify_init 262 | ||
673 | __SYSCALL(__NR_fanotify_init, sys_fanotify_init) | ||
674 | #define __NR_fanotify_mark 263 | ||
675 | __SYSCALL(__NR_fanotify_mark, sys_fanotify_mark) | ||
676 | #define __NR_name_to_handle_at 264 | ||
677 | __SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at) | ||
678 | #define __NR_open_by_handle_at 265 | ||
679 | __SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \ | ||
680 | compat_sys_open_by_handle_at) | ||
681 | #define __NR_clock_adjtime 266 | ||
682 | __SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime) | ||
683 | #define __NR_syncfs 267 | ||
684 | __SYSCALL(__NR_syncfs, sys_syncfs) | ||
685 | #define __NR_setns 268 | ||
686 | __SYSCALL(__NR_setns, sys_setns) | ||
687 | #define __NR_sendmmsg 269 | ||
688 | __SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg) | ||
689 | #define __NR_process_vm_readv 270 | ||
690 | __SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \ | ||
691 | compat_sys_process_vm_readv) | ||
692 | #define __NR_process_vm_writev 271 | ||
693 | __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \ | ||
694 | compat_sys_process_vm_writev) | ||
695 | #define __NR_kcmp 272 | ||
696 | __SYSCALL(__NR_kcmp, sys_kcmp) | ||
697 | #define __NR_finit_module 273 | ||
698 | __SYSCALL(__NR_finit_module, sys_finit_module) | ||
699 | #define __NR_sched_setattr 274 | ||
700 | __SYSCALL(__NR_sched_setattr, sys_sched_setattr) | ||
701 | #define __NR_sched_getattr 275 | ||
702 | __SYSCALL(__NR_sched_getattr, sys_sched_getattr) | ||
703 | #define __NR_renameat2 276 | ||
704 | __SYSCALL(__NR_renameat2, sys_renameat2) | ||
705 | #define __NR_seccomp 277 | ||
706 | __SYSCALL(__NR_seccomp, sys_seccomp) | ||
707 | #define __NR_getrandom 278 | ||
708 | __SYSCALL(__NR_getrandom, sys_getrandom) | ||
709 | #define __NR_memfd_create 279 | ||
710 | __SYSCALL(__NR_memfd_create, sys_memfd_create) | ||
711 | #define __NR_bpf 280 | ||
712 | __SYSCALL(__NR_bpf, sys_bpf) | ||
713 | #define __NR_execveat 281 | ||
714 | __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat) | ||
715 | #define __NR_userfaultfd 282 | ||
716 | __SYSCALL(__NR_userfaultfd, sys_userfaultfd) | ||
717 | #define __NR_membarrier 283 | ||
718 | __SYSCALL(__NR_membarrier, sys_membarrier) | ||
719 | #define __NR_mlock2 284 | ||
720 | __SYSCALL(__NR_mlock2, sys_mlock2) | ||
721 | #define __NR_copy_file_range 285 | ||
722 | __SYSCALL(__NR_copy_file_range, sys_copy_file_range) | ||
723 | #define __NR_preadv2 286 | ||
724 | __SC_COMP(__NR_preadv2, sys_preadv2, compat_sys_preadv2) | ||
725 | #define __NR_pwritev2 287 | ||
726 | __SC_COMP(__NR_pwritev2, sys_pwritev2, compat_sys_pwritev2) | ||
727 | #define __NR_pkey_mprotect 288 | ||
728 | __SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect) | ||
729 | #define __NR_pkey_alloc 289 | ||
730 | __SYSCALL(__NR_pkey_alloc, sys_pkey_alloc) | ||
731 | #define __NR_pkey_free 290 | ||
732 | __SYSCALL(__NR_pkey_free, sys_pkey_free) | ||
733 | #define __NR_statx 291 | ||
734 | __SYSCALL(__NR_statx, sys_statx) | ||
735 | #define __NR_io_pgetevents 292 | ||
736 | __SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents) | ||
737 | |||
738 | #undef __NR_syscalls | ||
739 | #define __NR_syscalls 293 | ||
740 | |||
741 | /* | ||
742 | * 32 bit systems traditionally used different | ||
743 | * syscalls for off_t and loff_t arguments, while | ||
744 | * 64 bit systems only need the off_t version. | ||
745 | * For new 32 bit platforms, there is no need to | ||
746 | * implement the old 32 bit off_t syscalls, so | ||
747 | * they take different names. | ||
748 | * Here we map the numbers so that both versions | ||
749 | * use the same syscall table layout. | ||
750 | */ | ||
751 | #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT) | ||
752 | #define __NR_fcntl __NR3264_fcntl | ||
753 | #define __NR_statfs __NR3264_statfs | ||
754 | #define __NR_fstatfs __NR3264_fstatfs | ||
755 | #define __NR_truncate __NR3264_truncate | ||
756 | #define __NR_ftruncate __NR3264_ftruncate | ||
757 | #define __NR_lseek __NR3264_lseek | ||
758 | #define __NR_sendfile __NR3264_sendfile | ||
759 | #define __NR_newfstatat __NR3264_fstatat | ||
760 | #define __NR_fstat __NR3264_fstat | ||
761 | #define __NR_mmap __NR3264_mmap | ||
762 | #define __NR_fadvise64 __NR3264_fadvise64 | ||
763 | #ifdef __NR3264_stat | ||
764 | #define __NR_stat __NR3264_stat | ||
765 | #define __NR_lstat __NR3264_lstat | ||
766 | #endif | ||
767 | #else | ||
768 | #define __NR_fcntl64 __NR3264_fcntl | ||
769 | #define __NR_statfs64 __NR3264_statfs | ||
770 | #define __NR_fstatfs64 __NR3264_fstatfs | ||
771 | #define __NR_truncate64 __NR3264_truncate | ||
772 | #define __NR_ftruncate64 __NR3264_ftruncate | ||
773 | #define __NR_llseek __NR3264_lseek | ||
774 | #define __NR_sendfile64 __NR3264_sendfile | ||
775 | #define __NR_fstatat64 __NR3264_fstatat | ||
776 | #define __NR_fstat64 __NR3264_fstat | ||
777 | #define __NR_mmap2 __NR3264_mmap | ||
778 | #define __NR_fadvise64_64 __NR3264_fadvise64 | ||
779 | #ifdef __NR3264_stat | ||
780 | #define __NR_stat64 __NR3264_stat | ||
781 | #define __NR_lstat64 __NR3264_lstat | ||
782 | #endif | ||
783 | #endif | ||
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index b7db3261c62d..66917a4eba27 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
@@ -75,6 +75,11 @@ struct bpf_lpm_trie_key { | |||
75 | __u8 data[0]; /* Arbitrary size */ | 75 | __u8 data[0]; /* Arbitrary size */ |
76 | }; | 76 | }; |
77 | 77 | ||
78 | struct bpf_cgroup_storage_key { | ||
79 | __u64 cgroup_inode_id; /* cgroup inode id */ | ||
80 | __u32 attach_type; /* program attach type */ | ||
81 | }; | ||
82 | |||
78 | /* BPF syscall commands, see bpf(2) man-page for details. */ | 83 | /* BPF syscall commands, see bpf(2) man-page for details. */ |
79 | enum bpf_cmd { | 84 | enum bpf_cmd { |
80 | BPF_MAP_CREATE, | 85 | BPF_MAP_CREATE, |
@@ -120,6 +125,8 @@ enum bpf_map_type { | |||
120 | BPF_MAP_TYPE_CPUMAP, | 125 | BPF_MAP_TYPE_CPUMAP, |
121 | BPF_MAP_TYPE_XSKMAP, | 126 | BPF_MAP_TYPE_XSKMAP, |
122 | BPF_MAP_TYPE_SOCKHASH, | 127 | BPF_MAP_TYPE_SOCKHASH, |
128 | BPF_MAP_TYPE_CGROUP_STORAGE, | ||
129 | BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, | ||
123 | }; | 130 | }; |
124 | 131 | ||
125 | enum bpf_prog_type { | 132 | enum bpf_prog_type { |
@@ -144,6 +151,7 @@ enum bpf_prog_type { | |||
144 | BPF_PROG_TYPE_CGROUP_SOCK_ADDR, | 151 | BPF_PROG_TYPE_CGROUP_SOCK_ADDR, |
145 | BPF_PROG_TYPE_LWT_SEG6LOCAL, | 152 | BPF_PROG_TYPE_LWT_SEG6LOCAL, |
146 | BPF_PROG_TYPE_LIRC_MODE2, | 153 | BPF_PROG_TYPE_LIRC_MODE2, |
154 | BPF_PROG_TYPE_SK_REUSEPORT, | ||
147 | }; | 155 | }; |
148 | 156 | ||
149 | enum bpf_attach_type { | 157 | enum bpf_attach_type { |
@@ -1371,6 +1379,20 @@ union bpf_attr { | |||
1371 | * A 8-byte long non-decreasing number on success, or 0 if the | 1379 | * A 8-byte long non-decreasing number on success, or 0 if the |
1372 | * socket field is missing inside *skb*. | 1380 | * socket field is missing inside *skb*. |
1373 | * | 1381 | * |
1382 | * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx) | ||
1383 | * Description | ||
1384 | * Equivalent to bpf_get_socket_cookie() helper that accepts | ||
1385 | * *skb*, but gets socket from **struct bpf_sock_addr** contex. | ||
1386 | * Return | ||
1387 | * A 8-byte long non-decreasing number. | ||
1388 | * | ||
1389 | * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx) | ||
1390 | * Description | ||
1391 | * Equivalent to bpf_get_socket_cookie() helper that accepts | ||
1392 | * *skb*, but gets socket from **struct bpf_sock_ops** contex. | ||
1393 | * Return | ||
1394 | * A 8-byte long non-decreasing number. | ||
1395 | * | ||
1374 | * u32 bpf_get_socket_uid(struct sk_buff *skb) | 1396 | * u32 bpf_get_socket_uid(struct sk_buff *skb) |
1375 | * Return | 1397 | * Return |
1376 | * The owner UID of the socket associated to *skb*. If the socket | 1398 | * The owner UID of the socket associated to *skb*. If the socket |
@@ -1826,7 +1848,7 @@ union bpf_attr { | |||
1826 | * A non-negative value equal to or less than *size* on success, | 1848 | * A non-negative value equal to or less than *size* on success, |
1827 | * or a negative error in case of failure. | 1849 | * or a negative error in case of failure. |
1828 | * | 1850 | * |
1829 | * int skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header) | 1851 | * int bpf_skb_load_bytes_relative(const struct sk_buff *skb, u32 offset, void *to, u32 len, u32 start_header) |
1830 | * Description | 1852 | * Description |
1831 | * This helper is similar to **bpf_skb_load_bytes**\ () in that | 1853 | * This helper is similar to **bpf_skb_load_bytes**\ () in that |
1832 | * it provides an easy way to load *len* bytes from *offset* | 1854 | * it provides an easy way to load *len* bytes from *offset* |
@@ -1877,7 +1899,7 @@ union bpf_attr { | |||
1877 | * * < 0 if any input argument is invalid | 1899 | * * < 0 if any input argument is invalid |
1878 | * * 0 on success (packet is forwarded, nexthop neighbor exists) | 1900 | * * 0 on success (packet is forwarded, nexthop neighbor exists) |
1879 | * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the | 1901 | * * > 0 one of **BPF_FIB_LKUP_RET_** codes explaining why the |
1880 | * * packet is not forwarded or needs assist from full stack | 1902 | * packet is not forwarded or needs assist from full stack |
1881 | * | 1903 | * |
1882 | * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags) | 1904 | * int bpf_sock_hash_update(struct bpf_sock_ops_kern *skops, struct bpf_map *map, void *key, u64 flags) |
1883 | * Description | 1905 | * Description |
@@ -2033,7 +2055,6 @@ union bpf_attr { | |||
2033 | * This helper is only available is the kernel was compiled with | 2055 | * This helper is only available is the kernel was compiled with |
2034 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to | 2056 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to |
2035 | * "**y**". | 2057 | * "**y**". |
2036 | * | ||
2037 | * Return | 2058 | * Return |
2038 | * 0 | 2059 | * 0 |
2039 | * | 2060 | * |
@@ -2053,7 +2074,6 @@ union bpf_attr { | |||
2053 | * This helper is only available is the kernel was compiled with | 2074 | * This helper is only available is the kernel was compiled with |
2054 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to | 2075 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to |
2055 | * "**y**". | 2076 | * "**y**". |
2056 | * | ||
2057 | * Return | 2077 | * Return |
2058 | * 0 | 2078 | * 0 |
2059 | * | 2079 | * |
@@ -2073,10 +2093,54 @@ union bpf_attr { | |||
2073 | * Return | 2093 | * Return |
2074 | * The id is returned or 0 in case the id could not be retrieved. | 2094 | * The id is returned or 0 in case the id could not be retrieved. |
2075 | * | 2095 | * |
2096 | * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level) | ||
2097 | * Description | ||
2098 | * Return id of cgroup v2 that is ancestor of cgroup associated | ||
2099 | * with the *skb* at the *ancestor_level*. The root cgroup is at | ||
2100 | * *ancestor_level* zero and each step down the hierarchy | ||
2101 | * increments the level. If *ancestor_level* == level of cgroup | ||
2102 | * associated with *skb*, then return value will be same as that | ||
2103 | * of **bpf_skb_cgroup_id**\ (). | ||
2104 | * | ||
2105 | * The helper is useful to implement policies based on cgroups | ||
2106 | * that are upper in hierarchy than immediate cgroup associated | ||
2107 | * with *skb*. | ||
2108 | * | ||
2109 | * The format of returned id and helper limitations are same as in | ||
2110 | * **bpf_skb_cgroup_id**\ (). | ||
2111 | * Return | ||
2112 | * The id is returned or 0 in case the id could not be retrieved. | ||
2113 | * | ||
2076 | * u64 bpf_get_current_cgroup_id(void) | 2114 | * u64 bpf_get_current_cgroup_id(void) |
2077 | * Return | 2115 | * Return |
2078 | * A 64-bit integer containing the current cgroup id based | 2116 | * A 64-bit integer containing the current cgroup id based |
2079 | * on the cgroup within which the current task is running. | 2117 | * on the cgroup within which the current task is running. |
2118 | * | ||
2119 | * void* get_local_storage(void *map, u64 flags) | ||
2120 | * Description | ||
2121 | * Get the pointer to the local storage area. | ||
2122 | * The type and the size of the local storage is defined | ||
2123 | * by the *map* argument. | ||
2124 | * The *flags* meaning is specific for each map type, | ||
2125 | * and has to be 0 for cgroup local storage. | ||
2126 | * | ||
2127 | * Depending on the bpf program type, a local storage area | ||
2128 | * can be shared between multiple instances of the bpf program, | ||
2129 | * running simultaneously. | ||
2130 | * | ||
2131 | * A user should care about the synchronization by himself. | ||
2132 | * For example, by using the BPF_STX_XADD instruction to alter | ||
2133 | * the shared data. | ||
2134 | * Return | ||
2135 | * Pointer to the local storage area. | ||
2136 | * | ||
2137 | * int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags) | ||
2138 | * Description | ||
2139 | * Select a SO_REUSEPORT sk from a BPF_MAP_TYPE_REUSEPORT_ARRAY map | ||
2140 | * It checks the selected sk is matching the incoming | ||
2141 | * request in the skb. | ||
2142 | * Return | ||
2143 | * 0 on success, or a negative error in case of failure. | ||
2080 | */ | 2144 | */ |
2081 | #define __BPF_FUNC_MAPPER(FN) \ | 2145 | #define __BPF_FUNC_MAPPER(FN) \ |
2082 | FN(unspec), \ | 2146 | FN(unspec), \ |
@@ -2159,7 +2223,10 @@ union bpf_attr { | |||
2159 | FN(rc_repeat), \ | 2223 | FN(rc_repeat), \ |
2160 | FN(rc_keydown), \ | 2224 | FN(rc_keydown), \ |
2161 | FN(skb_cgroup_id), \ | 2225 | FN(skb_cgroup_id), \ |
2162 | FN(get_current_cgroup_id), | 2226 | FN(get_current_cgroup_id), \ |
2227 | FN(get_local_storage), \ | ||
2228 | FN(sk_select_reuseport), \ | ||
2229 | FN(skb_ancestor_cgroup_id), | ||
2163 | 2230 | ||
2164 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 2231 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
2165 | * function eBPF program intends to call | 2232 | * function eBPF program intends to call |
@@ -2376,6 +2443,30 @@ struct sk_msg_md { | |||
2376 | __u32 local_port; /* stored in host byte order */ | 2443 | __u32 local_port; /* stored in host byte order */ |
2377 | }; | 2444 | }; |
2378 | 2445 | ||
2446 | struct sk_reuseport_md { | ||
2447 | /* | ||
2448 | * Start of directly accessible data. It begins from | ||
2449 | * the tcp/udp header. | ||
2450 | */ | ||
2451 | void *data; | ||
2452 | void *data_end; /* End of directly accessible data */ | ||
2453 | /* | ||
2454 | * Total length of packet (starting from the tcp/udp header). | ||
2455 | * Note that the directly accessible bytes (data_end - data) | ||
2456 | * could be less than this "len". Those bytes could be | ||
2457 | * indirectly read by a helper "bpf_skb_load_bytes()". | ||
2458 | */ | ||
2459 | __u32 len; | ||
2460 | /* | ||
2461 | * Eth protocol in the mac header (network byte order). e.g. | ||
2462 | * ETH_P_IP(0x0800) and ETH_P_IPV6(0x86DD) | ||
2463 | */ | ||
2464 | __u32 eth_protocol; | ||
2465 | __u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */ | ||
2466 | __u32 bind_inany; /* Is sock bound to an INANY address? */ | ||
2467 | __u32 hash; /* A hash of the packet 4 tuples */ | ||
2468 | }; | ||
2469 | |||
2379 | #define BPF_TAG_SIZE 8 | 2470 | #define BPF_TAG_SIZE 8 |
2380 | 2471 | ||
2381 | struct bpf_prog_info { | 2472 | struct bpf_prog_info { |
@@ -2557,6 +2648,9 @@ enum { | |||
2557 | * Arg1: old_state | 2648 | * Arg1: old_state |
2558 | * Arg2: new_state | 2649 | * Arg2: new_state |
2559 | */ | 2650 | */ |
2651 | BPF_SOCK_OPS_TCP_LISTEN_CB, /* Called on listen(2), right after | ||
2652 | * socket transition to LISTEN state. | ||
2653 | */ | ||
2560 | }; | 2654 | }; |
2561 | 2655 | ||
2562 | /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect | 2656 | /* List of TCP states. There is a build check in net/ipv4/tcp.c to detect |
diff --git a/tools/include/uapi/linux/in.h b/tools/include/uapi/linux/in.h new file mode 100644 index 000000000000..48e8a225b985 --- /dev/null +++ b/tools/include/uapi/linux/in.h | |||
@@ -0,0 +1,301 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ | ||
2 | /* | ||
3 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
4 | * operating system. INET is implemented using the BSD Socket | ||
5 | * interface as the means of communication with the user level. | ||
6 | * | ||
7 | * Definitions of the Internet Protocol. | ||
8 | * | ||
9 | * Version: @(#)in.h 1.0.1 04/21/93 | ||
10 | * | ||
11 | * Authors: Original taken from the GNU Project <netinet/in.h> file. | ||
12 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version | ||
17 | * 2 of the License, or (at your option) any later version. | ||
18 | */ | ||
19 | #ifndef _UAPI_LINUX_IN_H | ||
20 | #define _UAPI_LINUX_IN_H | ||
21 | |||
22 | #include <linux/types.h> | ||
23 | #include <linux/libc-compat.h> | ||
24 | #include <linux/socket.h> | ||
25 | |||
26 | #if __UAPI_DEF_IN_IPPROTO | ||
27 | /* Standard well-defined IP protocols. */ | ||
28 | enum { | ||
29 | IPPROTO_IP = 0, /* Dummy protocol for TCP */ | ||
30 | #define IPPROTO_IP IPPROTO_IP | ||
31 | IPPROTO_ICMP = 1, /* Internet Control Message Protocol */ | ||
32 | #define IPPROTO_ICMP IPPROTO_ICMP | ||
33 | IPPROTO_IGMP = 2, /* Internet Group Management Protocol */ | ||
34 | #define IPPROTO_IGMP IPPROTO_IGMP | ||
35 | IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */ | ||
36 | #define IPPROTO_IPIP IPPROTO_IPIP | ||
37 | IPPROTO_TCP = 6, /* Transmission Control Protocol */ | ||
38 | #define IPPROTO_TCP IPPROTO_TCP | ||
39 | IPPROTO_EGP = 8, /* Exterior Gateway Protocol */ | ||
40 | #define IPPROTO_EGP IPPROTO_EGP | ||
41 | IPPROTO_PUP = 12, /* PUP protocol */ | ||
42 | #define IPPROTO_PUP IPPROTO_PUP | ||
43 | IPPROTO_UDP = 17, /* User Datagram Protocol */ | ||
44 | #define IPPROTO_UDP IPPROTO_UDP | ||
45 | IPPROTO_IDP = 22, /* XNS IDP protocol */ | ||
46 | #define IPPROTO_IDP IPPROTO_IDP | ||
47 | IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */ | ||
48 | #define IPPROTO_TP IPPROTO_TP | ||
49 | IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */ | ||
50 | #define IPPROTO_DCCP IPPROTO_DCCP | ||
51 | IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */ | ||
52 | #define IPPROTO_IPV6 IPPROTO_IPV6 | ||
53 | IPPROTO_RSVP = 46, /* RSVP Protocol */ | ||
54 | #define IPPROTO_RSVP IPPROTO_RSVP | ||
55 | IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */ | ||
56 | #define IPPROTO_GRE IPPROTO_GRE | ||
57 | IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */ | ||
58 | #define IPPROTO_ESP IPPROTO_ESP | ||
59 | IPPROTO_AH = 51, /* Authentication Header protocol */ | ||
60 | #define IPPROTO_AH IPPROTO_AH | ||
61 | IPPROTO_MTP = 92, /* Multicast Transport Protocol */ | ||
62 | #define IPPROTO_MTP IPPROTO_MTP | ||
63 | IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ | ||
64 | #define IPPROTO_BEETPH IPPROTO_BEETPH | ||
65 | IPPROTO_ENCAP = 98, /* Encapsulation Header */ | ||
66 | #define IPPROTO_ENCAP IPPROTO_ENCAP | ||
67 | IPPROTO_PIM = 103, /* Protocol Independent Multicast */ | ||
68 | #define IPPROTO_PIM IPPROTO_PIM | ||
69 | IPPROTO_COMP = 108, /* Compression Header Protocol */ | ||
70 | #define IPPROTO_COMP IPPROTO_COMP | ||
71 | IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */ | ||
72 | #define IPPROTO_SCTP IPPROTO_SCTP | ||
73 | IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */ | ||
74 | #define IPPROTO_UDPLITE IPPROTO_UDPLITE | ||
75 | IPPROTO_MPLS = 137, /* MPLS in IP (RFC 4023) */ | ||
76 | #define IPPROTO_MPLS IPPROTO_MPLS | ||
77 | IPPROTO_RAW = 255, /* Raw IP packets */ | ||
78 | #define IPPROTO_RAW IPPROTO_RAW | ||
79 | IPPROTO_MAX | ||
80 | }; | ||
81 | #endif | ||
82 | |||
83 | #if __UAPI_DEF_IN_ADDR | ||
84 | /* Internet address. */ | ||
85 | struct in_addr { | ||
86 | __be32 s_addr; | ||
87 | }; | ||
88 | #endif | ||
89 | |||
90 | #define IP_TOS 1 | ||
91 | #define IP_TTL 2 | ||
92 | #define IP_HDRINCL 3 | ||
93 | #define IP_OPTIONS 4 | ||
94 | #define IP_ROUTER_ALERT 5 | ||
95 | #define IP_RECVOPTS 6 | ||
96 | #define IP_RETOPTS 7 | ||
97 | #define IP_PKTINFO 8 | ||
98 | #define IP_PKTOPTIONS 9 | ||
99 | #define IP_MTU_DISCOVER 10 | ||
100 | #define IP_RECVERR 11 | ||
101 | #define IP_RECVTTL 12 | ||
102 | #define IP_RECVTOS 13 | ||
103 | #define IP_MTU 14 | ||
104 | #define IP_FREEBIND 15 | ||
105 | #define IP_IPSEC_POLICY 16 | ||
106 | #define IP_XFRM_POLICY 17 | ||
107 | #define IP_PASSSEC 18 | ||
108 | #define IP_TRANSPARENT 19 | ||
109 | |||
110 | /* BSD compatibility */ | ||
111 | #define IP_RECVRETOPTS IP_RETOPTS | ||
112 | |||
113 | /* TProxy original addresses */ | ||
114 | #define IP_ORIGDSTADDR 20 | ||
115 | #define IP_RECVORIGDSTADDR IP_ORIGDSTADDR | ||
116 | |||
117 | #define IP_MINTTL 21 | ||
118 | #define IP_NODEFRAG 22 | ||
119 | #define IP_CHECKSUM 23 | ||
120 | #define IP_BIND_ADDRESS_NO_PORT 24 | ||
121 | #define IP_RECVFRAGSIZE 25 | ||
122 | |||
123 | /* IP_MTU_DISCOVER values */ | ||
124 | #define IP_PMTUDISC_DONT 0 /* Never send DF frames */ | ||
125 | #define IP_PMTUDISC_WANT 1 /* Use per route hints */ | ||
126 | #define IP_PMTUDISC_DO 2 /* Always DF */ | ||
127 | #define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */ | ||
128 | /* Always use interface mtu (ignores dst pmtu) but don't set DF flag. | ||
129 | * Also incoming ICMP frag_needed notifications will be ignored on | ||
130 | * this socket to prevent accepting spoofed ones. | ||
131 | */ | ||
132 | #define IP_PMTUDISC_INTERFACE 4 | ||
133 | /* weaker version of IP_PMTUDISC_INTERFACE, which allos packets to get | ||
134 | * fragmented if they exeed the interface mtu | ||
135 | */ | ||
136 | #define IP_PMTUDISC_OMIT 5 | ||
137 | |||
138 | #define IP_MULTICAST_IF 32 | ||
139 | #define IP_MULTICAST_TTL 33 | ||
140 | #define IP_MULTICAST_LOOP 34 | ||
141 | #define IP_ADD_MEMBERSHIP 35 | ||
142 | #define IP_DROP_MEMBERSHIP 36 | ||
143 | #define IP_UNBLOCK_SOURCE 37 | ||
144 | #define IP_BLOCK_SOURCE 38 | ||
145 | #define IP_ADD_SOURCE_MEMBERSHIP 39 | ||
146 | #define IP_DROP_SOURCE_MEMBERSHIP 40 | ||
147 | #define IP_MSFILTER 41 | ||
148 | #define MCAST_JOIN_GROUP 42 | ||
149 | #define MCAST_BLOCK_SOURCE 43 | ||
150 | #define MCAST_UNBLOCK_SOURCE 44 | ||
151 | #define MCAST_LEAVE_GROUP 45 | ||
152 | #define MCAST_JOIN_SOURCE_GROUP 46 | ||
153 | #define MCAST_LEAVE_SOURCE_GROUP 47 | ||
154 | #define MCAST_MSFILTER 48 | ||
155 | #define IP_MULTICAST_ALL 49 | ||
156 | #define IP_UNICAST_IF 50 | ||
157 | |||
158 | #define MCAST_EXCLUDE 0 | ||
159 | #define MCAST_INCLUDE 1 | ||
160 | |||
161 | /* These need to appear somewhere around here */ | ||
162 | #define IP_DEFAULT_MULTICAST_TTL 1 | ||
163 | #define IP_DEFAULT_MULTICAST_LOOP 1 | ||
164 | |||
165 | /* Request struct for multicast socket ops */ | ||
166 | |||
167 | #if __UAPI_DEF_IP_MREQ | ||
168 | struct ip_mreq { | ||
169 | struct in_addr imr_multiaddr; /* IP multicast address of group */ | ||
170 | struct in_addr imr_interface; /* local IP address of interface */ | ||
171 | }; | ||
172 | |||
173 | struct ip_mreqn { | ||
174 | struct in_addr imr_multiaddr; /* IP multicast address of group */ | ||
175 | struct in_addr imr_address; /* local IP address of interface */ | ||
176 | int imr_ifindex; /* Interface index */ | ||
177 | }; | ||
178 | |||
179 | struct ip_mreq_source { | ||
180 | __be32 imr_multiaddr; | ||
181 | __be32 imr_interface; | ||
182 | __be32 imr_sourceaddr; | ||
183 | }; | ||
184 | |||
185 | struct ip_msfilter { | ||
186 | __be32 imsf_multiaddr; | ||
187 | __be32 imsf_interface; | ||
188 | __u32 imsf_fmode; | ||
189 | __u32 imsf_numsrc; | ||
190 | __be32 imsf_slist[1]; | ||
191 | }; | ||
192 | |||
193 | #define IP_MSFILTER_SIZE(numsrc) \ | ||
194 | (sizeof(struct ip_msfilter) - sizeof(__u32) \ | ||
195 | + (numsrc) * sizeof(__u32)) | ||
196 | |||
197 | struct group_req { | ||
198 | __u32 gr_interface; /* interface index */ | ||
199 | struct __kernel_sockaddr_storage gr_group; /* group address */ | ||
200 | }; | ||
201 | |||
202 | struct group_source_req { | ||
203 | __u32 gsr_interface; /* interface index */ | ||
204 | struct __kernel_sockaddr_storage gsr_group; /* group address */ | ||
205 | struct __kernel_sockaddr_storage gsr_source; /* source address */ | ||
206 | }; | ||
207 | |||
208 | struct group_filter { | ||
209 | __u32 gf_interface; /* interface index */ | ||
210 | struct __kernel_sockaddr_storage gf_group; /* multicast address */ | ||
211 | __u32 gf_fmode; /* filter mode */ | ||
212 | __u32 gf_numsrc; /* number of sources */ | ||
213 | struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */ | ||
214 | }; | ||
215 | |||
216 | #define GROUP_FILTER_SIZE(numsrc) \ | ||
217 | (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \ | ||
218 | + (numsrc) * sizeof(struct __kernel_sockaddr_storage)) | ||
219 | #endif | ||
220 | |||
221 | #if __UAPI_DEF_IN_PKTINFO | ||
222 | struct in_pktinfo { | ||
223 | int ipi_ifindex; | ||
224 | struct in_addr ipi_spec_dst; | ||
225 | struct in_addr ipi_addr; | ||
226 | }; | ||
227 | #endif | ||
228 | |||
229 | /* Structure describing an Internet (IP) socket address. */ | ||
230 | #if __UAPI_DEF_SOCKADDR_IN | ||
231 | #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ | ||
232 | struct sockaddr_in { | ||
233 | __kernel_sa_family_t sin_family; /* Address family */ | ||
234 | __be16 sin_port; /* Port number */ | ||
235 | struct in_addr sin_addr; /* Internet address */ | ||
236 | |||
237 | /* Pad to size of `struct sockaddr'. */ | ||
238 | unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - | ||
239 | sizeof(unsigned short int) - sizeof(struct in_addr)]; | ||
240 | }; | ||
241 | #define sin_zero __pad /* for BSD UNIX comp. -FvK */ | ||
242 | #endif | ||
243 | |||
244 | #if __UAPI_DEF_IN_CLASS | ||
245 | /* | ||
246 | * Definitions of the bits in an Internet address integer. | ||
247 | * On subnets, host and network parts are found according | ||
248 | * to the subnet mask, not these masks. | ||
249 | */ | ||
250 | #define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0) | ||
251 | #define IN_CLASSA_NET 0xff000000 | ||
252 | #define IN_CLASSA_NSHIFT 24 | ||
253 | #define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) | ||
254 | #define IN_CLASSA_MAX 128 | ||
255 | |||
256 | #define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000) | ||
257 | #define IN_CLASSB_NET 0xffff0000 | ||
258 | #define IN_CLASSB_NSHIFT 16 | ||
259 | #define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) | ||
260 | #define IN_CLASSB_MAX 65536 | ||
261 | |||
262 | #define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000) | ||
263 | #define IN_CLASSC_NET 0xffffff00 | ||
264 | #define IN_CLASSC_NSHIFT 8 | ||
265 | #define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) | ||
266 | |||
267 | #define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) | ||
268 | #define IN_MULTICAST(a) IN_CLASSD(a) | ||
269 | #define IN_MULTICAST_NET 0xF0000000 | ||
270 | |||
271 | #define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) | ||
272 | #define IN_BADCLASS(a) IN_EXPERIMENTAL((a)) | ||
273 | |||
274 | /* Address to accept any incoming messages. */ | ||
275 | #define INADDR_ANY ((unsigned long int) 0x00000000) | ||
276 | |||
277 | /* Address to send to all hosts. */ | ||
278 | #define INADDR_BROADCAST ((unsigned long int) 0xffffffff) | ||
279 | |||
280 | /* Address indicating an error return. */ | ||
281 | #define INADDR_NONE ((unsigned long int) 0xffffffff) | ||
282 | |||
283 | /* Network number for local host loopback. */ | ||
284 | #define IN_LOOPBACKNET 127 | ||
285 | |||
286 | /* Address to loopback in software to local host. */ | ||
287 | #define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ | ||
288 | #define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000) | ||
289 | |||
290 | /* Defines for Multicast INADDR */ | ||
291 | #define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */ | ||
292 | #define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */ | ||
293 | #define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */ | ||
294 | #define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */ | ||
295 | #endif | ||
296 | |||
297 | /* <asm/byteorder.h> contains the htonl type stuff.. */ | ||
298 | #include <asm/byteorder.h> | ||
299 | |||
300 | |||
301 | #endif /* _UAPI_LINUX_IN_H */ | ||
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build index 6070e655042d..13a861135127 100644 --- a/tools/lib/bpf/Build +++ b/tools/lib/bpf/Build | |||
@@ -1 +1 @@ | |||
libbpf-y := libbpf.o bpf.o nlattr.o btf.o | libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o | ||
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 5390e7725e43..d49902e818b5 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile | |||
@@ -66,7 +66,7 @@ ifndef VERBOSE | |||
66 | endif | 66 | endif |
67 | 67 | ||
68 | FEATURE_USER = .libbpf | 68 | FEATURE_USER = .libbpf |
69 | FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf | 69 | FEATURE_TESTS = libelf libelf-mmap bpf reallocarray |
70 | FEATURE_DISPLAY = libelf bpf | 70 | FEATURE_DISPLAY = libelf bpf |
71 | 71 | ||
72 | INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi -I$(srctree)/tools/perf | 72 | INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi -I$(srctree)/tools/perf |
@@ -116,8 +116,8 @@ ifeq ($(feature-libelf-mmap), 1) | |||
116 | override CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT | 116 | override CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT |
117 | endif | 117 | endif |
118 | 118 | ||
119 | ifeq ($(feature-libelf-getphdrnum), 1) | 119 | ifeq ($(feature-reallocarray), 0) |
120 | override CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT | 120 | override CFLAGS += -DCOMPAT_NEED_REALLOCARRAY |
121 | endif | 121 | endif |
122 | 122 | ||
123 | # Append required CFLAGS | 123 | # Append required CFLAGS |
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 9ddc89dae962..60aa4ca8b2c5 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c | |||
@@ -92,6 +92,7 @@ int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr) | |||
92 | attr.btf_key_type_id = create_attr->btf_key_type_id; | 92 | attr.btf_key_type_id = create_attr->btf_key_type_id; |
93 | attr.btf_value_type_id = create_attr->btf_value_type_id; | 93 | attr.btf_value_type_id = create_attr->btf_value_type_id; |
94 | attr.map_ifindex = create_attr->map_ifindex; | 94 | attr.map_ifindex = create_attr->map_ifindex; |
95 | attr.inner_map_fd = create_attr->inner_map_fd; | ||
95 | 96 | ||
96 | return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); | 97 | return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); |
97 | } | 98 | } |
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 0639a30a457d..6f38164b2618 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h | |||
@@ -39,6 +39,7 @@ struct bpf_create_map_attr { | |||
39 | __u32 btf_key_type_id; | 39 | __u32 btf_key_type_id; |
40 | __u32 btf_value_type_id; | 40 | __u32 btf_value_type_id; |
41 | __u32 map_ifindex; | 41 | __u32 map_ifindex; |
42 | __u32 inner_map_fd; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr); | 45 | int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr); |
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index c36a3a76986a..cf94b0770522 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c | |||
@@ -16,6 +16,11 @@ | |||
16 | 16 | ||
17 | #define BTF_MAX_NR_TYPES 65535 | 17 | #define BTF_MAX_NR_TYPES 65535 |
18 | 18 | ||
19 | #define IS_MODIFIER(k) (((k) == BTF_KIND_TYPEDEF) || \ | ||
20 | ((k) == BTF_KIND_VOLATILE) || \ | ||
21 | ((k) == BTF_KIND_CONST) || \ | ||
22 | ((k) == BTF_KIND_RESTRICT)) | ||
23 | |||
19 | static struct btf_type btf_void; | 24 | static struct btf_type btf_void; |
20 | 25 | ||
21 | struct btf { | 26 | struct btf { |
@@ -32,14 +37,6 @@ struct btf { | |||
32 | int fd; | 37 | int fd; |
33 | }; | 38 | }; |
34 | 39 | ||
35 | static const char *btf_name_by_offset(const struct btf *btf, __u32 offset) | ||
36 | { | ||
37 | if (offset < btf->hdr->str_len) | ||
38 | return &btf->strings[offset]; | ||
39 | else | ||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | static int btf_add_type(struct btf *btf, struct btf_type *t) | 40 | static int btf_add_type(struct btf *btf, struct btf_type *t) |
44 | { | 41 | { |
45 | if (btf->types_size - btf->nr_types < 2) { | 42 | if (btf->types_size - btf->nr_types < 2) { |
@@ -269,6 +266,26 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) | |||
269 | return nelems * size; | 266 | return nelems * size; |
270 | } | 267 | } |
271 | 268 | ||
269 | int btf__resolve_type(const struct btf *btf, __u32 type_id) | ||
270 | { | ||
271 | const struct btf_type *t; | ||
272 | int depth = 0; | ||
273 | |||
274 | t = btf__type_by_id(btf, type_id); | ||
275 | while (depth < MAX_RESOLVE_DEPTH && | ||
276 | !btf_type_is_void_or_null(t) && | ||
277 | IS_MODIFIER(BTF_INFO_KIND(t->info))) { | ||
278 | type_id = t->type; | ||
279 | t = btf__type_by_id(btf, type_id); | ||
280 | depth++; | ||
281 | } | ||
282 | |||
283 | if (depth == MAX_RESOLVE_DEPTH || btf_type_is_void_or_null(t)) | ||
284 | return -EINVAL; | ||
285 | |||
286 | return type_id; | ||
287 | } | ||
288 | |||
272 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name) | 289 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name) |
273 | { | 290 | { |
274 | __u32 i; | 291 | __u32 i; |
@@ -278,7 +295,7 @@ __s32 btf__find_by_name(const struct btf *btf, const char *type_name) | |||
278 | 295 | ||
279 | for (i = 1; i <= btf->nr_types; i++) { | 296 | for (i = 1; i <= btf->nr_types; i++) { |
280 | const struct btf_type *t = btf->types[i]; | 297 | const struct btf_type *t = btf->types[i]; |
281 | const char *name = btf_name_by_offset(btf, t->name_off); | 298 | const char *name = btf__name_by_offset(btf, t->name_off); |
282 | 299 | ||
283 | if (name && !strcmp(type_name, name)) | 300 | if (name && !strcmp(type_name, name)) |
284 | return i; | 301 | return i; |
@@ -368,3 +385,11 @@ int btf__fd(const struct btf *btf) | |||
368 | { | 385 | { |
369 | return btf->fd; | 386 | return btf->fd; |
370 | } | 387 | } |
388 | |||
389 | const char *btf__name_by_offset(const struct btf *btf, __u32 offset) | ||
390 | { | ||
391 | if (offset < btf->hdr->str_len) | ||
392 | return &btf->strings[offset]; | ||
393 | else | ||
394 | return NULL; | ||
395 | } | ||
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index caac3a404dc5..4897e0724d4e 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h | |||
@@ -19,6 +19,8 @@ struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); | |||
19 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name); | 19 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name); |
20 | const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); | 20 | const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); |
21 | __s64 btf__resolve_size(const struct btf *btf, __u32 type_id); | 21 | __s64 btf__resolve_size(const struct btf *btf, __u32 type_id); |
22 | int btf__resolve_type(const struct btf *btf, __u32 type_id); | ||
22 | int btf__fd(const struct btf *btf); | 23 | int btf__fd(const struct btf *btf); |
24 | const char *btf__name_by_offset(const struct btf *btf, __u32 offset); | ||
23 | 25 | ||
24 | #endif | 26 | #endif |
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 1aafdbe827fe..2abd0f112627 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -22,6 +22,7 @@ | |||
22 | * License along with this program; if not, see <http://www.gnu.org/licenses> | 22 | * License along with this program; if not, see <http://www.gnu.org/licenses> |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define _GNU_SOURCE | ||
25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
26 | #include <stdio.h> | 27 | #include <stdio.h> |
27 | #include <stdarg.h> | 28 | #include <stdarg.h> |
@@ -42,6 +43,7 @@ | |||
42 | #include <sys/stat.h> | 43 | #include <sys/stat.h> |
43 | #include <sys/types.h> | 44 | #include <sys/types.h> |
44 | #include <sys/vfs.h> | 45 | #include <sys/vfs.h> |
46 | #include <tools/libc_compat.h> | ||
45 | #include <libelf.h> | 47 | #include <libelf.h> |
46 | #include <gelf.h> | 48 | #include <gelf.h> |
47 | 49 | ||
@@ -96,54 +98,6 @@ void libbpf_set_print(libbpf_print_fn_t warn, | |||
96 | 98 | ||
97 | #define STRERR_BUFSIZE 128 | 99 | #define STRERR_BUFSIZE 128 |
98 | 100 | ||
99 | #define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START) | ||
100 | #define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c) | ||
101 | #define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START) | ||
102 | |||
103 | static const char *libbpf_strerror_table[NR_ERRNO] = { | ||
104 | [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf", | ||
105 | [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid", | ||
106 | [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost", | ||
107 | [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch", | ||
108 | [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf", | ||
109 | [ERRCODE_OFFSET(RELOC)] = "Relocation failed", | ||
110 | [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading", | ||
111 | [ERRCODE_OFFSET(PROG2BIG)] = "Program too big", | ||
112 | [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version", | ||
113 | [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type", | ||
114 | [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message", | ||
115 | [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence", | ||
116 | }; | ||
117 | |||
118 | int libbpf_strerror(int err, char *buf, size_t size) | ||
119 | { | ||
120 | if (!buf || !size) | ||
121 | return -1; | ||
122 | |||
123 | err = err > 0 ? err : -err; | ||
124 | |||
125 | if (err < __LIBBPF_ERRNO__START) { | ||
126 | int ret; | ||
127 | |||
128 | ret = strerror_r(err, buf, size); | ||
129 | buf[size - 1] = '\0'; | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | if (err < __LIBBPF_ERRNO__END) { | ||
134 | const char *msg; | ||
135 | |||
136 | msg = libbpf_strerror_table[ERRNO_OFFSET(err)]; | ||
137 | snprintf(buf, size, "%s", msg); | ||
138 | buf[size - 1] = '\0'; | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | snprintf(buf, size, "Unknown libbpf error %d", err); | ||
143 | buf[size - 1] = '\0'; | ||
144 | return -1; | ||
145 | } | ||
146 | |||
147 | #define CHECK_ERR(action, err, out) do { \ | 101 | #define CHECK_ERR(action, err, out) do { \ |
148 | err = action; \ | 102 | err = action; \ |
149 | if (err) \ | 103 | if (err) \ |
@@ -235,6 +189,7 @@ struct bpf_object { | |||
235 | size_t nr_maps; | 189 | size_t nr_maps; |
236 | 190 | ||
237 | bool loaded; | 191 | bool loaded; |
192 | bool has_pseudo_calls; | ||
238 | 193 | ||
239 | /* | 194 | /* |
240 | * Information when doing elf related work. Only valid if fd | 195 | * Information when doing elf related work. Only valid if fd |
@@ -369,7 +324,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size, | |||
369 | progs = obj->programs; | 324 | progs = obj->programs; |
370 | nr_progs = obj->nr_programs; | 325 | nr_progs = obj->nr_programs; |
371 | 326 | ||
372 | progs = realloc(progs, sizeof(progs[0]) * (nr_progs + 1)); | 327 | progs = reallocarray(progs, nr_progs + 1, sizeof(progs[0])); |
373 | if (!progs) { | 328 | if (!progs) { |
374 | /* | 329 | /* |
375 | * In this case the original obj->programs | 330 | * In this case the original obj->programs |
@@ -401,10 +356,6 @@ bpf_object__init_prog_names(struct bpf_object *obj) | |||
401 | const char *name = NULL; | 356 | const char *name = NULL; |
402 | 357 | ||
403 | prog = &obj->programs[pi]; | 358 | prog = &obj->programs[pi]; |
404 | if (prog->idx == obj->efile.text_shndx) { | ||
405 | name = ".text"; | ||
406 | goto skip_search; | ||
407 | } | ||
408 | 359 | ||
409 | for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; | 360 | for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name; |
410 | si++) { | 361 | si++) { |
@@ -427,12 +378,15 @@ bpf_object__init_prog_names(struct bpf_object *obj) | |||
427 | } | 378 | } |
428 | } | 379 | } |
429 | 380 | ||
381 | if (!name && prog->idx == obj->efile.text_shndx) | ||
382 | name = ".text"; | ||
383 | |||
430 | if (!name) { | 384 | if (!name) { |
431 | pr_warning("failed to find sym for prog %s\n", | 385 | pr_warning("failed to find sym for prog %s\n", |
432 | prog->section_name); | 386 | prog->section_name); |
433 | return -EINVAL; | 387 | return -EINVAL; |
434 | } | 388 | } |
435 | skip_search: | 389 | |
436 | prog->name = strdup(name); | 390 | prog->name = strdup(name); |
437 | if (!prog->name) { | 391 | if (!prog->name) { |
438 | pr_warning("failed to allocate memory for prog sym %s\n", | 392 | pr_warning("failed to allocate memory for prog sym %s\n", |
@@ -514,8 +468,10 @@ static int bpf_object__elf_init(struct bpf_object *obj) | |||
514 | } else { | 468 | } else { |
515 | obj->efile.fd = open(obj->path, O_RDONLY); | 469 | obj->efile.fd = open(obj->path, O_RDONLY); |
516 | if (obj->efile.fd < 0) { | 470 | if (obj->efile.fd < 0) { |
517 | pr_warning("failed to open %s: %s\n", obj->path, | 471 | char errmsg[STRERR_BUFSIZE]; |
518 | strerror(errno)); | 472 | char *cp = strerror_r(errno, errmsg, sizeof(errmsg)); |
473 | |||
474 | pr_warning("failed to open %s: %s\n", obj->path, cp); | ||
519 | return -errno; | 475 | return -errno; |
520 | } | 476 | } |
521 | 477 | ||
@@ -854,10 +810,11 @@ static int bpf_object__elf_collect(struct bpf_object *obj) | |||
854 | data->d_size, name, idx); | 810 | data->d_size, name, idx); |
855 | if (err) { | 811 | if (err) { |
856 | char errmsg[STRERR_BUFSIZE]; | 812 | char errmsg[STRERR_BUFSIZE]; |
813 | char *cp = strerror_r(-err, errmsg, | ||
814 | sizeof(errmsg)); | ||
857 | 815 | ||
858 | strerror_r(-err, errmsg, sizeof(errmsg)); | ||
859 | pr_warning("failed to alloc program %s (%s): %s", | 816 | pr_warning("failed to alloc program %s (%s): %s", |
860 | name, obj->path, errmsg); | 817 | name, obj->path, cp); |
861 | } | 818 | } |
862 | } else if (sh.sh_type == SHT_REL) { | 819 | } else if (sh.sh_type == SHT_REL) { |
863 | void *reloc = obj->efile.reloc; | 820 | void *reloc = obj->efile.reloc; |
@@ -871,8 +828,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj) | |||
871 | continue; | 828 | continue; |
872 | } | 829 | } |
873 | 830 | ||
874 | reloc = realloc(reloc, | 831 | reloc = reallocarray(reloc, nr_reloc, |
875 | sizeof(*obj->efile.reloc) * nr_reloc); | 832 | sizeof(*obj->efile.reloc)); |
876 | if (!reloc) { | 833 | if (!reloc) { |
877 | pr_warning("realloc failed\n"); | 834 | pr_warning("realloc failed\n"); |
878 | err = -ENOMEM; | 835 | err = -ENOMEM; |
@@ -920,6 +877,18 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx) | |||
920 | return NULL; | 877 | return NULL; |
921 | } | 878 | } |
922 | 879 | ||
880 | struct bpf_program * | ||
881 | bpf_object__find_program_by_title(struct bpf_object *obj, const char *title) | ||
882 | { | ||
883 | struct bpf_program *pos; | ||
884 | |||
885 | bpf_object__for_each_program(pos, obj) { | ||
886 | if (pos->section_name && !strcmp(pos->section_name, title)) | ||
887 | return pos; | ||
888 | } | ||
889 | return NULL; | ||
890 | } | ||
891 | |||
923 | static int | 892 | static int |
924 | bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, | 893 | bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, |
925 | Elf_Data *data, struct bpf_object *obj) | 894 | Elf_Data *data, struct bpf_object *obj) |
@@ -982,6 +951,7 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, | |||
982 | prog->reloc_desc[i].type = RELO_CALL; | 951 | prog->reloc_desc[i].type = RELO_CALL; |
983 | prog->reloc_desc[i].insn_idx = insn_idx; | 952 | prog->reloc_desc[i].insn_idx = insn_idx; |
984 | prog->reloc_desc[i].text_off = sym.st_value; | 953 | prog->reloc_desc[i].text_off = sym.st_value; |
954 | obj->has_pseudo_calls = true; | ||
985 | continue; | 955 | continue; |
986 | } | 956 | } |
987 | 957 | ||
@@ -1085,6 +1055,53 @@ static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) | |||
1085 | return 0; | 1055 | return 0; |
1086 | } | 1056 | } |
1087 | 1057 | ||
1058 | int bpf_map__reuse_fd(struct bpf_map *map, int fd) | ||
1059 | { | ||
1060 | struct bpf_map_info info = {}; | ||
1061 | __u32 len = sizeof(info); | ||
1062 | int new_fd, err; | ||
1063 | char *new_name; | ||
1064 | |||
1065 | err = bpf_obj_get_info_by_fd(fd, &info, &len); | ||
1066 | if (err) | ||
1067 | return err; | ||
1068 | |||
1069 | new_name = strdup(info.name); | ||
1070 | if (!new_name) | ||
1071 | return -errno; | ||
1072 | |||
1073 | new_fd = open("/", O_RDONLY | O_CLOEXEC); | ||
1074 | if (new_fd < 0) | ||
1075 | goto err_free_new_name; | ||
1076 | |||
1077 | new_fd = dup3(fd, new_fd, O_CLOEXEC); | ||
1078 | if (new_fd < 0) | ||
1079 | goto err_close_new_fd; | ||
1080 | |||
1081 | err = zclose(map->fd); | ||
1082 | if (err) | ||
1083 | goto err_close_new_fd; | ||
1084 | free(map->name); | ||
1085 | |||
1086 | map->fd = new_fd; | ||
1087 | map->name = new_name; | ||
1088 | map->def.type = info.type; | ||
1089 | map->def.key_size = info.key_size; | ||
1090 | map->def.value_size = info.value_size; | ||
1091 | map->def.max_entries = info.max_entries; | ||
1092 | map->def.map_flags = info.map_flags; | ||
1093 | map->btf_key_type_id = info.btf_key_type_id; | ||
1094 | map->btf_value_type_id = info.btf_value_type_id; | ||
1095 | |||
1096 | return 0; | ||
1097 | |||
1098 | err_close_new_fd: | ||
1099 | close(new_fd); | ||
1100 | err_free_new_name: | ||
1101 | free(new_name); | ||
1102 | return -errno; | ||
1103 | } | ||
1104 | |||
1088 | static int | 1105 | static int |
1089 | bpf_object__create_maps(struct bpf_object *obj) | 1106 | bpf_object__create_maps(struct bpf_object *obj) |
1090 | { | 1107 | { |
@@ -1095,8 +1112,15 @@ bpf_object__create_maps(struct bpf_object *obj) | |||
1095 | for (i = 0; i < obj->nr_maps; i++) { | 1112 | for (i = 0; i < obj->nr_maps; i++) { |
1096 | struct bpf_map *map = &obj->maps[i]; | 1113 | struct bpf_map *map = &obj->maps[i]; |
1097 | struct bpf_map_def *def = &map->def; | 1114 | struct bpf_map_def *def = &map->def; |
1115 | char *cp, errmsg[STRERR_BUFSIZE]; | ||
1098 | int *pfd = &map->fd; | 1116 | int *pfd = &map->fd; |
1099 | 1117 | ||
1118 | if (map->fd >= 0) { | ||
1119 | pr_debug("skip map create (preset) %s: fd=%d\n", | ||
1120 | map->name, map->fd); | ||
1121 | continue; | ||
1122 | } | ||
1123 | |||
1100 | create_attr.name = map->name; | 1124 | create_attr.name = map->name; |
1101 | create_attr.map_ifindex = map->map_ifindex; | 1125 | create_attr.map_ifindex = map->map_ifindex; |
1102 | create_attr.map_type = def->type; | 1126 | create_attr.map_type = def->type; |
@@ -1116,8 +1140,9 @@ bpf_object__create_maps(struct bpf_object *obj) | |||
1116 | 1140 | ||
1117 | *pfd = bpf_create_map_xattr(&create_attr); | 1141 | *pfd = bpf_create_map_xattr(&create_attr); |
1118 | if (*pfd < 0 && create_attr.btf_key_type_id) { | 1142 | if (*pfd < 0 && create_attr.btf_key_type_id) { |
1143 | cp = strerror_r(errno, errmsg, sizeof(errmsg)); | ||
1119 | pr_warning("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n", | 1144 | pr_warning("Error in bpf_create_map_xattr(%s):%s(%d). Retrying without BTF.\n", |
1120 | map->name, strerror(errno), errno); | 1145 | map->name, cp, errno); |
1121 | create_attr.btf_fd = 0; | 1146 | create_attr.btf_fd = 0; |
1122 | create_attr.btf_key_type_id = 0; | 1147 | create_attr.btf_key_type_id = 0; |
1123 | create_attr.btf_value_type_id = 0; | 1148 | create_attr.btf_value_type_id = 0; |
@@ -1130,9 +1155,9 @@ bpf_object__create_maps(struct bpf_object *obj) | |||
1130 | size_t j; | 1155 | size_t j; |
1131 | 1156 | ||
1132 | err = *pfd; | 1157 | err = *pfd; |
1158 | cp = strerror_r(errno, errmsg, sizeof(errmsg)); | ||
1133 | pr_warning("failed to create map (name: '%s'): %s\n", | 1159 | pr_warning("failed to create map (name: '%s'): %s\n", |
1134 | map->name, | 1160 | map->name, cp); |
1135 | strerror(errno)); | ||
1136 | for (j = 0; j < i; j++) | 1161 | for (j = 0; j < i; j++) |
1137 | zclose(obj->maps[j].fd); | 1162 | zclose(obj->maps[j].fd); |
1138 | return err; | 1163 | return err; |
@@ -1167,7 +1192,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, | |||
1167 | return -LIBBPF_ERRNO__RELOC; | 1192 | return -LIBBPF_ERRNO__RELOC; |
1168 | } | 1193 | } |
1169 | new_cnt = prog->insns_cnt + text->insns_cnt; | 1194 | new_cnt = prog->insns_cnt + text->insns_cnt; |
1170 | new_insn = realloc(prog->insns, new_cnt * sizeof(*insn)); | 1195 | new_insn = reallocarray(prog->insns, new_cnt, sizeof(*insn)); |
1171 | if (!new_insn) { | 1196 | if (!new_insn) { |
1172 | pr_warning("oom in prog realloc\n"); | 1197 | pr_warning("oom in prog realloc\n"); |
1173 | return -ENOMEM; | 1198 | return -ENOMEM; |
@@ -1284,6 +1309,7 @@ load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type, | |||
1284 | char *license, u32 kern_version, int *pfd, int prog_ifindex) | 1309 | char *license, u32 kern_version, int *pfd, int prog_ifindex) |
1285 | { | 1310 | { |
1286 | struct bpf_load_program_attr load_attr; | 1311 | struct bpf_load_program_attr load_attr; |
1312 | char *cp, errmsg[STRERR_BUFSIZE]; | ||
1287 | char *log_buf; | 1313 | char *log_buf; |
1288 | int ret; | 1314 | int ret; |
1289 | 1315 | ||
@@ -1313,7 +1339,8 @@ load_program(enum bpf_prog_type type, enum bpf_attach_type expected_attach_type, | |||
1313 | } | 1339 | } |
1314 | 1340 | ||
1315 | ret = -LIBBPF_ERRNO__LOAD; | 1341 | ret = -LIBBPF_ERRNO__LOAD; |
1316 | pr_warning("load bpf program failed: %s\n", strerror(errno)); | 1342 | cp = strerror_r(errno, errmsg, sizeof(errmsg)); |
1343 | pr_warning("load bpf program failed: %s\n", cp); | ||
1317 | 1344 | ||
1318 | if (log_buf && log_buf[0] != '\0') { | 1345 | if (log_buf && log_buf[0] != '\0') { |
1319 | ret = -LIBBPF_ERRNO__VERIFY; | 1346 | ret = -LIBBPF_ERRNO__VERIFY; |
@@ -1431,6 +1458,12 @@ out: | |||
1431 | return err; | 1458 | return err; |
1432 | } | 1459 | } |
1433 | 1460 | ||
1461 | static bool bpf_program__is_function_storage(struct bpf_program *prog, | ||
1462 | struct bpf_object *obj) | ||
1463 | { | ||
1464 | return prog->idx == obj->efile.text_shndx && obj->has_pseudo_calls; | ||
1465 | } | ||
1466 | |||
1434 | static int | 1467 | static int |
1435 | bpf_object__load_progs(struct bpf_object *obj) | 1468 | bpf_object__load_progs(struct bpf_object *obj) |
1436 | { | 1469 | { |
@@ -1438,7 +1471,7 @@ bpf_object__load_progs(struct bpf_object *obj) | |||
1438 | int err; | 1471 | int err; |
1439 | 1472 | ||
1440 | for (i = 0; i < obj->nr_programs; i++) { | 1473 | for (i = 0; i < obj->nr_programs; i++) { |
1441 | if (obj->programs[i].idx == obj->efile.text_shndx) | 1474 | if (bpf_program__is_function_storage(&obj->programs[i], obj)) |
1442 | continue; | 1475 | continue; |
1443 | err = bpf_program__load(&obj->programs[i], | 1476 | err = bpf_program__load(&obj->programs[i], |
1444 | obj->license, | 1477 | obj->license, |
@@ -1468,6 +1501,7 @@ static bool bpf_prog_type__needs_kver(enum bpf_prog_type type) | |||
1468 | case BPF_PROG_TYPE_SK_MSG: | 1501 | case BPF_PROG_TYPE_SK_MSG: |
1469 | case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: | 1502 | case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: |
1470 | case BPF_PROG_TYPE_LIRC_MODE2: | 1503 | case BPF_PROG_TYPE_LIRC_MODE2: |
1504 | case BPF_PROG_TYPE_SK_REUSEPORT: | ||
1471 | return false; | 1505 | return false; |
1472 | case BPF_PROG_TYPE_UNSPEC: | 1506 | case BPF_PROG_TYPE_UNSPEC: |
1473 | case BPF_PROG_TYPE_KPROBE: | 1507 | case BPF_PROG_TYPE_KPROBE: |
@@ -1518,15 +1552,26 @@ out: | |||
1518 | return ERR_PTR(err); | 1552 | return ERR_PTR(err); |
1519 | } | 1553 | } |
1520 | 1554 | ||
1521 | struct bpf_object *bpf_object__open(const char *path) | 1555 | struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr) |
1522 | { | 1556 | { |
1523 | /* param validation */ | 1557 | /* param validation */ |
1524 | if (!path) | 1558 | if (!attr->file) |
1525 | return NULL; | 1559 | return NULL; |
1526 | 1560 | ||
1527 | pr_debug("loading %s\n", path); | 1561 | pr_debug("loading %s\n", attr->file); |
1528 | 1562 | ||
1529 | return __bpf_object__open(path, NULL, 0, true); | 1563 | return __bpf_object__open(attr->file, NULL, 0, |
1564 | bpf_prog_type__needs_kver(attr->prog_type)); | ||
1565 | } | ||
1566 | |||
1567 | struct bpf_object *bpf_object__open(const char *path) | ||
1568 | { | ||
1569 | struct bpf_object_open_attr attr = { | ||
1570 | .file = path, | ||
1571 | .prog_type = BPF_PROG_TYPE_UNSPEC, | ||
1572 | }; | ||
1573 | |||
1574 | return bpf_object__open_xattr(&attr); | ||
1530 | } | 1575 | } |
1531 | 1576 | ||
1532 | struct bpf_object *bpf_object__open_buffer(void *obj_buf, | 1577 | struct bpf_object *bpf_object__open_buffer(void *obj_buf, |
@@ -1595,6 +1640,7 @@ out: | |||
1595 | 1640 | ||
1596 | static int check_path(const char *path) | 1641 | static int check_path(const char *path) |
1597 | { | 1642 | { |
1643 | char *cp, errmsg[STRERR_BUFSIZE]; | ||
1598 | struct statfs st_fs; | 1644 | struct statfs st_fs; |
1599 | char *dname, *dir; | 1645 | char *dname, *dir; |
1600 | int err = 0; | 1646 | int err = 0; |
@@ -1608,7 +1654,8 @@ static int check_path(const char *path) | |||
1608 | 1654 | ||
1609 | dir = dirname(dname); | 1655 | dir = dirname(dname); |
1610 | if (statfs(dir, &st_fs)) { | 1656 | if (statfs(dir, &st_fs)) { |
1611 | pr_warning("failed to statfs %s: %s\n", dir, strerror(errno)); | 1657 | cp = strerror_r(errno, errmsg, sizeof(errmsg)); |
1658 | pr_warning("failed to statfs %s: %s\n", dir, cp); | ||
1612 | err = -errno; | 1659 | err = -errno; |
1613 | } | 1660 | } |
1614 | free(dname); | 1661 | free(dname); |
@@ -1624,6 +1671,7 @@ static int check_path(const char *path) | |||
1624 | int bpf_program__pin_instance(struct bpf_program *prog, const char *path, | 1671 | int bpf_program__pin_instance(struct bpf_program *prog, const char *path, |
1625 | int instance) | 1672 | int instance) |
1626 | { | 1673 | { |
1674 | char *cp, errmsg[STRERR_BUFSIZE]; | ||
1627 | int err; | 1675 | int err; |
1628 | 1676 | ||
1629 | err = check_path(path); | 1677 | err = check_path(path); |
@@ -1642,7 +1690,8 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path, | |||
1642 | } | 1690 | } |
1643 | 1691 | ||
1644 | if (bpf_obj_pin(prog->instances.fds[instance], path)) { | 1692 | if (bpf_obj_pin(prog->instances.fds[instance], path)) { |
1645 | pr_warning("failed to pin program: %s\n", strerror(errno)); | 1693 | cp = strerror_r(errno, errmsg, sizeof(errmsg)); |
1694 | pr_warning("failed to pin program: %s\n", cp); | ||
1646 | return -errno; | 1695 | return -errno; |
1647 | } | 1696 | } |
1648 | pr_debug("pinned program '%s'\n", path); | 1697 | pr_debug("pinned program '%s'\n", path); |
@@ -1652,13 +1701,16 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path, | |||
1652 | 1701 | ||
1653 | static int make_dir(const char *path) | 1702 | static int make_dir(const char *path) |
1654 | { | 1703 | { |
1704 | char *cp, errmsg[STRERR_BUFSIZE]; | ||
1655 | int err = 0; | 1705 | int err = 0; |
1656 | 1706 | ||
1657 | if (mkdir(path, 0700) && errno != EEXIST) | 1707 | if (mkdir(path, 0700) && errno != EEXIST) |
1658 | err = -errno; | 1708 | err = -errno; |
1659 | 1709 | ||
1660 | if (err) | 1710 | if (err) { |
1661 | pr_warning("failed to mkdir %s: %s\n", path, strerror(-err)); | 1711 | cp = strerror_r(-err, errmsg, sizeof(errmsg)); |
1712 | pr_warning("failed to mkdir %s: %s\n", path, cp); | ||
1713 | } | ||
1662 | return err; | 1714 | return err; |
1663 | } | 1715 | } |
1664 | 1716 | ||
@@ -1705,6 +1757,7 @@ int bpf_program__pin(struct bpf_program *prog, const char *path) | |||
1705 | 1757 | ||
1706 | int bpf_map__pin(struct bpf_map *map, const char *path) | 1758 | int bpf_map__pin(struct bpf_map *map, const char *path) |
1707 | { | 1759 | { |
1760 | char *cp, errmsg[STRERR_BUFSIZE]; | ||
1708 | int err; | 1761 | int err; |
1709 | 1762 | ||
1710 | err = check_path(path); | 1763 | err = check_path(path); |
@@ -1717,7 +1770,8 @@ int bpf_map__pin(struct bpf_map *map, const char *path) | |||
1717 | } | 1770 | } |
1718 | 1771 | ||
1719 | if (bpf_obj_pin(map->fd, path)) { | 1772 | if (bpf_obj_pin(map->fd, path)) { |
1720 | pr_warning("failed to pin map: %s\n", strerror(errno)); | 1773 | cp = strerror_r(errno, errmsg, sizeof(errmsg)); |
1774 | pr_warning("failed to pin map: %s\n", cp); | ||
1721 | return -errno; | 1775 | return -errno; |
1722 | } | 1776 | } |
1723 | 1777 | ||
@@ -1863,8 +1917,8 @@ void *bpf_object__priv(struct bpf_object *obj) | |||
1863 | return obj ? obj->priv : ERR_PTR(-EINVAL); | 1917 | return obj ? obj->priv : ERR_PTR(-EINVAL); |
1864 | } | 1918 | } |
1865 | 1919 | ||
1866 | struct bpf_program * | 1920 | static struct bpf_program * |
1867 | bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) | 1921 | __bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) |
1868 | { | 1922 | { |
1869 | size_t idx; | 1923 | size_t idx; |
1870 | 1924 | ||
@@ -1885,6 +1939,18 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) | |||
1885 | return &obj->programs[idx]; | 1939 | return &obj->programs[idx]; |
1886 | } | 1940 | } |
1887 | 1941 | ||
1942 | struct bpf_program * | ||
1943 | bpf_program__next(struct bpf_program *prev, struct bpf_object *obj) | ||
1944 | { | ||
1945 | struct bpf_program *prog = prev; | ||
1946 | |||
1947 | do { | ||
1948 | prog = __bpf_program__next(prog, obj); | ||
1949 | } while (prog && bpf_program__is_function_storage(prog, obj)); | ||
1950 | |||
1951 | return prog; | ||
1952 | } | ||
1953 | |||
1888 | int bpf_program__set_priv(struct bpf_program *prog, void *priv, | 1954 | int bpf_program__set_priv(struct bpf_program *prog, void *priv, |
1889 | bpf_program_clear_priv_t clear_priv) | 1955 | bpf_program_clear_priv_t clear_priv) |
1890 | { | 1956 | { |
@@ -1901,6 +1967,11 @@ void *bpf_program__priv(struct bpf_program *prog) | |||
1901 | return prog ? prog->priv : ERR_PTR(-EINVAL); | 1967 | return prog ? prog->priv : ERR_PTR(-EINVAL); |
1902 | } | 1968 | } |
1903 | 1969 | ||
1970 | void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex) | ||
1971 | { | ||
1972 | prog->prog_ifindex = ifindex; | ||
1973 | } | ||
1974 | |||
1904 | const char *bpf_program__title(struct bpf_program *prog, bool needs_copy) | 1975 | const char *bpf_program__title(struct bpf_program *prog, bool needs_copy) |
1905 | { | 1976 | { |
1906 | const char *title; | 1977 | const char *title; |
@@ -1954,6 +2025,9 @@ int bpf_program__nth_fd(struct bpf_program *prog, int n) | |||
1954 | { | 2025 | { |
1955 | int fd; | 2026 | int fd; |
1956 | 2027 | ||
2028 | if (!prog) | ||
2029 | return -EINVAL; | ||
2030 | |||
1957 | if (n >= prog->instances.nr || n < 0) { | 2031 | if (n >= prog->instances.nr || n < 0) { |
1958 | pr_warning("Can't get the %dth fd from program %s: only %d instances\n", | 2032 | pr_warning("Can't get the %dth fd from program %s: only %d instances\n", |
1959 | n, prog->section_name, prog->instances.nr); | 2033 | n, prog->section_name, prog->instances.nr); |
@@ -2042,9 +2116,11 @@ static const struct { | |||
2042 | BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN), | 2116 | BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN), |
2043 | BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT), | 2117 | BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT), |
2044 | BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT), | 2118 | BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT), |
2119 | BPF_PROG_SEC("lwt_seg6local", BPF_PROG_TYPE_LWT_SEG6LOCAL), | ||
2045 | BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS), | 2120 | BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS), |
2046 | BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB), | 2121 | BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB), |
2047 | BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG), | 2122 | BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG), |
2123 | BPF_PROG_SEC("lirc_mode2", BPF_PROG_TYPE_LIRC_MODE2), | ||
2048 | BPF_SA_PROG_SEC("cgroup/bind4", BPF_CGROUP_INET4_BIND), | 2124 | BPF_SA_PROG_SEC("cgroup/bind4", BPF_CGROUP_INET4_BIND), |
2049 | BPF_SA_PROG_SEC("cgroup/bind6", BPF_CGROUP_INET6_BIND), | 2125 | BPF_SA_PROG_SEC("cgroup/bind6", BPF_CGROUP_INET6_BIND), |
2050 | BPF_SA_PROG_SEC("cgroup/connect4", BPF_CGROUP_INET4_CONNECT), | 2126 | BPF_SA_PROG_SEC("cgroup/connect4", BPF_CGROUP_INET4_CONNECT), |
@@ -2060,23 +2136,31 @@ static const struct { | |||
2060 | #undef BPF_S_PROG_SEC | 2136 | #undef BPF_S_PROG_SEC |
2061 | #undef BPF_SA_PROG_SEC | 2137 | #undef BPF_SA_PROG_SEC |
2062 | 2138 | ||
2063 | static int bpf_program__identify_section(struct bpf_program *prog) | 2139 | int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, |
2140 | enum bpf_attach_type *expected_attach_type) | ||
2064 | { | 2141 | { |
2065 | int i; | 2142 | int i; |
2066 | 2143 | ||
2067 | if (!prog->section_name) | 2144 | if (!name) |
2068 | goto err; | 2145 | return -EINVAL; |
2069 | |||
2070 | for (i = 0; i < ARRAY_SIZE(section_names); i++) | ||
2071 | if (strncmp(prog->section_name, section_names[i].sec, | ||
2072 | section_names[i].len) == 0) | ||
2073 | return i; | ||
2074 | 2146 | ||
2075 | err: | 2147 | for (i = 0; i < ARRAY_SIZE(section_names); i++) { |
2076 | pr_warning("failed to guess program type based on section name %s\n", | 2148 | if (strncmp(name, section_names[i].sec, section_names[i].len)) |
2077 | prog->section_name); | 2149 | continue; |
2150 | *prog_type = section_names[i].prog_type; | ||
2151 | *expected_attach_type = section_names[i].expected_attach_type; | ||
2152 | return 0; | ||
2153 | } | ||
2154 | return -EINVAL; | ||
2155 | } | ||
2078 | 2156 | ||
2079 | return -1; | 2157 | static int |
2158 | bpf_program__identify_section(struct bpf_program *prog, | ||
2159 | enum bpf_prog_type *prog_type, | ||
2160 | enum bpf_attach_type *expected_attach_type) | ||
2161 | { | ||
2162 | return libbpf_prog_type_by_name(prog->section_name, prog_type, | ||
2163 | expected_attach_type); | ||
2080 | } | 2164 | } |
2081 | 2165 | ||
2082 | int bpf_map__fd(struct bpf_map *map) | 2166 | int bpf_map__fd(struct bpf_map *map) |
@@ -2125,6 +2209,16 @@ void *bpf_map__priv(struct bpf_map *map) | |||
2125 | return map ? map->priv : ERR_PTR(-EINVAL); | 2209 | return map ? map->priv : ERR_PTR(-EINVAL); |
2126 | } | 2210 | } |
2127 | 2211 | ||
2212 | bool bpf_map__is_offload_neutral(struct bpf_map *map) | ||
2213 | { | ||
2214 | return map->def.type == BPF_MAP_TYPE_PERF_EVENT_ARRAY; | ||
2215 | } | ||
2216 | |||
2217 | void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex) | ||
2218 | { | ||
2219 | map->map_ifindex = ifindex; | ||
2220 | } | ||
2221 | |||
2128 | struct bpf_map * | 2222 | struct bpf_map * |
2129 | bpf_map__next(struct bpf_map *prev, struct bpf_object *obj) | 2223 | bpf_map__next(struct bpf_map *prev, struct bpf_object *obj) |
2130 | { | 2224 | { |
@@ -2199,12 +2293,15 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type, | |||
2199 | int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, | 2293 | int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, |
2200 | struct bpf_object **pobj, int *prog_fd) | 2294 | struct bpf_object **pobj, int *prog_fd) |
2201 | { | 2295 | { |
2296 | struct bpf_object_open_attr open_attr = { | ||
2297 | .file = attr->file, | ||
2298 | .prog_type = attr->prog_type, | ||
2299 | }; | ||
2202 | struct bpf_program *prog, *first_prog = NULL; | 2300 | struct bpf_program *prog, *first_prog = NULL; |
2203 | enum bpf_attach_type expected_attach_type; | 2301 | enum bpf_attach_type expected_attach_type; |
2204 | enum bpf_prog_type prog_type; | 2302 | enum bpf_prog_type prog_type; |
2205 | struct bpf_object *obj; | 2303 | struct bpf_object *obj; |
2206 | struct bpf_map *map; | 2304 | struct bpf_map *map; |
2207 | int section_idx; | ||
2208 | int err; | 2305 | int err; |
2209 | 2306 | ||
2210 | if (!attr) | 2307 | if (!attr) |
@@ -2212,8 +2309,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, | |||
2212 | if (!attr->file) | 2309 | if (!attr->file) |
2213 | return -EINVAL; | 2310 | return -EINVAL; |
2214 | 2311 | ||
2215 | obj = __bpf_object__open(attr->file, NULL, 0, | 2312 | obj = bpf_object__open_xattr(&open_attr); |
2216 | bpf_prog_type__needs_kver(attr->prog_type)); | ||
2217 | if (IS_ERR_OR_NULL(obj)) | 2313 | if (IS_ERR_OR_NULL(obj)) |
2218 | return -ENOENT; | 2314 | return -ENOENT; |
2219 | 2315 | ||
@@ -2226,26 +2322,27 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, | |||
2226 | prog->prog_ifindex = attr->ifindex; | 2322 | prog->prog_ifindex = attr->ifindex; |
2227 | expected_attach_type = attr->expected_attach_type; | 2323 | expected_attach_type = attr->expected_attach_type; |
2228 | if (prog_type == BPF_PROG_TYPE_UNSPEC) { | 2324 | if (prog_type == BPF_PROG_TYPE_UNSPEC) { |
2229 | section_idx = bpf_program__identify_section(prog); | 2325 | err = bpf_program__identify_section(prog, &prog_type, |
2230 | if (section_idx < 0) { | 2326 | &expected_attach_type); |
2327 | if (err < 0) { | ||
2328 | pr_warning("failed to guess program type based on section name %s\n", | ||
2329 | prog->section_name); | ||
2231 | bpf_object__close(obj); | 2330 | bpf_object__close(obj); |
2232 | return -EINVAL; | 2331 | return -EINVAL; |
2233 | } | 2332 | } |
2234 | prog_type = section_names[section_idx].prog_type; | ||
2235 | expected_attach_type = | ||
2236 | section_names[section_idx].expected_attach_type; | ||
2237 | } | 2333 | } |
2238 | 2334 | ||
2239 | bpf_program__set_type(prog, prog_type); | 2335 | bpf_program__set_type(prog, prog_type); |
2240 | bpf_program__set_expected_attach_type(prog, | 2336 | bpf_program__set_expected_attach_type(prog, |
2241 | expected_attach_type); | 2337 | expected_attach_type); |
2242 | 2338 | ||
2243 | if (prog->idx != obj->efile.text_shndx && !first_prog) | 2339 | if (!bpf_program__is_function_storage(prog, obj) && !first_prog) |
2244 | first_prog = prog; | 2340 | first_prog = prog; |
2245 | } | 2341 | } |
2246 | 2342 | ||
2247 | bpf_map__for_each(map, obj) { | 2343 | bpf_map__for_each(map, obj) { |
2248 | map->map_ifindex = attr->ifindex; | 2344 | if (!bpf_map__is_offload_neutral(map)) |
2345 | map->map_ifindex = attr->ifindex; | ||
2249 | } | 2346 | } |
2250 | 2347 | ||
2251 | if (!first_prog) { | 2348 | if (!first_prog) { |
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index b33ae02f7d0e..96c55fac54c3 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h | |||
@@ -66,7 +66,13 @@ void libbpf_set_print(libbpf_print_fn_t warn, | |||
66 | /* Hide internal to user */ | 66 | /* Hide internal to user */ |
67 | struct bpf_object; | 67 | struct bpf_object; |
68 | 68 | ||
69 | struct bpf_object_open_attr { | ||
70 | const char *file; | ||
71 | enum bpf_prog_type prog_type; | ||
72 | }; | ||
73 | |||
69 | struct bpf_object *bpf_object__open(const char *path); | 74 | struct bpf_object *bpf_object__open(const char *path); |
75 | struct bpf_object *bpf_object__open_xattr(struct bpf_object_open_attr *attr); | ||
70 | struct bpf_object *bpf_object__open_buffer(void *obj_buf, | 76 | struct bpf_object *bpf_object__open_buffer(void *obj_buf, |
71 | size_t obj_buf_sz, | 77 | size_t obj_buf_sz, |
72 | const char *name); | 78 | const char *name); |
@@ -80,6 +86,9 @@ const char *bpf_object__name(struct bpf_object *obj); | |||
80 | unsigned int bpf_object__kversion(struct bpf_object *obj); | 86 | unsigned int bpf_object__kversion(struct bpf_object *obj); |
81 | int bpf_object__btf_fd(const struct bpf_object *obj); | 87 | int bpf_object__btf_fd(const struct bpf_object *obj); |
82 | 88 | ||
89 | struct bpf_program * | ||
90 | bpf_object__find_program_by_title(struct bpf_object *obj, const char *title); | ||
91 | |||
83 | struct bpf_object *bpf_object__next(struct bpf_object *prev); | 92 | struct bpf_object *bpf_object__next(struct bpf_object *prev); |
84 | #define bpf_object__for_each_safe(pos, tmp) \ | 93 | #define bpf_object__for_each_safe(pos, tmp) \ |
85 | for ((pos) = bpf_object__next(NULL), \ | 94 | for ((pos) = bpf_object__next(NULL), \ |
@@ -92,6 +101,9 @@ int bpf_object__set_priv(struct bpf_object *obj, void *priv, | |||
92 | bpf_object_clear_priv_t clear_priv); | 101 | bpf_object_clear_priv_t clear_priv); |
93 | void *bpf_object__priv(struct bpf_object *prog); | 102 | void *bpf_object__priv(struct bpf_object *prog); |
94 | 103 | ||
104 | int libbpf_prog_type_by_name(const char *name, enum bpf_prog_type *prog_type, | ||
105 | enum bpf_attach_type *expected_attach_type); | ||
106 | |||
95 | /* Accessors of bpf_program */ | 107 | /* Accessors of bpf_program */ |
96 | struct bpf_program; | 108 | struct bpf_program; |
97 | struct bpf_program *bpf_program__next(struct bpf_program *prog, | 109 | struct bpf_program *bpf_program__next(struct bpf_program *prog, |
@@ -109,6 +121,7 @@ int bpf_program__set_priv(struct bpf_program *prog, void *priv, | |||
109 | bpf_program_clear_priv_t clear_priv); | 121 | bpf_program_clear_priv_t clear_priv); |
110 | 122 | ||
111 | void *bpf_program__priv(struct bpf_program *prog); | 123 | void *bpf_program__priv(struct bpf_program *prog); |
124 | void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex); | ||
112 | 125 | ||
113 | const char *bpf_program__title(struct bpf_program *prog, bool needs_copy); | 126 | const char *bpf_program__title(struct bpf_program *prog, bool needs_copy); |
114 | 127 | ||
@@ -251,6 +264,9 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); | |||
251 | int bpf_map__set_priv(struct bpf_map *map, void *priv, | 264 | int bpf_map__set_priv(struct bpf_map *map, void *priv, |
252 | bpf_map_clear_priv_t clear_priv); | 265 | bpf_map_clear_priv_t clear_priv); |
253 | void *bpf_map__priv(struct bpf_map *map); | 266 | void *bpf_map__priv(struct bpf_map *map); |
267 | int bpf_map__reuse_fd(struct bpf_map *map, int fd); | ||
268 | bool bpf_map__is_offload_neutral(struct bpf_map *map); | ||
269 | void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex); | ||
254 | int bpf_map__pin(struct bpf_map *map, const char *path); | 270 | int bpf_map__pin(struct bpf_map *map, const char *path); |
255 | 271 | ||
256 | long libbpf_get_error(const void *ptr); | 272 | long libbpf_get_error(const void *ptr); |
diff --git a/tools/lib/bpf/libbpf_errno.c b/tools/lib/bpf/libbpf_errno.c new file mode 100644 index 000000000000..d9ba851bd7f9 --- /dev/null +++ b/tools/lib/bpf/libbpf_errno.c | |||
@@ -0,0 +1,74 @@ | |||
1 | // SPDX-License-Identifier: LGPL-2.1 | ||
2 | |||
3 | /* | ||
4 | * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org> | ||
5 | * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com> | ||
6 | * Copyright (C) 2015 Huawei Inc. | ||
7 | * Copyright (C) 2017 Nicira, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU Lesser General Public | ||
11 | * License as published by the Free Software Foundation; | ||
12 | * version 2.1 of the License (not later!) | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU Lesser General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public | ||
20 | * License along with this program; if not, see <http://www.gnu.org/licenses> | ||
21 | */ | ||
22 | |||
23 | #include <stdio.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include "libbpf.h" | ||
27 | |||
28 | #define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START) | ||
29 | #define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c) | ||
30 | #define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START) | ||
31 | |||
32 | static const char *libbpf_strerror_table[NR_ERRNO] = { | ||
33 | [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf", | ||
34 | [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid", | ||
35 | [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost", | ||
36 | [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch", | ||
37 | [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf", | ||
38 | [ERRCODE_OFFSET(RELOC)] = "Relocation failed", | ||
39 | [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading", | ||
40 | [ERRCODE_OFFSET(PROG2BIG)] = "Program too big", | ||
41 | [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version", | ||
42 | [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type", | ||
43 | [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message", | ||
44 | [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence", | ||
45 | }; | ||
46 | |||
47 | int libbpf_strerror(int err, char *buf, size_t size) | ||
48 | { | ||
49 | if (!buf || !size) | ||
50 | return -1; | ||
51 | |||
52 | err = err > 0 ? err : -err; | ||
53 | |||
54 | if (err < __LIBBPF_ERRNO__START) { | ||
55 | int ret; | ||
56 | |||
57 | ret = strerror_r(err, buf, size); | ||
58 | buf[size - 1] = '\0'; | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | if (err < __LIBBPF_ERRNO__END) { | ||
63 | const char *msg; | ||
64 | |||
65 | msg = libbpf_strerror_table[ERRNO_OFFSET(err)]; | ||
66 | snprintf(buf, size, "%s", msg); | ||
67 | buf[size - 1] = '\0'; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | snprintf(buf, size, "Unknown libbpf error %d", err); | ||
72 | buf[size - 1] = '\0'; | ||
73 | return -1; | ||
74 | } | ||
diff --git a/tools/memory-model/Documentation/explanation.txt b/tools/memory-model/Documentation/explanation.txt index 1b09f3175a1f..0cbd1ef8f86d 100644 --- a/tools/memory-model/Documentation/explanation.txt +++ b/tools/memory-model/Documentation/explanation.txt | |||
@@ -804,7 +804,7 @@ type of fence: | |||
804 | Second, some types of fence affect the way the memory subsystem | 804 | Second, some types of fence affect the way the memory subsystem |
805 | propagates stores. When a fence instruction is executed on CPU C: | 805 | propagates stores. When a fence instruction is executed on CPU C: |
806 | 806 | ||
807 | For each other CPU C', smb_wmb() forces all po-earlier stores | 807 | For each other CPU C', smp_wmb() forces all po-earlier stores |
808 | on C to propagate to C' before any po-later stores do. | 808 | on C to propagate to C' before any po-later stores do. |
809 | 809 | ||
810 | For each other CPU C', any store which propagates to C before | 810 | For each other CPU C', any store which propagates to C before |
diff --git a/tools/memory-model/Documentation/recipes.txt b/tools/memory-model/Documentation/recipes.txt index ee4309a87fc4..af72700cc20a 100644 --- a/tools/memory-model/Documentation/recipes.txt +++ b/tools/memory-model/Documentation/recipes.txt | |||
@@ -126,7 +126,7 @@ However, it is not necessarily the case that accesses ordered by | |||
126 | locking will be seen as ordered by CPUs not holding that lock. | 126 | locking will be seen as ordered by CPUs not holding that lock. |
127 | Consider this example: | 127 | Consider this example: |
128 | 128 | ||
129 | /* See Z6.0+pooncelock+pooncelock+pombonce.litmus. */ | 129 | /* See Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus. */ |
130 | void CPU0(void) | 130 | void CPU0(void) |
131 | { | 131 | { |
132 | spin_lock(&mylock); | 132 | spin_lock(&mylock); |
@@ -292,7 +292,7 @@ and to use smp_load_acquire() instead of smp_rmb(). However, the older | |||
292 | smp_wmb() and smp_rmb() APIs are still heavily used, so it is important | 292 | smp_wmb() and smp_rmb() APIs are still heavily used, so it is important |
293 | to understand their use cases. The general approach is shown below: | 293 | to understand their use cases. The general approach is shown below: |
294 | 294 | ||
295 | /* See MP+wmbonceonce+rmbonceonce.litmus. */ | 295 | /* See MP+fencewmbonceonce+fencermbonceonce.litmus. */ |
296 | void CPU0(void) | 296 | void CPU0(void) |
297 | { | 297 | { |
298 | WRITE_ONCE(x, 1); | 298 | WRITE_ONCE(x, 1); |
@@ -322,9 +322,9 @@ the following write-side code fragment: | |||
322 | And the xlog_valid_lsn() function in fs/xfs/xfs_log_priv.h contains | 322 | And the xlog_valid_lsn() function in fs/xfs/xfs_log_priv.h contains |
323 | the corresponding read-side code fragment: | 323 | the corresponding read-side code fragment: |
324 | 324 | ||
325 | cur_cycle = ACCESS_ONCE(log->l_curr_cycle); | 325 | cur_cycle = READ_ONCE(log->l_curr_cycle); |
326 | smp_rmb(); | 326 | smp_rmb(); |
327 | cur_block = ACCESS_ONCE(log->l_curr_block); | 327 | cur_block = READ_ONCE(log->l_curr_block); |
328 | 328 | ||
329 | Alternatively, consider the following comment in function | 329 | Alternatively, consider the following comment in function |
330 | perf_output_put_handle() in kernel/events/ring_buffer.c: | 330 | perf_output_put_handle() in kernel/events/ring_buffer.c: |
@@ -360,7 +360,7 @@ can be seen in the LB+poonceonces.litmus litmus test. | |||
360 | One way of avoiding the counter-intuitive outcome is through the use of a | 360 | One way of avoiding the counter-intuitive outcome is through the use of a |
361 | control dependency paired with a full memory barrier: | 361 | control dependency paired with a full memory barrier: |
362 | 362 | ||
363 | /* See LB+ctrlonceonce+mbonceonce.litmus. */ | 363 | /* See LB+fencembonceonce+ctrlonceonce.litmus. */ |
364 | void CPU0(void) | 364 | void CPU0(void) |
365 | { | 365 | { |
366 | r0 = READ_ONCE(x); | 366 | r0 = READ_ONCE(x); |
@@ -476,7 +476,7 @@ that one CPU first stores to one variable and then loads from a second, | |||
476 | while another CPU stores to the second variable and then loads from the | 476 | while another CPU stores to the second variable and then loads from the |
477 | first. Preserving order requires nothing less than full barriers: | 477 | first. Preserving order requires nothing less than full barriers: |
478 | 478 | ||
479 | /* See SB+mbonceonces.litmus. */ | 479 | /* See SB+fencembonceonces.litmus. */ |
480 | void CPU0(void) | 480 | void CPU0(void) |
481 | { | 481 | { |
482 | WRITE_ONCE(x, 1); | 482 | WRITE_ONCE(x, 1); |
diff --git a/tools/memory-model/README b/tools/memory-model/README index 734f7feaa5dc..ee987ce20aae 100644 --- a/tools/memory-model/README +++ b/tools/memory-model/README | |||
@@ -35,13 +35,13 @@ BASIC USAGE: HERD7 | |||
35 | The memory model is used, in conjunction with "herd7", to exhaustively | 35 | The memory model is used, in conjunction with "herd7", to exhaustively |
36 | explore the state space of small litmus tests. | 36 | explore the state space of small litmus tests. |
37 | 37 | ||
38 | For example, to run SB+mbonceonces.litmus against the memory model: | 38 | For example, to run SB+fencembonceonces.litmus against the memory model: |
39 | 39 | ||
40 | $ herd7 -conf linux-kernel.cfg litmus-tests/SB+mbonceonces.litmus | 40 | $ herd7 -conf linux-kernel.cfg litmus-tests/SB+fencembonceonces.litmus |
41 | 41 | ||
42 | Here is the corresponding output: | 42 | Here is the corresponding output: |
43 | 43 | ||
44 | Test SB+mbonceonces Allowed | 44 | Test SB+fencembonceonces Allowed |
45 | States 3 | 45 | States 3 |
46 | 0:r0=0; 1:r0=1; | 46 | 0:r0=0; 1:r0=1; |
47 | 0:r0=1; 1:r0=0; | 47 | 0:r0=1; 1:r0=0; |
@@ -50,8 +50,8 @@ Here is the corresponding output: | |||
50 | Witnesses | 50 | Witnesses |
51 | Positive: 0 Negative: 3 | 51 | Positive: 0 Negative: 3 |
52 | Condition exists (0:r0=0 /\ 1:r0=0) | 52 | Condition exists (0:r0=0 /\ 1:r0=0) |
53 | Observation SB+mbonceonces Never 0 3 | 53 | Observation SB+fencembonceonces Never 0 3 |
54 | Time SB+mbonceonces 0.01 | 54 | Time SB+fencembonceonces 0.01 |
55 | Hash=d66d99523e2cac6b06e66f4c995ebb48 | 55 | Hash=d66d99523e2cac6b06e66f4c995ebb48 |
56 | 56 | ||
57 | The "Positive: 0 Negative: 3" and the "Never 0 3" each indicate that | 57 | The "Positive: 0 Negative: 3" and the "Never 0 3" each indicate that |
@@ -67,16 +67,16 @@ BASIC USAGE: KLITMUS7 | |||
67 | The "klitmus7" tool converts a litmus test into a Linux kernel module, | 67 | The "klitmus7" tool converts a litmus test into a Linux kernel module, |
68 | which may then be loaded and run. | 68 | which may then be loaded and run. |
69 | 69 | ||
70 | For example, to run SB+mbonceonces.litmus against hardware: | 70 | For example, to run SB+fencembonceonces.litmus against hardware: |
71 | 71 | ||
72 | $ mkdir mymodules | 72 | $ mkdir mymodules |
73 | $ klitmus7 -o mymodules litmus-tests/SB+mbonceonces.litmus | 73 | $ klitmus7 -o mymodules litmus-tests/SB+fencembonceonces.litmus |
74 | $ cd mymodules ; make | 74 | $ cd mymodules ; make |
75 | $ sudo sh run.sh | 75 | $ sudo sh run.sh |
76 | 76 | ||
77 | The corresponding output includes: | 77 | The corresponding output includes: |
78 | 78 | ||
79 | Test SB+mbonceonces Allowed | 79 | Test SB+fencembonceonces Allowed |
80 | Histogram (3 states) | 80 | Histogram (3 states) |
81 | 644580 :>0:r0=1; 1:r0=0; | 81 | 644580 :>0:r0=1; 1:r0=0; |
82 | 644328 :>0:r0=0; 1:r0=1; | 82 | 644328 :>0:r0=0; 1:r0=1; |
@@ -86,8 +86,8 @@ The corresponding output includes: | |||
86 | Positive: 0, Negative: 2000000 | 86 | Positive: 0, Negative: 2000000 |
87 | Condition exists (0:r0=0 /\ 1:r0=0) is NOT validated | 87 | Condition exists (0:r0=0 /\ 1:r0=0) is NOT validated |
88 | Hash=d66d99523e2cac6b06e66f4c995ebb48 | 88 | Hash=d66d99523e2cac6b06e66f4c995ebb48 |
89 | Observation SB+mbonceonces Never 0 2000000 | 89 | Observation SB+fencembonceonces Never 0 2000000 |
90 | Time SB+mbonceonces 0.16 | 90 | Time SB+fencembonceonces 0.16 |
91 | 91 | ||
92 | The "Positive: 0 Negative: 2000000" and the "Never 0 2000000" indicate | 92 | The "Positive: 0 Negative: 2000000" and the "Never 0 2000000" indicate |
93 | that during two million trials, the state specified in this litmus | 93 | that during two million trials, the state specified in this litmus |
diff --git a/tools/memory-model/linux-kernel.bell b/tools/memory-model/linux-kernel.bell index 64f5740e0e75..b84fb2f67109 100644 --- a/tools/memory-model/linux-kernel.bell +++ b/tools/memory-model/linux-kernel.bell | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | "Linux-kernel memory consistency model" | 14 | "Linux-kernel memory consistency model" |
15 | 15 | ||
16 | enum Accesses = 'once (*READ_ONCE,WRITE_ONCE,ACCESS_ONCE*) || | 16 | enum Accesses = 'once (*READ_ONCE,WRITE_ONCE*) || |
17 | 'release (*smp_store_release*) || | 17 | 'release (*smp_store_release*) || |
18 | 'acquire (*smp_load_acquire*) || | 18 | 'acquire (*smp_load_acquire*) || |
19 | 'noreturn (* R of non-return RMW *) | 19 | 'noreturn (* R of non-return RMW *) |
diff --git a/tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus b/tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus index 98a3716efa37..e729d2776e89 100644 --- a/tools/memory-model/litmus-tests/IRIW+mbonceonces+OnceOnce.litmus +++ b/tools/memory-model/litmus-tests/IRIW+fencembonceonces+OnceOnce.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C IRIW+mbonceonces+OnceOnce | 1 | C IRIW+fencembonceonces+OnceOnce |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus b/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus index 7a39a0aaa976..0f749e419b34 100644 --- a/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus +++ b/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C ISA2+pooncelock+pooncelock+pombonce.litmus | 1 | C ISA2+pooncelock+pooncelock+pombonce |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Sometimes | 4 | * Result: Sometimes |
diff --git a/tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus b/tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus index de6708229dd1..4727f5aaf03b 100644 --- a/tools/memory-model/litmus-tests/LB+ctrlonceonce+mbonceonce.litmus +++ b/tools/memory-model/litmus-tests/LB+fencembonceonce+ctrlonceonce.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C LB+ctrlonceonce+mbonceonce | 1 | C LB+fencembonceonce+ctrlonceonce |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus b/tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus index c078f38ff27a..a273da9faa6d 100644 --- a/tools/memory-model/litmus-tests/MP+wmbonceonce+rmbonceonce.litmus +++ b/tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C MP+wmbonceonce+rmbonceonce | 1 | C MP+fencewmbonceonce+fencermbonceonce |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/R+mbonceonces.litmus b/tools/memory-model/litmus-tests/R+fencembonceonces.litmus index a0e884ad2132..222a0b850b4a 100644 --- a/tools/memory-model/litmus-tests/R+mbonceonces.litmus +++ b/tools/memory-model/litmus-tests/R+fencembonceonces.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C R+mbonceonces | 1 | C R+fencembonceonces |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/README b/tools/memory-model/litmus-tests/README index 17eb9a8c222d..4581ec2d3c57 100644 --- a/tools/memory-model/litmus-tests/README +++ b/tools/memory-model/litmus-tests/README | |||
@@ -18,7 +18,7 @@ CoWW+poonceonce.litmus | |||
18 | Test of write-write coherence, that is, whether or not two | 18 | Test of write-write coherence, that is, whether or not two |
19 | successive writes to the same variable are ordered. | 19 | successive writes to the same variable are ordered. |
20 | 20 | ||
21 | IRIW+mbonceonces+OnceOnce.litmus | 21 | IRIW+fencembonceonces+OnceOnce.litmus |
22 | Test of independent reads from independent writes with smp_mb() | 22 | Test of independent reads from independent writes with smp_mb() |
23 | between each pairs of reads. In other words, is smp_mb() | 23 | between each pairs of reads. In other words, is smp_mb() |
24 | sufficient to cause two different reading processes to agree on | 24 | sufficient to cause two different reading processes to agree on |
@@ -47,7 +47,7 @@ ISA2+pooncerelease+poacquirerelease+poacquireonce.litmus | |||
47 | Can a release-acquire chain order a prior store against | 47 | Can a release-acquire chain order a prior store against |
48 | a later load? | 48 | a later load? |
49 | 49 | ||
50 | LB+ctrlonceonce+mbonceonce.litmus | 50 | LB+fencembonceonce+ctrlonceonce.litmus |
51 | Does a control dependency and an smp_mb() suffice for the | 51 | Does a control dependency and an smp_mb() suffice for the |
52 | load-buffering litmus test, where each process reads from one | 52 | load-buffering litmus test, where each process reads from one |
53 | of two variables then writes to the other? | 53 | of two variables then writes to the other? |
@@ -88,14 +88,14 @@ MP+porevlocks.litmus | |||
88 | As below, but with the first access of the writer process | 88 | As below, but with the first access of the writer process |
89 | and the second access of reader process protected by a lock. | 89 | and the second access of reader process protected by a lock. |
90 | 90 | ||
91 | MP+wmbonceonce+rmbonceonce.litmus | 91 | MP+fencewmbonceonce+fencermbonceonce.litmus |
92 | Does a smp_wmb() (between the stores) and an smp_rmb() (between | 92 | Does a smp_wmb() (between the stores) and an smp_rmb() (between |
93 | the loads) suffice for the message-passing litmus test, where one | 93 | the loads) suffice for the message-passing litmus test, where one |
94 | process writes data and then a flag, and the other process reads | 94 | process writes data and then a flag, and the other process reads |
95 | the flag and then the data. (This is similar to the ISA2 tests, | 95 | the flag and then the data. (This is similar to the ISA2 tests, |
96 | but with two processes instead of three.) | 96 | but with two processes instead of three.) |
97 | 97 | ||
98 | R+mbonceonces.litmus | 98 | R+fencembonceonces.litmus |
99 | This is the fully ordered (via smp_mb()) version of one of | 99 | This is the fully ordered (via smp_mb()) version of one of |
100 | the classic counterintuitive litmus tests that illustrates the | 100 | the classic counterintuitive litmus tests that illustrates the |
101 | effects of store propagation delays. | 101 | effects of store propagation delays. |
@@ -103,7 +103,7 @@ R+mbonceonces.litmus | |||
103 | R+poonceonces.litmus | 103 | R+poonceonces.litmus |
104 | As above, but without the smp_mb() invocations. | 104 | As above, but without the smp_mb() invocations. |
105 | 105 | ||
106 | SB+mbonceonces.litmus | 106 | SB+fencembonceonces.litmus |
107 | This is the fully ordered (again, via smp_mb() version of store | 107 | This is the fully ordered (again, via smp_mb() version of store |
108 | buffering, which forms the core of Dekker's mutual-exclusion | 108 | buffering, which forms the core of Dekker's mutual-exclusion |
109 | algorithm. | 109 | algorithm. |
@@ -111,15 +111,24 @@ SB+mbonceonces.litmus | |||
111 | SB+poonceonces.litmus | 111 | SB+poonceonces.litmus |
112 | As above, but without the smp_mb() invocations. | 112 | As above, but without the smp_mb() invocations. |
113 | 113 | ||
114 | SB+rfionceonce-poonceonces.litmus | ||
115 | This litmus test demonstrates that LKMM is not fully multicopy | ||
116 | atomic. (Neither is it other multicopy atomic.) This litmus test | ||
117 | also demonstrates the "locations" debugging aid, which designates | ||
118 | additional registers and locations to be printed out in the dump | ||
119 | of final states in the herd7 output. Without the "locations" | ||
120 | statement, only those registers and locations mentioned in the | ||
121 | "exists" clause will be printed. | ||
122 | |||
114 | S+poonceonces.litmus | 123 | S+poonceonces.litmus |
115 | As below, but without the smp_wmb() and acquire load. | 124 | As below, but without the smp_wmb() and acquire load. |
116 | 125 | ||
117 | S+wmbonceonce+poacquireonce.litmus | 126 | S+fencewmbonceonce+poacquireonce.litmus |
118 | Can a smp_wmb(), instead of a release, and an acquire order | 127 | Can a smp_wmb(), instead of a release, and an acquire order |
119 | a prior store against a subsequent store? | 128 | a prior store against a subsequent store? |
120 | 129 | ||
121 | WRC+poonceonces+Once.litmus | 130 | WRC+poonceonces+Once.litmus |
122 | WRC+pooncerelease+rmbonceonce+Once.litmus | 131 | WRC+pooncerelease+fencermbonceonce+Once.litmus |
123 | These two are members of an extension of the MP litmus-test | 132 | These two are members of an extension of the MP litmus-test |
124 | class in which the first write is moved to a separate process. | 133 | class in which the first write is moved to a separate process. |
125 | The second is forbidden because smp_store_release() is | 134 | The second is forbidden because smp_store_release() is |
@@ -134,7 +143,7 @@ Z6.0+pooncelock+poonceLock+pombonce.litmus | |||
134 | As above, but with smp_mb__after_spinlock() immediately | 143 | As above, but with smp_mb__after_spinlock() immediately |
135 | following the spin_lock(). | 144 | following the spin_lock(). |
136 | 145 | ||
137 | Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus | 146 | Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus |
138 | Is the ordering provided by a release-acquire chain sufficient | 147 | Is the ordering provided by a release-acquire chain sufficient |
139 | to make ordering apparent to accesses by a process that does | 148 | to make ordering apparent to accesses by a process that does |
140 | not participate in that release-acquire chain? | 149 | not participate in that release-acquire chain? |
diff --git a/tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus b/tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus index c53350205d28..18479823cd6c 100644 --- a/tools/memory-model/litmus-tests/S+wmbonceonce+poacquireonce.litmus +++ b/tools/memory-model/litmus-tests/S+fencewmbonceonce+poacquireonce.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C S+wmbonceonce+poacquireonce | 1 | C S+fencewmbonceonce+poacquireonce |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/SB+mbonceonces.litmus b/tools/memory-model/litmus-tests/SB+fencembonceonces.litmus index 74b874ffa8da..ed5fff18d223 100644 --- a/tools/memory-model/litmus-tests/SB+mbonceonces.litmus +++ b/tools/memory-model/litmus-tests/SB+fencembonceonces.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C SB+mbonceonces | 1 | C SB+fencembonceonces |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus b/tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus new file mode 100644 index 000000000000..04a16603660b --- /dev/null +++ b/tools/memory-model/litmus-tests/SB+rfionceonce-poonceonces.litmus | |||
@@ -0,0 +1,32 @@ | |||
1 | C SB+rfionceonce-poonceonces | ||
2 | |||
3 | (* | ||
4 | * Result: Sometimes | ||
5 | * | ||
6 | * This litmus test demonstrates that LKMM is not fully multicopy atomic. | ||
7 | *) | ||
8 | |||
9 | {} | ||
10 | |||
11 | P0(int *x, int *y) | ||
12 | { | ||
13 | int r1; | ||
14 | int r2; | ||
15 | |||
16 | WRITE_ONCE(*x, 1); | ||
17 | r1 = READ_ONCE(*x); | ||
18 | r2 = READ_ONCE(*y); | ||
19 | } | ||
20 | |||
21 | P1(int *x, int *y) | ||
22 | { | ||
23 | int r3; | ||
24 | int r4; | ||
25 | |||
26 | WRITE_ONCE(*y, 1); | ||
27 | r3 = READ_ONCE(*y); | ||
28 | r4 = READ_ONCE(*x); | ||
29 | } | ||
30 | |||
31 | locations [0:r1; 1:r3; x; y] (* Debug aid: Print things not in "exists". *) | ||
32 | exists (0:r2=0 /\ 1:r4=0) | ||
diff --git a/tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus b/tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus index ad3448b941e6..e9947250d7de 100644 --- a/tools/memory-model/litmus-tests/WRC+pooncerelease+rmbonceonce+Once.litmus +++ b/tools/memory-model/litmus-tests/WRC+pooncerelease+fencermbonceonce+Once.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C WRC+pooncerelease+rmbonceonce+Once | 1 | C WRC+pooncerelease+fencermbonceonce+Once |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Never | 4 | * Result: Never |
diff --git a/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus b/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus index a20fc3fafb53..88e70b87a683 100644 --- a/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+mbonceonce.litmus +++ b/tools/memory-model/litmus-tests/Z6.0+pooncerelease+poacquirerelease+fencembonceonce.litmus | |||
@@ -1,4 +1,4 @@ | |||
1 | C Z6.0+pooncerelease+poacquirerelease+mbonceonce | 1 | C Z6.0+pooncerelease+poacquirerelease+fencembonceonce |
2 | 2 | ||
3 | (* | 3 | (* |
4 | * Result: Sometimes | 4 | * Result: Sometimes |
diff --git a/tools/memory-model/scripts/checkalllitmus.sh b/tools/memory-model/scripts/checkalllitmus.sh index af0aa15ab84e..ca528f9a24d4 100644..100755 --- a/tools/memory-model/scripts/checkalllitmus.sh +++ b/tools/memory-model/scripts/checkalllitmus.sh | |||
@@ -9,7 +9,7 @@ | |||
9 | # appended. | 9 | # appended. |
10 | # | 10 | # |
11 | # Usage: | 11 | # Usage: |
12 | # sh checkalllitmus.sh [ directory ] | 12 | # checkalllitmus.sh [ directory ] |
13 | # | 13 | # |
14 | # The LINUX_HERD_OPTIONS environment variable may be used to specify | 14 | # The LINUX_HERD_OPTIONS environment variable may be used to specify |
15 | # arguments to herd, whose default is defined by the checklitmus.sh script. | 15 | # arguments to herd, whose default is defined by the checklitmus.sh script. |
diff --git a/tools/memory-model/scripts/checklitmus.sh b/tools/memory-model/scripts/checklitmus.sh index e2e477472844..bf12a75c0719 100644..100755 --- a/tools/memory-model/scripts/checklitmus.sh +++ b/tools/memory-model/scripts/checklitmus.sh | |||
@@ -8,7 +8,7 @@ | |||
8 | # with ".out" appended. | 8 | # with ".out" appended. |
9 | # | 9 | # |
10 | # Usage: | 10 | # Usage: |
11 | # sh checklitmus.sh file.litmus | 11 | # checklitmus.sh file.litmus |
12 | # | 12 | # |
13 | # The LINUX_HERD_OPTIONS environment variable may be used to specify | 13 | # The LINUX_HERD_OPTIONS environment variable may be used to specify |
14 | # arguments to herd, which default to "-conf linux-kernel.cfg". Thus, | 14 | # arguments to herd, which default to "-conf linux-kernel.cfg". Thus, |
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index f76d9914686a..c9d038f91af6 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile | |||
@@ -31,8 +31,8 @@ INCLUDES := -I$(srctree)/tools/include \ | |||
31 | -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ | 31 | -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ |
32 | -I$(srctree)/tools/objtool/arch/$(ARCH)/include | 32 | -I$(srctree)/tools/objtool/arch/$(ARCH)/include |
33 | WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed | 33 | WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed |
34 | CFLAGS += -Werror $(WARNINGS) $(HOSTCFLAGS) -g $(INCLUDES) | 34 | CFLAGS += -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) |
35 | LDFLAGS += -lelf $(LIBSUBCMD) $(HOSTLDFLAGS) | 35 | LDFLAGS += -lelf $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS) |
36 | 36 | ||
37 | # Allow old libelf to be used: | 37 | # Allow old libelf to be used: |
38 | elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr) | 38 | elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr) |
diff --git a/tools/objtool/arch/x86/include/asm/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h index 9c9dc579bd7d..46f516dd80ce 100644 --- a/tools/objtool/arch/x86/include/asm/orc_types.h +++ b/tools/objtool/arch/x86/include/asm/orc_types.h | |||
@@ -88,6 +88,7 @@ struct orc_entry { | |||
88 | unsigned sp_reg:4; | 88 | unsigned sp_reg:4; |
89 | unsigned bp_reg:4; | 89 | unsigned bp_reg:4; |
90 | unsigned type:2; | 90 | unsigned type:2; |
91 | unsigned end:1; | ||
91 | } __packed; | 92 | } __packed; |
92 | 93 | ||
93 | /* | 94 | /* |
@@ -101,6 +102,7 @@ struct unwind_hint { | |||
101 | s16 sp_offset; | 102 | s16 sp_offset; |
102 | u8 sp_reg; | 103 | u8 sp_reg; |
103 | u8 type; | 104 | u8 type; |
105 | u8 end; | ||
104 | }; | 106 | }; |
105 | #endif /* __ASSEMBLY__ */ | 107 | #endif /* __ASSEMBLY__ */ |
106 | 108 | ||
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f4a25bd1871f..2928939b98ec 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
@@ -1157,6 +1157,7 @@ static int read_unwind_hints(struct objtool_file *file) | |||
1157 | 1157 | ||
1158 | cfa->offset = hint->sp_offset; | 1158 | cfa->offset = hint->sp_offset; |
1159 | insn->state.type = hint->type; | 1159 | insn->state.type = hint->type; |
1160 | insn->state.end = hint->end; | ||
1160 | } | 1161 | } |
1161 | 1162 | ||
1162 | return 0; | 1163 | return 0; |
diff --git a/tools/objtool/check.h b/tools/objtool/check.h index c6b68fcb926f..95700a2bcb7c 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h | |||
@@ -31,7 +31,7 @@ struct insn_state { | |||
31 | int stack_size; | 31 | int stack_size; |
32 | unsigned char type; | 32 | unsigned char type; |
33 | bool bp_scratch; | 33 | bool bp_scratch; |
34 | bool drap; | 34 | bool drap, end; |
35 | int drap_reg, drap_offset; | 35 | int drap_reg, drap_offset; |
36 | struct cfi_reg vals[CFI_NUM_REGS]; | 36 | struct cfi_reg vals[CFI_NUM_REGS]; |
37 | }; | 37 | }; |
diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c index c3343820916a..faa444270ee3 100644 --- a/tools/objtool/orc_dump.c +++ b/tools/objtool/orc_dump.c | |||
@@ -203,7 +203,8 @@ int orc_dump(const char *_objname) | |||
203 | 203 | ||
204 | print_reg(orc[i].bp_reg, orc[i].bp_offset); | 204 | print_reg(orc[i].bp_reg, orc[i].bp_offset); |
205 | 205 | ||
206 | printf(" type:%s\n", orc_type_name(orc[i].type)); | 206 | printf(" type:%s end:%d\n", |
207 | orc_type_name(orc[i].type), orc[i].end); | ||
207 | } | 208 | } |
208 | 209 | ||
209 | elf_end(elf); | 210 | elf_end(elf); |
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 18384d9be4e1..3f98dcfbc177 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c | |||
@@ -31,6 +31,8 @@ int create_orc(struct objtool_file *file) | |||
31 | struct cfi_reg *cfa = &insn->state.cfa; | 31 | struct cfi_reg *cfa = &insn->state.cfa; |
32 | struct cfi_reg *bp = &insn->state.regs[CFI_BP]; | 32 | struct cfi_reg *bp = &insn->state.regs[CFI_BP]; |
33 | 33 | ||
34 | orc->end = insn->state.end; | ||
35 | |||
34 | if (cfa->base == CFI_UNDEFINED) { | 36 | if (cfa->base == CFI_UNDEFINED) { |
35 | orc->sp_reg = ORC_REG_UNDEFINED; | 37 | orc->sp_reg = ORC_REG_UNDEFINED; |
36 | continue; | 38 | continue; |
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index 9074b477bff0..af146bb03b4d 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c | |||
@@ -31,12 +31,17 @@ | |||
31 | #define BILLION 1E9 | 31 | #define BILLION 1E9 |
32 | 32 | ||
33 | static char *result[] = { "NOT OKAY", "OKAY" }; | 33 | static char *result[] = { "NOT OKAY", "OKAY" }; |
34 | static char *irq[] = { "LEGACY", "MSI", "MSI-X" }; | ||
34 | 35 | ||
35 | struct pci_test { | 36 | struct pci_test { |
36 | char *device; | 37 | char *device; |
37 | char barnum; | 38 | char barnum; |
38 | bool legacyirq; | 39 | bool legacyirq; |
39 | unsigned int msinum; | 40 | unsigned int msinum; |
41 | unsigned int msixnum; | ||
42 | int irqtype; | ||
43 | bool set_irqtype; | ||
44 | bool get_irqtype; | ||
40 | bool read; | 45 | bool read; |
41 | bool write; | 46 | bool write; |
42 | bool copy; | 47 | bool copy; |
@@ -65,6 +70,24 @@ static int run_test(struct pci_test *test) | |||
65 | fprintf(stdout, "%s\n", result[ret]); | 70 | fprintf(stdout, "%s\n", result[ret]); |
66 | } | 71 | } |
67 | 72 | ||
73 | if (test->set_irqtype) { | ||
74 | ret = ioctl(fd, PCITEST_SET_IRQTYPE, test->irqtype); | ||
75 | fprintf(stdout, "SET IRQ TYPE TO %s:\t\t", irq[test->irqtype]); | ||
76 | if (ret < 0) | ||
77 | fprintf(stdout, "FAILED\n"); | ||
78 | else | ||
79 | fprintf(stdout, "%s\n", result[ret]); | ||
80 | } | ||
81 | |||
82 | if (test->get_irqtype) { | ||
83 | ret = ioctl(fd, PCITEST_GET_IRQTYPE); | ||
84 | fprintf(stdout, "GET IRQ TYPE:\t\t"); | ||
85 | if (ret < 0) | ||
86 | fprintf(stdout, "FAILED\n"); | ||
87 | else | ||
88 | fprintf(stdout, "%s\n", irq[ret]); | ||
89 | } | ||
90 | |||
68 | if (test->legacyirq) { | 91 | if (test->legacyirq) { |
69 | ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0); | 92 | ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0); |
70 | fprintf(stdout, "LEGACY IRQ:\t"); | 93 | fprintf(stdout, "LEGACY IRQ:\t"); |
@@ -83,6 +106,15 @@ static int run_test(struct pci_test *test) | |||
83 | fprintf(stdout, "%s\n", result[ret]); | 106 | fprintf(stdout, "%s\n", result[ret]); |
84 | } | 107 | } |
85 | 108 | ||
109 | if (test->msixnum > 0 && test->msixnum <= 2048) { | ||
110 | ret = ioctl(fd, PCITEST_MSIX, test->msixnum); | ||
111 | fprintf(stdout, "MSI-X%d:\t\t", test->msixnum); | ||
112 | if (ret < 0) | ||
113 | fprintf(stdout, "TEST FAILED\n"); | ||
114 | else | ||
115 | fprintf(stdout, "%s\n", result[ret]); | ||
116 | } | ||
117 | |||
86 | if (test->write) { | 118 | if (test->write) { |
87 | ret = ioctl(fd, PCITEST_WRITE, test->size); | 119 | ret = ioctl(fd, PCITEST_WRITE, test->size); |
88 | fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); | 120 | fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size); |
@@ -133,7 +165,7 @@ int main(int argc, char **argv) | |||
133 | /* set default endpoint device */ | 165 | /* set default endpoint device */ |
134 | test->device = "/dev/pci-endpoint-test.0"; | 166 | test->device = "/dev/pci-endpoint-test.0"; |
135 | 167 | ||
136 | while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF) | 168 | while ((c = getopt(argc, argv, "D:b:m:x:i:Ilrwcs:")) != EOF) |
137 | switch (c) { | 169 | switch (c) { |
138 | case 'D': | 170 | case 'D': |
139 | test->device = optarg; | 171 | test->device = optarg; |
@@ -151,6 +183,20 @@ int main(int argc, char **argv) | |||
151 | if (test->msinum < 1 || test->msinum > 32) | 183 | if (test->msinum < 1 || test->msinum > 32) |
152 | goto usage; | 184 | goto usage; |
153 | continue; | 185 | continue; |
186 | case 'x': | ||
187 | test->msixnum = atoi(optarg); | ||
188 | if (test->msixnum < 1 || test->msixnum > 2048) | ||
189 | goto usage; | ||
190 | continue; | ||
191 | case 'i': | ||
192 | test->irqtype = atoi(optarg); | ||
193 | if (test->irqtype < 0 || test->irqtype > 2) | ||
194 | goto usage; | ||
195 | test->set_irqtype = true; | ||
196 | continue; | ||
197 | case 'I': | ||
198 | test->get_irqtype = true; | ||
199 | continue; | ||
154 | case 'r': | 200 | case 'r': |
155 | test->read = true; | 201 | test->read = true; |
156 | continue; | 202 | continue; |
@@ -173,6 +219,9 @@ usage: | |||
173 | "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" | 219 | "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" |
174 | "\t-b <bar num> BAR test (bar number between 0..5)\n" | 220 | "\t-b <bar num> BAR test (bar number between 0..5)\n" |
175 | "\t-m <msi num> MSI test (msi number between 1..32)\n" | 221 | "\t-m <msi num> MSI test (msi number between 1..32)\n" |
222 | "\t-x <msix num> \tMSI-X test (msix number between 1..2048)\n" | ||
223 | "\t-i <irq type> \tSet IRQ type (0 - Legacy, 1 - MSI, 2 - MSI-X)\n" | ||
224 | "\t-I Get current IRQ type configured\n" | ||
176 | "\t-l Legacy IRQ test\n" | 225 | "\t-l Legacy IRQ test\n" |
177 | "\t-r Read buffer test\n" | 226 | "\t-r Read buffer test\n" |
178 | "\t-w Write buffer test\n" | 227 | "\t-w Write buffer test\n" |
diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh index 77e8c85ef744..75ed48ff2990 100644 --- a/tools/pci/pcitest.sh +++ b/tools/pci/pcitest.sh | |||
@@ -16,7 +16,10 @@ echo | |||
16 | echo "Interrupt tests" | 16 | echo "Interrupt tests" |
17 | echo | 17 | echo |
18 | 18 | ||
19 | pcitest -i 0 | ||
19 | pcitest -l | 20 | pcitest -l |
21 | |||
22 | pcitest -i 1 | ||
20 | msi=1 | 23 | msi=1 |
21 | 24 | ||
22 | while [ $msi -lt 33 ] | 25 | while [ $msi -lt 33 ] |
@@ -26,9 +29,21 @@ do | |||
26 | done | 29 | done |
27 | echo | 30 | echo |
28 | 31 | ||
32 | pcitest -i 2 | ||
33 | msix=1 | ||
34 | |||
35 | while [ $msix -lt 2049 ] | ||
36 | do | ||
37 | pcitest -x $msix | ||
38 | msix=`expr $msix + 1` | ||
39 | done | ||
40 | echo | ||
41 | |||
29 | echo "Read Tests" | 42 | echo "Read Tests" |
30 | echo | 43 | echo |
31 | 44 | ||
45 | pcitest -i 1 | ||
46 | |||
32 | pcitest -r -s 1 | 47 | pcitest -r -s 1 |
33 | pcitest -r -s 1024 | 48 | pcitest -r -s 1024 |
34 | pcitest -r -s 1025 | 49 | pcitest -r -s 1025 |
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 11300dbe35c5..236b9b97dfdb 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt | |||
@@ -18,6 +18,10 @@ various perf commands with the -e option. | |||
18 | 18 | ||
19 | OPTIONS | 19 | OPTIONS |
20 | ------- | 20 | ------- |
21 | -d:: | ||
22 | --desc:: | ||
23 | Print extra event descriptions. (default) | ||
24 | |||
21 | --no-desc:: | 25 | --no-desc:: |
22 | Don't print descriptions. | 26 | Don't print descriptions. |
23 | 27 | ||
@@ -25,11 +29,13 @@ Don't print descriptions. | |||
25 | --long-desc:: | 29 | --long-desc:: |
26 | Print longer event descriptions. | 30 | Print longer event descriptions. |
27 | 31 | ||
32 | --debug:: | ||
33 | Enable debugging output. | ||
34 | |||
28 | --details:: | 35 | --details:: |
29 | Print how named events are resolved internally into perf events, and also | 36 | Print how named events are resolved internally into perf events, and also |
30 | any extra expressions computed by perf stat. | 37 | any extra expressions computed by perf stat. |
31 | 38 | ||
32 | |||
33 | [[EVENT_MODIFIERS]] | 39 | [[EVENT_MODIFIERS]] |
34 | EVENT MODIFIERS | 40 | EVENT MODIFIERS |
35 | --------------- | 41 | --------------- |
@@ -234,7 +240,7 @@ perf also supports group leader sampling using the :S specifier. | |||
234 | perf record -e '{cycles,instructions}:S' ... | 240 | perf record -e '{cycles,instructions}:S' ... |
235 | perf report --group | 241 | perf report --group |
236 | 242 | ||
237 | Normally all events in a event group sample, but with :S only | 243 | Normally all events in an event group sample, but with :S only |
238 | the first event (the leader) samples, and it only reads the values of the | 244 | the first event (the leader) samples, and it only reads the values of the |
239 | other events in the group. | 245 | other events in the group. |
240 | 246 | ||
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 04168da4268e..246dee081efd 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -94,7 +94,7 @@ OPTIONS | |||
94 | "perf report" to view group events together. | 94 | "perf report" to view group events together. |
95 | 95 | ||
96 | --filter=<filter>:: | 96 | --filter=<filter>:: |
97 | Event filter. This option should follow a event selector (-e) which | 97 | Event filter. This option should follow an event selector (-e) which |
98 | selects either tracepoint event(s) or a hardware trace PMU | 98 | selects either tracepoint event(s) or a hardware trace PMU |
99 | (e.g. Intel PT or CoreSight). | 99 | (e.g. Intel PT or CoreSight). |
100 | 100 | ||
@@ -153,7 +153,7 @@ OPTIONS | |||
153 | 153 | ||
154 | --exclude-perf:: | 154 | --exclude-perf:: |
155 | Don't record events issued by perf itself. This option should follow | 155 | Don't record events issued by perf itself. This option should follow |
156 | a event selector (-e) which selects tracepoint event(s). It adds a | 156 | an event selector (-e) which selects tracepoint event(s). It adds a |
157 | filter expression 'common_pid != $PERFPID' to filters. If other | 157 | filter expression 'common_pid != $PERFPID' to filters. If other |
158 | '--filter' exists, the new filter expression will be combined with | 158 | '--filter' exists, the new filter expression will be combined with |
159 | them by '&&'. | 159 | them by '&&'. |
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index f5a3b402589e..f6d1a03c7523 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config | |||
@@ -54,6 +54,8 @@ endif | |||
54 | 54 | ||
55 | ifeq ($(SRCARCH),arm64) | 55 | ifeq ($(SRCARCH),arm64) |
56 | NO_PERF_REGS := 0 | 56 | NO_PERF_REGS := 0 |
57 | NO_SYSCALL_TABLE := 0 | ||
58 | CFLAGS += -I$(OUTPUT)arch/arm64/include/generated | ||
57 | LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 | 59 | LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 |
58 | endif | 60 | endif |
59 | 61 | ||
@@ -905,8 +907,8 @@ bindir = $(abspath $(prefix)/$(bindir_relative)) | |||
905 | mandir = share/man | 907 | mandir = share/man |
906 | infodir = share/info | 908 | infodir = share/info |
907 | perfexecdir = libexec/perf-core | 909 | perfexecdir = libexec/perf-core |
908 | perf_include_dir = lib/include/perf | 910 | perf_include_dir = lib/perf/include |
909 | perf_examples_dir = lib/examples/perf | 911 | perf_examples_dir = lib/perf/examples |
910 | sharedir = $(prefix)/share | 912 | sharedir = $(prefix)/share |
911 | template_dir = share/perf-core/templates | 913 | template_dir = share/perf-core/templates |
912 | STRACE_GROUPS_DIR = share/perf-core/strace/groups | 914 | STRACE_GROUPS_DIR = share/perf-core/strace/groups |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index ecc9fc952655..b3d1b12a5081 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -384,6 +384,8 @@ export INSTALL SHELL_PATH | |||
384 | 384 | ||
385 | SHELL = $(SHELL_PATH) | 385 | SHELL = $(SHELL_PATH) |
386 | 386 | ||
387 | linux_uapi_dir := $(srctree)/tools/include/uapi/linux | ||
388 | |||
387 | beauty_outdir := $(OUTPUT)trace/beauty/generated | 389 | beauty_outdir := $(OUTPUT)trace/beauty/generated |
388 | beauty_ioctl_outdir := $(beauty_outdir)/ioctl | 390 | beauty_ioctl_outdir := $(beauty_outdir)/ioctl |
389 | drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c | 391 | drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c |
@@ -431,6 +433,12 @@ kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh | |||
431 | $(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) | 433 | $(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) |
432 | $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@ | 434 | $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@ |
433 | 435 | ||
436 | socket_ipproto_array := $(beauty_outdir)/socket_ipproto_array.c | ||
437 | socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh | ||
438 | |||
439 | $(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl) | ||
440 | $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@ | ||
441 | |||
434 | vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c | 442 | vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c |
435 | vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux | 443 | vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux |
436 | vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh | 444 | vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh |
@@ -566,6 +574,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc | |||
566 | $(sndrv_ctl_ioctl_array) \ | 574 | $(sndrv_ctl_ioctl_array) \ |
567 | $(kcmp_type_array) \ | 575 | $(kcmp_type_array) \ |
568 | $(kvm_ioctl_array) \ | 576 | $(kvm_ioctl_array) \ |
577 | $(socket_ipproto_array) \ | ||
569 | $(vhost_virtio_ioctl_array) \ | 578 | $(vhost_virtio_ioctl_array) \ |
570 | $(madvise_behavior_array) \ | 579 | $(madvise_behavior_array) \ |
571 | $(perf_ioctl_array) \ | 580 | $(perf_ioctl_array) \ |
@@ -860,6 +869,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea | |||
860 | $(OUTPUT)$(sndrv_pcm_ioctl_array) \ | 869 | $(OUTPUT)$(sndrv_pcm_ioctl_array) \ |
861 | $(OUTPUT)$(kvm_ioctl_array) \ | 870 | $(OUTPUT)$(kvm_ioctl_array) \ |
862 | $(OUTPUT)$(kcmp_type_array) \ | 871 | $(OUTPUT)$(kcmp_type_array) \ |
872 | $(OUTPUT)$(socket_ipproto_array) \ | ||
863 | $(OUTPUT)$(vhost_virtio_ioctl_array) \ | 873 | $(OUTPUT)$(vhost_virtio_ioctl_array) \ |
864 | $(OUTPUT)$(perf_ioctl_array) \ | 874 | $(OUTPUT)$(perf_ioctl_array) \ |
865 | $(OUTPUT)$(prctl_option_array) \ | 875 | $(OUTPUT)$(prctl_option_array) \ |
diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile index 91de4860faad..f013b115dc86 100644 --- a/tools/perf/arch/arm64/Makefile +++ b/tools/perf/arch/arm64/Makefile | |||
@@ -4,3 +4,24 @@ PERF_HAVE_DWARF_REGS := 1 | |||
4 | endif | 4 | endif |
5 | PERF_HAVE_JITDUMP := 1 | 5 | PERF_HAVE_JITDUMP := 1 |
6 | PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 | 6 | PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1 |
7 | |||
8 | # | ||
9 | # Syscall table generation for perf | ||
10 | # | ||
11 | |||
12 | out := $(OUTPUT)arch/arm64/include/generated/asm | ||
13 | header := $(out)/syscalls.c | ||
14 | sysdef := $(srctree)/tools/include/uapi/asm-generic/unistd.h | ||
15 | sysprf := $(srctree)/tools/perf/arch/arm64/entry/syscalls/ | ||
16 | systbl := $(sysprf)/mksyscalltbl | ||
17 | |||
18 | # Create output directory if not already present | ||
19 | _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') | ||
20 | |||
21 | $(header): $(sysdef) $(systbl) | ||
22 | $(Q)$(SHELL) '$(systbl)' '$(CC)' '$(HOSTCC)' $(sysdef) > $@ | ||
23 | |||
24 | clean:: | ||
25 | $(call QUIET_CLEAN, arm64) $(RM) $(header) | ||
26 | |||
27 | archheaders: $(header) | ||
diff --git a/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl new file mode 100755 index 000000000000..52e197317d3e --- /dev/null +++ b/tools/perf/arch/arm64/entry/syscalls/mksyscalltbl | |||
@@ -0,0 +1,62 @@ | |||
1 | #!/bin/sh | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | # | ||
4 | # Generate system call table for perf. Derived from | ||
5 | # powerpc script. | ||
6 | # | ||
7 | # Copyright IBM Corp. 2017 | ||
8 | # Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | ||
9 | # Changed by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> | ||
10 | # Changed by: Kim Phillips <kim.phillips@arm.com> | ||
11 | |||
12 | gcc=$1 | ||
13 | hostcc=$2 | ||
14 | input=$3 | ||
15 | |||
16 | if ! test -r $input; then | ||
17 | echo "Could not read input file" >&2 | ||
18 | exit 1 | ||
19 | fi | ||
20 | |||
21 | create_table_from_c() | ||
22 | { | ||
23 | local sc nr last_sc | ||
24 | |||
25 | create_table_exe=`mktemp /tmp/create-table-XXXXXX` | ||
26 | |||
27 | { | ||
28 | |||
29 | cat <<-_EoHEADER | ||
30 | #include <stdio.h> | ||
31 | #define __ARCH_WANT_RENAMEAT | ||
32 | #include "$input" | ||
33 | int main(int argc, char *argv[]) | ||
34 | { | ||
35 | _EoHEADER | ||
36 | |||
37 | while read sc nr; do | ||
38 | printf "%s\n" " printf(\"\\t[%d] = \\\"$sc\\\",\\n\", __NR_$sc);" | ||
39 | last_sc=$sc | ||
40 | done | ||
41 | |||
42 | printf "%s\n" " printf(\"#define SYSCALLTBL_ARM64_MAX_ID %d\\n\", __NR_$last_sc);" | ||
43 | printf "}\n" | ||
44 | |||
45 | } | $hostcc -o $create_table_exe -x c - | ||
46 | |||
47 | $create_table_exe | ||
48 | |||
49 | rm -f $create_table_exe | ||
50 | } | ||
51 | |||
52 | create_table() | ||
53 | { | ||
54 | echo "static const char *syscalltbl_arm64[] = {" | ||
55 | create_table_from_c | ||
56 | echo "};" | ||
57 | } | ||
58 | |||
59 | $gcc -E -dM -x c $input \ | ||
60 | |sed -ne 's/^#define __NR_//p' \ | ||
61 | |sort -t' ' -k2 -nu \ | ||
62 | |create_table | ||
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index ef5d59a5742e..7c6eeb4633fe 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c | |||
@@ -58,9 +58,13 @@ static int check_return_reg(int ra_regno, Dwarf_Frame *frame) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Check if return address is on the stack. | 61 | * Check if return address is on the stack. If return address |
62 | * is in a register (typically R0), it is yet to be saved on | ||
63 | * the stack. | ||
62 | */ | 64 | */ |
63 | if (nops != 0 || ops != NULL) | 65 | if ((nops != 0 || ops != NULL) && |
66 | !(nops == 1 && ops[0].atom == DW_OP_regx && | ||
67 | ops[0].number2 == 0 && ops[0].offset == 0)) | ||
64 | return 0; | 68 | return 0; |
65 | 69 | ||
66 | /* | 70 | /* |
@@ -246,7 +250,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) | |||
246 | if (!chain || chain->nr < 3) | 250 | if (!chain || chain->nr < 3) |
247 | return skip_slot; | 251 | return skip_slot; |
248 | 252 | ||
249 | ip = chain->ips[2]; | 253 | ip = chain->ips[1]; |
250 | 254 | ||
251 | thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); | 255 | thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); |
252 | 256 | ||
diff --git a/tools/perf/arch/s390/util/kvm-stat.c b/tools/perf/arch/s390/util/kvm-stat.c index d233e2eb9592..aaabab5e2830 100644 --- a/tools/perf/arch/s390/util/kvm-stat.c +++ b/tools/perf/arch/s390/util/kvm-stat.c | |||
@@ -102,7 +102,7 @@ const char * const kvm_skip_events[] = { | |||
102 | 102 | ||
103 | int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) | 103 | int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) |
104 | { | 104 | { |
105 | if (strstr(cpuid, "IBM/S390")) { | 105 | if (strstr(cpuid, "IBM")) { |
106 | kvm->exit_reasons = sie_exit_reasons; | 106 | kvm->exit_reasons = sie_exit_reasons; |
107 | kvm->exit_reasons_isa = "SIE"; | 107 | kvm->exit_reasons_isa = "SIE"; |
108 | } else | 108 | } else |
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 6a8738f7ead3..f3aa9d02a5ab 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c | |||
@@ -2193,7 +2193,7 @@ static void print_cacheline(struct c2c_hists *c2c_hists, | |||
2193 | fprintf(out, "%s\n", bf); | 2193 | fprintf(out, "%s\n", bf); |
2194 | fprintf(out, " -------------------------------------------------------------\n"); | 2194 | fprintf(out, " -------------------------------------------------------------\n"); |
2195 | 2195 | ||
2196 | hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, true); | 2196 | hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, false); |
2197 | } | 2197 | } |
2198 | 2198 | ||
2199 | static void print_pareto(FILE *out) | 2199 | static void print_pareto(FILE *out) |
@@ -2268,7 +2268,7 @@ static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session) | |||
2268 | fprintf(out, "=================================================\n"); | 2268 | fprintf(out, "=================================================\n"); |
2269 | fprintf(out, "#\n"); | 2269 | fprintf(out, "#\n"); |
2270 | 2270 | ||
2271 | hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, false); | 2271 | hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, true); |
2272 | 2272 | ||
2273 | fprintf(out, "\n"); | 2273 | fprintf(out, "\n"); |
2274 | fprintf(out, "=================================================\n"); | 2274 | fprintf(out, "=================================================\n"); |
@@ -2349,6 +2349,9 @@ static int perf_c2c__browse_cacheline(struct hist_entry *he) | |||
2349 | " s Toggle full length of symbol and source line columns \n" | 2349 | " s Toggle full length of symbol and source line columns \n" |
2350 | " q Return back to cacheline list \n"; | 2350 | " q Return back to cacheline list \n"; |
2351 | 2351 | ||
2352 | if (!he) | ||
2353 | return 0; | ||
2354 | |||
2352 | /* Display compact version first. */ | 2355 | /* Display compact version first. */ |
2353 | c2c.symbol_full = false; | 2356 | c2c.symbol_full = false; |
2354 | 2357 | ||
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index d660cb7b222b..39db2ee32d48 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -696,7 +696,7 @@ static void hists__process(struct hists *hists) | |||
696 | hists__output_resort(hists, NULL); | 696 | hists__output_resort(hists, NULL); |
697 | 697 | ||
698 | hists__fprintf(hists, !quiet, 0, 0, 0, stdout, | 698 | hists__fprintf(hists, !quiet, 0, 0, 0, stdout, |
699 | symbol_conf.use_callchain); | 699 | !symbol_conf.use_callchain); |
700 | } | 700 | } |
701 | 701 | ||
702 | static void data__fprintf(void) | 702 | static void data__fprintf(void) |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c04dc7b53797..02f7a3c27761 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -478,8 +478,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
478 | 478 | ||
479 | hists__fprintf_nr_sample_events(hists, rep, evname, stdout); | 479 | hists__fprintf_nr_sample_events(hists, rep, evname, stdout); |
480 | hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout, | 480 | hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout, |
481 | symbol_conf.use_callchain || | 481 | !(symbol_conf.use_callchain || |
482 | symbol_conf.show_branchflag_count); | 482 | symbol_conf.show_branchflag_count)); |
483 | fprintf(stdout, "\n\n"); | 483 | fprintf(stdout, "\n\n"); |
484 | } | 484 | } |
485 | 485 | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 05be023c3f0e..d097b5b47eb8 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -296,18 +296,6 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
296 | return perf_evsel__open_per_thread(evsel, evsel_list->threads); | 296 | return perf_evsel__open_per_thread(evsel, evsel_list->threads); |
297 | } | 297 | } |
298 | 298 | ||
299 | /* | ||
300 | * Does the counter have nsecs as a unit? | ||
301 | */ | ||
302 | static inline int nsec_counter(struct perf_evsel *evsel) | ||
303 | { | ||
304 | if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || | ||
305 | perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) | ||
306 | return 1; | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int process_synthesized_event(struct perf_tool *tool __maybe_unused, | 299 | static int process_synthesized_event(struct perf_tool *tool __maybe_unused, |
312 | union perf_event *event, | 300 | union perf_event *event, |
313 | struct perf_sample *sample __maybe_unused, | 301 | struct perf_sample *sample __maybe_unused, |
@@ -1058,34 +1046,6 @@ static void print_metric_header(void *ctx, const char *color __maybe_unused, | |||
1058 | fprintf(os->fh, "%*s ", metric_only_len, unit); | 1046 | fprintf(os->fh, "%*s ", metric_only_len, unit); |
1059 | } | 1047 | } |
1060 | 1048 | ||
1061 | static void nsec_printout(int id, int nr, struct perf_evsel *evsel, double avg) | ||
1062 | { | ||
1063 | FILE *output = stat_config.output; | ||
1064 | double msecs = avg / NSEC_PER_MSEC; | ||
1065 | const char *fmt_v, *fmt_n; | ||
1066 | char name[25]; | ||
1067 | |||
1068 | fmt_v = csv_output ? "%.6f%s" : "%18.6f%s"; | ||
1069 | fmt_n = csv_output ? "%s" : "%-25s"; | ||
1070 | |||
1071 | aggr_printout(evsel, id, nr); | ||
1072 | |||
1073 | scnprintf(name, sizeof(name), "%s%s", | ||
1074 | perf_evsel__name(evsel), csv_output ? "" : " (msec)"); | ||
1075 | |||
1076 | fprintf(output, fmt_v, msecs, csv_sep); | ||
1077 | |||
1078 | if (csv_output) | ||
1079 | fprintf(output, "%s%s", evsel->unit, csv_sep); | ||
1080 | else | ||
1081 | fprintf(output, "%-*s%s", unit_width, evsel->unit, csv_sep); | ||
1082 | |||
1083 | fprintf(output, fmt_n, name); | ||
1084 | |||
1085 | if (evsel->cgrp) | ||
1086 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); | ||
1087 | } | ||
1088 | |||
1089 | static int first_shadow_cpu(struct perf_evsel *evsel, int id) | 1049 | static int first_shadow_cpu(struct perf_evsel *evsel, int id) |
1090 | { | 1050 | { |
1091 | int i; | 1051 | int i; |
@@ -1241,11 +1201,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, | |||
1241 | return; | 1201 | return; |
1242 | } | 1202 | } |
1243 | 1203 | ||
1244 | if (metric_only) | 1204 | if (!metric_only) |
1245 | /* nothing */; | ||
1246 | else if (nsec_counter(counter)) | ||
1247 | nsec_printout(id, nr, counter, uval); | ||
1248 | else | ||
1249 | abs_printout(id, nr, counter, uval); | 1205 | abs_printout(id, nr, counter, uval); |
1250 | 1206 | ||
1251 | out.print_metric = pm; | 1207 | out.print_metric = pm; |
@@ -1331,7 +1287,7 @@ static void collect_all_aliases(struct perf_evsel *counter, | |||
1331 | alias->scale != counter->scale || | 1287 | alias->scale != counter->scale || |
1332 | alias->cgrp != counter->cgrp || | 1288 | alias->cgrp != counter->cgrp || |
1333 | strcmp(alias->unit, counter->unit) || | 1289 | strcmp(alias->unit, counter->unit) || |
1334 | nsec_counter(alias) != nsec_counter(counter)) | 1290 | perf_evsel__is_clock(alias) != perf_evsel__is_clock(counter)) |
1335 | break; | 1291 | break; |
1336 | alias->merged_stat = true; | 1292 | alias->merged_stat = true; |
1337 | cb(alias, data, false); | 1293 | cb(alias, data, false); |
@@ -2449,6 +2405,18 @@ static int add_default_attributes(void) | |||
2449 | return 0; | 2405 | return 0; |
2450 | 2406 | ||
2451 | if (transaction_run) { | 2407 | if (transaction_run) { |
2408 | /* Handle -T as -M transaction. Once platform specific metrics | ||
2409 | * support has been added to the json files, all archictures | ||
2410 | * will use this approach. To determine transaction support | ||
2411 | * on an architecture test for such a metric name. | ||
2412 | */ | ||
2413 | if (metricgroup__has_metric("transaction")) { | ||
2414 | struct option opt = { .value = &evsel_list }; | ||
2415 | |||
2416 | return metricgroup__parse_groups(&opt, "transaction", | ||
2417 | &metric_events); | ||
2418 | } | ||
2419 | |||
2452 | if (pmu_have_event("cpu", "cycles-ct") && | 2420 | if (pmu_have_event("cpu", "cycles-ct") && |
2453 | pmu_have_event("cpu", "el-start")) | 2421 | pmu_have_event("cpu", "el-start")) |
2454 | err = parse_events(evsel_list, transaction_attrs, | 2422 | err = parse_events(evsel_list, transaction_attrs, |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ffdc2769ff9f..d21d8751e749 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -307,7 +307,7 @@ static void perf_top__print_sym_table(struct perf_top *top) | |||
307 | hists__output_recalc_col_len(hists, top->print_entries - printed); | 307 | hists__output_recalc_col_len(hists, top->print_entries - printed); |
308 | putchar('\n'); | 308 | putchar('\n'); |
309 | hists__fprintf(hists, false, top->print_entries - printed, win_width, | 309 | hists__fprintf(hists, false, top->print_entries - printed, win_width, |
310 | top->min_percent, stdout, symbol_conf.use_callchain); | 310 | top->min_percent, stdout, !symbol_conf.use_callchain); |
311 | } | 311 | } |
312 | 312 | ||
313 | static void prompt_integer(int *target, const char *msg) | 313 | static void prompt_integer(int *target, const char *msg) |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 6a748eca2edb..88561eed7950 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -291,7 +291,7 @@ size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const cha | |||
291 | { | 291 | { |
292 | int idx = val - sa->offset; | 292 | int idx = val - sa->offset; |
293 | 293 | ||
294 | if (idx < 0 || idx >= sa->nr_entries) | 294 | if (idx < 0 || idx >= sa->nr_entries || sa->entries[idx] == NULL) |
295 | return scnprintf(bf, size, intfmt, val); | 295 | return scnprintf(bf, size, intfmt, val); |
296 | 296 | ||
297 | return scnprintf(bf, size, "%s", sa->entries[idx]); | 297 | return scnprintf(bf, size, "%s", sa->entries[idx]); |
@@ -761,10 +761,12 @@ static struct syscall_fmt { | |||
761 | .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, | 761 | .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, |
762 | { .name = "socket", | 762 | { .name = "socket", |
763 | .arg = { [0] = STRARRAY(family, socket_families), | 763 | .arg = { [0] = STRARRAY(family, socket_families), |
764 | [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, | 764 | [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, |
765 | [2] = { .scnprintf = SCA_SK_PROTO, /* protocol */ }, }, }, | ||
765 | { .name = "socketpair", | 766 | { .name = "socketpair", |
766 | .arg = { [0] = STRARRAY(family, socket_families), | 767 | .arg = { [0] = STRARRAY(family, socket_families), |
767 | [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, | 768 | [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, |
769 | [2] = { .scnprintf = SCA_SK_PROTO, /* protocol */ }, }, }, | ||
768 | { .name = "stat", .alias = "newstat", }, | 770 | { .name = "stat", .alias = "newstat", }, |
769 | { .name = "statx", | 771 | { .name = "statx", |
770 | .arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ }, | 772 | .arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ }, |
@@ -2990,6 +2992,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str, | |||
2990 | 2992 | ||
2991 | if (trace__validate_ev_qualifier(trace)) | 2993 | if (trace__validate_ev_qualifier(trace)) |
2992 | goto out; | 2994 | goto out; |
2995 | trace->trace_syscalls = true; | ||
2993 | } | 2996 | } |
2994 | 2997 | ||
2995 | err = 0; | 2998 | err = 0; |
@@ -3045,7 +3048,7 @@ int cmd_trace(int argc, const char **argv) | |||
3045 | }, | 3048 | }, |
3046 | .output = stderr, | 3049 | .output = stderr, |
3047 | .show_comm = true, | 3050 | .show_comm = true, |
3048 | .trace_syscalls = true, | 3051 | .trace_syscalls = false, |
3049 | .kernel_syscallchains = false, | 3052 | .kernel_syscallchains = false, |
3050 | .max_stack = UINT_MAX, | 3053 | .max_stack = UINT_MAX, |
3051 | }; | 3054 | }; |
@@ -3191,13 +3194,7 @@ int cmd_trace(int argc, const char **argv) | |||
3191 | 3194 | ||
3192 | if (!trace.trace_syscalls && !trace.trace_pgfaults && | 3195 | if (!trace.trace_syscalls && !trace.trace_pgfaults && |
3193 | trace.evlist->nr_entries == 0 /* Was --events used? */) { | 3196 | trace.evlist->nr_entries == 0 /* Was --events used? */) { |
3194 | pr_err("Please specify something to trace.\n"); | 3197 | trace.trace_syscalls = true; |
3195 | return -1; | ||
3196 | } | ||
3197 | |||
3198 | if (!trace.trace_syscalls && trace.ev_qualifier) { | ||
3199 | pr_err("The -e option can't be used with --no-syscalls.\n"); | ||
3200 | goto out; | ||
3201 | } | 3198 | } |
3202 | 3199 | ||
3203 | if (output_name != NULL) { | 3200 | if (output_name != NULL) { |
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 10f333e2e825..de28466c0186 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh | |||
@@ -7,6 +7,7 @@ include/uapi/drm/i915_drm.h | |||
7 | include/uapi/linux/fcntl.h | 7 | include/uapi/linux/fcntl.h |
8 | include/uapi/linux/kcmp.h | 8 | include/uapi/linux/kcmp.h |
9 | include/uapi/linux/kvm.h | 9 | include/uapi/linux/kvm.h |
10 | include/uapi/linux/in.h | ||
10 | include/uapi/linux/perf_event.h | 11 | include/uapi/linux/perf_event.h |
11 | include/uapi/linux/prctl.h | 12 | include/uapi/linux/prctl.h |
12 | include/uapi/linux/sched.h | 13 | include/uapi/linux/sched.h |
@@ -35,6 +36,7 @@ arch/s390/include/uapi/asm/ptrace.h | |||
35 | arch/s390/include/uapi/asm/sie.h | 36 | arch/s390/include/uapi/asm/sie.h |
36 | arch/arm/include/uapi/asm/kvm.h | 37 | arch/arm/include/uapi/asm/kvm.h |
37 | arch/arm64/include/uapi/asm/kvm.h | 38 | arch/arm64/include/uapi/asm/kvm.h |
39 | arch/arm64/include/uapi/asm/unistd.h | ||
38 | arch/alpha/include/uapi/asm/errno.h | 40 | arch/alpha/include/uapi/asm/errno.h |
39 | arch/mips/include/asm/errno.h | 41 | arch/mips/include/asm/errno.h |
40 | arch/mips/include/uapi/asm/errno.h | 42 | arch/mips/include/uapi/asm/errno.h |
@@ -53,6 +55,7 @@ include/uapi/asm-generic/errno.h | |||
53 | include/uapi/asm-generic/errno-base.h | 55 | include/uapi/asm-generic/errno-base.h |
54 | include/uapi/asm-generic/ioctls.h | 56 | include/uapi/asm-generic/ioctls.h |
55 | include/uapi/asm-generic/mman-common.h | 57 | include/uapi/asm-generic/mman-common.h |
58 | include/uapi/asm-generic/unistd.h | ||
56 | ' | 59 | ' |
57 | 60 | ||
58 | check_2 () { | 61 | check_2 () { |
diff --git a/tools/perf/include/bpf/bpf.h b/tools/perf/include/bpf/bpf.h index dd764ad5efdf..a63aa6241b7f 100644 --- a/tools/perf/include/bpf/bpf.h +++ b/tools/perf/include/bpf/bpf.h | |||
@@ -1,6 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #ifndef _PERF_BPF_H | 2 | #ifndef _PERF_BPF_H |
3 | #define _PERF_BPF_H | 3 | #define _PERF_BPF_H |
4 | |||
5 | #include <uapi/linux/bpf.h> | ||
6 | |||
4 | #define SEC(NAME) __attribute__((section(NAME), used)) | 7 | #define SEC(NAME) __attribute__((section(NAME), used)) |
5 | 8 | ||
6 | #define probe(function, vars) \ | 9 | #define probe(function, vars) \ |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index d215714f48df..21bf7f5a3cf5 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -25,7 +25,9 @@ static inline unsigned long long rdclock(void) | |||
25 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; | 25 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; |
26 | } | 26 | } |
27 | 27 | ||
28 | #ifndef MAX_NR_CPUS | ||
28 | #define MAX_NR_CPUS 1024 | 29 | #define MAX_NR_CPUS 1024 |
30 | #endif | ||
29 | 31 | ||
30 | extern const char *input_name; | 32 | extern const char *input_name; |
31 | extern bool perf_host, perf_guest; | 33 | extern bool perf_host, perf_guest; |
diff --git a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json index bc03c06c3918..752e47eb6977 100644 --- a/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json +++ b/tools/perf/pmu-events/arch/arm64/cavium/thunderx2/core-imp-def.json | |||
@@ -12,6 +12,21 @@ | |||
12 | "ArchStdEvent": "L1D_CACHE_REFILL_WR", | 12 | "ArchStdEvent": "L1D_CACHE_REFILL_WR", |
13 | }, | 13 | }, |
14 | { | 14 | { |
15 | "ArchStdEvent": "L1D_CACHE_REFILL_INNER", | ||
16 | }, | ||
17 | { | ||
18 | "ArchStdEvent": "L1D_CACHE_REFILL_OUTER", | ||
19 | }, | ||
20 | { | ||
21 | "ArchStdEvent": "L1D_CACHE_WB_VICTIM", | ||
22 | }, | ||
23 | { | ||
24 | "ArchStdEvent": "L1D_CACHE_WB_CLEAN", | ||
25 | }, | ||
26 | { | ||
27 | "ArchStdEvent": "L1D_CACHE_INVAL", | ||
28 | }, | ||
29 | { | ||
15 | "ArchStdEvent": "L1D_TLB_REFILL_RD", | 30 | "ArchStdEvent": "L1D_TLB_REFILL_RD", |
16 | }, | 31 | }, |
17 | { | 32 | { |
@@ -24,9 +39,75 @@ | |||
24 | "ArchStdEvent": "L1D_TLB_WR", | 39 | "ArchStdEvent": "L1D_TLB_WR", |
25 | }, | 40 | }, |
26 | { | 41 | { |
42 | "ArchStdEvent": "L2D_TLB_REFILL_RD", | ||
43 | }, | ||
44 | { | ||
45 | "ArchStdEvent": "L2D_TLB_REFILL_WR", | ||
46 | }, | ||
47 | { | ||
48 | "ArchStdEvent": "L2D_TLB_RD", | ||
49 | }, | ||
50 | { | ||
51 | "ArchStdEvent": "L2D_TLB_WR", | ||
52 | }, | ||
53 | { | ||
27 | "ArchStdEvent": "BUS_ACCESS_RD", | 54 | "ArchStdEvent": "BUS_ACCESS_RD", |
28 | }, | 55 | }, |
29 | { | 56 | { |
30 | "ArchStdEvent": "BUS_ACCESS_WR", | 57 | "ArchStdEvent": "BUS_ACCESS_WR", |
31 | } | 58 | }, |
59 | { | ||
60 | "ArchStdEvent": "MEM_ACCESS_RD", | ||
61 | }, | ||
62 | { | ||
63 | "ArchStdEvent": "MEM_ACCESS_WR", | ||
64 | }, | ||
65 | { | ||
66 | "ArchStdEvent": "UNALIGNED_LD_SPEC", | ||
67 | }, | ||
68 | { | ||
69 | "ArchStdEvent": "UNALIGNED_ST_SPEC", | ||
70 | }, | ||
71 | { | ||
72 | "ArchStdEvent": "UNALIGNED_LDST_SPEC", | ||
73 | }, | ||
74 | { | ||
75 | "ArchStdEvent": "EXC_UNDEF", | ||
76 | }, | ||
77 | { | ||
78 | "ArchStdEvent": "EXC_SVC", | ||
79 | }, | ||
80 | { | ||
81 | "ArchStdEvent": "EXC_PABORT", | ||
82 | }, | ||
83 | { | ||
84 | "ArchStdEvent": "EXC_DABORT", | ||
85 | }, | ||
86 | { | ||
87 | "ArchStdEvent": "EXC_IRQ", | ||
88 | }, | ||
89 | { | ||
90 | "ArchStdEvent": "EXC_FIQ", | ||
91 | }, | ||
92 | { | ||
93 | "ArchStdEvent": "EXC_SMC", | ||
94 | }, | ||
95 | { | ||
96 | "ArchStdEvent": "EXC_HVC", | ||
97 | }, | ||
98 | { | ||
99 | "ArchStdEvent": "EXC_TRAP_PABORT", | ||
100 | }, | ||
101 | { | ||
102 | "ArchStdEvent": "EXC_TRAP_DABORT", | ||
103 | }, | ||
104 | { | ||
105 | "ArchStdEvent": "EXC_TRAP_OTHER", | ||
106 | }, | ||
107 | { | ||
108 | "ArchStdEvent": "EXC_TRAP_IRQ", | ||
109 | }, | ||
110 | { | ||
111 | "ArchStdEvent": "EXC_TRAP_FIQ", | ||
112 | } | ||
32 | ] | 113 | ] |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z10/basic.json b/tools/perf/pmu-events/arch/s390/cf_z10/basic.json index 8bf16759ca53..2dd8dafff2ef 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z10/basic.json +++ b/tools/perf/pmu-events/arch/s390/cf_z10/basic.json | |||
@@ -1,71 +1,83 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "0", | 4 | "EventCode": "0", |
4 | "EventName": "CPU_CYCLES", | 5 | "EventName": "CPU_CYCLES", |
5 | "BriefDescription": "CPU Cycles", | 6 | "BriefDescription": "CPU Cycles", |
6 | "PublicDescription": "Cycle Count" | 7 | "PublicDescription": "Cycle Count" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "1", | 11 | "EventCode": "1", |
10 | "EventName": "INSTRUCTIONS", | 12 | "EventName": "INSTRUCTIONS", |
11 | "BriefDescription": "Instructions", | 13 | "BriefDescription": "Instructions", |
12 | "PublicDescription": "Instruction Count" | 14 | "PublicDescription": "Instruction Count" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "2", | 18 | "EventCode": "2", |
16 | "EventName": "L1I_DIR_WRITES", | 19 | "EventName": "L1I_DIR_WRITES", |
17 | "BriefDescription": "L1I Directory Writes", | 20 | "BriefDescription": "L1I Directory Writes", |
18 | "PublicDescription": "Level-1 I-Cache Directory Write Count" | 21 | "PublicDescription": "Level-1 I-Cache Directory Write Count" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "3", | 25 | "EventCode": "3", |
22 | "EventName": "L1I_PENALTY_CYCLES", | 26 | "EventName": "L1I_PENALTY_CYCLES", |
23 | "BriefDescription": "L1I Penalty Cycles", | 27 | "BriefDescription": "L1I Penalty Cycles", |
24 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" | 28 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "4", | 32 | "EventCode": "4", |
28 | "EventName": "L1D_DIR_WRITES", | 33 | "EventName": "L1D_DIR_WRITES", |
29 | "BriefDescription": "L1D Directory Writes", | 34 | "BriefDescription": "L1D Directory Writes", |
30 | "PublicDescription": "Level-1 D-Cache Directory Write Count" | 35 | "PublicDescription": "Level-1 D-Cache Directory Write Count" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "5", | 39 | "EventCode": "5", |
34 | "EventName": "L1D_PENALTY_CYCLES", | 40 | "EventName": "L1D_PENALTY_CYCLES", |
35 | "BriefDescription": "L1D Penalty Cycles", | 41 | "BriefDescription": "L1D Penalty Cycles", |
36 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" | 42 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "32", | 46 | "EventCode": "32", |
40 | "EventName": "PROBLEM_STATE_CPU_CYCLES", | 47 | "EventName": "PROBLEM_STATE_CPU_CYCLES", |
41 | "BriefDescription": "Problem-State CPU Cycles", | 48 | "BriefDescription": "Problem-State CPU Cycles", |
42 | "PublicDescription": "Problem-State Cycle Count" | 49 | "PublicDescription": "Problem-State Cycle Count" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "33", | 53 | "EventCode": "33", |
46 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", | 54 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", |
47 | "BriefDescription": "Problem-State Instructions", | 55 | "BriefDescription": "Problem-State Instructions", |
48 | "PublicDescription": "Problem-State Instruction Count" | 56 | "PublicDescription": "Problem-State Instruction Count" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "34", | 60 | "EventCode": "34", |
52 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", | 61 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", |
53 | "BriefDescription": "Problem-State L1I Directory Writes", | 62 | "BriefDescription": "Problem-State L1I Directory Writes", |
54 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" | 63 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "35", | 67 | "EventCode": "35", |
58 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", | 68 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", |
59 | "BriefDescription": "Problem-State L1I Penalty Cycles", | 69 | "BriefDescription": "Problem-State L1I Penalty Cycles", |
60 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" | 70 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "36", | 74 | "EventCode": "36", |
64 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", | 75 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", |
65 | "BriefDescription": "Problem-State L1D Directory Writes", | 76 | "BriefDescription": "Problem-State L1D Directory Writes", |
66 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" | 77 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "37", | 81 | "EventCode": "37", |
70 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", | 82 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", |
71 | "BriefDescription": "Problem-State L1D Penalty Cycles", | 83 | "BriefDescription": "Problem-State L1D Penalty Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json index 7e5b72492141..db286f19e7b6 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json +++ b/tools/perf/pmu-events/arch/s390/cf_z10/crypto.json | |||
@@ -1,95 +1,111 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "64", | 4 | "EventCode": "64", |
4 | "EventName": "PRNG_FUNCTIONS", | 5 | "EventName": "PRNG_FUNCTIONS", |
5 | "BriefDescription": "PRNG Functions", | 6 | "BriefDescription": "PRNG Functions", |
6 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" | 7 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "65", | 11 | "EventCode": "65", |
10 | "EventName": "PRNG_CYCLES", | 12 | "EventName": "PRNG_CYCLES", |
11 | "BriefDescription": "PRNG Cycles", | 13 | "BriefDescription": "PRNG Cycles", |
12 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" | 14 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "66", | 18 | "EventCode": "66", |
16 | "EventName": "PRNG_BLOCKED_FUNCTIONS", | 19 | "EventName": "PRNG_BLOCKED_FUNCTIONS", |
17 | "BriefDescription": "PRNG Blocked Functions", | 20 | "BriefDescription": "PRNG Blocked Functions", |
18 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 21 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "67", | 25 | "EventCode": "67", |
22 | "EventName": "PRNG_BLOCKED_CYCLES", | 26 | "EventName": "PRNG_BLOCKED_CYCLES", |
23 | "BriefDescription": "PRNG Blocked Cycles", | 27 | "BriefDescription": "PRNG Blocked Cycles", |
24 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 28 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "68", | 32 | "EventCode": "68", |
28 | "EventName": "SHA_FUNCTIONS", | 33 | "EventName": "SHA_FUNCTIONS", |
29 | "BriefDescription": "SHA Functions", | 34 | "BriefDescription": "SHA Functions", |
30 | "PublicDescription": "Total number of SHA functions issued by the CPU" | 35 | "PublicDescription": "Total number of SHA functions issued by the CPU" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "69", | 39 | "EventCode": "69", |
34 | "EventName": "SHA_CYCLES", | 40 | "EventName": "SHA_CYCLES", |
35 | "BriefDescription": "SHA Cycles", | 41 | "BriefDescription": "SHA Cycles", |
36 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" | 42 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "70", | 46 | "EventCode": "70", |
40 | "EventName": "SHA_BLOCKED_FUNCTIONS", | 47 | "EventName": "SHA_BLOCKED_FUNCTIONS", |
41 | "BriefDescription": "SHA Blocked Functions", | 48 | "BriefDescription": "SHA Blocked Functions", |
42 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" | 49 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "71", | 53 | "EventCode": "71", |
46 | "EventName": "SHA_BLOCKED_CYCLES", | 54 | "EventName": "SHA_BLOCKED_CYCLES", |
47 | "BriefDescription": "SHA Bloced Cycles", | 55 | "BriefDescription": "SHA Bloced Cycles", |
48 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" | 56 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "72", | 60 | "EventCode": "72", |
52 | "EventName": "DEA_FUNCTIONS", | 61 | "EventName": "DEA_FUNCTIONS", |
53 | "BriefDescription": "DEA Functions", | 62 | "BriefDescription": "DEA Functions", |
54 | "PublicDescription": "Total number of the DEA functions issued by the CPU" | 63 | "PublicDescription": "Total number of the DEA functions issued by the CPU" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "73", | 67 | "EventCode": "73", |
58 | "EventName": "DEA_CYCLES", | 68 | "EventName": "DEA_CYCLES", |
59 | "BriefDescription": "DEA Cycles", | 69 | "BriefDescription": "DEA Cycles", |
60 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" | 70 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "74", | 74 | "EventCode": "74", |
64 | "EventName": "DEA_BLOCKED_FUNCTIONS", | 75 | "EventName": "DEA_BLOCKED_FUNCTIONS", |
65 | "BriefDescription": "DEA Blocked Functions", | 76 | "BriefDescription": "DEA Blocked Functions", |
66 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 77 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "75", | 81 | "EventCode": "75", |
70 | "EventName": "DEA_BLOCKED_CYCLES", | 82 | "EventName": "DEA_BLOCKED_CYCLES", |
71 | "BriefDescription": "DEA Blocked Cycles", | 83 | "BriefDescription": "DEA Blocked Cycles", |
72 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 84 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "76", | 88 | "EventCode": "76", |
76 | "EventName": "AES_FUNCTIONS", | 89 | "EventName": "AES_FUNCTIONS", |
77 | "BriefDescription": "AES Functions", | 90 | "BriefDescription": "AES Functions", |
78 | "PublicDescription": "Total number of AES functions issued by the CPU" | 91 | "PublicDescription": "Total number of AES functions issued by the CPU" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "77", | 95 | "EventCode": "77", |
82 | "EventName": "AES_CYCLES", | 96 | "EventName": "AES_CYCLES", |
83 | "BriefDescription": "AES Cycles", | 97 | "BriefDescription": "AES Cycles", |
84 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" | 98 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "78", | 102 | "EventCode": "78", |
88 | "EventName": "AES_BLOCKED_FUNCTIONS", | 103 | "EventName": "AES_BLOCKED_FUNCTIONS", |
89 | "BriefDescription": "AES Blocked Functions", | 104 | "BriefDescription": "AES Blocked Functions", |
90 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 105 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "79", | 109 | "EventCode": "79", |
94 | "EventName": "AES_BLOCKED_CYCLES", | 110 | "EventName": "AES_BLOCKED_CYCLES", |
95 | "BriefDescription": "AES Blocked Cycles", | 111 | "BriefDescription": "AES Blocked Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z10/extended.json b/tools/perf/pmu-events/arch/s390/cf_z10/extended.json index 0feedb40f30f..b6b7f29ca831 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z10/extended.json +++ b/tools/perf/pmu-events/arch/s390/cf_z10/extended.json | |||
@@ -1,107 +1,125 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "128", | 4 | "EventCode": "128", |
4 | "EventName": "L1I_L2_SOURCED_WRITES", | 5 | "EventName": "L1I_L2_SOURCED_WRITES", |
5 | "BriefDescription": "L1I L2 Sourced Writes", | 6 | "BriefDescription": "L1I L2 Sourced Writes", |
6 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 (L1.5) cache" | 7 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 (L1.5) cache" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "129", | 11 | "EventCode": "129", |
10 | "EventName": "L1D_L2_SOURCED_WRITES", | 12 | "EventName": "L1D_L2_SOURCED_WRITES", |
11 | "BriefDescription": "L1D L2 Sourced Writes", | 13 | "BriefDescription": "L1D L2 Sourced Writes", |
12 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from the Level-2 (L1.5) cache" | 14 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from the Level-2 (L1.5) cache" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "130", | 18 | "EventCode": "130", |
16 | "EventName": "L1I_L3_LOCAL_WRITES", | 19 | "EventName": "L1I_L3_LOCAL_WRITES", |
17 | "BriefDescription": "L1I L3 Local Writes", | 20 | "BriefDescription": "L1I L3 Local Writes", |
18 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from the Level-3 cache that is on the same book as the Instruction cache (Local L2 cache)" | 21 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from the Level-3 cache that is on the same book as the Instruction cache (Local L2 cache)" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "131", | 25 | "EventCode": "131", |
22 | "EventName": "L1D_L3_LOCAL_WRITES", | 26 | "EventName": "L1D_L3_LOCAL_WRITES", |
23 | "BriefDescription": "L1D L3 Local Writes", | 27 | "BriefDescription": "L1D L3 Local Writes", |
24 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installtion cache line was source from the Level-3 cache that is on the same book as the Data cache (Local L2 cache)" | 28 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installtion cache line was source from the Level-3 cache that is on the same book as the Data cache (Local L2 cache)" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "132", | 32 | "EventCode": "132", |
28 | "EventName": "L1I_L3_REMOTE_WRITES", | 33 | "EventName": "L1I_L3_REMOTE_WRITES", |
29 | "BriefDescription": "L1I L3 Remote Writes", | 34 | "BriefDescription": "L1I L3 Remote Writes", |
30 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Instruction cache (Remote L2 cache)" | 35 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Instruction cache (Remote L2 cache)" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "133", | 39 | "EventCode": "133", |
34 | "EventName": "L1D_L3_REMOTE_WRITES", | 40 | "EventName": "L1D_L3_REMOTE_WRITES", |
35 | "BriefDescription": "L1D L3 Remote Writes", | 41 | "BriefDescription": "L1D L3 Remote Writes", |
36 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Data cache (Remote L2 cache)" | 42 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from a Level-3 cache that is not on the same book as the Data cache (Remote L2 cache)" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "134", | 46 | "EventCode": "134", |
40 | "EventName": "L1D_LMEM_SOURCED_WRITES", | 47 | "EventName": "L1D_LMEM_SOURCED_WRITES", |
41 | "BriefDescription": "L1D Local Memory Sourced Writes", | 48 | "BriefDescription": "L1D Local Memory Sourced Writes", |
42 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" | 49 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "135", | 53 | "EventCode": "135", |
46 | "EventName": "L1I_LMEM_SOURCED_WRITES", | 54 | "EventName": "L1I_LMEM_SOURCED_WRITES", |
47 | "BriefDescription": "L1I Local Memory Sourced Writes", | 55 | "BriefDescription": "L1I Local Memory Sourced Writes", |
48 | "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the s ame book as the Instruction cache (Local Memory)" | 56 | "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the s ame book as the Instruction cache (Local Memory)" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "136", | 60 | "EventCode": "136", |
52 | "EventName": "L1D_RO_EXCL_WRITES", | 61 | "EventName": "L1D_RO_EXCL_WRITES", |
53 | "BriefDescription": "L1D Read-only Exclusive Writes", | 62 | "BriefDescription": "L1D Read-only Exclusive Writes", |
54 | "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" | 63 | "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "137", | 67 | "EventCode": "137", |
58 | "EventName": "L1I_CACHELINE_INVALIDATES", | 68 | "EventName": "L1I_CACHELINE_INVALIDATES", |
59 | "BriefDescription": "L1I Cacheline Invalidates", | 69 | "BriefDescription": "L1I Cacheline Invalidates", |
60 | "PublicDescription": "A cache line in the Level-1 I-Cache has been invalidated by a store on the same CPU as the Level-1 I-Cache" | 70 | "PublicDescription": "A cache line in the Level-1 I-Cache has been invalidated by a store on the same CPU as the Level-1 I-Cache" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "138", | 74 | "EventCode": "138", |
64 | "EventName": "ITLB1_WRITES", | 75 | "EventName": "ITLB1_WRITES", |
65 | "BriefDescription": "ITLB1 Writes", | 76 | "BriefDescription": "ITLB1 Writes", |
66 | "PublicDescription": "A translation entry has been written into the Level-1 Instruction Translation Lookaside Buffer" | 77 | "PublicDescription": "A translation entry has been written into the Level-1 Instruction Translation Lookaside Buffer" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "139", | 81 | "EventCode": "139", |
70 | "EventName": "DTLB1_WRITES", | 82 | "EventName": "DTLB1_WRITES", |
71 | "BriefDescription": "DTLB1 Writes", | 83 | "BriefDescription": "DTLB1 Writes", |
72 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" | 84 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "140", | 88 | "EventCode": "140", |
76 | "EventName": "TLB2_PTE_WRITES", | 89 | "EventName": "TLB2_PTE_WRITES", |
77 | "BriefDescription": "TLB2 PTE Writes", | 90 | "BriefDescription": "TLB2 PTE Writes", |
78 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" | 91 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "141", | 95 | "EventCode": "141", |
82 | "EventName": "TLB2_CRSTE_WRITES", | 96 | "EventName": "TLB2_CRSTE_WRITES", |
83 | "BriefDescription": "TLB2 CRSTE Writes", | 97 | "BriefDescription": "TLB2 CRSTE Writes", |
84 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" | 98 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "142", | 102 | "EventCode": "142", |
88 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", | 103 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", |
89 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", | 104 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", |
90 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" | 105 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "145", | 109 | "EventCode": "145", |
94 | "EventName": "ITLB1_MISSES", | 110 | "EventName": "ITLB1_MISSES", |
95 | "BriefDescription": "ITLB1 Misses", | 111 | "BriefDescription": "ITLB1 Misses", |
96 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress" | 112 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress" |
97 | }, | 113 | }, |
98 | { | 114 | { |
115 | "Unit": "CPU-M-CF", | ||
99 | "EventCode": "146", | 116 | "EventCode": "146", |
100 | "EventName": "DTLB1_MISSES", | 117 | "EventName": "DTLB1_MISSES", |
101 | "BriefDescription": "DTLB1 Misses", | 118 | "BriefDescription": "DTLB1 Misses", |
102 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle an DTLB1 miss is in progress" | 119 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle an DTLB1 miss is in progress" |
103 | }, | 120 | }, |
104 | { | 121 | { |
122 | "Unit": "CPU-M-CF", | ||
105 | "EventCode": "147", | 123 | "EventCode": "147", |
106 | "EventName": "L2C_STORES_SENT", | 124 | "EventName": "L2C_STORES_SENT", |
107 | "BriefDescription": "L2C Stores Sent", | 125 | "BriefDescription": "L2C Stores Sent", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/basic.json b/tools/perf/pmu-events/arch/s390/cf_z13/basic.json index 8bf16759ca53..2dd8dafff2ef 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z13/basic.json +++ b/tools/perf/pmu-events/arch/s390/cf_z13/basic.json | |||
@@ -1,71 +1,83 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "0", | 4 | "EventCode": "0", |
4 | "EventName": "CPU_CYCLES", | 5 | "EventName": "CPU_CYCLES", |
5 | "BriefDescription": "CPU Cycles", | 6 | "BriefDescription": "CPU Cycles", |
6 | "PublicDescription": "Cycle Count" | 7 | "PublicDescription": "Cycle Count" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "1", | 11 | "EventCode": "1", |
10 | "EventName": "INSTRUCTIONS", | 12 | "EventName": "INSTRUCTIONS", |
11 | "BriefDescription": "Instructions", | 13 | "BriefDescription": "Instructions", |
12 | "PublicDescription": "Instruction Count" | 14 | "PublicDescription": "Instruction Count" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "2", | 18 | "EventCode": "2", |
16 | "EventName": "L1I_DIR_WRITES", | 19 | "EventName": "L1I_DIR_WRITES", |
17 | "BriefDescription": "L1I Directory Writes", | 20 | "BriefDescription": "L1I Directory Writes", |
18 | "PublicDescription": "Level-1 I-Cache Directory Write Count" | 21 | "PublicDescription": "Level-1 I-Cache Directory Write Count" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "3", | 25 | "EventCode": "3", |
22 | "EventName": "L1I_PENALTY_CYCLES", | 26 | "EventName": "L1I_PENALTY_CYCLES", |
23 | "BriefDescription": "L1I Penalty Cycles", | 27 | "BriefDescription": "L1I Penalty Cycles", |
24 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" | 28 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "4", | 32 | "EventCode": "4", |
28 | "EventName": "L1D_DIR_WRITES", | 33 | "EventName": "L1D_DIR_WRITES", |
29 | "BriefDescription": "L1D Directory Writes", | 34 | "BriefDescription": "L1D Directory Writes", |
30 | "PublicDescription": "Level-1 D-Cache Directory Write Count" | 35 | "PublicDescription": "Level-1 D-Cache Directory Write Count" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "5", | 39 | "EventCode": "5", |
34 | "EventName": "L1D_PENALTY_CYCLES", | 40 | "EventName": "L1D_PENALTY_CYCLES", |
35 | "BriefDescription": "L1D Penalty Cycles", | 41 | "BriefDescription": "L1D Penalty Cycles", |
36 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" | 42 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "32", | 46 | "EventCode": "32", |
40 | "EventName": "PROBLEM_STATE_CPU_CYCLES", | 47 | "EventName": "PROBLEM_STATE_CPU_CYCLES", |
41 | "BriefDescription": "Problem-State CPU Cycles", | 48 | "BriefDescription": "Problem-State CPU Cycles", |
42 | "PublicDescription": "Problem-State Cycle Count" | 49 | "PublicDescription": "Problem-State Cycle Count" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "33", | 53 | "EventCode": "33", |
46 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", | 54 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", |
47 | "BriefDescription": "Problem-State Instructions", | 55 | "BriefDescription": "Problem-State Instructions", |
48 | "PublicDescription": "Problem-State Instruction Count" | 56 | "PublicDescription": "Problem-State Instruction Count" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "34", | 60 | "EventCode": "34", |
52 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", | 61 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", |
53 | "BriefDescription": "Problem-State L1I Directory Writes", | 62 | "BriefDescription": "Problem-State L1I Directory Writes", |
54 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" | 63 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "35", | 67 | "EventCode": "35", |
58 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", | 68 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", |
59 | "BriefDescription": "Problem-State L1I Penalty Cycles", | 69 | "BriefDescription": "Problem-State L1I Penalty Cycles", |
60 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" | 70 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "36", | 74 | "EventCode": "36", |
64 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", | 75 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", |
65 | "BriefDescription": "Problem-State L1D Directory Writes", | 76 | "BriefDescription": "Problem-State L1D Directory Writes", |
66 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" | 77 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "37", | 81 | "EventCode": "37", |
70 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", | 82 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", |
71 | "BriefDescription": "Problem-State L1D Penalty Cycles", | 83 | "BriefDescription": "Problem-State L1D Penalty Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json index 7e5b72492141..db286f19e7b6 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json +++ b/tools/perf/pmu-events/arch/s390/cf_z13/crypto.json | |||
@@ -1,95 +1,111 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "64", | 4 | "EventCode": "64", |
4 | "EventName": "PRNG_FUNCTIONS", | 5 | "EventName": "PRNG_FUNCTIONS", |
5 | "BriefDescription": "PRNG Functions", | 6 | "BriefDescription": "PRNG Functions", |
6 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" | 7 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "65", | 11 | "EventCode": "65", |
10 | "EventName": "PRNG_CYCLES", | 12 | "EventName": "PRNG_CYCLES", |
11 | "BriefDescription": "PRNG Cycles", | 13 | "BriefDescription": "PRNG Cycles", |
12 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" | 14 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "66", | 18 | "EventCode": "66", |
16 | "EventName": "PRNG_BLOCKED_FUNCTIONS", | 19 | "EventName": "PRNG_BLOCKED_FUNCTIONS", |
17 | "BriefDescription": "PRNG Blocked Functions", | 20 | "BriefDescription": "PRNG Blocked Functions", |
18 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 21 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "67", | 25 | "EventCode": "67", |
22 | "EventName": "PRNG_BLOCKED_CYCLES", | 26 | "EventName": "PRNG_BLOCKED_CYCLES", |
23 | "BriefDescription": "PRNG Blocked Cycles", | 27 | "BriefDescription": "PRNG Blocked Cycles", |
24 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 28 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "68", | 32 | "EventCode": "68", |
28 | "EventName": "SHA_FUNCTIONS", | 33 | "EventName": "SHA_FUNCTIONS", |
29 | "BriefDescription": "SHA Functions", | 34 | "BriefDescription": "SHA Functions", |
30 | "PublicDescription": "Total number of SHA functions issued by the CPU" | 35 | "PublicDescription": "Total number of SHA functions issued by the CPU" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "69", | 39 | "EventCode": "69", |
34 | "EventName": "SHA_CYCLES", | 40 | "EventName": "SHA_CYCLES", |
35 | "BriefDescription": "SHA Cycles", | 41 | "BriefDescription": "SHA Cycles", |
36 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" | 42 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "70", | 46 | "EventCode": "70", |
40 | "EventName": "SHA_BLOCKED_FUNCTIONS", | 47 | "EventName": "SHA_BLOCKED_FUNCTIONS", |
41 | "BriefDescription": "SHA Blocked Functions", | 48 | "BriefDescription": "SHA Blocked Functions", |
42 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" | 49 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "71", | 53 | "EventCode": "71", |
46 | "EventName": "SHA_BLOCKED_CYCLES", | 54 | "EventName": "SHA_BLOCKED_CYCLES", |
47 | "BriefDescription": "SHA Bloced Cycles", | 55 | "BriefDescription": "SHA Bloced Cycles", |
48 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" | 56 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "72", | 60 | "EventCode": "72", |
52 | "EventName": "DEA_FUNCTIONS", | 61 | "EventName": "DEA_FUNCTIONS", |
53 | "BriefDescription": "DEA Functions", | 62 | "BriefDescription": "DEA Functions", |
54 | "PublicDescription": "Total number of the DEA functions issued by the CPU" | 63 | "PublicDescription": "Total number of the DEA functions issued by the CPU" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "73", | 67 | "EventCode": "73", |
58 | "EventName": "DEA_CYCLES", | 68 | "EventName": "DEA_CYCLES", |
59 | "BriefDescription": "DEA Cycles", | 69 | "BriefDescription": "DEA Cycles", |
60 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" | 70 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "74", | 74 | "EventCode": "74", |
64 | "EventName": "DEA_BLOCKED_FUNCTIONS", | 75 | "EventName": "DEA_BLOCKED_FUNCTIONS", |
65 | "BriefDescription": "DEA Blocked Functions", | 76 | "BriefDescription": "DEA Blocked Functions", |
66 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 77 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "75", | 81 | "EventCode": "75", |
70 | "EventName": "DEA_BLOCKED_CYCLES", | 82 | "EventName": "DEA_BLOCKED_CYCLES", |
71 | "BriefDescription": "DEA Blocked Cycles", | 83 | "BriefDescription": "DEA Blocked Cycles", |
72 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 84 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "76", | 88 | "EventCode": "76", |
76 | "EventName": "AES_FUNCTIONS", | 89 | "EventName": "AES_FUNCTIONS", |
77 | "BriefDescription": "AES Functions", | 90 | "BriefDescription": "AES Functions", |
78 | "PublicDescription": "Total number of AES functions issued by the CPU" | 91 | "PublicDescription": "Total number of AES functions issued by the CPU" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "77", | 95 | "EventCode": "77", |
82 | "EventName": "AES_CYCLES", | 96 | "EventName": "AES_CYCLES", |
83 | "BriefDescription": "AES Cycles", | 97 | "BriefDescription": "AES Cycles", |
84 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" | 98 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "78", | 102 | "EventCode": "78", |
88 | "EventName": "AES_BLOCKED_FUNCTIONS", | 103 | "EventName": "AES_BLOCKED_FUNCTIONS", |
89 | "BriefDescription": "AES Blocked Functions", | 104 | "BriefDescription": "AES Blocked Functions", |
90 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 105 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "79", | 109 | "EventCode": "79", |
94 | "EventName": "AES_BLOCKED_CYCLES", | 110 | "EventName": "AES_BLOCKED_CYCLES", |
95 | "BriefDescription": "AES Blocked Cycles", | 111 | "BriefDescription": "AES Blocked Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/extended.json b/tools/perf/pmu-events/arch/s390/cf_z13/extended.json index 9a002b6967f1..436ce33f1182 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z13/extended.json +++ b/tools/perf/pmu-events/arch/s390/cf_z13/extended.json | |||
@@ -1,335 +1,391 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "128", | 4 | "EventCode": "128", |
4 | "EventName": "L1D_RO_EXCL_WRITES", | 5 | "EventName": "L1D_RO_EXCL_WRITES", |
5 | "BriefDescription": "L1D Read-only Exclusive Writes", | 6 | "BriefDescription": "L1D Read-only Exclusive Writes", |
6 | "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line." | 7 | "PublicDescription": "A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line." |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "129", | 11 | "EventCode": "129", |
10 | "EventName": "DTLB1_WRITES", | 12 | "EventName": "DTLB1_WRITES", |
11 | "BriefDescription": "DTLB1 Writes", | 13 | "BriefDescription": "DTLB1 Writes", |
12 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" | 14 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "130", | 18 | "EventCode": "130", |
16 | "EventName": "DTLB1_MISSES", | 19 | "EventName": "DTLB1_MISSES", |
17 | "BriefDescription": "DTLB1 Misses", | 20 | "BriefDescription": "DTLB1 Misses", |
18 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." | 21 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "131", | 25 | "EventCode": "131", |
22 | "EventName": "DTLB1_HPAGE_WRITES", | 26 | "EventName": "DTLB1_HPAGE_WRITES", |
23 | "BriefDescription": "DTLB1 One-Megabyte Page Writes", | 27 | "BriefDescription": "DTLB1 One-Megabyte Page Writes", |
24 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" | 28 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "132", | 32 | "EventCode": "132", |
28 | "EventName": "DTLB1_GPAGE_WRITES", | 33 | "EventName": "DTLB1_GPAGE_WRITES", |
29 | "BriefDescription": "DTLB1 Two-Gigabyte Page Writes", | 34 | "BriefDescription": "DTLB1 Two-Gigabyte Page Writes", |
30 | "PublicDescription": "Counter:132 Name:DTLB1_GPAGE_WRITES A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a two-gigabyte page." | 35 | "PublicDescription": "Counter:132 Name:DTLB1_GPAGE_WRITES A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a two-gigabyte page." |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "133", | 39 | "EventCode": "133", |
34 | "EventName": "L1D_L2D_SOURCED_WRITES", | 40 | "EventName": "L1D_L2D_SOURCED_WRITES", |
35 | "BriefDescription": "L1D L2D Sourced Writes", | 41 | "BriefDescription": "L1D L2D Sourced Writes", |
36 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" | 42 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "134", | 46 | "EventCode": "134", |
40 | "EventName": "ITLB1_WRITES", | 47 | "EventName": "ITLB1_WRITES", |
41 | "BriefDescription": "ITLB1 Writes", | 48 | "BriefDescription": "ITLB1 Writes", |
42 | "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" | 49 | "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "135", | 53 | "EventCode": "135", |
46 | "EventName": "ITLB1_MISSES", | 54 | "EventName": "ITLB1_MISSES", |
47 | "BriefDescription": "ITLB1 Misses", | 55 | "BriefDescription": "ITLB1 Misses", |
48 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress" | 56 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle an ITLB1 miss is in progress" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "136", | 60 | "EventCode": "136", |
52 | "EventName": "L1I_L2I_SOURCED_WRITES", | 61 | "EventName": "L1I_L2I_SOURCED_WRITES", |
53 | "BriefDescription": "L1I L2I Sourced Writes", | 62 | "BriefDescription": "L1I L2I Sourced Writes", |
54 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" | 63 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "137", | 67 | "EventCode": "137", |
58 | "EventName": "TLB2_PTE_WRITES", | 68 | "EventName": "TLB2_PTE_WRITES", |
59 | "BriefDescription": "TLB2 PTE Writes", | 69 | "BriefDescription": "TLB2 PTE Writes", |
60 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" | 70 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "138", | 74 | "EventCode": "138", |
64 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", | 75 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", |
65 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", | 76 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", |
66 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays for a one-megabyte large page translation" | 77 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays for a one-megabyte large page translation" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "139", | 81 | "EventCode": "139", |
70 | "EventName": "TLB2_CRSTE_WRITES", | 82 | "EventName": "TLB2_CRSTE_WRITES", |
71 | "BriefDescription": "TLB2 CRSTE Writes", | 83 | "BriefDescription": "TLB2 CRSTE Writes", |
72 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays" | 84 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Combined Region Segment Table Entry arrays" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "140", | 88 | "EventCode": "140", |
76 | "EventName": "TX_C_TEND", | 89 | "EventName": "TX_C_TEND", |
77 | "BriefDescription": "Completed TEND instructions in constrained TX mode", | 90 | "BriefDescription": "Completed TEND instructions in constrained TX mode", |
78 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" | 91 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "141", | 95 | "EventCode": "141", |
82 | "EventName": "TX_NC_TEND", | 96 | "EventName": "TX_NC_TEND", |
83 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", | 97 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", |
84 | "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" | 98 | "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "143", | 102 | "EventCode": "143", |
88 | "EventName": "L1C_TLB1_MISSES", | 103 | "EventName": "L1C_TLB1_MISSES", |
89 | "BriefDescription": "L1C TLB1 Misses", | 104 | "BriefDescription": "L1C TLB1 Misses", |
90 | "PublicDescription": "Increments by one for any cycle where a Level-1 cache or Level-1 TLB miss is in progress." | 105 | "PublicDescription": "Increments by one for any cycle where a Level-1 cache or Level-1 TLB miss is in progress." |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "144", | 109 | "EventCode": "144", |
94 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", | 110 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", |
95 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", | 111 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", |
96 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" | 112 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" |
97 | }, | 113 | }, |
98 | { | 114 | { |
115 | "Unit": "CPU-M-CF", | ||
99 | "EventCode": "145", | 116 | "EventCode": "145", |
100 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", | 117 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", |
101 | "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", | 118 | "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", |
102 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" | 119 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" |
103 | }, | 120 | }, |
104 | { | 121 | { |
122 | "Unit": "CPU-M-CF", | ||
105 | "EventCode": "146", | 123 | "EventCode": "146", |
106 | "EventName": "L1D_ONNODE_L4_SOURCED_WRITES", | 124 | "EventName": "L1D_ONNODE_L4_SOURCED_WRITES", |
107 | "BriefDescription": "L1D On-Node L4 Sourced Writes", | 125 | "BriefDescription": "L1D On-Node L4 Sourced Writes", |
108 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-4 cache" | 126 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-4 cache" |
109 | }, | 127 | }, |
110 | { | 128 | { |
129 | "Unit": "CPU-M-CF", | ||
111 | "EventCode": "147", | 130 | "EventCode": "147", |
112 | "EventName": "L1D_ONNODE_L3_SOURCED_WRITES_IV", | 131 | "EventName": "L1D_ONNODE_L3_SOURCED_WRITES_IV", |
113 | "BriefDescription": "L1D On-Node L3 Sourced Writes with Intervention", | 132 | "BriefDescription": "L1D On-Node L3 Sourced Writes with Intervention", |
114 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention" | 133 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention" |
115 | }, | 134 | }, |
116 | { | 135 | { |
136 | "Unit": "CPU-M-CF", | ||
117 | "EventCode": "148", | 137 | "EventCode": "148", |
118 | "EventName": "L1D_ONNODE_L3_SOURCED_WRITES", | 138 | "EventName": "L1D_ONNODE_L3_SOURCED_WRITES", |
119 | "BriefDescription": "L1D On-Node L3 Sourced Writes", | 139 | "BriefDescription": "L1D On-Node L3 Sourced Writes", |
120 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention" | 140 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention" |
121 | }, | 141 | }, |
122 | { | 142 | { |
143 | "Unit": "CPU-M-CF", | ||
123 | "EventCode": "149", | 144 | "EventCode": "149", |
124 | "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", | 145 | "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", |
125 | "BriefDescription": "L1D On-Drawer L4 Sourced Writes", | 146 | "BriefDescription": "L1D On-Drawer L4 Sourced Writes", |
126 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache" | 147 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache" |
127 | }, | 148 | }, |
128 | { | 149 | { |
150 | "Unit": "CPU-M-CF", | ||
129 | "EventCode": "150", | 151 | "EventCode": "150", |
130 | "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES_IV", | 152 | "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES_IV", |
131 | "BriefDescription": "L1D On-Drawer L3 Sourced Writes with Intervention", | 153 | "BriefDescription": "L1D On-Drawer L3 Sourced Writes with Intervention", |
132 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention" | 154 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention" |
133 | }, | 155 | }, |
134 | { | 156 | { |
157 | "Unit": "CPU-M-CF", | ||
135 | "EventCode": "151", | 158 | "EventCode": "151", |
136 | "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES", | 159 | "EventName": "L1D_ONDRAWER_L3_SOURCED_WRITES", |
137 | "BriefDescription": "L1D On-Drawer L3 Sourced Writes", | 160 | "BriefDescription": "L1D On-Drawer L3 Sourced Writes", |
138 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention" | 161 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention" |
139 | }, | 162 | }, |
140 | { | 163 | { |
164 | "Unit": "CPU-M-CF", | ||
141 | "EventCode": "152", | 165 | "EventCode": "152", |
142 | "EventName": "L1D_OFFDRAWER_SCOL_L4_SOURCED_WRITES", | 166 | "EventName": "L1D_OFFDRAWER_SCOL_L4_SOURCED_WRITES", |
143 | "BriefDescription": "L1D Off-Drawer Same-Column L4 Sourced Writes", | 167 | "BriefDescription": "L1D Off-Drawer Same-Column L4 Sourced Writes", |
144 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache" | 168 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache" |
145 | }, | 169 | }, |
146 | { | 170 | { |
171 | "Unit": "CPU-M-CF", | ||
147 | "EventCode": "153", | 172 | "EventCode": "153", |
148 | "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV", | 173 | "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV", |
149 | "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes with Intervention", | 174 | "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes with Intervention", |
150 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention" | 175 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention" |
151 | }, | 176 | }, |
152 | { | 177 | { |
178 | "Unit": "CPU-M-CF", | ||
153 | "EventCode": "154", | 179 | "EventCode": "154", |
154 | "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES", | 180 | "EventName": "L1D_OFFDRAWER_SCOL_L3_SOURCED_WRITES", |
155 | "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes", | 181 | "BriefDescription": "L1D Off-Drawer Same-Column L3 Sourced Writes", |
156 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention" | 182 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention" |
157 | }, | 183 | }, |
158 | { | 184 | { |
185 | "Unit": "CPU-M-CF", | ||
159 | "EventCode": "155", | 186 | "EventCode": "155", |
160 | "EventName": "L1D_OFFDRAWER_FCOL_L4_SOURCED_WRITES", | 187 | "EventName": "L1D_OFFDRAWER_FCOL_L4_SOURCED_WRITES", |
161 | "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes", | 188 | "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes", |
162 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache" | 189 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache" |
163 | }, | 190 | }, |
164 | { | 191 | { |
192 | "Unit": "CPU-M-CF", | ||
165 | "EventCode": "156", | 193 | "EventCode": "156", |
166 | "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV", | 194 | "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV", |
167 | "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes with Intervention", | 195 | "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes with Intervention", |
168 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention" | 196 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention" |
169 | }, | 197 | }, |
170 | { | 198 | { |
199 | "Unit": "CPU-M-CF", | ||
171 | "EventCode": "157", | 200 | "EventCode": "157", |
172 | "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES", | 201 | "EventName": "L1D_OFFDRAWER_FCOL_L3_SOURCED_WRITES", |
173 | "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes", | 202 | "BriefDescription": "L1D Off-Drawer Far-Column L3 Sourced Writes", |
174 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention" | 203 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention" |
175 | }, | 204 | }, |
176 | { | 205 | { |
206 | "Unit": "CPU-M-CF", | ||
177 | "EventCode": "158", | 207 | "EventCode": "158", |
178 | "EventName": "L1D_ONNODE_MEM_SOURCED_WRITES", | 208 | "EventName": "L1D_ONNODE_MEM_SOURCED_WRITES", |
179 | "BriefDescription": "L1D On-Node Memory Sourced Writes", | 209 | "BriefDescription": "L1D On-Node Memory Sourced Writes", |
180 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Node memory" | 210 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Node memory" |
181 | }, | 211 | }, |
182 | { | 212 | { |
213 | "Unit": "CPU-M-CF", | ||
183 | "EventCode": "159", | 214 | "EventCode": "159", |
184 | "EventName": "L1D_ONDRAWER_MEM_SOURCED_WRITES", | 215 | "EventName": "L1D_ONDRAWER_MEM_SOURCED_WRITES", |
185 | "BriefDescription": "L1D On-Drawer Memory Sourced Writes", | 216 | "BriefDescription": "L1D On-Drawer Memory Sourced Writes", |
186 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory" | 217 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory" |
187 | }, | 218 | }, |
188 | { | 219 | { |
220 | "Unit": "CPU-M-CF", | ||
189 | "EventCode": "160", | 221 | "EventCode": "160", |
190 | "EventName": "L1D_OFFDRAWER_MEM_SOURCED_WRITES", | 222 | "EventName": "L1D_OFFDRAWER_MEM_SOURCED_WRITES", |
191 | "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", | 223 | "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", |
192 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory" | 224 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer memory" |
193 | }, | 225 | }, |
194 | { | 226 | { |
227 | "Unit": "CPU-M-CF", | ||
195 | "EventCode": "161", | 228 | "EventCode": "161", |
196 | "EventName": "L1D_ONCHIP_MEM_SOURCED_WRITES", | 229 | "EventName": "L1D_ONCHIP_MEM_SOURCED_WRITES", |
197 | "BriefDescription": "L1D On-Chip Memory Sourced Writes", | 230 | "BriefDescription": "L1D On-Chip Memory Sourced Writes", |
198 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" | 231 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" |
199 | }, | 232 | }, |
200 | { | 233 | { |
234 | "Unit": "CPU-M-CF", | ||
201 | "EventCode": "162", | 235 | "EventCode": "162", |
202 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", | 236 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", |
203 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", | 237 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", |
204 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" | 238 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" |
205 | }, | 239 | }, |
206 | { | 240 | { |
241 | "Unit": "CPU-M-CF", | ||
207 | "EventCode": "163", | 242 | "EventCode": "163", |
208 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", | 243 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", |
209 | "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", | 244 | "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", |
210 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention" | 245 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention" |
211 | }, | 246 | }, |
212 | { | 247 | { |
248 | "Unit": "CPU-M-CF", | ||
213 | "EventCode": "164", | 249 | "EventCode": "164", |
214 | "EventName": "L1I_ONNODE_L4_SOURCED_WRITES", | 250 | "EventName": "L1I_ONNODE_L4_SOURCED_WRITES", |
215 | "BriefDescription": "L1I On-Chip L4 Sourced Writes", | 251 | "BriefDescription": "L1I On-Chip L4 Sourced Writes", |
216 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-4 cache" | 252 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-4 cache" |
217 | }, | 253 | }, |
218 | { | 254 | { |
255 | "Unit": "CPU-M-CF", | ||
219 | "EventCode": "165", | 256 | "EventCode": "165", |
220 | "EventName": "L1I_ONNODE_L3_SOURCED_WRITES_IV", | 257 | "EventName": "L1I_ONNODE_L3_SOURCED_WRITES_IV", |
221 | "BriefDescription": "L1I On-Node L3 Sourced Writes with Intervention", | 258 | "BriefDescription": "L1I On-Node L3 Sourced Writes with Intervention", |
222 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention" | 259 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache with intervention" |
223 | }, | 260 | }, |
224 | { | 261 | { |
262 | "Unit": "CPU-M-CF", | ||
225 | "EventCode": "166", | 263 | "EventCode": "166", |
226 | "EventName": "L1I_ONNODE_L3_SOURCED_WRITES", | 264 | "EventName": "L1I_ONNODE_L3_SOURCED_WRITES", |
227 | "BriefDescription": "L1I On-Node L3 Sourced Writes", | 265 | "BriefDescription": "L1I On-Node L3 Sourced Writes", |
228 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention" | 266 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Node Level-3 cache without intervention" |
229 | }, | 267 | }, |
230 | { | 268 | { |
269 | "Unit": "CPU-M-CF", | ||
231 | "EventCode": "167", | 270 | "EventCode": "167", |
232 | "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", | 271 | "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", |
233 | "BriefDescription": "L1I On-Drawer L4 Sourced Writes", | 272 | "BriefDescription": "L1I On-Drawer L4 Sourced Writes", |
234 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache" | 273 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-4 cache" |
235 | }, | 274 | }, |
236 | { | 275 | { |
276 | "Unit": "CPU-M-CF", | ||
237 | "EventCode": "168", | 277 | "EventCode": "168", |
238 | "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES_IV", | 278 | "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES_IV", |
239 | "BriefDescription": "L1I On-Drawer L3 Sourced Writes with Intervention", | 279 | "BriefDescription": "L1I On-Drawer L3 Sourced Writes with Intervention", |
240 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention" | 280 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache with intervention" |
241 | }, | 281 | }, |
242 | { | 282 | { |
283 | "Unit": "CPU-M-CF", | ||
243 | "EventCode": "169", | 284 | "EventCode": "169", |
244 | "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES", | 285 | "EventName": "L1I_ONDRAWER_L3_SOURCED_WRITES", |
245 | "BriefDescription": "L1I On-Drawer L3 Sourced Writes", | 286 | "BriefDescription": "L1I On-Drawer L3 Sourced Writes", |
246 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention" | 287 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Drawer Level-3 cache without intervention" |
247 | }, | 288 | }, |
248 | { | 289 | { |
290 | "Unit": "CPU-M-CF", | ||
249 | "EventCode": "170", | 291 | "EventCode": "170", |
250 | "EventName": "L1I_OFFDRAWER_SCOL_L4_SOURCED_WRITES", | 292 | "EventName": "L1I_OFFDRAWER_SCOL_L4_SOURCED_WRITES", |
251 | "BriefDescription": "L1I Off-Drawer Same-Column L4 Sourced Writes", | 293 | "BriefDescription": "L1I Off-Drawer Same-Column L4 Sourced Writes", |
252 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache" | 294 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-4 cache" |
253 | }, | 295 | }, |
254 | { | 296 | { |
297 | "Unit": "CPU-M-CF", | ||
255 | "EventCode": "171", | 298 | "EventCode": "171", |
256 | "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV", | 299 | "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES_IV", |
257 | "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes with Intervention", | 300 | "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes with Intervention", |
258 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention" | 301 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache with intervention" |
259 | }, | 302 | }, |
260 | { | 303 | { |
304 | "Unit": "CPU-M-CF", | ||
261 | "EventCode": "172", | 305 | "EventCode": "172", |
262 | "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES", | 306 | "EventName": "L1I_OFFDRAWER_SCOL_L3_SOURCED_WRITES", |
263 | "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes", | 307 | "BriefDescription": "L1I Off-Drawer Same-Column L3 Sourced Writes", |
264 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention" | 308 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Same-Column Level-3 cache without intervention" |
265 | }, | 309 | }, |
266 | { | 310 | { |
311 | "Unit": "CPU-M-CF", | ||
267 | "EventCode": "173", | 312 | "EventCode": "173", |
268 | "EventName": "L1I_OFFDRAWER_FCOL_L4_SOURCED_WRITES", | 313 | "EventName": "L1I_OFFDRAWER_FCOL_L4_SOURCED_WRITES", |
269 | "BriefDescription": "L1I Off-Drawer Far-Column L4 Sourced Writes", | 314 | "BriefDescription": "L1I Off-Drawer Far-Column L4 Sourced Writes", |
270 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache" | 315 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-4 cache" |
271 | }, | 316 | }, |
272 | { | 317 | { |
318 | "Unit": "CPU-M-CF", | ||
273 | "EventCode": "174", | 319 | "EventCode": "174", |
274 | "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV", | 320 | "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES_IV", |
275 | "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes with Intervention", | 321 | "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes with Intervention", |
276 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention" | 322 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache with intervention" |
277 | }, | 323 | }, |
278 | { | 324 | { |
325 | "Unit": "CPU-M-CF", | ||
279 | "EventCode": "175", | 326 | "EventCode": "175", |
280 | "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES", | 327 | "EventName": "L1I_OFFDRAWER_FCOL_L3_SOURCED_WRITES", |
281 | "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes", | 328 | "BriefDescription": "L1I Off-Drawer Far-Column L3 Sourced Writes", |
282 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention" | 329 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Far-Column Level-3 cache without intervention" |
283 | }, | 330 | }, |
284 | { | 331 | { |
332 | "Unit": "CPU-M-CF", | ||
285 | "EventCode": "176", | 333 | "EventCode": "176", |
286 | "EventName": "L1I_ONNODE_MEM_SOURCED_WRITES", | 334 | "EventName": "L1I_ONNODE_MEM_SOURCED_WRITES", |
287 | "BriefDescription": "L1I On-Node Memory Sourced Writes", | 335 | "BriefDescription": "L1I On-Node Memory Sourced Writes", |
288 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Node memory" | 336 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Node memory" |
289 | }, | 337 | }, |
290 | { | 338 | { |
339 | "Unit": "CPU-M-CF", | ||
291 | "EventCode": "177", | 340 | "EventCode": "177", |
292 | "EventName": "L1I_ONDRAWER_MEM_SOURCED_WRITES", | 341 | "EventName": "L1I_ONDRAWER_MEM_SOURCED_WRITES", |
293 | "BriefDescription": "L1I On-Drawer Memory Sourced Writes", | 342 | "BriefDescription": "L1I On-Drawer Memory Sourced Writes", |
294 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory" | 343 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory" |
295 | }, | 344 | }, |
296 | { | 345 | { |
346 | "Unit": "CPU-M-CF", | ||
297 | "EventCode": "178", | 347 | "EventCode": "178", |
298 | "EventName": "L1I_OFFDRAWER_MEM_SOURCED_WRITES", | 348 | "EventName": "L1I_OFFDRAWER_MEM_SOURCED_WRITES", |
299 | "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", | 349 | "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", |
300 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory" | 350 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer memory" |
301 | }, | 351 | }, |
302 | { | 352 | { |
353 | "Unit": "CPU-M-CF", | ||
303 | "EventCode": "179", | 354 | "EventCode": "179", |
304 | "EventName": "L1I_ONCHIP_MEM_SOURCED_WRITES", | 355 | "EventName": "L1I_ONCHIP_MEM_SOURCED_WRITES", |
305 | "BriefDescription": "L1I On-Chip Memory Sourced Writes", | 356 | "BriefDescription": "L1I On-Chip Memory Sourced Writes", |
306 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Chip memory" | 357 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Chip memory" |
307 | }, | 358 | }, |
308 | { | 359 | { |
360 | "Unit": "CPU-M-CF", | ||
309 | "EventCode": "218", | 361 | "EventCode": "218", |
310 | "EventName": "TX_NC_TABORT", | 362 | "EventName": "TX_NC_TABORT", |
311 | "BriefDescription": "Aborted transactions in non-constrained TX mode", | 363 | "BriefDescription": "Aborted transactions in non-constrained TX mode", |
312 | "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" | 364 | "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" |
313 | }, | 365 | }, |
314 | { | 366 | { |
367 | "Unit": "CPU-M-CF", | ||
315 | "EventCode": "219", | 368 | "EventCode": "219", |
316 | "EventName": "TX_C_TABORT_NO_SPECIAL", | 369 | "EventName": "TX_C_TABORT_NO_SPECIAL", |
317 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", | 370 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", |
318 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" | 371 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" |
319 | }, | 372 | }, |
320 | { | 373 | { |
374 | "Unit": "CPU-M-CF", | ||
321 | "EventCode": "220", | 375 | "EventCode": "220", |
322 | "EventName": "TX_C_TABORT_SPECIAL", | 376 | "EventName": "TX_C_TABORT_SPECIAL", |
323 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", | 377 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", |
324 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" | 378 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" |
325 | }, | 379 | }, |
326 | { | 380 | { |
381 | "Unit": "CPU-M-CF", | ||
327 | "EventCode": "448", | 382 | "EventCode": "448", |
328 | "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", | 383 | "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", |
329 | "BriefDescription": "Cycle count with one thread active", | 384 | "BriefDescription": "Cycle count with one thread active", |
330 | "PublicDescription": "Cycle count with one thread active" | 385 | "PublicDescription": "Cycle count with one thread active" |
331 | }, | 386 | }, |
332 | { | 387 | { |
388 | "Unit": "CPU-M-CF", | ||
333 | "EventCode": "449", | 389 | "EventCode": "449", |
334 | "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", | 390 | "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", |
335 | "BriefDescription": "Cycle count with two threads active", | 391 | "BriefDescription": "Cycle count with two threads active", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z13/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z13/transaction.json new file mode 100644 index 000000000000..1a0034f79f73 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z13/transaction.json | |||
@@ -0,0 +1,7 @@ | |||
1 | [ | ||
2 | { | ||
3 | "BriefDescription": "Transaction count", | ||
4 | "MetricName": "transaction", | ||
5 | "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL" | ||
6 | } | ||
7 | ] | ||
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/basic.json b/tools/perf/pmu-events/arch/s390/cf_z14/basic.json index 8f653c9d899d..17fb5241928b 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z14/basic.json +++ b/tools/perf/pmu-events/arch/s390/cf_z14/basic.json | |||
@@ -1,47 +1,55 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "0", | 4 | "EventCode": "0", |
4 | "EventName": "CPU_CYCLES", | 5 | "EventName": "CPU_CYCLES", |
5 | "BriefDescription": "CPU Cycles", | 6 | "BriefDescription": "CPU Cycles", |
6 | "PublicDescription": "Cycle Count" | 7 | "PublicDescription": "Cycle Count" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "1", | 11 | "EventCode": "1", |
10 | "EventName": "INSTRUCTIONS", | 12 | "EventName": "INSTRUCTIONS", |
11 | "BriefDescription": "Instructions", | 13 | "BriefDescription": "Instructions", |
12 | "PublicDescription": "Instruction Count" | 14 | "PublicDescription": "Instruction Count" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "2", | 18 | "EventCode": "2", |
16 | "EventName": "L1I_DIR_WRITES", | 19 | "EventName": "L1I_DIR_WRITES", |
17 | "BriefDescription": "L1I Directory Writes", | 20 | "BriefDescription": "L1I Directory Writes", |
18 | "PublicDescription": "Level-1 I-Cache Directory Write Count" | 21 | "PublicDescription": "Level-1 I-Cache Directory Write Count" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "3", | 25 | "EventCode": "3", |
22 | "EventName": "L1I_PENALTY_CYCLES", | 26 | "EventName": "L1I_PENALTY_CYCLES", |
23 | "BriefDescription": "L1I Penalty Cycles", | 27 | "BriefDescription": "L1I Penalty Cycles", |
24 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" | 28 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "4", | 32 | "EventCode": "4", |
28 | "EventName": "L1D_DIR_WRITES", | 33 | "EventName": "L1D_DIR_WRITES", |
29 | "BriefDescription": "L1D Directory Writes", | 34 | "BriefDescription": "L1D Directory Writes", |
30 | "PublicDescription": "Level-1 D-Cache Directory Write Count" | 35 | "PublicDescription": "Level-1 D-Cache Directory Write Count" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "5", | 39 | "EventCode": "5", |
34 | "EventName": "L1D_PENALTY_CYCLES", | 40 | "EventName": "L1D_PENALTY_CYCLES", |
35 | "BriefDescription": "L1D Penalty Cycles", | 41 | "BriefDescription": "L1D Penalty Cycles", |
36 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" | 42 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "32", | 46 | "EventCode": "32", |
40 | "EventName": "PROBLEM_STATE_CPU_CYCLES", | 47 | "EventName": "PROBLEM_STATE_CPU_CYCLES", |
41 | "BriefDescription": "Problem-State CPU Cycles", | 48 | "BriefDescription": "Problem-State CPU Cycles", |
42 | "PublicDescription": "Problem-State Cycle Count" | 49 | "PublicDescription": "Problem-State Cycle Count" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "33", | 53 | "EventCode": "33", |
46 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", | 54 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", |
47 | "BriefDescription": "Problem-State Instructions", | 55 | "BriefDescription": "Problem-State Instructions", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json index 7e5b72492141..db286f19e7b6 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json +++ b/tools/perf/pmu-events/arch/s390/cf_z14/crypto.json | |||
@@ -1,95 +1,111 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "64", | 4 | "EventCode": "64", |
4 | "EventName": "PRNG_FUNCTIONS", | 5 | "EventName": "PRNG_FUNCTIONS", |
5 | "BriefDescription": "PRNG Functions", | 6 | "BriefDescription": "PRNG Functions", |
6 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" | 7 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "65", | 11 | "EventCode": "65", |
10 | "EventName": "PRNG_CYCLES", | 12 | "EventName": "PRNG_CYCLES", |
11 | "BriefDescription": "PRNG Cycles", | 13 | "BriefDescription": "PRNG Cycles", |
12 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" | 14 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "66", | 18 | "EventCode": "66", |
16 | "EventName": "PRNG_BLOCKED_FUNCTIONS", | 19 | "EventName": "PRNG_BLOCKED_FUNCTIONS", |
17 | "BriefDescription": "PRNG Blocked Functions", | 20 | "BriefDescription": "PRNG Blocked Functions", |
18 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 21 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "67", | 25 | "EventCode": "67", |
22 | "EventName": "PRNG_BLOCKED_CYCLES", | 26 | "EventName": "PRNG_BLOCKED_CYCLES", |
23 | "BriefDescription": "PRNG Blocked Cycles", | 27 | "BriefDescription": "PRNG Blocked Cycles", |
24 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 28 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "68", | 32 | "EventCode": "68", |
28 | "EventName": "SHA_FUNCTIONS", | 33 | "EventName": "SHA_FUNCTIONS", |
29 | "BriefDescription": "SHA Functions", | 34 | "BriefDescription": "SHA Functions", |
30 | "PublicDescription": "Total number of SHA functions issued by the CPU" | 35 | "PublicDescription": "Total number of SHA functions issued by the CPU" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "69", | 39 | "EventCode": "69", |
34 | "EventName": "SHA_CYCLES", | 40 | "EventName": "SHA_CYCLES", |
35 | "BriefDescription": "SHA Cycles", | 41 | "BriefDescription": "SHA Cycles", |
36 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" | 42 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "70", | 46 | "EventCode": "70", |
40 | "EventName": "SHA_BLOCKED_FUNCTIONS", | 47 | "EventName": "SHA_BLOCKED_FUNCTIONS", |
41 | "BriefDescription": "SHA Blocked Functions", | 48 | "BriefDescription": "SHA Blocked Functions", |
42 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" | 49 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "71", | 53 | "EventCode": "71", |
46 | "EventName": "SHA_BLOCKED_CYCLES", | 54 | "EventName": "SHA_BLOCKED_CYCLES", |
47 | "BriefDescription": "SHA Bloced Cycles", | 55 | "BriefDescription": "SHA Bloced Cycles", |
48 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" | 56 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "72", | 60 | "EventCode": "72", |
52 | "EventName": "DEA_FUNCTIONS", | 61 | "EventName": "DEA_FUNCTIONS", |
53 | "BriefDescription": "DEA Functions", | 62 | "BriefDescription": "DEA Functions", |
54 | "PublicDescription": "Total number of the DEA functions issued by the CPU" | 63 | "PublicDescription": "Total number of the DEA functions issued by the CPU" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "73", | 67 | "EventCode": "73", |
58 | "EventName": "DEA_CYCLES", | 68 | "EventName": "DEA_CYCLES", |
59 | "BriefDescription": "DEA Cycles", | 69 | "BriefDescription": "DEA Cycles", |
60 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" | 70 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "74", | 74 | "EventCode": "74", |
64 | "EventName": "DEA_BLOCKED_FUNCTIONS", | 75 | "EventName": "DEA_BLOCKED_FUNCTIONS", |
65 | "BriefDescription": "DEA Blocked Functions", | 76 | "BriefDescription": "DEA Blocked Functions", |
66 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 77 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "75", | 81 | "EventCode": "75", |
70 | "EventName": "DEA_BLOCKED_CYCLES", | 82 | "EventName": "DEA_BLOCKED_CYCLES", |
71 | "BriefDescription": "DEA Blocked Cycles", | 83 | "BriefDescription": "DEA Blocked Cycles", |
72 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 84 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "76", | 88 | "EventCode": "76", |
76 | "EventName": "AES_FUNCTIONS", | 89 | "EventName": "AES_FUNCTIONS", |
77 | "BriefDescription": "AES Functions", | 90 | "BriefDescription": "AES Functions", |
78 | "PublicDescription": "Total number of AES functions issued by the CPU" | 91 | "PublicDescription": "Total number of AES functions issued by the CPU" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "77", | 95 | "EventCode": "77", |
82 | "EventName": "AES_CYCLES", | 96 | "EventName": "AES_CYCLES", |
83 | "BriefDescription": "AES Cycles", | 97 | "BriefDescription": "AES Cycles", |
84 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" | 98 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "78", | 102 | "EventCode": "78", |
88 | "EventName": "AES_BLOCKED_FUNCTIONS", | 103 | "EventName": "AES_BLOCKED_FUNCTIONS", |
89 | "BriefDescription": "AES Blocked Functions", | 104 | "BriefDescription": "AES Blocked Functions", |
90 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 105 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "79", | 109 | "EventCode": "79", |
94 | "EventName": "AES_BLOCKED_CYCLES", | 110 | "EventName": "AES_BLOCKED_CYCLES", |
95 | "BriefDescription": "AES Blocked Cycles", | 111 | "BriefDescription": "AES Blocked Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/extended.json b/tools/perf/pmu-events/arch/s390/cf_z14/extended.json index aa4dfb46b65b..e7a3524b748f 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z14/extended.json +++ b/tools/perf/pmu-events/arch/s390/cf_z14/extended.json | |||
@@ -1,317 +1,370 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "128", | 4 | "EventCode": "128", |
4 | "EventName": "L1D_RO_EXCL_WRITES", | 5 | "EventName": "L1D_RO_EXCL_WRITES", |
5 | "BriefDescription": "L1D Read-only Exclusive Writes", | 6 | "BriefDescription": "L1D Read-only Exclusive Writes", |
6 | "PublicDescription": "Counter:128 Name:L1D_RO_EXCL_WRITES A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" | 7 | "PublicDescription": "Counter:128 Name:L1D_RO_EXCL_WRITES A directory write to the Level-1 Data cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "129", | 11 | "EventCode": "129", |
10 | "EventName": "DTLB2_WRITES", | 12 | "EventName": "DTLB2_WRITES", |
11 | "BriefDescription": "DTLB2 Writes", | 13 | "BriefDescription": "DTLB2 Writes", |
12 | "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" | 14 | "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "130", | 18 | "EventCode": "130", |
16 | "EventName": "DTLB2_MISSES", | 19 | "EventName": "DTLB2_MISSES", |
17 | "BriefDescription": "DTLB2 Misses", | 20 | "BriefDescription": "DTLB2 Misses", |
18 | "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle" | 21 | "PublicDescription": "A TLB2 miss is in progress for a request made by the data cache. Incremented by one for every TLB2 miss in progress for the Level-1 Data cache on this cycle" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "131", | 25 | "EventCode": "131", |
22 | "EventName": "DTLB2_HPAGE_WRITES", | 26 | "EventName": "DTLB2_HPAGE_WRITES", |
23 | "BriefDescription": "DTLB2 One-Megabyte Page Writes", | 27 | "BriefDescription": "DTLB2 One-Megabyte Page Writes", |
24 | "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done" | 28 | "PublicDescription": "A translation entry was written into the Combined Region and Segment Table Entry array in the Level-2 TLB for a one-megabyte page or a Last Host Translation was done" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "132", | 32 | "EventCode": "132", |
28 | "EventName": "DTLB2_GPAGE_WRITES", | 33 | "EventName": "DTLB2_GPAGE_WRITES", |
29 | "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", | 34 | "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", |
30 | "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" | 35 | "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "133", | 39 | "EventCode": "133", |
34 | "EventName": "L1D_L2D_SOURCED_WRITES", | 40 | "EventName": "L1D_L2D_SOURCED_WRITES", |
35 | "BriefDescription": "L1D L2D Sourced Writes", | 41 | "BriefDescription": "L1D L2D Sourced Writes", |
36 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" | 42 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "134", | 46 | "EventCode": "134", |
40 | "EventName": "ITLB2_WRITES", | 47 | "EventName": "ITLB2_WRITES", |
41 | "BriefDescription": "ITLB2 Writes", | 48 | "BriefDescription": "ITLB2 Writes", |
42 | "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" | 49 | "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "135", | 53 | "EventCode": "135", |
46 | "EventName": "ITLB2_MISSES", | 54 | "EventName": "ITLB2_MISSES", |
47 | "BriefDescription": "ITLB2 Misses", | 55 | "BriefDescription": "ITLB2 Misses", |
48 | "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle" | 56 | "PublicDescription": "A TLB2 miss is in progress for a request made by the instruction cache. Incremented by one for every TLB2 miss in progress for the Level-1 Instruction cache in a cycle" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "136", | 60 | "EventCode": "136", |
52 | "EventName": "L1I_L2I_SOURCED_WRITES", | 61 | "EventName": "L1I_L2I_SOURCED_WRITES", |
53 | "BriefDescription": "L1I L2I Sourced Writes", | 62 | "BriefDescription": "L1I L2I Sourced Writes", |
54 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" | 63 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "137", | 67 | "EventCode": "137", |
58 | "EventName": "TLB2_PTE_WRITES", | 68 | "EventName": "TLB2_PTE_WRITES", |
59 | "BriefDescription": "TLB2 PTE Writes", | 69 | "BriefDescription": "TLB2 PTE Writes", |
60 | "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" | 70 | "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "138", | 74 | "EventCode": "138", |
64 | "EventName": "TLB2_CRSTE_WRITES", | 75 | "EventName": "TLB2_CRSTE_WRITES", |
65 | "BriefDescription": "TLB2 CRSTE Writes", | 76 | "BriefDescription": "TLB2 CRSTE Writes", |
66 | "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB" | 77 | "PublicDescription": "Translation entries were written into the Combined Region and Segment Table Entry array and the Page Table Entry array in the Level-2 TLB" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "139", | 81 | "EventCode": "139", |
70 | "EventName": "TLB2_ENGINES_BUSY", | 82 | "EventName": "TLB2_ENGINES_BUSY", |
71 | "BriefDescription": "TLB2 Engines Busy", | 83 | "BriefDescription": "TLB2 Engines Busy", |
72 | "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" | 84 | "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "140", | 88 | "EventCode": "140", |
76 | "EventName": "TX_C_TEND", | 89 | "EventName": "TX_C_TEND", |
77 | "BriefDescription": "Completed TEND instructions in constrained TX mode", | 90 | "BriefDescription": "Completed TEND instructions in constrained TX mode", |
78 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" | 91 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "141", | 95 | "EventCode": "141", |
82 | "EventName": "TX_NC_TEND", | 96 | "EventName": "TX_NC_TEND", |
83 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", | 97 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", |
84 | "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" | 98 | "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "143", | 102 | "EventCode": "143", |
88 | "EventName": "L1C_TLB2_MISSES", | 103 | "EventName": "L1C_TLB2_MISSES", |
89 | "BriefDescription": "L1C TLB2 Misses", | 104 | "BriefDescription": "L1C TLB2 Misses", |
90 | "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" | 105 | "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "144", | 109 | "EventCode": "144", |
94 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", | 110 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", |
95 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", | 111 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", |
96 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" | 112 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache without intervention" |
97 | }, | 113 | }, |
98 | { | 114 | { |
115 | "Unit": "CPU-M-CF", | ||
99 | "EventCode": "145", | 116 | "EventCode": "145", |
100 | "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", | 117 | "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", |
101 | "BriefDescription": "L1D On-Chip Memory Sourced Writes", | 118 | "BriefDescription": "L1D On-Chip Memory Sourced Writes", |
102 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" | 119 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" |
103 | }, | 120 | }, |
104 | { | 121 | { |
122 | "Unit": "CPU-M-CF", | ||
105 | "EventCode": "146", | 123 | "EventCode": "146", |
106 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", | 124 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", |
107 | "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", | 125 | "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", |
108 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" | 126 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Chip Level-3 cache with intervention" |
109 | }, | 127 | }, |
110 | { | 128 | { |
129 | "Unit": "CPU-M-CF", | ||
111 | "EventCode": "147", | 130 | "EventCode": "147", |
112 | "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", | 131 | "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", |
113 | "BriefDescription": "L1D On-Cluster L3 Sourced Writes", | 132 | "BriefDescription": "L1D On-Cluster L3 Sourced Writes", |
114 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention" | 133 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Cluster Level-3 cache withountervention" |
115 | }, | 134 | }, |
116 | { | 135 | { |
136 | "Unit": "CPU-M-CF", | ||
117 | "EventCode": "148", | 137 | "EventCode": "148", |
118 | "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", | 138 | "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", |
119 | "BriefDescription": "L1D On-Cluster Memory Sourced Writes", | 139 | "BriefDescription": "L1D On-Cluster Memory Sourced Writes", |
120 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" | 140 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" |
121 | }, | 141 | }, |
122 | { | 142 | { |
143 | "Unit": "CPU-M-CF", | ||
123 | "EventCode": "149", | 144 | "EventCode": "149", |
124 | "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", | 145 | "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", |
125 | "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention", | 146 | "BriefDescription": "L1D On-Cluster L3 Sourced Writes with Intervention", |
126 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention" | 147 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache with intervention" |
127 | }, | 148 | }, |
128 | { | 149 | { |
150 | "Unit": "CPU-M-CF", | ||
129 | "EventCode": "150", | 151 | "EventCode": "150", |
130 | "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", | 152 | "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", |
131 | "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", | 153 | "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", |
132 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" | 154 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" |
133 | }, | 155 | }, |
134 | { | 156 | { |
157 | "Unit": "CPU-M-CF", | ||
135 | "EventCode": "151", | 158 | "EventCode": "151", |
136 | "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", | 159 | "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", |
137 | "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", | 160 | "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", |
138 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" | 161 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" |
139 | }, | 162 | }, |
140 | { | 163 | { |
164 | "Unit": "CPU-M-CF", | ||
141 | "EventCode": "152", | 165 | "EventCode": "152", |
142 | "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", | 166 | "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", |
143 | "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention", | 167 | "BriefDescription": "L1D Off-Cluster L3 Sourced Writes with Intervention", |
144 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" | 168 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" |
145 | }, | 169 | }, |
146 | { | 170 | { |
171 | "Unit": "CPU-M-CF", | ||
147 | "EventCode": "153", | 172 | "EventCode": "153", |
148 | "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", | 173 | "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", |
149 | "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", | 174 | "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", |
150 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" | 175 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" |
151 | }, | 176 | }, |
152 | { | 177 | { |
178 | "Unit": "CPU-M-CF", | ||
153 | "EventCode": "154", | 179 | "EventCode": "154", |
154 | "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", | 180 | "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", |
155 | "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", | 181 | "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", |
156 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" | 182 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" |
157 | }, | 183 | }, |
158 | { | 184 | { |
185 | "Unit": "CPU-M-CF", | ||
159 | "EventCode": "155", | 186 | "EventCode": "155", |
160 | "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", | 187 | "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", |
161 | "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention", | 188 | "BriefDescription": "L1D Off-Drawer L3 Sourced Writes with Intervention", |
162 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" | 189 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" |
163 | }, | 190 | }, |
164 | { | 191 | { |
192 | "Unit": "CPU-M-CF", | ||
165 | "EventCode": "156", | 193 | "EventCode": "156", |
166 | "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", | 194 | "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", |
167 | "BriefDescription": "L1D On-Drawer L4 Sourced Writes", | 195 | "BriefDescription": "L1D On-Drawer L4 Sourced Writes", |
168 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" | 196 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" |
169 | }, | 197 | }, |
170 | { | 198 | { |
199 | "Unit": "CPU-M-CF", | ||
171 | "EventCode": "157", | 200 | "EventCode": "157", |
172 | "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", | 201 | "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", |
173 | "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", | 202 | "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", |
174 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" | 203 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" |
175 | }, | 204 | }, |
176 | { | 205 | { |
206 | "Unit": "CPU-M-CF", | ||
177 | "EventCode": "158", | 207 | "EventCode": "158", |
178 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", | 208 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", |
179 | "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", | 209 | "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", |
180 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line" | 210 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip L3 but a read-only invalidate was done to remove other copies of the cache line" |
181 | }, | 211 | }, |
182 | { | 212 | { |
213 | "Unit": "CPU-M-CF", | ||
183 | "EventCode": "162", | 214 | "EventCode": "162", |
184 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", | 215 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", |
185 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", | 216 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", |
186 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention" | 217 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache without intervention" |
187 | }, | 218 | }, |
188 | { | 219 | { |
220 | "Unit": "CPU-M-CF", | ||
189 | "EventCode": "163", | 221 | "EventCode": "163", |
190 | "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", | 222 | "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", |
191 | "BriefDescription": "L1I On-Chip Memory Sourced Writes", | 223 | "BriefDescription": "L1I On-Chip Memory Sourced Writes", |
192 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" | 224 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" |
193 | }, | 225 | }, |
194 | { | 226 | { |
227 | "Unit": "CPU-M-CF", | ||
195 | "EventCode": "164", | 228 | "EventCode": "164", |
196 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", | 229 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", |
197 | "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", | 230 | "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", |
198 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention" | 231 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from an On-Chip Level-3 cache with intervention" |
199 | }, | 232 | }, |
200 | { | 233 | { |
234 | "Unit": "CPU-M-CF", | ||
201 | "EventCode": "165", | 235 | "EventCode": "165", |
202 | "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", | 236 | "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", |
203 | "BriefDescription": "L1I On-Cluster L3 Sourced Writes", | 237 | "BriefDescription": "L1I On-Cluster L3 Sourced Writes", |
204 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention" | 238 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster Level-3 cache without intervention" |
205 | }, | 239 | }, |
206 | { | 240 | { |
241 | "Unit": "CPU-M-CF", | ||
207 | "EventCode": "166", | 242 | "EventCode": "166", |
208 | "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", | 243 | "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", |
209 | "BriefDescription": "L1I On-Cluster Memory Sourced Writes", | 244 | "BriefDescription": "L1I On-Cluster Memory Sourced Writes", |
210 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" | 245 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" |
211 | }, | 246 | }, |
212 | { | 247 | { |
248 | "Unit": "CPU-M-CF", | ||
213 | "EventCode": "167", | 249 | "EventCode": "167", |
214 | "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", | 250 | "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", |
215 | "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention", | 251 | "BriefDescription": "L1I On-Cluster L3 Sourced Writes with Intervention", |
216 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention" | 252 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Cluster Level-3 cache with intervention" |
217 | }, | 253 | }, |
218 | { | 254 | { |
255 | "Unit": "CPU-M-CF", | ||
219 | "EventCode": "168", | 256 | "EventCode": "168", |
220 | "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", | 257 | "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", |
221 | "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", | 258 | "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", |
222 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" | 259 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache without intervention" |
223 | }, | 260 | }, |
224 | { | 261 | { |
262 | "Unit": "CPU-M-CF", | ||
225 | "EventCode": "169", | 263 | "EventCode": "169", |
226 | "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", | 264 | "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", |
227 | "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", | 265 | "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", |
228 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" | 266 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" |
229 | }, | 267 | }, |
230 | { | 268 | { |
269 | "Unit": "CPU-M-CF", | ||
231 | "EventCode": "170", | 270 | "EventCode": "170", |
232 | "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", | 271 | "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", |
233 | "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention", | 272 | "BriefDescription": "L1I Off-Cluster L3 Sourced Writes with Intervention", |
234 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" | 273 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Cluster Level-3 cache with intervention" |
235 | }, | 274 | }, |
236 | { | 275 | { |
276 | "Unit": "CPU-M-CF", | ||
237 | "EventCode": "171", | 277 | "EventCode": "171", |
238 | "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", | 278 | "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", |
239 | "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", | 279 | "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", |
240 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" | 280 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache without intervention" |
241 | }, | 281 | }, |
242 | { | 282 | { |
283 | "Unit": "CPU-M-CF", | ||
243 | "EventCode": "172", | 284 | "EventCode": "172", |
244 | "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", | 285 | "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", |
245 | "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", | 286 | "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", |
246 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" | 287 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" |
247 | }, | 288 | }, |
248 | { | 289 | { |
290 | "Unit": "CPU-M-CF", | ||
249 | "EventCode": "173", | 291 | "EventCode": "173", |
250 | "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", | 292 | "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", |
251 | "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention", | 293 | "BriefDescription": "L1I Off-Drawer L3 Sourced Writes with Intervention", |
252 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" | 294 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off-Drawer Level-3 cache with intervention" |
253 | }, | 295 | }, |
254 | { | 296 | { |
297 | "Unit": "CPU-M-CF", | ||
255 | "EventCode": "174", | 298 | "EventCode": "174", |
256 | "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", | 299 | "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", |
257 | "BriefDescription": "L1I On-Drawer L4 Sourced Writes", | 300 | "BriefDescription": "L1I On-Drawer L4 Sourced Writes", |
258 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" | 301 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from On-Drawer Level-4 cache" |
259 | }, | 302 | }, |
260 | { | 303 | { |
304 | "Unit": "CPU-M-CF", | ||
261 | "EventCode": "175", | 305 | "EventCode": "175", |
262 | "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", | 306 | "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", |
263 | "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", | 307 | "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", |
264 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" | 308 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer Level-4 cache" |
265 | }, | 309 | }, |
266 | { | 310 | { |
311 | "Unit": "CPU-M-CF", | ||
267 | "EventCode": "224", | 312 | "EventCode": "224", |
268 | "EventName": "BCD_DFP_EXECUTION_SLOTS", | 313 | "EventName": "BCD_DFP_EXECUTION_SLOTS", |
269 | "BriefDescription": "BCD DFP Execution Slots", | 314 | "BriefDescription": "BCD DFP Execution Slots", |
270 | "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" | 315 | "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" |
271 | }, | 316 | }, |
272 | { | 317 | { |
318 | "Unit": "CPU-M-CF", | ||
273 | "EventCode": "225", | 319 | "EventCode": "225", |
274 | "EventName": "VX_BCD_EXECUTION_SLOTS", | 320 | "EventName": "VX_BCD_EXECUTION_SLOTS", |
275 | "BriefDescription": "VX BCD Execution Slots", | 321 | "BriefDescription": "VX BCD Execution Slots", |
276 | "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG" | 322 | "PublicDescription": "Count of floating point execution slots used for finished vector arithmetic Binary Coded Decimal instructions. Instructions: VAP, VSP, VMPVMSP, VDP, VSDP, VRP, VLIP, VSRP, VPSOPVCP, VTP, VPKZ, VUPKZ, VCVB, VCVBG, VCVDVCVDG" |
277 | }, | 323 | }, |
278 | { | 324 | { |
325 | "Unit": "CPU-M-CF", | ||
279 | "EventCode": "226", | 326 | "EventCode": "226", |
280 | "EventName": "DECIMAL_INSTRUCTIONS", | 327 | "EventName": "DECIMAL_INSTRUCTIONS", |
281 | "BriefDescription": "Decimal Instructions", | 328 | "BriefDescription": "Decimal Instructions", |
282 | "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" | 329 | "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" |
283 | }, | 330 | }, |
284 | { | 331 | { |
332 | "Unit": "CPU-M-CF", | ||
285 | "EventCode": "232", | 333 | "EventCode": "232", |
286 | "EventName": "LAST_HOST_TRANSLATIONS", | 334 | "EventName": "LAST_HOST_TRANSLATIONS", |
287 | "BriefDescription": "Last host translation done", | 335 | "BriefDescription": "Last host translation done", |
288 | "PublicDescription": "Last Host Translation done" | 336 | "PublicDescription": "Last Host Translation done" |
289 | }, | 337 | }, |
290 | { | 338 | { |
339 | "Unit": "CPU-M-CF", | ||
291 | "EventCode": "243", | 340 | "EventCode": "243", |
292 | "EventName": "TX_NC_TABORT", | 341 | "EventName": "TX_NC_TABORT", |
293 | "BriefDescription": "Aborted transactions in non-constrained TX mode", | 342 | "BriefDescription": "Aborted transactions in non-constrained TX mode", |
294 | "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" | 343 | "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" |
295 | }, | 344 | }, |
296 | { | 345 | { |
346 | "Unit": "CPU-M-CF", | ||
297 | "EventCode": "244", | 347 | "EventCode": "244", |
298 | "EventName": "TX_C_TABORT_NO_SPECIAL", | 348 | "EventName": "TX_C_TABORT_NO_SPECIAL", |
299 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", | 349 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", |
300 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" | 350 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" |
301 | }, | 351 | }, |
302 | { | 352 | { |
353 | "Unit": "CPU-M-CF", | ||
303 | "EventCode": "245", | 354 | "EventCode": "245", |
304 | "EventName": "TX_C_TABORT_SPECIAL", | 355 | "EventName": "TX_C_TABORT_SPECIAL", |
305 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", | 356 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", |
306 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" | 357 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is using special logic to allow the transaction to complete" |
307 | }, | 358 | }, |
308 | { | 359 | { |
360 | "Unit": "CPU-M-CF", | ||
309 | "EventCode": "448", | 361 | "EventCode": "448", |
310 | "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", | 362 | "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", |
311 | "BriefDescription": "Cycle count with one thread active", | 363 | "BriefDescription": "Cycle count with one thread active", |
312 | "PublicDescription": "Cycle count with one thread active" | 364 | "PublicDescription": "Cycle count with one thread active" |
313 | }, | 365 | }, |
314 | { | 366 | { |
367 | "Unit": "CPU-M-CF", | ||
315 | "EventCode": "449", | 368 | "EventCode": "449", |
316 | "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", | 369 | "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", |
317 | "BriefDescription": "Cycle count with two threads active", | 370 | "BriefDescription": "Cycle count with two threads active", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z14/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z14/transaction.json new file mode 100644 index 000000000000..1a0034f79f73 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_z14/transaction.json | |||
@@ -0,0 +1,7 @@ | |||
1 | [ | ||
2 | { | ||
3 | "BriefDescription": "Transaction count", | ||
4 | "MetricName": "transaction", | ||
5 | "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL" | ||
6 | } | ||
7 | ] | ||
diff --git a/tools/perf/pmu-events/arch/s390/cf_z196/basic.json b/tools/perf/pmu-events/arch/s390/cf_z196/basic.json index 8bf16759ca53..2dd8dafff2ef 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z196/basic.json +++ b/tools/perf/pmu-events/arch/s390/cf_z196/basic.json | |||
@@ -1,71 +1,83 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "0", | 4 | "EventCode": "0", |
4 | "EventName": "CPU_CYCLES", | 5 | "EventName": "CPU_CYCLES", |
5 | "BriefDescription": "CPU Cycles", | 6 | "BriefDescription": "CPU Cycles", |
6 | "PublicDescription": "Cycle Count" | 7 | "PublicDescription": "Cycle Count" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "1", | 11 | "EventCode": "1", |
10 | "EventName": "INSTRUCTIONS", | 12 | "EventName": "INSTRUCTIONS", |
11 | "BriefDescription": "Instructions", | 13 | "BriefDescription": "Instructions", |
12 | "PublicDescription": "Instruction Count" | 14 | "PublicDescription": "Instruction Count" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "2", | 18 | "EventCode": "2", |
16 | "EventName": "L1I_DIR_WRITES", | 19 | "EventName": "L1I_DIR_WRITES", |
17 | "BriefDescription": "L1I Directory Writes", | 20 | "BriefDescription": "L1I Directory Writes", |
18 | "PublicDescription": "Level-1 I-Cache Directory Write Count" | 21 | "PublicDescription": "Level-1 I-Cache Directory Write Count" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "3", | 25 | "EventCode": "3", |
22 | "EventName": "L1I_PENALTY_CYCLES", | 26 | "EventName": "L1I_PENALTY_CYCLES", |
23 | "BriefDescription": "L1I Penalty Cycles", | 27 | "BriefDescription": "L1I Penalty Cycles", |
24 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" | 28 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "4", | 32 | "EventCode": "4", |
28 | "EventName": "L1D_DIR_WRITES", | 33 | "EventName": "L1D_DIR_WRITES", |
29 | "BriefDescription": "L1D Directory Writes", | 34 | "BriefDescription": "L1D Directory Writes", |
30 | "PublicDescription": "Level-1 D-Cache Directory Write Count" | 35 | "PublicDescription": "Level-1 D-Cache Directory Write Count" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "5", | 39 | "EventCode": "5", |
34 | "EventName": "L1D_PENALTY_CYCLES", | 40 | "EventName": "L1D_PENALTY_CYCLES", |
35 | "BriefDescription": "L1D Penalty Cycles", | 41 | "BriefDescription": "L1D Penalty Cycles", |
36 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" | 42 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "32", | 46 | "EventCode": "32", |
40 | "EventName": "PROBLEM_STATE_CPU_CYCLES", | 47 | "EventName": "PROBLEM_STATE_CPU_CYCLES", |
41 | "BriefDescription": "Problem-State CPU Cycles", | 48 | "BriefDescription": "Problem-State CPU Cycles", |
42 | "PublicDescription": "Problem-State Cycle Count" | 49 | "PublicDescription": "Problem-State Cycle Count" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "33", | 53 | "EventCode": "33", |
46 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", | 54 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", |
47 | "BriefDescription": "Problem-State Instructions", | 55 | "BriefDescription": "Problem-State Instructions", |
48 | "PublicDescription": "Problem-State Instruction Count" | 56 | "PublicDescription": "Problem-State Instruction Count" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "34", | 60 | "EventCode": "34", |
52 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", | 61 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", |
53 | "BriefDescription": "Problem-State L1I Directory Writes", | 62 | "BriefDescription": "Problem-State L1I Directory Writes", |
54 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" | 63 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "35", | 67 | "EventCode": "35", |
58 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", | 68 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", |
59 | "BriefDescription": "Problem-State L1I Penalty Cycles", | 69 | "BriefDescription": "Problem-State L1I Penalty Cycles", |
60 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" | 70 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "36", | 74 | "EventCode": "36", |
64 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", | 75 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", |
65 | "BriefDescription": "Problem-State L1D Directory Writes", | 76 | "BriefDescription": "Problem-State L1D Directory Writes", |
66 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" | 77 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "37", | 81 | "EventCode": "37", |
70 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", | 82 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", |
71 | "BriefDescription": "Problem-State L1D Penalty Cycles", | 83 | "BriefDescription": "Problem-State L1D Penalty Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json b/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json index 7e5b72492141..db286f19e7b6 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json +++ b/tools/perf/pmu-events/arch/s390/cf_z196/crypto.json | |||
@@ -1,95 +1,111 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "64", | 4 | "EventCode": "64", |
4 | "EventName": "PRNG_FUNCTIONS", | 5 | "EventName": "PRNG_FUNCTIONS", |
5 | "BriefDescription": "PRNG Functions", | 6 | "BriefDescription": "PRNG Functions", |
6 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" | 7 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "65", | 11 | "EventCode": "65", |
10 | "EventName": "PRNG_CYCLES", | 12 | "EventName": "PRNG_CYCLES", |
11 | "BriefDescription": "PRNG Cycles", | 13 | "BriefDescription": "PRNG Cycles", |
12 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" | 14 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "66", | 18 | "EventCode": "66", |
16 | "EventName": "PRNG_BLOCKED_FUNCTIONS", | 19 | "EventName": "PRNG_BLOCKED_FUNCTIONS", |
17 | "BriefDescription": "PRNG Blocked Functions", | 20 | "BriefDescription": "PRNG Blocked Functions", |
18 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 21 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "67", | 25 | "EventCode": "67", |
22 | "EventName": "PRNG_BLOCKED_CYCLES", | 26 | "EventName": "PRNG_BLOCKED_CYCLES", |
23 | "BriefDescription": "PRNG Blocked Cycles", | 27 | "BriefDescription": "PRNG Blocked Cycles", |
24 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 28 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "68", | 32 | "EventCode": "68", |
28 | "EventName": "SHA_FUNCTIONS", | 33 | "EventName": "SHA_FUNCTIONS", |
29 | "BriefDescription": "SHA Functions", | 34 | "BriefDescription": "SHA Functions", |
30 | "PublicDescription": "Total number of SHA functions issued by the CPU" | 35 | "PublicDescription": "Total number of SHA functions issued by the CPU" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "69", | 39 | "EventCode": "69", |
34 | "EventName": "SHA_CYCLES", | 40 | "EventName": "SHA_CYCLES", |
35 | "BriefDescription": "SHA Cycles", | 41 | "BriefDescription": "SHA Cycles", |
36 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" | 42 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "70", | 46 | "EventCode": "70", |
40 | "EventName": "SHA_BLOCKED_FUNCTIONS", | 47 | "EventName": "SHA_BLOCKED_FUNCTIONS", |
41 | "BriefDescription": "SHA Blocked Functions", | 48 | "BriefDescription": "SHA Blocked Functions", |
42 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" | 49 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "71", | 53 | "EventCode": "71", |
46 | "EventName": "SHA_BLOCKED_CYCLES", | 54 | "EventName": "SHA_BLOCKED_CYCLES", |
47 | "BriefDescription": "SHA Bloced Cycles", | 55 | "BriefDescription": "SHA Bloced Cycles", |
48 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" | 56 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "72", | 60 | "EventCode": "72", |
52 | "EventName": "DEA_FUNCTIONS", | 61 | "EventName": "DEA_FUNCTIONS", |
53 | "BriefDescription": "DEA Functions", | 62 | "BriefDescription": "DEA Functions", |
54 | "PublicDescription": "Total number of the DEA functions issued by the CPU" | 63 | "PublicDescription": "Total number of the DEA functions issued by the CPU" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "73", | 67 | "EventCode": "73", |
58 | "EventName": "DEA_CYCLES", | 68 | "EventName": "DEA_CYCLES", |
59 | "BriefDescription": "DEA Cycles", | 69 | "BriefDescription": "DEA Cycles", |
60 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" | 70 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "74", | 74 | "EventCode": "74", |
64 | "EventName": "DEA_BLOCKED_FUNCTIONS", | 75 | "EventName": "DEA_BLOCKED_FUNCTIONS", |
65 | "BriefDescription": "DEA Blocked Functions", | 76 | "BriefDescription": "DEA Blocked Functions", |
66 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 77 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "75", | 81 | "EventCode": "75", |
70 | "EventName": "DEA_BLOCKED_CYCLES", | 82 | "EventName": "DEA_BLOCKED_CYCLES", |
71 | "BriefDescription": "DEA Blocked Cycles", | 83 | "BriefDescription": "DEA Blocked Cycles", |
72 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 84 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "76", | 88 | "EventCode": "76", |
76 | "EventName": "AES_FUNCTIONS", | 89 | "EventName": "AES_FUNCTIONS", |
77 | "BriefDescription": "AES Functions", | 90 | "BriefDescription": "AES Functions", |
78 | "PublicDescription": "Total number of AES functions issued by the CPU" | 91 | "PublicDescription": "Total number of AES functions issued by the CPU" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "77", | 95 | "EventCode": "77", |
82 | "EventName": "AES_CYCLES", | 96 | "EventName": "AES_CYCLES", |
83 | "BriefDescription": "AES Cycles", | 97 | "BriefDescription": "AES Cycles", |
84 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" | 98 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "78", | 102 | "EventCode": "78", |
88 | "EventName": "AES_BLOCKED_FUNCTIONS", | 103 | "EventName": "AES_BLOCKED_FUNCTIONS", |
89 | "BriefDescription": "AES Blocked Functions", | 104 | "BriefDescription": "AES Blocked Functions", |
90 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 105 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "79", | 109 | "EventCode": "79", |
94 | "EventName": "AES_BLOCKED_CYCLES", | 110 | "EventName": "AES_BLOCKED_CYCLES", |
95 | "BriefDescription": "AES Blocked Cycles", | 111 | "BriefDescription": "AES Blocked Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_z196/extended.json b/tools/perf/pmu-events/arch/s390/cf_z196/extended.json index b6d7fec7c2e7..b7b42a870bb0 100644 --- a/tools/perf/pmu-events/arch/s390/cf_z196/extended.json +++ b/tools/perf/pmu-events/arch/s390/cf_z196/extended.json | |||
@@ -1,143 +1,167 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "128", | 4 | "EventCode": "128", |
4 | "EventName": "L1D_L2_SOURCED_WRITES", | 5 | "EventName": "L1D_L2_SOURCED_WRITES", |
5 | "BriefDescription": "L1D L2 Sourced Writes", | 6 | "BriefDescription": "L1D L2 Sourced Writes", |
6 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from the Level-2 cache" | 7 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from the Level-2 cache" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "129", | 11 | "EventCode": "129", |
10 | "EventName": "L1I_L2_SOURCED_WRITES", | 12 | "EventName": "L1I_L2_SOURCED_WRITES", |
11 | "BriefDescription": "L1I L2 Sourced Writes", | 13 | "BriefDescription": "L1I L2 Sourced Writes", |
12 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 cache" | 14 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from the Level-2 cache" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "130", | 18 | "EventCode": "130", |
16 | "EventName": "DTLB1_MISSES", | 19 | "EventName": "DTLB1_MISSES", |
17 | "BriefDescription": "DTLB1 Misses", | 20 | "BriefDescription": "DTLB1 Misses", |
18 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." | 21 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "131", | 25 | "EventCode": "131", |
22 | "EventName": "ITLB1_MISSES", | 26 | "EventName": "ITLB1_MISSES", |
23 | "BriefDescription": "ITLB1 Misses", | 27 | "BriefDescription": "ITLB1 Misses", |
24 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress." | 28 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress." |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "133", | 32 | "EventCode": "133", |
28 | "EventName": "L2C_STORES_SENT", | 33 | "EventName": "L2C_STORES_SENT", |
29 | "BriefDescription": "L2C Stores Sent", | 34 | "BriefDescription": "L2C Stores Sent", |
30 | "PublicDescription": "Incremented by one for every store sent to Level-2 cache" | 35 | "PublicDescription": "Incremented by one for every store sent to Level-2 cache" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "134", | 39 | "EventCode": "134", |
34 | "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES", | 40 | "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES", |
35 | "BriefDescription": "L1D Off-Book L3 Sourced Writes", | 41 | "BriefDescription": "L1D Off-Book L3 Sourced Writes", |
36 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache" | 42 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "135", | 46 | "EventCode": "135", |
40 | "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES", | 47 | "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES", |
41 | "BriefDescription": "L1D On-Book L4 Sourced Writes", | 48 | "BriefDescription": "L1D On-Book L4 Sourced Writes", |
42 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Book Level-4 cache" | 49 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Book Level-4 cache" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "136", | 53 | "EventCode": "136", |
46 | "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES", | 54 | "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES", |
47 | "BriefDescription": "L1I On-Book L4 Sourced Writes", | 55 | "BriefDescription": "L1I On-Book L4 Sourced Writes", |
48 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Book Level-4 cache" | 56 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Book Level-4 cache" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "137", | 60 | "EventCode": "137", |
52 | "EventName": "L1D_RO_EXCL_WRITES", | 61 | "EventName": "L1D_RO_EXCL_WRITES", |
53 | "BriefDescription": "L1D Read-only Exclusive Writes", | 62 | "BriefDescription": "L1D Read-only Exclusive Writes", |
54 | "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" | 63 | "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "138", | 67 | "EventCode": "138", |
58 | "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES", | 68 | "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES", |
59 | "BriefDescription": "L1D Off-Book L4 Sourced Writes", | 69 | "BriefDescription": "L1D Off-Book L4 Sourced Writes", |
60 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache" | 70 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "139", | 74 | "EventCode": "139", |
64 | "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES", | 75 | "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES", |
65 | "BriefDescription": "L1I Off-Book L4 Sourced Writes", | 76 | "BriefDescription": "L1I Off-Book L4 Sourced Writes", |
66 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache" | 77 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-4 cache" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "140", | 81 | "EventCode": "140", |
70 | "EventName": "DTLB1_HPAGE_WRITES", | 82 | "EventName": "DTLB1_HPAGE_WRITES", |
71 | "BriefDescription": "DTLB1 One-Megabyte Page Writes", | 83 | "BriefDescription": "DTLB1 One-Megabyte Page Writes", |
72 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" | 84 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "141", | 88 | "EventCode": "141", |
76 | "EventName": "L1D_LMEM_SOURCED_WRITES", | 89 | "EventName": "L1D_LMEM_SOURCED_WRITES", |
77 | "BriefDescription": "L1D Local Memory Sourced Writes", | 90 | "BriefDescription": "L1D Local Memory Sourced Writes", |
78 | "PublicDescription": "A directory write to the Level-1 D-Cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" | 91 | "PublicDescription": "A directory write to the Level-1 D-Cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "142", | 95 | "EventCode": "142", |
82 | "EventName": "L1I_LMEM_SOURCED_WRITES", | 96 | "EventName": "L1I_LMEM_SOURCED_WRITES", |
83 | "BriefDescription": "L1I Local Memory Sourced Writes", | 97 | "BriefDescription": "L1I Local Memory Sourced Writes", |
84 | "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)" | 98 | "PublicDescription": "A directory write to the Level-1 I-Cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "143", | 102 | "EventCode": "143", |
88 | "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES", | 103 | "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES", |
89 | "BriefDescription": "L1I Off-Book L3 Sourced Writes", | 104 | "BriefDescription": "L1I Off-Book L3 Sourced Writes", |
90 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache" | 105 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an Off Book Level-3 cache" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "144", | 109 | "EventCode": "144", |
94 | "EventName": "DTLB1_WRITES", | 110 | "EventName": "DTLB1_WRITES", |
95 | "BriefDescription": "DTLB1 Writes", | 111 | "BriefDescription": "DTLB1 Writes", |
96 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" | 112 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" |
97 | }, | 113 | }, |
98 | { | 114 | { |
115 | "Unit": "CPU-M-CF", | ||
99 | "EventCode": "145", | 116 | "EventCode": "145", |
100 | "EventName": "ITLB1_WRITES", | 117 | "EventName": "ITLB1_WRITES", |
101 | "BriefDescription": "ITLB1 Writes", | 118 | "BriefDescription": "ITLB1 Writes", |
102 | "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" | 119 | "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" |
103 | }, | 120 | }, |
104 | { | 121 | { |
122 | "Unit": "CPU-M-CF", | ||
105 | "EventCode": "146", | 123 | "EventCode": "146", |
106 | "EventName": "TLB2_PTE_WRITES", | 124 | "EventName": "TLB2_PTE_WRITES", |
107 | "BriefDescription": "TLB2 PTE Writes", | 125 | "BriefDescription": "TLB2 PTE Writes", |
108 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" | 126 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" |
109 | }, | 127 | }, |
110 | { | 128 | { |
129 | "Unit": "CPU-M-CF", | ||
111 | "EventCode": "147", | 130 | "EventCode": "147", |
112 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", | 131 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", |
113 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", | 132 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", |
114 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" | 133 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" |
115 | }, | 134 | }, |
116 | { | 135 | { |
136 | "Unit": "CPU-M-CF", | ||
117 | "EventCode": "148", | 137 | "EventCode": "148", |
118 | "EventName": "TLB2_CRSTE_WRITES", | 138 | "EventName": "TLB2_CRSTE_WRITES", |
119 | "BriefDescription": "TLB2 CRSTE Writes", | 139 | "BriefDescription": "TLB2 CRSTE Writes", |
120 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" | 140 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" |
121 | }, | 141 | }, |
122 | { | 142 | { |
143 | "Unit": "CPU-M-CF", | ||
123 | "EventCode": "150", | 144 | "EventCode": "150", |
124 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", | 145 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", |
125 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", | 146 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", |
126 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache" | 147 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache" |
127 | }, | 148 | }, |
128 | { | 149 | { |
150 | "Unit": "CPU-M-CF", | ||
129 | "EventCode": "152", | 151 | "EventCode": "152", |
130 | "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES", | 152 | "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES", |
131 | "BriefDescription": "L1D Off-Chip L3 Sourced Writes", | 153 | "BriefDescription": "L1D Off-Chip L3 Sourced Writes", |
132 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache" | 154 | "PublicDescription": "A directory write to the Level-1 D-Cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache" |
133 | }, | 155 | }, |
134 | { | 156 | { |
157 | "Unit": "CPU-M-CF", | ||
135 | "EventCode": "153", | 158 | "EventCode": "153", |
136 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", | 159 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", |
137 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", | 160 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", |
138 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache" | 161 | "PublicDescription": "A directory write to the Level-1 I-Cache directory where the returned cache line was sourced from an On Chip Level-3 cache" |
139 | }, | 162 | }, |
140 | { | 163 | { |
164 | "Unit": "CPU-M-CF", | ||
141 | "EventCode": "155", | 165 | "EventCode": "155", |
142 | "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES", | 166 | "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES", |
143 | "BriefDescription": "L1I Off-Chip L3 Sourced Writes", | 167 | "BriefDescription": "L1I Off-Chip L3 Sourced Writes", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json b/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json index 8bf16759ca53..2dd8dafff2ef 100644 --- a/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json +++ b/tools/perf/pmu-events/arch/s390/cf_zec12/basic.json | |||
@@ -1,71 +1,83 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "0", | 4 | "EventCode": "0", |
4 | "EventName": "CPU_CYCLES", | 5 | "EventName": "CPU_CYCLES", |
5 | "BriefDescription": "CPU Cycles", | 6 | "BriefDescription": "CPU Cycles", |
6 | "PublicDescription": "Cycle Count" | 7 | "PublicDescription": "Cycle Count" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "1", | 11 | "EventCode": "1", |
10 | "EventName": "INSTRUCTIONS", | 12 | "EventName": "INSTRUCTIONS", |
11 | "BriefDescription": "Instructions", | 13 | "BriefDescription": "Instructions", |
12 | "PublicDescription": "Instruction Count" | 14 | "PublicDescription": "Instruction Count" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "2", | 18 | "EventCode": "2", |
16 | "EventName": "L1I_DIR_WRITES", | 19 | "EventName": "L1I_DIR_WRITES", |
17 | "BriefDescription": "L1I Directory Writes", | 20 | "BriefDescription": "L1I Directory Writes", |
18 | "PublicDescription": "Level-1 I-Cache Directory Write Count" | 21 | "PublicDescription": "Level-1 I-Cache Directory Write Count" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "3", | 25 | "EventCode": "3", |
22 | "EventName": "L1I_PENALTY_CYCLES", | 26 | "EventName": "L1I_PENALTY_CYCLES", |
23 | "BriefDescription": "L1I Penalty Cycles", | 27 | "BriefDescription": "L1I Penalty Cycles", |
24 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" | 28 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "4", | 32 | "EventCode": "4", |
28 | "EventName": "L1D_DIR_WRITES", | 33 | "EventName": "L1D_DIR_WRITES", |
29 | "BriefDescription": "L1D Directory Writes", | 34 | "BriefDescription": "L1D Directory Writes", |
30 | "PublicDescription": "Level-1 D-Cache Directory Write Count" | 35 | "PublicDescription": "Level-1 D-Cache Directory Write Count" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "5", | 39 | "EventCode": "5", |
34 | "EventName": "L1D_PENALTY_CYCLES", | 40 | "EventName": "L1D_PENALTY_CYCLES", |
35 | "BriefDescription": "L1D Penalty Cycles", | 41 | "BriefDescription": "L1D Penalty Cycles", |
36 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" | 42 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "32", | 46 | "EventCode": "32", |
40 | "EventName": "PROBLEM_STATE_CPU_CYCLES", | 47 | "EventName": "PROBLEM_STATE_CPU_CYCLES", |
41 | "BriefDescription": "Problem-State CPU Cycles", | 48 | "BriefDescription": "Problem-State CPU Cycles", |
42 | "PublicDescription": "Problem-State Cycle Count" | 49 | "PublicDescription": "Problem-State Cycle Count" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "33", | 53 | "EventCode": "33", |
46 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", | 54 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", |
47 | "BriefDescription": "Problem-State Instructions", | 55 | "BriefDescription": "Problem-State Instructions", |
48 | "PublicDescription": "Problem-State Instruction Count" | 56 | "PublicDescription": "Problem-State Instruction Count" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "34", | 60 | "EventCode": "34", |
52 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", | 61 | "EventName": "PROBLEM_STATE_L1I_DIR_WRITES", |
53 | "BriefDescription": "Problem-State L1I Directory Writes", | 62 | "BriefDescription": "Problem-State L1I Directory Writes", |
54 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" | 63 | "PublicDescription": "Problem-State Level-1 I-Cache Directory Write Count" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "35", | 67 | "EventCode": "35", |
58 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", | 68 | "EventName": "PROBLEM_STATE_L1I_PENALTY_CYCLES", |
59 | "BriefDescription": "Problem-State L1I Penalty Cycles", | 69 | "BriefDescription": "Problem-State L1I Penalty Cycles", |
60 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" | 70 | "PublicDescription": "Problem-State Level-1 I-Cache Penalty Cycle Count" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "36", | 74 | "EventCode": "36", |
64 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", | 75 | "EventName": "PROBLEM_STATE_L1D_DIR_WRITES", |
65 | "BriefDescription": "Problem-State L1D Directory Writes", | 76 | "BriefDescription": "Problem-State L1D Directory Writes", |
66 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" | 77 | "PublicDescription": "Problem-State Level-1 D-Cache Directory Write Count" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "37", | 81 | "EventCode": "37", |
70 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", | 82 | "EventName": "PROBLEM_STATE_L1D_PENALTY_CYCLES", |
71 | "BriefDescription": "Problem-State L1D Penalty Cycles", | 83 | "BriefDescription": "Problem-State L1D Penalty Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json b/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json index 7e5b72492141..db286f19e7b6 100644 --- a/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json +++ b/tools/perf/pmu-events/arch/s390/cf_zec12/crypto.json | |||
@@ -1,95 +1,111 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "64", | 4 | "EventCode": "64", |
4 | "EventName": "PRNG_FUNCTIONS", | 5 | "EventName": "PRNG_FUNCTIONS", |
5 | "BriefDescription": "PRNG Functions", | 6 | "BriefDescription": "PRNG Functions", |
6 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" | 7 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "65", | 11 | "EventCode": "65", |
10 | "EventName": "PRNG_CYCLES", | 12 | "EventName": "PRNG_CYCLES", |
11 | "BriefDescription": "PRNG Cycles", | 13 | "BriefDescription": "PRNG Cycles", |
12 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" | 14 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "66", | 18 | "EventCode": "66", |
16 | "EventName": "PRNG_BLOCKED_FUNCTIONS", | 19 | "EventName": "PRNG_BLOCKED_FUNCTIONS", |
17 | "BriefDescription": "PRNG Blocked Functions", | 20 | "BriefDescription": "PRNG Blocked Functions", |
18 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 21 | "PublicDescription": "Total number of the PRNG functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "67", | 25 | "EventCode": "67", |
22 | "EventName": "PRNG_BLOCKED_CYCLES", | 26 | "EventName": "PRNG_BLOCKED_CYCLES", |
23 | "BriefDescription": "PRNG Blocked Cycles", | 27 | "BriefDescription": "PRNG Blocked Cycles", |
24 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 28 | "PublicDescription": "Total number of CPU cycles blocked for the PRNG functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "68", | 32 | "EventCode": "68", |
28 | "EventName": "SHA_FUNCTIONS", | 33 | "EventName": "SHA_FUNCTIONS", |
29 | "BriefDescription": "SHA Functions", | 34 | "BriefDescription": "SHA Functions", |
30 | "PublicDescription": "Total number of SHA functions issued by the CPU" | 35 | "PublicDescription": "Total number of SHA functions issued by the CPU" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "69", | 39 | "EventCode": "69", |
34 | "EventName": "SHA_CYCLES", | 40 | "EventName": "SHA_CYCLES", |
35 | "BriefDescription": "SHA Cycles", | 41 | "BriefDescription": "SHA Cycles", |
36 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" | 42 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "70", | 46 | "EventCode": "70", |
40 | "EventName": "SHA_BLOCKED_FUNCTIONS", | 47 | "EventName": "SHA_BLOCKED_FUNCTIONS", |
41 | "BriefDescription": "SHA Blocked Functions", | 48 | "BriefDescription": "SHA Blocked Functions", |
42 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" | 49 | "PublicDescription": "Total number of the SHA functions that are issued by the CPU and are blocked because the SHA coprocessor is busy performing a function issued by another CPU" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "71", | 53 | "EventCode": "71", |
46 | "EventName": "SHA_BLOCKED_CYCLES", | 54 | "EventName": "SHA_BLOCKED_CYCLES", |
47 | "BriefDescription": "SHA Bloced Cycles", | 55 | "BriefDescription": "SHA Bloced Cycles", |
48 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" | 56 | "PublicDescription": "Total number of CPU cycles blocked for the SHA functions issued by the CPU because the SHA coprocessor is busy performing a function issued by another CPU" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "72", | 60 | "EventCode": "72", |
52 | "EventName": "DEA_FUNCTIONS", | 61 | "EventName": "DEA_FUNCTIONS", |
53 | "BriefDescription": "DEA Functions", | 62 | "BriefDescription": "DEA Functions", |
54 | "PublicDescription": "Total number of the DEA functions issued by the CPU" | 63 | "PublicDescription": "Total number of the DEA functions issued by the CPU" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "73", | 67 | "EventCode": "73", |
58 | "EventName": "DEA_CYCLES", | 68 | "EventName": "DEA_CYCLES", |
59 | "BriefDescription": "DEA Cycles", | 69 | "BriefDescription": "DEA Cycles", |
60 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" | 70 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "74", | 74 | "EventCode": "74", |
64 | "EventName": "DEA_BLOCKED_FUNCTIONS", | 75 | "EventName": "DEA_BLOCKED_FUNCTIONS", |
65 | "BriefDescription": "DEA Blocked Functions", | 76 | "BriefDescription": "DEA Blocked Functions", |
66 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 77 | "PublicDescription": "Total number of the DEA functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "75", | 81 | "EventCode": "75", |
70 | "EventName": "DEA_BLOCKED_CYCLES", | 82 | "EventName": "DEA_BLOCKED_CYCLES", |
71 | "BriefDescription": "DEA Blocked Cycles", | 83 | "BriefDescription": "DEA Blocked Cycles", |
72 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 84 | "PublicDescription": "Total number of CPU cycles blocked for the DEA functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "76", | 88 | "EventCode": "76", |
76 | "EventName": "AES_FUNCTIONS", | 89 | "EventName": "AES_FUNCTIONS", |
77 | "BriefDescription": "AES Functions", | 90 | "BriefDescription": "AES Functions", |
78 | "PublicDescription": "Total number of AES functions issued by the CPU" | 91 | "PublicDescription": "Total number of AES functions issued by the CPU" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "77", | 95 | "EventCode": "77", |
82 | "EventName": "AES_CYCLES", | 96 | "EventName": "AES_CYCLES", |
83 | "BriefDescription": "AES Cycles", | 97 | "BriefDescription": "AES Cycles", |
84 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" | 98 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "78", | 102 | "EventCode": "78", |
88 | "EventName": "AES_BLOCKED_FUNCTIONS", | 103 | "EventName": "AES_BLOCKED_FUNCTIONS", |
89 | "BriefDescription": "AES Blocked Functions", | 104 | "BriefDescription": "AES Blocked Functions", |
90 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" | 105 | "PublicDescription": "Total number of AES functions that are issued by the CPU and are blocked because the DEA/AES coprocessor is busy performing a function issued by another CPU" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "79", | 109 | "EventCode": "79", |
94 | "EventName": "AES_BLOCKED_CYCLES", | 110 | "EventName": "AES_BLOCKED_CYCLES", |
95 | "BriefDescription": "AES Blocked Cycles", | 111 | "BriefDescription": "AES Blocked Cycles", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json b/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json index 8682126aabb2..162251037219 100644 --- a/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json +++ b/tools/perf/pmu-events/arch/s390/cf_zec12/extended.json | |||
@@ -1,209 +1,244 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "Unit": "CPU-M-CF", | ||
3 | "EventCode": "128", | 4 | "EventCode": "128", |
4 | "EventName": "DTLB1_MISSES", | 5 | "EventName": "DTLB1_MISSES", |
5 | "BriefDescription": "DTLB1 Misses", | 6 | "BriefDescription": "DTLB1 Misses", |
6 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." | 7 | "PublicDescription": "Level-1 Data TLB miss in progress. Incremented by one for every cycle a DTLB1 miss is in progress." |
7 | }, | 8 | }, |
8 | { | 9 | { |
10 | "Unit": "CPU-M-CF", | ||
9 | "EventCode": "129", | 11 | "EventCode": "129", |
10 | "EventName": "ITLB1_MISSES", | 12 | "EventName": "ITLB1_MISSES", |
11 | "BriefDescription": "ITLB1 Misses", | 13 | "BriefDescription": "ITLB1 Misses", |
12 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress." | 14 | "PublicDescription": "Level-1 Instruction TLB miss in progress. Incremented by one for every cycle a ITLB1 miss is in progress." |
13 | }, | 15 | }, |
14 | { | 16 | { |
17 | "Unit": "CPU-M-CF", | ||
15 | "EventCode": "130", | 18 | "EventCode": "130", |
16 | "EventName": "L1D_L2I_SOURCED_WRITES", | 19 | "EventName": "L1D_L2I_SOURCED_WRITES", |
17 | "BriefDescription": "L1D L2I Sourced Writes", | 20 | "BriefDescription": "L1D L2I Sourced Writes", |
18 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Instruction cache" | 21 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Instruction cache" |
19 | }, | 22 | }, |
20 | { | 23 | { |
24 | "Unit": "CPU-M-CF", | ||
21 | "EventCode": "131", | 25 | "EventCode": "131", |
22 | "EventName": "L1I_L2I_SOURCED_WRITES", | 26 | "EventName": "L1I_L2I_SOURCED_WRITES", |
23 | "BriefDescription": "L1I L2I Sourced Writes", | 27 | "BriefDescription": "L1I L2I Sourced Writes", |
24 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" | 28 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from the Level-2 Instruction cache" |
25 | }, | 29 | }, |
26 | { | 30 | { |
31 | "Unit": "CPU-M-CF", | ||
27 | "EventCode": "132", | 32 | "EventCode": "132", |
28 | "EventName": "L1D_L2D_SOURCED_WRITES", | 33 | "EventName": "L1D_L2D_SOURCED_WRITES", |
29 | "BriefDescription": "L1D L2D Sourced Writes", | 34 | "BriefDescription": "L1D L2D Sourced Writes", |
30 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" | 35 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from the Level-2 Data cache" |
31 | }, | 36 | }, |
32 | { | 37 | { |
38 | "Unit": "CPU-M-CF", | ||
33 | "EventCode": "133", | 39 | "EventCode": "133", |
34 | "EventName": "DTLB1_WRITES", | 40 | "EventName": "DTLB1_WRITES", |
35 | "BriefDescription": "DTLB1 Writes", | 41 | "BriefDescription": "DTLB1 Writes", |
36 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" | 42 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer" |
37 | }, | 43 | }, |
38 | { | 44 | { |
45 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "135", | 46 | "EventCode": "135", |
40 | "EventName": "L1D_LMEM_SOURCED_WRITES", | 47 | "EventName": "L1D_LMEM_SOURCED_WRITES", |
41 | "BriefDescription": "L1D Local Memory Sourced Writes", | 48 | "BriefDescription": "L1D Local Memory Sourced Writes", |
42 | "PublicDescription": "A directory write to the Level-1 Data cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" | 49 | "PublicDescription": "A directory write to the Level-1 Data cache where the installed cache line was sourced from memory that is attached to the same book as the Data cache (Local Memory)" |
43 | }, | 50 | }, |
44 | { | 51 | { |
52 | "Unit": "CPU-M-CF", | ||
45 | "EventCode": "137", | 53 | "EventCode": "137", |
46 | "EventName": "L1I_LMEM_SOURCED_WRITES", | 54 | "EventName": "L1I_LMEM_SOURCED_WRITES", |
47 | "BriefDescription": "L1I Local Memory Sourced Writes", | 55 | "BriefDescription": "L1I Local Memory Sourced Writes", |
48 | "PublicDescription": "A directory write to the Level-1 Instruction cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)" | 56 | "PublicDescription": "A directory write to the Level-1 Instruction cache where the installed cache line was sourced from memory that is attached to the same book as the Instruction cache (Local Memory)" |
49 | }, | 57 | }, |
50 | { | 58 | { |
59 | "Unit": "CPU-M-CF", | ||
51 | "EventCode": "138", | 60 | "EventCode": "138", |
52 | "EventName": "L1D_RO_EXCL_WRITES", | 61 | "EventName": "L1D_RO_EXCL_WRITES", |
53 | "BriefDescription": "L1D Read-only Exclusive Writes", | 62 | "BriefDescription": "L1D Read-only Exclusive Writes", |
54 | "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" | 63 | "PublicDescription": "A directory write to the Level-1 D-Cache where the line was originally in a Read-Only state in the cache but has been updated to be in the Exclusive state that allows stores to the cache line" |
55 | }, | 64 | }, |
56 | { | 65 | { |
66 | "Unit": "CPU-M-CF", | ||
57 | "EventCode": "139", | 67 | "EventCode": "139", |
58 | "EventName": "DTLB1_HPAGE_WRITES", | 68 | "EventName": "DTLB1_HPAGE_WRITES", |
59 | "BriefDescription": "DTLB1 One-Megabyte Page Writes", | 69 | "BriefDescription": "DTLB1 One-Megabyte Page Writes", |
60 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" | 70 | "PublicDescription": "A translation entry has been written to the Level-1 Data Translation Lookaside Buffer for a one-megabyte page" |
61 | }, | 71 | }, |
62 | { | 72 | { |
73 | "Unit": "CPU-M-CF", | ||
63 | "EventCode": "140", | 74 | "EventCode": "140", |
64 | "EventName": "ITLB1_WRITES", | 75 | "EventName": "ITLB1_WRITES", |
65 | "BriefDescription": "ITLB1 Writes", | 76 | "BriefDescription": "ITLB1 Writes", |
66 | "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" | 77 | "PublicDescription": "A translation entry has been written to the Level-1 Instruction Translation Lookaside Buffer" |
67 | }, | 78 | }, |
68 | { | 79 | { |
80 | "Unit": "CPU-M-CF", | ||
69 | "EventCode": "141", | 81 | "EventCode": "141", |
70 | "EventName": "TLB2_PTE_WRITES", | 82 | "EventName": "TLB2_PTE_WRITES", |
71 | "BriefDescription": "TLB2 PTE Writes", | 83 | "BriefDescription": "TLB2 PTE Writes", |
72 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" | 84 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Page Table Entry arrays" |
73 | }, | 85 | }, |
74 | { | 86 | { |
87 | "Unit": "CPU-M-CF", | ||
75 | "EventCode": "142", | 88 | "EventCode": "142", |
76 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", | 89 | "EventName": "TLB2_CRSTE_HPAGE_WRITES", |
77 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", | 90 | "BriefDescription": "TLB2 CRSTE One-Megabyte Page Writes", |
78 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" | 91 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays for a one-megabyte large page translation" |
79 | }, | 92 | }, |
80 | { | 93 | { |
94 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "143", | 95 | "EventCode": "143", |
82 | "EventName": "TLB2_CRSTE_WRITES", | 96 | "EventName": "TLB2_CRSTE_WRITES", |
83 | "BriefDescription": "TLB2 CRSTE Writes", | 97 | "BriefDescription": "TLB2 CRSTE Writes", |
84 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" | 98 | "PublicDescription": "A translation entry has been written to the Level-2 TLB Common Region Segment Table Entry arrays" |
85 | }, | 99 | }, |
86 | { | 100 | { |
101 | "Unit": "CPU-M-CF", | ||
87 | "EventCode": "144", | 102 | "EventCode": "144", |
88 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", | 103 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", |
89 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", | 104 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", |
90 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention" | 105 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention" |
91 | }, | 106 | }, |
92 | { | 107 | { |
108 | "Unit": "CPU-M-CF", | ||
93 | "EventCode": "145", | 109 | "EventCode": "145", |
94 | "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES", | 110 | "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES", |
95 | "BriefDescription": "L1D Off-Chip L3 Sourced Writes", | 111 | "BriefDescription": "L1D Off-Chip L3 Sourced Writes", |
96 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention" | 112 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention" |
97 | }, | 113 | }, |
98 | { | 114 | { |
115 | "Unit": "CPU-M-CF", | ||
99 | "EventCode": "146", | 116 | "EventCode": "146", |
100 | "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES", | 117 | "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES", |
101 | "BriefDescription": "L1D Off-Book L3 Sourced Writes", | 118 | "BriefDescription": "L1D Off-Book L3 Sourced Writes", |
102 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention" | 119 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention" |
103 | }, | 120 | }, |
104 | { | 121 | { |
122 | "Unit": "CPU-M-CF", | ||
105 | "EventCode": "147", | 123 | "EventCode": "147", |
106 | "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES", | 124 | "EventName": "L1D_ONBOOK_L4_SOURCED_WRITES", |
107 | "BriefDescription": "L1D On-Book L4 Sourced Writes", | 125 | "BriefDescription": "L1D On-Book L4 Sourced Writes", |
108 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Book Level-4 cache" | 126 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On Book Level-4 cache" |
109 | }, | 127 | }, |
110 | { | 128 | { |
129 | "Unit": "CPU-M-CF", | ||
111 | "EventCode": "148", | 130 | "EventCode": "148", |
112 | "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES", | 131 | "EventName": "L1D_OFFBOOK_L4_SOURCED_WRITES", |
113 | "BriefDescription": "L1D Off-Book L4 Sourced Writes", | 132 | "BriefDescription": "L1D Off-Book L4 Sourced Writes", |
114 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-4 cache" | 133 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-4 cache" |
115 | }, | 134 | }, |
116 | { | 135 | { |
136 | "Unit": "CPU-M-CF", | ||
117 | "EventCode": "149", | 137 | "EventCode": "149", |
118 | "EventName": "TX_NC_TEND", | 138 | "EventName": "TX_NC_TEND", |
119 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", | 139 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", |
120 | "PublicDescription": "A TEND instruction has completed in a nonconstrained transactional-execution mode" | 140 | "PublicDescription": "A TEND instruction has completed in a nonconstrained transactional-execution mode" |
121 | }, | 141 | }, |
122 | { | 142 | { |
143 | "Unit": "CPU-M-CF", | ||
123 | "EventCode": "150", | 144 | "EventCode": "150", |
124 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", | 145 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", |
125 | "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", | 146 | "BriefDescription": "L1D On-Chip L3 Sourced Writes with Intervention", |
126 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from a On Chip Level-3 cache with intervention" | 147 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from a On Chip Level-3 cache with intervention" |
127 | }, | 148 | }, |
128 | { | 149 | { |
150 | "Unit": "CPU-M-CF", | ||
129 | "EventCode": "151", | 151 | "EventCode": "151", |
130 | "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES_IV", | 152 | "EventName": "L1D_OFFCHIP_L3_SOURCED_WRITES_IV", |
131 | "BriefDescription": "L1D Off-Chip L3 Sourced Writes with Intervention", | 153 | "BriefDescription": "L1D Off-Chip L3 Sourced Writes with Intervention", |
132 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention" | 154 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention" |
133 | }, | 155 | }, |
134 | { | 156 | { |
157 | "Unit": "CPU-M-CF", | ||
135 | "EventCode": "152", | 158 | "EventCode": "152", |
136 | "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES_IV", | 159 | "EventName": "L1D_OFFBOOK_L3_SOURCED_WRITES_IV", |
137 | "BriefDescription": "L1D Off-Book L3 Sourced Writes with Intervention", | 160 | "BriefDescription": "L1D Off-Book L3 Sourced Writes with Intervention", |
138 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention" | 161 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention" |
139 | }, | 162 | }, |
140 | { | 163 | { |
164 | "Unit": "CPU-M-CF", | ||
141 | "EventCode": "153", | 165 | "EventCode": "153", |
142 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", | 166 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", |
143 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", | 167 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", |
144 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention" | 168 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache without intervention" |
145 | }, | 169 | }, |
146 | { | 170 | { |
171 | "Unit": "CPU-M-CF", | ||
147 | "EventCode": "154", | 172 | "EventCode": "154", |
148 | "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES", | 173 | "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES", |
149 | "BriefDescription": "L1I Off-Chip L3 Sourced Writes", | 174 | "BriefDescription": "L1I Off-Chip L3 Sourced Writes", |
150 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention" | 175 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache without intervention" |
151 | }, | 176 | }, |
152 | { | 177 | { |
178 | "Unit": "CPU-M-CF", | ||
153 | "EventCode": "155", | 179 | "EventCode": "155", |
154 | "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES", | 180 | "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES", |
155 | "BriefDescription": "L1I Off-Book L3 Sourced Writes", | 181 | "BriefDescription": "L1I Off-Book L3 Sourced Writes", |
156 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention" | 182 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache without intervention" |
157 | }, | 183 | }, |
158 | { | 184 | { |
185 | "Unit": "CPU-M-CF", | ||
159 | "EventCode": "156", | 186 | "EventCode": "156", |
160 | "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES", | 187 | "EventName": "L1I_ONBOOK_L4_SOURCED_WRITES", |
161 | "BriefDescription": "L1I On-Book L4 Sourced Writes", | 188 | "BriefDescription": "L1I On-Book L4 Sourced Writes", |
162 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Book Level-4 cache" | 189 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Book Level-4 cache" |
163 | }, | 190 | }, |
164 | { | 191 | { |
192 | "Unit": "CPU-M-CF", | ||
165 | "EventCode": "157", | 193 | "EventCode": "157", |
166 | "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES", | 194 | "EventName": "L1I_OFFBOOK_L4_SOURCED_WRITES", |
167 | "BriefDescription": "L1I Off-Book L4 Sourced Writes", | 195 | "BriefDescription": "L1I Off-Book L4 Sourced Writes", |
168 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-4 cache" | 196 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-4 cache" |
169 | }, | 197 | }, |
170 | { | 198 | { |
199 | "Unit": "CPU-M-CF", | ||
171 | "EventCode": "158", | 200 | "EventCode": "158", |
172 | "EventName": "TX_C_TEND", | 201 | "EventName": "TX_C_TEND", |
173 | "BriefDescription": "Completed TEND instructions in constrained TX mode", | 202 | "BriefDescription": "Completed TEND instructions in constrained TX mode", |
174 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" | 203 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" |
175 | }, | 204 | }, |
176 | { | 205 | { |
206 | "Unit": "CPU-M-CF", | ||
177 | "EventCode": "159", | 207 | "EventCode": "159", |
178 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", | 208 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", |
179 | "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", | 209 | "BriefDescription": "L1I On-Chip L3 Sourced Writes with Intervention", |
180 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention" | 210 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On Chip Level-3 cache with intervention" |
181 | }, | 211 | }, |
182 | { | 212 | { |
213 | "Unit": "CPU-M-CF", | ||
183 | "EventCode": "160", | 214 | "EventCode": "160", |
184 | "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES_IV", | 215 | "EventName": "L1I_OFFCHIP_L3_SOURCED_WRITES_IV", |
185 | "BriefDescription": "L1I Off-Chip L3 Sourced Writes with Intervention", | 216 | "BriefDescription": "L1I Off-Chip L3 Sourced Writes with Intervention", |
186 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention" | 217 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Chip/On Book Level-3 cache with intervention" |
187 | }, | 218 | }, |
188 | { | 219 | { |
220 | "Unit": "CPU-M-CF", | ||
189 | "EventCode": "161", | 221 | "EventCode": "161", |
190 | "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES_IV", | 222 | "EventName": "L1I_OFFBOOK_L3_SOURCED_WRITES_IV", |
191 | "BriefDescription": "L1I Off-Book L3 Sourced Writes with Intervention", | 223 | "BriefDescription": "L1I Off-Book L3 Sourced Writes with Intervention", |
192 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention" | 224 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an Off Book Level-3 cache with intervention" |
193 | }, | 225 | }, |
194 | { | 226 | { |
227 | "Unit": "CPU-M-CF", | ||
195 | "EventCode": "177", | 228 | "EventCode": "177", |
196 | "EventName": "TX_NC_TABORT", | 229 | "EventName": "TX_NC_TABORT", |
197 | "BriefDescription": "Aborted transactions in non-constrained TX mode", | 230 | "BriefDescription": "Aborted transactions in non-constrained TX mode", |
198 | "PublicDescription": "A transaction abort has occurred in a nonconstrained transactional-execution mode" | 231 | "PublicDescription": "A transaction abort has occurred in a nonconstrained transactional-execution mode" |
199 | }, | 232 | }, |
200 | { | 233 | { |
234 | "Unit": "CPU-M-CF", | ||
201 | "EventCode": "178", | 235 | "EventCode": "178", |
202 | "EventName": "TX_C_TABORT_NO_SPECIAL", | 236 | "EventName": "TX_C_TABORT_NO_SPECIAL", |
203 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", | 237 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", |
204 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" | 238 | "PublicDescription": "A transaction abort has occurred in a constrained transactional-execution mode and the CPU is not using any special logic to allow the transaction to complete" |
205 | }, | 239 | }, |
206 | { | 240 | { |
241 | "Unit": "CPU-M-CF", | ||
207 | "EventCode": "179", | 242 | "EventCode": "179", |
208 | "EventName": "TX_C_TABORT_SPECIAL", | 243 | "EventName": "TX_C_TABORT_SPECIAL", |
209 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", | 244 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", |
diff --git a/tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json b/tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json new file mode 100644 index 000000000000..1a0034f79f73 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_zec12/transaction.json | |||
@@ -0,0 +1,7 @@ | |||
1 | [ | ||
2 | { | ||
3 | "BriefDescription": "Transaction count", | ||
4 | "MetricName": "transaction", | ||
5 | "MetricExpr": "TX_C_TEND + TX_NC_TEND + TX_NC_TABORT + TX_C_TABORT_SPECIAL + TX_C_TABORT_NO_SPECIAL" | ||
6 | } | ||
7 | ] | ||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index db3a594ee1e4..68c92bb599ee 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c | |||
@@ -233,6 +233,8 @@ static struct map { | |||
233 | { "QPI LL", "uncore_qpi" }, | 233 | { "QPI LL", "uncore_qpi" }, |
234 | { "SBO", "uncore_sbox" }, | 234 | { "SBO", "uncore_sbox" }, |
235 | { "iMPH-U", "uncore_arb" }, | 235 | { "iMPH-U", "uncore_arb" }, |
236 | { "CPU-M-CF", "cpum_cf" }, | ||
237 | { "CPU-M-SF", "cpum_sf" }, | ||
236 | {} | 238 | {} |
237 | }; | 239 | }; |
238 | 240 | ||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index dd850a26d579..d7a5e1b9aa6f 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
@@ -385,7 +385,7 @@ static int test_and_print(struct test *t, bool force_skip, int subtest) | |||
385 | if (!t->subtest.get_nr) | 385 | if (!t->subtest.get_nr) |
386 | pr_debug("%s:", t->desc); | 386 | pr_debug("%s:", t->desc); |
387 | else | 387 | else |
388 | pr_debug("%s subtest %d:", t->desc, subtest); | 388 | pr_debug("%s subtest %d:", t->desc, subtest + 1); |
389 | 389 | ||
390 | switch (err) { | 390 | switch (err) { |
391 | case TEST_OK: | 391 | case TEST_OK: |
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 61211918bfba..3b97ac018d5a 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c | |||
@@ -1322,6 +1322,14 @@ static int test__intel_pt(struct perf_evlist *evlist) | |||
1322 | return 0; | 1322 | return 0; |
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | static int test__checkevent_complex_name(struct perf_evlist *evlist) | ||
1326 | { | ||
1327 | struct perf_evsel *evsel = perf_evlist__first(evlist); | ||
1328 | |||
1329 | TEST_ASSERT_VAL("wrong complex name parsing", strcmp(evsel->name, "COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks") == 0); | ||
1330 | return 0; | ||
1331 | } | ||
1332 | |||
1325 | static int count_tracepoints(void) | 1333 | static int count_tracepoints(void) |
1326 | { | 1334 | { |
1327 | struct dirent *events_ent; | 1335 | struct dirent *events_ent; |
@@ -1658,6 +1666,11 @@ static struct evlist_test test__events[] = { | |||
1658 | .check = test__intel_pt, | 1666 | .check = test__intel_pt, |
1659 | .id = 52, | 1667 | .id = 52, |
1660 | }, | 1668 | }, |
1669 | { | ||
1670 | .name = "cycles/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks'/Duk", | ||
1671 | .check = test__checkevent_complex_name, | ||
1672 | .id = 53 | ||
1673 | } | ||
1661 | }; | 1674 | }; |
1662 | 1675 | ||
1663 | static struct evlist_test test__events_pmu[] = { | 1676 | static struct evlist_test test__events_pmu[] = { |
@@ -1676,6 +1689,11 @@ static struct evlist_test test__events_pmu[] = { | |||
1676 | .check = test__checkevent_pmu_partial_time_callgraph, | 1689 | .check = test__checkevent_pmu_partial_time_callgraph, |
1677 | .id = 2, | 1690 | .id = 2, |
1678 | }, | 1691 | }, |
1692 | { | ||
1693 | .name = "cpu/name='COMPLEX_CYCLES_NAME:orig=cycles,desc=chip-clock-ticks',period=0x1,event=0x2/ukp", | ||
1694 | .check = test__checkevent_complex_name, | ||
1695 | .id = 3, | ||
1696 | } | ||
1679 | }; | 1697 | }; |
1680 | 1698 | ||
1681 | struct terms_test { | 1699 | struct terms_test { |
diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh index 94e513e62b34..3013ac8f83d0 100755 --- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh | |||
@@ -13,11 +13,24 @@ | |||
13 | libc=$(grep -w libc /proc/self/maps | head -1 | sed -r 's/.*[[:space:]](\/.*)/\1/g') | 13 | libc=$(grep -w libc /proc/self/maps | head -1 | sed -r 's/.*[[:space:]](\/.*)/\1/g') |
14 | nm -Dg $libc 2>/dev/null | fgrep -q inet_pton || exit 254 | 14 | nm -Dg $libc 2>/dev/null | fgrep -q inet_pton || exit 254 |
15 | 15 | ||
16 | event_pattern='probe_libc:inet_pton(\_[[:digit:]]+)?' | ||
17 | |||
18 | add_libc_inet_pton_event() { | ||
19 | |||
20 | event_name=$(perf probe -f -x $libc -a inet_pton 2>&1 | tail -n +2 | head -n -5 | \ | ||
21 | grep -P -o "$event_pattern(?=[[:space:]]\(on inet_pton in $libc\))") | ||
22 | |||
23 | if [ $? -ne 0 -o -z "$event_name" ] ; then | ||
24 | printf "FAIL: could not add event\n" | ||
25 | return 1 | ||
26 | fi | ||
27 | } | ||
28 | |||
16 | trace_libc_inet_pton_backtrace() { | 29 | trace_libc_inet_pton_backtrace() { |
17 | 30 | ||
18 | expected=`mktemp -u /tmp/expected.XXX` | 31 | expected=`mktemp -u /tmp/expected.XXX` |
19 | 32 | ||
20 | echo "ping[][0-9 \.:]+probe_libc:inet_pton: \([[:xdigit:]]+\)" > $expected | 33 | echo "ping[][0-9 \.:]+$event_name: \([[:xdigit:]]+\)" > $expected |
21 | echo ".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected | 34 | echo ".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected |
22 | case "$(uname -m)" in | 35 | case "$(uname -m)" in |
23 | s390x) | 36 | s390x) |
@@ -26,6 +39,12 @@ trace_libc_inet_pton_backtrace() { | |||
26 | echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected | 39 | echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected |
27 | echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected | 40 | echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected |
28 | ;; | 41 | ;; |
42 | ppc64|ppc64le) | ||
43 | eventattr='max-stack=4' | ||
44 | echo "gaih_inet.*\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected | ||
45 | echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected | ||
46 | echo ".*\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected | ||
47 | ;; | ||
29 | *) | 48 | *) |
30 | eventattr='max-stack=3' | 49 | eventattr='max-stack=3' |
31 | echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected | 50 | echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected |
@@ -35,7 +54,7 @@ trace_libc_inet_pton_backtrace() { | |||
35 | 54 | ||
36 | perf_data=`mktemp -u /tmp/perf.data.XXX` | 55 | perf_data=`mktemp -u /tmp/perf.data.XXX` |
37 | perf_script=`mktemp -u /tmp/perf.script.XXX` | 56 | perf_script=`mktemp -u /tmp/perf.script.XXX` |
38 | perf record -e probe_libc:inet_pton/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1 | 57 | perf record -e $event_name/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1 |
39 | perf script -i $perf_data > $perf_script | 58 | perf script -i $perf_data > $perf_script |
40 | 59 | ||
41 | exec 3<$perf_script | 60 | exec 3<$perf_script |
@@ -46,7 +65,7 @@ trace_libc_inet_pton_backtrace() { | |||
46 | echo "$line" | egrep -q "$pattern" | 65 | echo "$line" | egrep -q "$pattern" |
47 | if [ $? -ne 0 ] ; then | 66 | if [ $? -ne 0 ] ; then |
48 | printf "FAIL: expected backtrace entry \"%s\" got \"%s\"\n" "$pattern" "$line" | 67 | printf "FAIL: expected backtrace entry \"%s\" got \"%s\"\n" "$pattern" "$line" |
49 | exit 1 | 68 | return 1 |
50 | fi | 69 | fi |
51 | done | 70 | done |
52 | 71 | ||
@@ -56,13 +75,20 @@ trace_libc_inet_pton_backtrace() { | |||
56 | # even if the perf script output does not match. | 75 | # even if the perf script output does not match. |
57 | } | 76 | } |
58 | 77 | ||
78 | delete_libc_inet_pton_event() { | ||
79 | |||
80 | if [ -n "$event_name" ] ; then | ||
81 | perf probe -q -d $event_name | ||
82 | fi | ||
83 | } | ||
84 | |||
59 | # Check for IPv6 interface existence | 85 | # Check for IPv6 interface existence |
60 | ip a sh lo | fgrep -q inet6 || exit 2 | 86 | ip a sh lo | fgrep -q inet6 || exit 2 |
61 | 87 | ||
62 | skip_if_no_perf_probe && \ | 88 | skip_if_no_perf_probe && \ |
63 | perf probe -q $libc inet_pton && \ | 89 | add_libc_inet_pton_event && \ |
64 | trace_libc_inet_pton_backtrace | 90 | trace_libc_inet_pton_backtrace |
65 | err=$? | 91 | err=$? |
66 | rm -f ${perf_data} ${perf_script} ${expected} | 92 | rm -f ${perf_data} ${perf_script} ${expected} |
67 | perf probe -q -d probe_libc:inet_pton | 93 | delete_libc_inet_pton_event |
68 | exit $err | 94 | exit $err |
diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index 66330d4b739b..f528ba35e140 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build | |||
@@ -7,4 +7,5 @@ endif | |||
7 | libperf-y += kcmp.o | 7 | libperf-y += kcmp.o |
8 | libperf-y += pkey_alloc.o | 8 | libperf-y += pkey_alloc.o |
9 | libperf-y += prctl.o | 9 | libperf-y += prctl.o |
10 | libperf-y += socket.o | ||
10 | libperf-y += statx.o | 11 | libperf-y += statx.o |
diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 984a504d335c..9615af5d412b 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h | |||
@@ -106,6 +106,9 @@ size_t syscall_arg__scnprintf_prctl_arg2(char *bf, size_t size, struct syscall_a | |||
106 | size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg); | 106 | size_t syscall_arg__scnprintf_prctl_arg3(char *bf, size_t size, struct syscall_arg *arg); |
107 | #define SCA_PRCTL_ARG3 syscall_arg__scnprintf_prctl_arg3 | 107 | #define SCA_PRCTL_ARG3 syscall_arg__scnprintf_prctl_arg3 |
108 | 108 | ||
109 | size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct syscall_arg *arg); | ||
110 | #define SCA_SK_PROTO syscall_arg__scnprintf_socket_protocol | ||
111 | |||
109 | size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); | 112 | size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); |
110 | #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags | 113 | #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags |
111 | 114 | ||
diff --git a/tools/perf/trace/beauty/drm_ioctl.sh b/tools/perf/trace/beauty/drm_ioctl.sh index 2149d3a98e42..9d3816815e60 100755 --- a/tools/perf/trace/beauty/drm_ioctl.sh +++ b/tools/perf/trace/beauty/drm_ioctl.sh | |||
@@ -1,13 +1,14 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | drm_header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/drm/ |
4 | |||
4 | printf "#ifndef DRM_COMMAND_BASE\n" | 5 | printf "#ifndef DRM_COMMAND_BASE\n" |
5 | grep "#define DRM_COMMAND_BASE" $drm_header_dir/drm.h | 6 | grep "#define DRM_COMMAND_BASE" $header_dir/drm.h |
6 | printf "#endif\n" | 7 | printf "#endif\n" |
7 | 8 | ||
8 | printf "static const char *drm_ioctl_cmds[] = {\n" | 9 | printf "static const char *drm_ioctl_cmds[] = {\n" |
9 | grep "^#define DRM_IOCTL.*DRM_IO" $drm_header_dir/drm.h | \ | 10 | grep "^#define DRM_IOCTL.*DRM_IO" $header_dir/drm.h | \ |
10 | sed -r 's/^#define +DRM_IOCTL_([A-Z0-9_]+)[ ]+DRM_IO[A-Z]* *\( *(0x[[:xdigit:]]+),*.*/ [\2] = "\1",/g' | 11 | sed -r 's/^#define +DRM_IOCTL_([A-Z0-9_]+)[ ]+DRM_IO[A-Z]* *\( *(0x[[:xdigit:]]+),*.*/ [\2] = "\1",/g' |
11 | grep "^#define DRM_I915_[A-Z_0-9]\+[ ]\+0x" $drm_header_dir/i915_drm.h | \ | 12 | grep "^#define DRM_I915_[A-Z_0-9]\+[ ]\+0x" $header_dir/i915_drm.h | \ |
12 | sed -r 's/^#define +DRM_I915_([A-Z0-9_]+)[ ]+(0x[[:xdigit:]]+)/\t[DRM_COMMAND_BASE + \2] = "I915_\1",/g' | 13 | sed -r 's/^#define +DRM_I915_([A-Z0-9_]+)[ ]+(0x[[:xdigit:]]+)/\t[DRM_COMMAND_BASE + \2] = "I915_\1",/g' |
13 | printf "};\n" | 14 | printf "};\n" |
diff --git a/tools/perf/trace/beauty/kcmp_type.sh b/tools/perf/trace/beauty/kcmp_type.sh index 40d063b8c082..a3c304caa336 100755 --- a/tools/perf/trace/beauty/kcmp_type.sh +++ b/tools/perf/trace/beauty/kcmp_type.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ |
4 | 4 | ||
5 | printf "static const char *kcmp_types[] = {\n" | 5 | printf "static const char *kcmp_types[] = {\n" |
6 | regex='^[[:space:]]+(KCMP_(\w+)),' | 6 | regex='^[[:space:]]+(KCMP_(\w+)),' |
diff --git a/tools/perf/trace/beauty/kvm_ioctl.sh b/tools/perf/trace/beauty/kvm_ioctl.sh index bd28817afced..c4699fd46bb6 100755 --- a/tools/perf/trace/beauty/kvm_ioctl.sh +++ b/tools/perf/trace/beauty/kvm_ioctl.sh | |||
@@ -1,10 +1,10 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | kvm_header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ |
4 | 4 | ||
5 | printf "static const char *kvm_ioctl_cmds[] = {\n" | 5 | printf "static const char *kvm_ioctl_cmds[] = {\n" |
6 | regex='^#[[:space:]]*define[[:space:]]+KVM_(\w+)[[:space:]]+_IO[RW]*\([[:space:]]*KVMIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' | 6 | regex='^#[[:space:]]*define[[:space:]]+KVM_(\w+)[[:space:]]+_IO[RW]*\([[:space:]]*KVMIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' |
7 | egrep $regex ${kvm_header_dir}/kvm.h | \ | 7 | egrep $regex ${header_dir}/kvm.h | \ |
8 | sed -r "s/$regex/\2 \1/g" | \ | 8 | sed -r "s/$regex/\2 \1/g" | \ |
9 | egrep -v " ((ARM|PPC|S390)_|[GS]ET_(DEBUGREGS|PIT2|XSAVE|TSC_KHZ)|CREATE_SPAPR_TCE_64)" | \ | 9 | egrep -v " ((ARM|PPC|S390)_|[GS]ET_(DEBUGREGS|PIT2|XSAVE|TSC_KHZ)|CREATE_SPAPR_TCE_64)" | \ |
10 | sort | xargs printf "\t[%s] = \"%s\",\n" | 10 | sort | xargs printf "\t[%s] = \"%s\",\n" |
diff --git a/tools/perf/trace/beauty/madvise_behavior.sh b/tools/perf/trace/beauty/madvise_behavior.sh index 60ef8640ee70..431639eb4d29 100755 --- a/tools/perf/trace/beauty/madvise_behavior.sh +++ b/tools/perf/trace/beauty/madvise_behavior.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/ |
4 | 4 | ||
5 | printf "static const char *madvise_advices[] = {\n" | 5 | printf "static const char *madvise_advices[] = {\n" |
6 | regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MADV_([[:alnum:]_]+)[[:space:]]+([[:digit:]]+)[[:space:]]*.*' | 6 | regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+MADV_([[:alnum:]_]+)[[:space:]]+([[:digit:]]+)[[:space:]]*.*' |
diff --git a/tools/perf/trace/beauty/perf_ioctl.sh b/tools/perf/trace/beauty/perf_ioctl.sh index faea4237c793..6492c74df928 100755 --- a/tools/perf/trace/beauty/perf_ioctl.sh +++ b/tools/perf/trace/beauty/perf_ioctl.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ |
4 | 4 | ||
5 | printf "static const char *perf_ioctl_cmds[] = {\n" | 5 | printf "static const char *perf_ioctl_cmds[] = {\n" |
6 | regex='^#[[:space:]]*define[[:space:]]+PERF_EVENT_IOC_(\w+)[[:space:]]+_IO[RW]*[[:space:]]*\([[:space:]]*.\$.[[:space:]]*,[[:space:]]*([[:digit:]]+).*' | 6 | regex='^#[[:space:]]*define[[:space:]]+PERF_EVENT_IOC_(\w+)[[:space:]]+_IO[RW]*[[:space:]]*\([[:space:]]*.\$.[[:space:]]*,[[:space:]]*([[:digit:]]+).*' |
diff --git a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh index 62e51a02b839..e0a51aeb20b2 100755 --- a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh +++ b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/asm-generic/ |
4 | 4 | ||
5 | printf "static const char *pkey_alloc_access_rights[] = {\n" | 5 | printf "static const char *pkey_alloc_access_rights[] = {\n" |
6 | regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+PKEY_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*' | 6 | regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+PKEY_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*' |
diff --git a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh index aad5ab130539..eb511bb5fbd3 100755 --- a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh +++ b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh | |||
@@ -1,8 +1,8 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | sound_header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/ |
4 | 4 | ||
5 | printf "static const char *sndrv_ctl_ioctl_cmds[] = {\n" | 5 | printf "static const char *sndrv_ctl_ioctl_cmds[] = {\n" |
6 | grep "^#define[\t ]\+SNDRV_CTL_IOCTL_" $sound_header_dir/asound.h | \ | 6 | grep "^#define[\t ]\+SNDRV_CTL_IOCTL_" $header_dir/asound.h | \ |
7 | sed -r 's/^#define +SNDRV_CTL_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.U., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' | 7 | sed -r 's/^#define +SNDRV_CTL_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.U., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' |
8 | printf "};\n" | 8 | printf "};\n" |
diff --git a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh index b7e9ef6b2f55..6818392968b2 100755 --- a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh +++ b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh | |||
@@ -1,8 +1,8 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | sound_header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/sound/ |
4 | 4 | ||
5 | printf "static const char *sndrv_pcm_ioctl_cmds[] = {\n" | 5 | printf "static const char *sndrv_pcm_ioctl_cmds[] = {\n" |
6 | grep "^#define[\t ]\+SNDRV_PCM_IOCTL_" $sound_header_dir/asound.h | \ | 6 | grep "^#define[\t ]\+SNDRV_PCM_IOCTL_" $header_dir/asound.h | \ |
7 | sed -r 's/^#define +SNDRV_PCM_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.A., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' | 7 | sed -r 's/^#define +SNDRV_PCM_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.A., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' |
8 | printf "};\n" | 8 | printf "};\n" |
diff --git a/tools/perf/trace/beauty/socket.c b/tools/perf/trace/beauty/socket.c new file mode 100644 index 000000000000..65227269384b --- /dev/null +++ b/tools/perf/trace/beauty/socket.c | |||
@@ -0,0 +1,28 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * trace/beauty/socket.c | ||
4 | * | ||
5 | * Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | ||
6 | */ | ||
7 | |||
8 | #include "trace/beauty/beauty.h" | ||
9 | #include <sys/types.h> | ||
10 | #include <sys/socket.h> | ||
11 | |||
12 | static size_t socket__scnprintf_ipproto(int protocol, char *bf, size_t size) | ||
13 | { | ||
14 | #include "trace/beauty/generated/socket_ipproto_array.c" | ||
15 | static DEFINE_STRARRAY(socket_ipproto); | ||
16 | |||
17 | return strarray__scnprintf(&strarray__socket_ipproto, bf, size, "%d", protocol); | ||
18 | } | ||
19 | |||
20 | size_t syscall_arg__scnprintf_socket_protocol(char *bf, size_t size, struct syscall_arg *arg) | ||
21 | { | ||
22 | int domain = syscall_arg__val(arg, 0); | ||
23 | |||
24 | if (domain == AF_INET || domain == AF_INET6) | ||
25 | return socket__scnprintf_ipproto(arg->val, bf, size); | ||
26 | |||
27 | return syscall_arg__scnprintf_int(bf, size, arg); | ||
28 | } | ||
diff --git a/tools/perf/trace/beauty/socket_ipproto.sh b/tools/perf/trace/beauty/socket_ipproto.sh new file mode 100755 index 000000000000..a3cc24633bec --- /dev/null +++ b/tools/perf/trace/beauty/socket_ipproto.sh | |||
@@ -0,0 +1,11 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ | ||
4 | |||
5 | printf "static const char *socket_ipproto[] = {\n" | ||
6 | regex='^[[:space:]]+IPPROTO_(\w+)[[:space:]]+=[[:space:]]+([[:digit:]]+),.*' | ||
7 | |||
8 | egrep $regex ${header_dir}/in.h | \ | ||
9 | sed -r "s/$regex/\2 \1/g" | \ | ||
10 | sort | xargs printf "\t[%s] = \"%s\",\n" | ||
11 | printf "};\n" | ||
diff --git a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh index 76f1de697787..0f6a5197d0be 100755 --- a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh +++ b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh | |||
@@ -1,17 +1,17 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | vhost_virtio_header_dir=$1 | 3 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ |
4 | 4 | ||
5 | printf "static const char *vhost_virtio_ioctl_cmds[] = {\n" | 5 | printf "static const char *vhost_virtio_ioctl_cmds[] = {\n" |
6 | regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' | 6 | regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' |
7 | egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ | 7 | egrep $regex ${header_dir}/vhost.h | \ |
8 | sed -r "s/$regex/\2 \1/g" | \ | 8 | sed -r "s/$regex/\2 \1/g" | \ |
9 | sort | xargs printf "\t[%s] = \"%s\",\n" | 9 | sort | xargs printf "\t[%s] = \"%s\",\n" |
10 | printf "};\n" | 10 | printf "};\n" |
11 | 11 | ||
12 | printf "static const char *vhost_virtio_ioctl_read_cmds[] = {\n" | 12 | printf "static const char *vhost_virtio_ioctl_read_cmds[] = {\n" |
13 | regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?R\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' | 13 | regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?R\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' |
14 | egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ | 14 | egrep $regex ${header_dir}/vhost.h | \ |
15 | sed -r "s/$regex/\2 \1/g" | \ | 15 | sed -r "s/$regex/\2 \1/g" | \ |
16 | sort | xargs printf "\t[%s] = \"%s\",\n" | 16 | sort | xargs printf "\t[%s] = \"%s\",\n" |
17 | printf "};\n" | 17 | printf "};\n" |
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 69b7a28f7a1c..74c4ae1f0a05 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -529,7 +529,7 @@ out: | |||
529 | 529 | ||
530 | static int hist_entry__fprintf(struct hist_entry *he, size_t size, | 530 | static int hist_entry__fprintf(struct hist_entry *he, size_t size, |
531 | char *bf, size_t bfsz, FILE *fp, | 531 | char *bf, size_t bfsz, FILE *fp, |
532 | bool use_callchain) | 532 | bool ignore_callchains) |
533 | { | 533 | { |
534 | int ret; | 534 | int ret; |
535 | int callchain_ret = 0; | 535 | int callchain_ret = 0; |
@@ -550,7 +550,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, | |||
550 | 550 | ||
551 | ret = fprintf(fp, "%s\n", bf); | 551 | ret = fprintf(fp, "%s\n", bf); |
552 | 552 | ||
553 | if (hist_entry__has_callchains(he) && use_callchain) | 553 | if (hist_entry__has_callchains(he) && !ignore_callchains) |
554 | callchain_ret = hist_entry_callchain__fprintf(he, total_period, | 554 | callchain_ret = hist_entry_callchain__fprintf(he, total_period, |
555 | 0, fp); | 555 | 0, fp); |
556 | 556 | ||
@@ -755,7 +755,7 @@ int hists__fprintf_headers(struct hists *hists, FILE *fp) | |||
755 | 755 | ||
756 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | 756 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, |
757 | int max_cols, float min_pcnt, FILE *fp, | 757 | int max_cols, float min_pcnt, FILE *fp, |
758 | bool use_callchain) | 758 | bool ignore_callchains) |
759 | { | 759 | { |
760 | struct rb_node *nd; | 760 | struct rb_node *nd; |
761 | size_t ret = 0; | 761 | size_t ret = 0; |
@@ -799,7 +799,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | |||
799 | if (percent < min_pcnt) | 799 | if (percent < min_pcnt) |
800 | continue; | 800 | continue; |
801 | 801 | ||
802 | ret += hist_entry__fprintf(h, max_cols, line, linesz, fp, use_callchain); | 802 | ret += hist_entry__fprintf(h, max_cols, line, linesz, fp, ignore_callchains); |
803 | 803 | ||
804 | if (max_rows && ++nr_rows >= max_rows) | 804 | if (max_rows && ++nr_rows >= max_rows) |
805 | break; | 805 | break; |
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index cee658733e2c..3d02ae38ec56 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c | |||
@@ -747,7 +747,9 @@ int bpf__load(struct bpf_object *obj) | |||
747 | 747 | ||
748 | err = bpf_object__load(obj); | 748 | err = bpf_object__load(obj); |
749 | if (err) { | 749 | if (err) { |
750 | pr_debug("bpf: load objects failed\n"); | 750 | char bf[128]; |
751 | libbpf_strerror(err, bf, sizeof(bf)); | ||
752 | pr_debug("bpf: load objects failed: err=%d: (%s)\n", err, bf); | ||
751 | return err; | 753 | return err; |
752 | } | 754 | } |
753 | return 0; | 755 | return 0; |
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index 7798a2cc8a86..31279a7bd919 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
@@ -20,9 +20,10 @@ static struct rw_semaphore comm_str_lock = {.lock = PTHREAD_RWLOCK_INITIALIZER,} | |||
20 | 20 | ||
21 | static struct comm_str *comm_str__get(struct comm_str *cs) | 21 | static struct comm_str *comm_str__get(struct comm_str *cs) |
22 | { | 22 | { |
23 | if (cs) | 23 | if (cs && refcount_inc_not_zero(&cs->refcnt)) |
24 | refcount_inc(&cs->refcnt); | 24 | return cs; |
25 | return cs; | 25 | |
26 | return NULL; | ||
26 | } | 27 | } |
27 | 28 | ||
28 | static void comm_str__put(struct comm_str *cs) | 29 | static void comm_str__put(struct comm_str *cs) |
@@ -67,9 +68,14 @@ struct comm_str *__comm_str__findnew(const char *str, struct rb_root *root) | |||
67 | parent = *p; | 68 | parent = *p; |
68 | iter = rb_entry(parent, struct comm_str, rb_node); | 69 | iter = rb_entry(parent, struct comm_str, rb_node); |
69 | 70 | ||
71 | /* | ||
72 | * If we race with comm_str__put, iter->refcnt is 0 | ||
73 | * and it will be removed within comm_str__put call | ||
74 | * shortly, ignore it in this search. | ||
75 | */ | ||
70 | cmp = strcmp(str, iter->str); | 76 | cmp = strcmp(str, iter->str); |
71 | if (!cmp) | 77 | if (!cmp && comm_str__get(iter)) |
72 | return comm_str__get(iter); | 78 | return iter; |
73 | 79 | ||
74 | if (cmp < 0) | 80 | if (cmp < 0) |
75 | p = &(*p)->rb_left; | 81 | p = &(*p)->rb_left; |
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 4d5fc374e730..938def6d0bb9 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #endif | 31 | #endif |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #define CS_ETM_INVAL_ADDR 0xdeadbeefdeadbeefUL | ||
35 | |||
34 | struct cs_etm_decoder { | 36 | struct cs_etm_decoder { |
35 | void *data; | 37 | void *data; |
36 | void (*packet_printer)(const char *msg); | 38 | void (*packet_printer)(const char *msg); |
@@ -261,8 +263,8 @@ static void cs_etm_decoder__clear_buffer(struct cs_etm_decoder *decoder) | |||
261 | decoder->tail = 0; | 263 | decoder->tail = 0; |
262 | decoder->packet_count = 0; | 264 | decoder->packet_count = 0; |
263 | for (i = 0; i < MAX_BUFFER; i++) { | 265 | for (i = 0; i < MAX_BUFFER; i++) { |
264 | decoder->packet_buffer[i].start_addr = 0xdeadbeefdeadbeefUL; | 266 | decoder->packet_buffer[i].start_addr = CS_ETM_INVAL_ADDR; |
265 | decoder->packet_buffer[i].end_addr = 0xdeadbeefdeadbeefUL; | 267 | decoder->packet_buffer[i].end_addr = CS_ETM_INVAL_ADDR; |
266 | decoder->packet_buffer[i].last_instr_taken_branch = false; | 268 | decoder->packet_buffer[i].last_instr_taken_branch = false; |
267 | decoder->packet_buffer[i].exc = false; | 269 | decoder->packet_buffer[i].exc = false; |
268 | decoder->packet_buffer[i].exc_ret = false; | 270 | decoder->packet_buffer[i].exc_ret = false; |
@@ -295,8 +297,8 @@ cs_etm_decoder__buffer_packet(struct cs_etm_decoder *decoder, | |||
295 | decoder->packet_buffer[et].exc = false; | 297 | decoder->packet_buffer[et].exc = false; |
296 | decoder->packet_buffer[et].exc_ret = false; | 298 | decoder->packet_buffer[et].exc_ret = false; |
297 | decoder->packet_buffer[et].cpu = *((int *)inode->priv); | 299 | decoder->packet_buffer[et].cpu = *((int *)inode->priv); |
298 | decoder->packet_buffer[et].start_addr = 0xdeadbeefdeadbeefUL; | 300 | decoder->packet_buffer[et].start_addr = CS_ETM_INVAL_ADDR; |
299 | decoder->packet_buffer[et].end_addr = 0xdeadbeefdeadbeefUL; | 301 | decoder->packet_buffer[et].end_addr = CS_ETM_INVAL_ADDR; |
300 | 302 | ||
301 | if (decoder->packet_count == MAX_BUFFER - 1) | 303 | if (decoder->packet_count == MAX_BUFFER - 1) |
302 | return OCSD_RESP_WAIT; | 304 | return OCSD_RESP_WAIT; |
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index 743f5f444304..612b5755f742 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | |||
@@ -23,6 +23,7 @@ struct cs_etm_buffer { | |||
23 | }; | 23 | }; |
24 | 24 | ||
25 | enum cs_etm_sample_type { | 25 | enum cs_etm_sample_type { |
26 | CS_ETM_EMPTY = 0, | ||
26 | CS_ETM_RANGE = 1 << 0, | 27 | CS_ETM_RANGE = 1 << 0, |
27 | CS_ETM_TRACE_ON = 1 << 1, | 28 | CS_ETM_TRACE_ON = 1 << 1, |
28 | }; | 29 | }; |
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 822ba915d144..2ae640257fdb 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c | |||
@@ -494,6 +494,10 @@ static inline void cs_etm__reset_last_branch_rb(struct cs_etm_queue *etmq) | |||
494 | 494 | ||
495 | static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet) | 495 | static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet) |
496 | { | 496 | { |
497 | /* Returns 0 for the CS_ETM_TRACE_ON packet */ | ||
498 | if (packet->sample_type == CS_ETM_TRACE_ON) | ||
499 | return 0; | ||
500 | |||
497 | /* | 501 | /* |
498 | * The packet records the execution range with an exclusive end address | 502 | * The packet records the execution range with an exclusive end address |
499 | * | 503 | * |
@@ -505,6 +509,15 @@ static inline u64 cs_etm__last_executed_instr(struct cs_etm_packet *packet) | |||
505 | return packet->end_addr - A64_INSTR_SIZE; | 509 | return packet->end_addr - A64_INSTR_SIZE; |
506 | } | 510 | } |
507 | 511 | ||
512 | static inline u64 cs_etm__first_executed_instr(struct cs_etm_packet *packet) | ||
513 | { | ||
514 | /* Returns 0 for the CS_ETM_TRACE_ON packet */ | ||
515 | if (packet->sample_type == CS_ETM_TRACE_ON) | ||
516 | return 0; | ||
517 | |||
518 | return packet->start_addr; | ||
519 | } | ||
520 | |||
508 | static inline u64 cs_etm__instr_count(const struct cs_etm_packet *packet) | 521 | static inline u64 cs_etm__instr_count(const struct cs_etm_packet *packet) |
509 | { | 522 | { |
510 | /* | 523 | /* |
@@ -546,7 +559,7 @@ static void cs_etm__update_last_branch_rb(struct cs_etm_queue *etmq) | |||
546 | 559 | ||
547 | be = &bs->entries[etmq->last_branch_pos]; | 560 | be = &bs->entries[etmq->last_branch_pos]; |
548 | be->from = cs_etm__last_executed_instr(etmq->prev_packet); | 561 | be->from = cs_etm__last_executed_instr(etmq->prev_packet); |
549 | be->to = etmq->packet->start_addr; | 562 | be->to = cs_etm__first_executed_instr(etmq->packet); |
550 | /* No support for mispredict */ | 563 | /* No support for mispredict */ |
551 | be->flags.mispred = 0; | 564 | be->flags.mispred = 0; |
552 | be->flags.predicted = 1; | 565 | be->flags.predicted = 1; |
@@ -701,7 +714,7 @@ static int cs_etm__synth_branch_sample(struct cs_etm_queue *etmq) | |||
701 | sample.ip = cs_etm__last_executed_instr(etmq->prev_packet); | 714 | sample.ip = cs_etm__last_executed_instr(etmq->prev_packet); |
702 | sample.pid = etmq->pid; | 715 | sample.pid = etmq->pid; |
703 | sample.tid = etmq->tid; | 716 | sample.tid = etmq->tid; |
704 | sample.addr = etmq->packet->start_addr; | 717 | sample.addr = cs_etm__first_executed_instr(etmq->packet); |
705 | sample.id = etmq->etm->branches_id; | 718 | sample.id = etmq->etm->branches_id; |
706 | sample.stream_id = etmq->etm->branches_id; | 719 | sample.stream_id = etmq->etm->branches_id; |
707 | sample.period = 1; | 720 | sample.period = 1; |
@@ -897,13 +910,23 @@ static int cs_etm__sample(struct cs_etm_queue *etmq) | |||
897 | etmq->period_instructions = instrs_over; | 910 | etmq->period_instructions = instrs_over; |
898 | } | 911 | } |
899 | 912 | ||
900 | if (etm->sample_branches && | 913 | if (etm->sample_branches && etmq->prev_packet) { |
901 | etmq->prev_packet && | 914 | bool generate_sample = false; |
902 | etmq->prev_packet->sample_type == CS_ETM_RANGE && | 915 | |
903 | etmq->prev_packet->last_instr_taken_branch) { | 916 | /* Generate sample for tracing on packet */ |
904 | ret = cs_etm__synth_branch_sample(etmq); | 917 | if (etmq->prev_packet->sample_type == CS_ETM_TRACE_ON) |
905 | if (ret) | 918 | generate_sample = true; |
906 | return ret; | 919 | |
920 | /* Generate sample for branch taken packet */ | ||
921 | if (etmq->prev_packet->sample_type == CS_ETM_RANGE && | ||
922 | etmq->prev_packet->last_instr_taken_branch) | ||
923 | generate_sample = true; | ||
924 | |||
925 | if (generate_sample) { | ||
926 | ret = cs_etm__synth_branch_sample(etmq); | ||
927 | if (ret) | ||
928 | return ret; | ||
929 | } | ||
907 | } | 930 | } |
908 | 931 | ||
909 | if (etm->sample_branches || etm->synth_opts.last_branch) { | 932 | if (etm->sample_branches || etm->synth_opts.last_branch) { |
@@ -922,10 +945,17 @@ static int cs_etm__sample(struct cs_etm_queue *etmq) | |||
922 | static int cs_etm__flush(struct cs_etm_queue *etmq) | 945 | static int cs_etm__flush(struct cs_etm_queue *etmq) |
923 | { | 946 | { |
924 | int err = 0; | 947 | int err = 0; |
948 | struct cs_etm_auxtrace *etm = etmq->etm; | ||
925 | struct cs_etm_packet *tmp; | 949 | struct cs_etm_packet *tmp; |
926 | 950 | ||
951 | if (!etmq->prev_packet) | ||
952 | return 0; | ||
953 | |||
954 | /* Handle start tracing packet */ | ||
955 | if (etmq->prev_packet->sample_type == CS_ETM_EMPTY) | ||
956 | goto swap_packet; | ||
957 | |||
927 | if (etmq->etm->synth_opts.last_branch && | 958 | if (etmq->etm->synth_opts.last_branch && |
928 | etmq->prev_packet && | ||
929 | etmq->prev_packet->sample_type == CS_ETM_RANGE) { | 959 | etmq->prev_packet->sample_type == CS_ETM_RANGE) { |
930 | /* | 960 | /* |
931 | * Generate a last branch event for the branches left in the | 961 | * Generate a last branch event for the branches left in the |
@@ -939,8 +969,22 @@ static int cs_etm__flush(struct cs_etm_queue *etmq) | |||
939 | err = cs_etm__synth_instruction_sample( | 969 | err = cs_etm__synth_instruction_sample( |
940 | etmq, addr, | 970 | etmq, addr, |
941 | etmq->period_instructions); | 971 | etmq->period_instructions); |
972 | if (err) | ||
973 | return err; | ||
974 | |||
942 | etmq->period_instructions = 0; | 975 | etmq->period_instructions = 0; |
943 | 976 | ||
977 | } | ||
978 | |||
979 | if (etm->sample_branches && | ||
980 | etmq->prev_packet->sample_type == CS_ETM_RANGE) { | ||
981 | err = cs_etm__synth_branch_sample(etmq); | ||
982 | if (err) | ||
983 | return err; | ||
984 | } | ||
985 | |||
986 | swap_packet: | ||
987 | if (etmq->etm->synth_opts.last_branch) { | ||
944 | /* | 988 | /* |
945 | * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for | 989 | * Swap PACKET with PREV_PACKET: PACKET becomes PREV_PACKET for |
946 | * the next incoming packet. | 990 | * the next incoming packet. |
@@ -1020,6 +1064,13 @@ static int cs_etm__run_decoder(struct cs_etm_queue *etmq) | |||
1020 | */ | 1064 | */ |
1021 | cs_etm__flush(etmq); | 1065 | cs_etm__flush(etmq); |
1022 | break; | 1066 | break; |
1067 | case CS_ETM_EMPTY: | ||
1068 | /* | ||
1069 | * Should not receive empty packet, | ||
1070 | * report error. | ||
1071 | */ | ||
1072 | pr_err("CS ETM Trace: empty packet\n"); | ||
1073 | return -EINVAL; | ||
1023 | default: | 1074 | default: |
1024 | break; | 1075 | break; |
1025 | } | 1076 | } |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 94fce4f537e9..ddf84b941abf 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -260,6 +260,17 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | |||
260 | evsel->attr.sample_period = 1; | 260 | evsel->attr.sample_period = 1; |
261 | } | 261 | } |
262 | 262 | ||
263 | if (perf_evsel__is_clock(evsel)) { | ||
264 | /* | ||
265 | * The evsel->unit points to static alias->unit | ||
266 | * so it's ok to use static string in here. | ||
267 | */ | ||
268 | static const char *unit = "msec"; | ||
269 | |||
270 | evsel->unit = unit; | ||
271 | evsel->scale = 1e-6; | ||
272 | } | ||
273 | |||
263 | return evsel; | 274 | return evsel; |
264 | } | 275 | } |
265 | 276 | ||
@@ -848,6 +859,12 @@ static void apply_config_terms(struct perf_evsel *evsel, | |||
848 | } | 859 | } |
849 | } | 860 | } |
850 | 861 | ||
862 | static bool is_dummy_event(struct perf_evsel *evsel) | ||
863 | { | ||
864 | return (evsel->attr.type == PERF_TYPE_SOFTWARE) && | ||
865 | (evsel->attr.config == PERF_COUNT_SW_DUMMY); | ||
866 | } | ||
867 | |||
851 | /* | 868 | /* |
852 | * The enable_on_exec/disabled value strategy: | 869 | * The enable_on_exec/disabled value strategy: |
853 | * | 870 | * |
@@ -1086,6 +1103,14 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, | |||
1086 | else | 1103 | else |
1087 | perf_evsel__reset_sample_bit(evsel, PERIOD); | 1104 | perf_evsel__reset_sample_bit(evsel, PERIOD); |
1088 | } | 1105 | } |
1106 | |||
1107 | /* | ||
1108 | * For initial_delay, a dummy event is added implicitly. | ||
1109 | * The software event will trigger -EOPNOTSUPP error out, | ||
1110 | * if BRANCH_STACK bit is set. | ||
1111 | */ | ||
1112 | if (opts->initial_delay && is_dummy_event(evsel)) | ||
1113 | perf_evsel__reset_sample_bit(evsel, BRANCH_STACK); | ||
1089 | } | 1114 | } |
1090 | 1115 | ||
1091 | static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 1116 | static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d277930b19a1..973c03167947 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -402,10 +402,13 @@ bool perf_evsel__is_function_event(struct perf_evsel *evsel); | |||
402 | 402 | ||
403 | static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel) | 403 | static inline bool perf_evsel__is_bpf_output(struct perf_evsel *evsel) |
404 | { | 404 | { |
405 | struct perf_event_attr *attr = &evsel->attr; | 405 | return perf_evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT); |
406 | } | ||
406 | 407 | ||
407 | return (attr->config == PERF_COUNT_SW_BPF_OUTPUT) && | 408 | static inline bool perf_evsel__is_clock(struct perf_evsel *evsel) |
408 | (attr->type == PERF_TYPE_SOFTWARE); | 409 | { |
410 | return perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) || | ||
411 | perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK); | ||
409 | } | 412 | } |
410 | 413 | ||
411 | struct perf_attr_details { | 414 | struct perf_attr_details { |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 653ff65aa2c3..5af58aac91ad 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -2587,7 +2587,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { | |||
2587 | FEAT_OPR(NUMA_TOPOLOGY, numa_topology, true), | 2587 | FEAT_OPR(NUMA_TOPOLOGY, numa_topology, true), |
2588 | FEAT_OPN(BRANCH_STACK, branch_stack, false), | 2588 | FEAT_OPN(BRANCH_STACK, branch_stack, false), |
2589 | FEAT_OPR(PMU_MAPPINGS, pmu_mappings, false), | 2589 | FEAT_OPR(PMU_MAPPINGS, pmu_mappings, false), |
2590 | FEAT_OPN(GROUP_DESC, group_desc, false), | 2590 | FEAT_OPR(GROUP_DESC, group_desc, false), |
2591 | FEAT_OPN(AUXTRACE, auxtrace, false), | 2591 | FEAT_OPN(AUXTRACE, auxtrace, false), |
2592 | FEAT_OPN(STAT, stat, false), | 2592 | FEAT_OPN(STAT, stat, false), |
2593 | FEAT_OPN(CACHE, cache, true), | 2593 | FEAT_OPN(CACHE, cache, true), |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 73049f7f0f60..3badd7f1e1b8 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -181,7 +181,7 @@ size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); | |||
181 | 181 | ||
182 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, | 182 | size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, |
183 | int max_cols, float min_pcnt, FILE *fp, | 183 | int max_cols, float min_pcnt, FILE *fp, |
184 | bool use_callchain); | 184 | bool ignore_callchains); |
185 | size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); | 185 | size_t perf_evlist__fprintf_nr_events(struct perf_evlist *evlist, FILE *fp); |
186 | 186 | ||
187 | void hists__filter_by_dso(struct hists *hists); | 187 | void hists__filter_by_dso(struct hists *hists); |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index e7b4a8b513f2..b300a3973448 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -408,23 +408,16 @@ out_err: | |||
408 | } | 408 | } |
409 | 409 | ||
410 | /* | 410 | /* |
411 | * Caller must eventually drop thread->refcnt returned with a successful | 411 | * Front-end cache - TID lookups come in blocks, |
412 | * lookup/new thread inserted. | 412 | * so most of the time we dont have to look up |
413 | * the full rbtree: | ||
413 | */ | 414 | */ |
414 | static struct thread *____machine__findnew_thread(struct machine *machine, | 415 | static struct thread* |
415 | struct threads *threads, | 416 | __threads__get_last_match(struct threads *threads, struct machine *machine, |
416 | pid_t pid, pid_t tid, | 417 | int pid, int tid) |
417 | bool create) | ||
418 | { | 418 | { |
419 | struct rb_node **p = &threads->entries.rb_node; | ||
420 | struct rb_node *parent = NULL; | ||
421 | struct thread *th; | 419 | struct thread *th; |
422 | 420 | ||
423 | /* | ||
424 | * Front-end cache - TID lookups come in blocks, | ||
425 | * so most of the time we dont have to look up | ||
426 | * the full rbtree: | ||
427 | */ | ||
428 | th = threads->last_match; | 421 | th = threads->last_match; |
429 | if (th != NULL) { | 422 | if (th != NULL) { |
430 | if (th->tid == tid) { | 423 | if (th->tid == tid) { |
@@ -435,12 +428,57 @@ static struct thread *____machine__findnew_thread(struct machine *machine, | |||
435 | threads->last_match = NULL; | 428 | threads->last_match = NULL; |
436 | } | 429 | } |
437 | 430 | ||
431 | return NULL; | ||
432 | } | ||
433 | |||
434 | static struct thread* | ||
435 | threads__get_last_match(struct threads *threads, struct machine *machine, | ||
436 | int pid, int tid) | ||
437 | { | ||
438 | struct thread *th = NULL; | ||
439 | |||
440 | if (perf_singlethreaded) | ||
441 | th = __threads__get_last_match(threads, machine, pid, tid); | ||
442 | |||
443 | return th; | ||
444 | } | ||
445 | |||
446 | static void | ||
447 | __threads__set_last_match(struct threads *threads, struct thread *th) | ||
448 | { | ||
449 | threads->last_match = th; | ||
450 | } | ||
451 | |||
452 | static void | ||
453 | threads__set_last_match(struct threads *threads, struct thread *th) | ||
454 | { | ||
455 | if (perf_singlethreaded) | ||
456 | __threads__set_last_match(threads, th); | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Caller must eventually drop thread->refcnt returned with a successful | ||
461 | * lookup/new thread inserted. | ||
462 | */ | ||
463 | static struct thread *____machine__findnew_thread(struct machine *machine, | ||
464 | struct threads *threads, | ||
465 | pid_t pid, pid_t tid, | ||
466 | bool create) | ||
467 | { | ||
468 | struct rb_node **p = &threads->entries.rb_node; | ||
469 | struct rb_node *parent = NULL; | ||
470 | struct thread *th; | ||
471 | |||
472 | th = threads__get_last_match(threads, machine, pid, tid); | ||
473 | if (th) | ||
474 | return th; | ||
475 | |||
438 | while (*p != NULL) { | 476 | while (*p != NULL) { |
439 | parent = *p; | 477 | parent = *p; |
440 | th = rb_entry(parent, struct thread, rb_node); | 478 | th = rb_entry(parent, struct thread, rb_node); |
441 | 479 | ||
442 | if (th->tid == tid) { | 480 | if (th->tid == tid) { |
443 | threads->last_match = th; | 481 | threads__set_last_match(threads, th); |
444 | machine__update_thread_pid(machine, th, pid); | 482 | machine__update_thread_pid(machine, th, pid); |
445 | return thread__get(th); | 483 | return thread__get(th); |
446 | } | 484 | } |
@@ -477,7 +515,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, | |||
477 | * It is now in the rbtree, get a ref | 515 | * It is now in the rbtree, get a ref |
478 | */ | 516 | */ |
479 | thread__get(th); | 517 | thread__get(th); |
480 | threads->last_match = th; | 518 | threads__set_last_match(threads, th); |
481 | ++threads->nr; | 519 | ++threads->nr; |
482 | } | 520 | } |
483 | 521 | ||
@@ -1635,7 +1673,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th, | |||
1635 | struct threads *threads = machine__threads(machine, th->tid); | 1673 | struct threads *threads = machine__threads(machine, th->tid); |
1636 | 1674 | ||
1637 | if (threads->last_match == th) | 1675 | if (threads->last_match == th) |
1638 | threads->last_match = NULL; | 1676 | threads__set_last_match(threads, NULL); |
1639 | 1677 | ||
1640 | BUG_ON(refcount_read(&th->refcnt) == 0); | 1678 | BUG_ON(refcount_read(&th->refcnt) == 0); |
1641 | if (lock) | 1679 | if (lock) |
@@ -2272,6 +2310,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) | |||
2272 | { | 2310 | { |
2273 | struct callchain_cursor *cursor = arg; | 2311 | struct callchain_cursor *cursor = arg; |
2274 | const char *srcline = NULL; | 2312 | const char *srcline = NULL; |
2313 | u64 addr; | ||
2275 | 2314 | ||
2276 | if (symbol_conf.hide_unresolved && entry->sym == NULL) | 2315 | if (symbol_conf.hide_unresolved && entry->sym == NULL) |
2277 | return 0; | 2316 | return 0; |
@@ -2279,7 +2318,13 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) | |||
2279 | if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0) | 2318 | if (append_inlines(cursor, entry->map, entry->sym, entry->ip) == 0) |
2280 | return 0; | 2319 | return 0; |
2281 | 2320 | ||
2282 | srcline = callchain_srcline(entry->map, entry->sym, entry->ip); | 2321 | /* |
2322 | * Convert entry->ip from a virtual address to an offset in | ||
2323 | * its corresponding binary. | ||
2324 | */ | ||
2325 | addr = map__map_ip(entry->map, entry->ip); | ||
2326 | |||
2327 | srcline = callchain_srcline(entry->map, entry->sym, addr); | ||
2283 | return callchain_cursor_append(cursor, entry->ip, | 2328 | return callchain_cursor_append(cursor, entry->ip, |
2284 | entry->map, entry->sym, | 2329 | entry->map, entry->sym, |
2285 | false, NULL, 0, 0, 0, srcline); | 2330 | false, NULL, 0, 0, 0, srcline); |
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 1ddc3d1d0147..a28f9b5cc4ff 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c | |||
@@ -326,8 +326,8 @@ void metricgroup__print(bool metrics, bool metricgroups, char *filter, | |||
326 | if (raw) | 326 | if (raw) |
327 | s = (char *)pe->metric_name; | 327 | s = (char *)pe->metric_name; |
328 | else { | 328 | else { |
329 | if (asprintf(&s, "%s\n\t[%s]", | 329 | if (asprintf(&s, "%s\n%*s%s]", |
330 | pe->metric_name, pe->desc) < 0) | 330 | pe->metric_name, 8, "[", pe->desc) < 0) |
331 | return; | 331 | return; |
332 | } | 332 | } |
333 | 333 | ||
@@ -490,3 +490,25 @@ out: | |||
490 | metricgroup__free_egroups(&group_list); | 490 | metricgroup__free_egroups(&group_list); |
491 | return ret; | 491 | return ret; |
492 | } | 492 | } |
493 | |||
494 | bool metricgroup__has_metric(const char *metric) | ||
495 | { | ||
496 | struct pmu_events_map *map = perf_pmu__find_map(NULL); | ||
497 | struct pmu_event *pe; | ||
498 | int i; | ||
499 | |||
500 | if (!map) | ||
501 | return false; | ||
502 | |||
503 | for (i = 0; ; i++) { | ||
504 | pe = &map->table[i]; | ||
505 | |||
506 | if (!pe->name && !pe->metric_group && !pe->metric_name) | ||
507 | break; | ||
508 | if (!pe->metric_expr) | ||
509 | continue; | ||
510 | if (match_metric(pe->metric_name, metric)) | ||
511 | return true; | ||
512 | } | ||
513 | return false; | ||
514 | } | ||
diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h index 06854e125ee7..8a155dba0581 100644 --- a/tools/perf/util/metricgroup.h +++ b/tools/perf/util/metricgroup.h | |||
@@ -28,4 +28,5 @@ int metricgroup__parse_groups(const struct option *opt, | |||
28 | struct rblist *metric_events); | 28 | struct rblist *metric_events); |
29 | 29 | ||
30 | void metricgroup__print(bool metrics, bool groups, char *filter, bool raw); | 30 | void metricgroup__print(bool metrics, bool groups, char *filter, bool raw); |
31 | bool metricgroup__has_metric(const char *metric); | ||
31 | #endif | 32 | #endif |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 3ba6a1742f91..afd68524ffa9 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -652,12 +652,6 @@ static int is_arm_pmu_core(const char *name) | |||
652 | if (stat(path, &st) == 0) | 652 | if (stat(path, &st) == 0) |
653 | return 1; | 653 | return 1; |
654 | 654 | ||
655 | /* Look for cpu sysfs (specific to s390) */ | ||
656 | scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s", | ||
657 | sysfs, name); | ||
658 | if (stat(path, &st) == 0 && !strncmp(name, "cpum_", 5)) | ||
659 | return 1; | ||
660 | |||
661 | return 0; | 655 | return 0; |
662 | } | 656 | } |
663 | 657 | ||
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 594d14a02b67..99990f5f2512 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c | |||
@@ -913,11 +913,10 @@ void perf_stat__print_shadow_stats(struct perf_evsel *evsel, | |||
913 | ratio = total / avg; | 913 | ratio = total / avg; |
914 | 914 | ||
915 | print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio); | 915 | print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio); |
916 | } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK) || | 916 | } else if (perf_evsel__is_clock(evsel)) { |
917 | perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK)) { | ||
918 | if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) | 917 | if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) |
919 | print_metric(ctxp, NULL, "%8.3f", "CPUs utilized", | 918 | print_metric(ctxp, NULL, "%8.3f", "CPUs utilized", |
920 | avg / ratio); | 919 | avg / (ratio * evsel->scale)); |
921 | else | 920 | else |
922 | print_metric(ctxp, NULL, NULL, "CPUs utilized", 0); | 921 | print_metric(ctxp, NULL, NULL, "CPUs utilized", 0); |
923 | } else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) { | 922 | } else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) { |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index 0ee7f568d60c..3393d7ee9401 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c | |||
@@ -38,6 +38,10 @@ static const char **syscalltbl_native = syscalltbl_powerpc_64; | |||
38 | #include <asm/syscalls_32.c> | 38 | #include <asm/syscalls_32.c> |
39 | const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID; | 39 | const int syscalltbl_native_max_id = SYSCALLTBL_POWERPC_32_MAX_ID; |
40 | static const char **syscalltbl_native = syscalltbl_powerpc_32; | 40 | static const char **syscalltbl_native = syscalltbl_powerpc_32; |
41 | #elif defined(__aarch64__) | ||
42 | #include <asm/syscalls.c> | ||
43 | const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID; | ||
44 | static const char **syscalltbl_native = syscalltbl_arm64; | ||
41 | #endif | 45 | #endif |
42 | 46 | ||
43 | struct syscall { | 47 | struct syscall { |
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 538db4e5d1e6..6f318b15950e 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c | |||
@@ -77,7 +77,7 @@ static int entry(u64 ip, struct unwind_info *ui) | |||
77 | if (__report_module(&al, ip, ui)) | 77 | if (__report_module(&al, ip, ui)) |
78 | return -1; | 78 | return -1; |
79 | 79 | ||
80 | e->ip = al.addr; | 80 | e->ip = ip; |
81 | e->map = al.map; | 81 | e->map = al.map; |
82 | e->sym = al.sym; | 82 | e->sym = al.sym; |
83 | 83 | ||
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 6a11bc7e6b27..79f521a552cf 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c | |||
@@ -575,7 +575,7 @@ static int entry(u64 ip, struct thread *thread, | |||
575 | struct addr_location al; | 575 | struct addr_location al; |
576 | 576 | ||
577 | e.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); | 577 | e.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); |
578 | e.ip = al.addr; | 578 | e.ip = ip; |
579 | e.map = al.map; | 579 | e.map = al.map; |
580 | 580 | ||
581 | pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", | 581 | pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", |
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index a362e3d7abc6..fff7fb1285fc 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile | |||
@@ -22,7 +22,8 @@ $(TEST_CUSTOM_PROGS): $(OUTPUT)/%: %.c | |||
22 | # Order correspond to 'make run_tests' order | 22 | # Order correspond to 'make run_tests' order |
23 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ | 23 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ |
24 | test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \ | 24 | test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \ |
25 | test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user | 25 | test_sock test_btf test_sockmap test_lirc_mode2_user get_cgroup_id_user \ |
26 | test_socket_cookie test_cgroup_storage test_select_reuseport | ||
26 | 27 | ||
27 | TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \ | 28 | TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test_obj_id.o \ |
28 | test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ | 29 | test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \ |
@@ -33,7 +34,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test | |||
33 | test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \ | 34 | test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \ |
34 | test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \ | 35 | test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \ |
35 | test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \ | 36 | test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \ |
36 | get_cgroup_id_kern.o | 37 | get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \ |
38 | test_skb_cgroup_id_kern.o | ||
37 | 39 | ||
38 | # Order correspond to 'make run_tests' order | 40 | # Order correspond to 'make run_tests' order |
39 | TEST_PROGS := test_kmod.sh \ | 41 | TEST_PROGS := test_kmod.sh \ |
@@ -44,10 +46,11 @@ TEST_PROGS := test_kmod.sh \ | |||
44 | test_sock_addr.sh \ | 46 | test_sock_addr.sh \ |
45 | test_tunnel.sh \ | 47 | test_tunnel.sh \ |
46 | test_lwt_seg6local.sh \ | 48 | test_lwt_seg6local.sh \ |
47 | test_lirc_mode2.sh | 49 | test_lirc_mode2.sh \ |
50 | test_skb_cgroup_id.sh | ||
48 | 51 | ||
49 | # Compile but not part of 'make run_tests' | 52 | # Compile but not part of 'make run_tests' |
50 | TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr | 53 | TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user |
51 | 54 | ||
52 | include ../lib.mk | 55 | include ../lib.mk |
53 | 56 | ||
@@ -58,11 +61,15 @@ $(TEST_GEN_PROGS): $(BPFOBJ) | |||
58 | $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a | 61 | $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a |
59 | 62 | ||
60 | $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c | 63 | $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c |
64 | $(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c | ||
61 | $(OUTPUT)/test_sock: cgroup_helpers.c | 65 | $(OUTPUT)/test_sock: cgroup_helpers.c |
62 | $(OUTPUT)/test_sock_addr: cgroup_helpers.c | 66 | $(OUTPUT)/test_sock_addr: cgroup_helpers.c |
67 | $(OUTPUT)/test_socket_cookie: cgroup_helpers.c | ||
63 | $(OUTPUT)/test_sockmap: cgroup_helpers.c | 68 | $(OUTPUT)/test_sockmap: cgroup_helpers.c |
69 | $(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c | ||
64 | $(OUTPUT)/test_progs: trace_helpers.c | 70 | $(OUTPUT)/test_progs: trace_helpers.c |
65 | $(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c | 71 | $(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c |
72 | $(OUTPUT)/test_cgroup_storage: cgroup_helpers.c | ||
66 | 73 | ||
67 | .PHONY: force | 74 | .PHONY: force |
68 | 75 | ||
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 810de20e8e26..e4be7730222d 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
@@ -65,6 +65,8 @@ static int (*bpf_xdp_adjust_head)(void *ctx, int offset) = | |||
65 | (void *) BPF_FUNC_xdp_adjust_head; | 65 | (void *) BPF_FUNC_xdp_adjust_head; |
66 | static int (*bpf_xdp_adjust_meta)(void *ctx, int offset) = | 66 | static int (*bpf_xdp_adjust_meta)(void *ctx, int offset) = |
67 | (void *) BPF_FUNC_xdp_adjust_meta; | 67 | (void *) BPF_FUNC_xdp_adjust_meta; |
68 | static int (*bpf_get_socket_cookie)(void *ctx) = | ||
69 | (void *) BPF_FUNC_get_socket_cookie; | ||
68 | static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, | 70 | static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, |
69 | int optlen) = | 71 | int optlen) = |
70 | (void *) BPF_FUNC_setsockopt; | 72 | (void *) BPF_FUNC_setsockopt; |
@@ -109,6 +111,8 @@ static int (*bpf_xdp_adjust_tail)(void *ctx, int offset) = | |||
109 | static int (*bpf_skb_get_xfrm_state)(void *ctx, int index, void *state, | 111 | static int (*bpf_skb_get_xfrm_state)(void *ctx, int index, void *state, |
110 | int size, int flags) = | 112 | int size, int flags) = |
111 | (void *) BPF_FUNC_skb_get_xfrm_state; | 113 | (void *) BPF_FUNC_skb_get_xfrm_state; |
114 | static int (*bpf_sk_select_reuseport)(void *ctx, void *map, void *key, __u32 flags) = | ||
115 | (void *) BPF_FUNC_sk_select_reuseport; | ||
112 | static int (*bpf_get_stack)(void *ctx, void *buf, int size, int flags) = | 116 | static int (*bpf_get_stack)(void *ctx, void *buf, int size, int flags) = |
113 | (void *) BPF_FUNC_get_stack; | 117 | (void *) BPF_FUNC_get_stack; |
114 | static int (*bpf_fib_lookup)(void *ctx, struct bpf_fib_lookup *params, | 118 | static int (*bpf_fib_lookup)(void *ctx, struct bpf_fib_lookup *params, |
@@ -133,6 +137,12 @@ static int (*bpf_rc_keydown)(void *ctx, unsigned int protocol, | |||
133 | (void *) BPF_FUNC_rc_keydown; | 137 | (void *) BPF_FUNC_rc_keydown; |
134 | static unsigned long long (*bpf_get_current_cgroup_id)(void) = | 138 | static unsigned long long (*bpf_get_current_cgroup_id)(void) = |
135 | (void *) BPF_FUNC_get_current_cgroup_id; | 139 | (void *) BPF_FUNC_get_current_cgroup_id; |
140 | static void *(*bpf_get_local_storage)(void *map, unsigned long long flags) = | ||
141 | (void *) BPF_FUNC_get_local_storage; | ||
142 | static unsigned long long (*bpf_skb_cgroup_id)(void *ctx) = | ||
143 | (void *) BPF_FUNC_skb_cgroup_id; | ||
144 | static unsigned long long (*bpf_skb_ancestor_cgroup_id)(void *ctx, int level) = | ||
145 | (void *) BPF_FUNC_skb_ancestor_cgroup_id; | ||
136 | 146 | ||
137 | /* llvm builtin functions that eBPF C program may use to | 147 | /* llvm builtin functions that eBPF C program may use to |
138 | * emit BPF_LD_ABS and BPF_LD_IND instructions | 148 | * emit BPF_LD_ABS and BPF_LD_IND instructions |
@@ -169,6 +179,8 @@ struct bpf_map_def { | |||
169 | 179 | ||
170 | static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = | 180 | static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = |
171 | (void *) BPF_FUNC_skb_load_bytes; | 181 | (void *) BPF_FUNC_skb_load_bytes; |
182 | static int (*bpf_skb_load_bytes_relative)(void *ctx, int off, void *to, int len, __u32 start_header) = | ||
183 | (void *) BPF_FUNC_skb_load_bytes_relative; | ||
172 | static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = | 184 | static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = |
173 | (void *) BPF_FUNC_skb_store_bytes; | 185 | (void *) BPF_FUNC_skb_store_bytes; |
174 | static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flags) = | 186 | static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flags) = |
diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h index d0811b3d6a6f..315a44fa32af 100644 --- a/tools/testing/selftests/bpf/bpf_util.h +++ b/tools/testing/selftests/bpf/bpf_util.h | |||
@@ -44,4 +44,8 @@ static inline unsigned int bpf_num_possible_cpus(void) | |||
44 | name[bpf_num_possible_cpus()] | 44 | name[bpf_num_possible_cpus()] |
45 | #define bpf_percpu(name, cpu) name[(cpu)].v | 45 | #define bpf_percpu(name, cpu) name[(cpu)].v |
46 | 46 | ||
47 | #ifndef ARRAY_SIZE | ||
48 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
49 | #endif | ||
50 | |||
47 | #endif /* __BPF_UTIL__ */ | 51 | #endif /* __BPF_UTIL__ */ |
diff --git a/tools/testing/selftests/bpf/cgroup_helpers.c b/tools/testing/selftests/bpf/cgroup_helpers.c index c87b4e052ce9..cf16948aad4a 100644 --- a/tools/testing/selftests/bpf/cgroup_helpers.c +++ b/tools/testing/selftests/bpf/cgroup_helpers.c | |||
@@ -118,7 +118,7 @@ static int join_cgroup_from_top(char *cgroup_path) | |||
118 | * | 118 | * |
119 | * On success, it returns 0, otherwise on failure it returns 1. | 119 | * On success, it returns 0, otherwise on failure it returns 1. |
120 | */ | 120 | */ |
121 | int join_cgroup(char *path) | 121 | int join_cgroup(const char *path) |
122 | { | 122 | { |
123 | char cgroup_path[PATH_MAX + 1]; | 123 | char cgroup_path[PATH_MAX + 1]; |
124 | 124 | ||
@@ -158,7 +158,7 @@ void cleanup_cgroup_environment(void) | |||
158 | * On success, it returns the file descriptor. On failure it returns 0. | 158 | * On success, it returns the file descriptor. On failure it returns 0. |
159 | * If there is a failure, it prints the error to stderr. | 159 | * If there is a failure, it prints the error to stderr. |
160 | */ | 160 | */ |
161 | int create_and_get_cgroup(char *path) | 161 | int create_and_get_cgroup(const char *path) |
162 | { | 162 | { |
163 | char cgroup_path[PATH_MAX + 1]; | 163 | char cgroup_path[PATH_MAX + 1]; |
164 | int fd; | 164 | int fd; |
@@ -186,7 +186,7 @@ int create_and_get_cgroup(char *path) | |||
186 | * which is an invalid cgroup id. | 186 | * which is an invalid cgroup id. |
187 | * If there is a failure, it prints the error to stderr. | 187 | * If there is a failure, it prints the error to stderr. |
188 | */ | 188 | */ |
189 | unsigned long long get_cgroup_id(char *path) | 189 | unsigned long long get_cgroup_id(const char *path) |
190 | { | 190 | { |
191 | int dirfd, err, flags, mount_id, fhsize; | 191 | int dirfd, err, flags, mount_id, fhsize; |
192 | union { | 192 | union { |
diff --git a/tools/testing/selftests/bpf/cgroup_helpers.h b/tools/testing/selftests/bpf/cgroup_helpers.h index 20a4a5dcd469..d64bb8957090 100644 --- a/tools/testing/selftests/bpf/cgroup_helpers.h +++ b/tools/testing/selftests/bpf/cgroup_helpers.h | |||
@@ -9,10 +9,10 @@ | |||
9 | __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) | 9 | __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) |
10 | 10 | ||
11 | 11 | ||
12 | int create_and_get_cgroup(char *path); | 12 | int create_and_get_cgroup(const char *path); |
13 | int join_cgroup(char *path); | 13 | int join_cgroup(const char *path); |
14 | int setup_cgroup_environment(void); | 14 | int setup_cgroup_environment(void); |
15 | void cleanup_cgroup_environment(void); | 15 | void cleanup_cgroup_environment(void); |
16 | unsigned long long get_cgroup_id(char *path); | 16 | unsigned long long get_cgroup_id(const char *path); |
17 | 17 | ||
18 | #endif | 18 | #endif |
diff --git a/tools/testing/selftests/bpf/socket_cookie_prog.c b/tools/testing/selftests/bpf/socket_cookie_prog.c new file mode 100644 index 000000000000..9ff8ac4b0bf6 --- /dev/null +++ b/tools/testing/selftests/bpf/socket_cookie_prog.c | |||
@@ -0,0 +1,60 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (c) 2018 Facebook | ||
3 | |||
4 | #include <linux/bpf.h> | ||
5 | #include <sys/socket.h> | ||
6 | |||
7 | #include "bpf_helpers.h" | ||
8 | #include "bpf_endian.h" | ||
9 | |||
10 | struct bpf_map_def SEC("maps") socket_cookies = { | ||
11 | .type = BPF_MAP_TYPE_HASH, | ||
12 | .key_size = sizeof(__u64), | ||
13 | .value_size = sizeof(__u32), | ||
14 | .max_entries = 1 << 8, | ||
15 | }; | ||
16 | |||
17 | SEC("cgroup/connect6") | ||
18 | int set_cookie(struct bpf_sock_addr *ctx) | ||
19 | { | ||
20 | __u32 cookie_value = 0xFF; | ||
21 | __u64 cookie_key; | ||
22 | |||
23 | if (ctx->family != AF_INET6 || ctx->user_family != AF_INET6) | ||
24 | return 1; | ||
25 | |||
26 | cookie_key = bpf_get_socket_cookie(ctx); | ||
27 | if (bpf_map_update_elem(&socket_cookies, &cookie_key, &cookie_value, 0)) | ||
28 | return 0; | ||
29 | |||
30 | return 1; | ||
31 | } | ||
32 | |||
33 | SEC("sockops") | ||
34 | int update_cookie(struct bpf_sock_ops *ctx) | ||
35 | { | ||
36 | __u32 new_cookie_value; | ||
37 | __u32 *cookie_value; | ||
38 | __u64 cookie_key; | ||
39 | |||
40 | if (ctx->family != AF_INET6) | ||
41 | return 1; | ||
42 | |||
43 | if (ctx->op != BPF_SOCK_OPS_TCP_CONNECT_CB) | ||
44 | return 1; | ||
45 | |||
46 | cookie_key = bpf_get_socket_cookie(ctx); | ||
47 | |||
48 | cookie_value = bpf_map_lookup_elem(&socket_cookies, &cookie_key); | ||
49 | if (!cookie_value) | ||
50 | return 1; | ||
51 | |||
52 | new_cookie_value = (ctx->local_port << 8) | *cookie_value; | ||
53 | bpf_map_update_elem(&socket_cookies, &cookie_key, &new_cookie_value, 0); | ||
54 | |||
55 | return 1; | ||
56 | } | ||
57 | |||
58 | int _version SEC("version") = 1; | ||
59 | |||
60 | char _license[] SEC("license") = "GPL"; | ||
diff --git a/tools/testing/selftests/bpf/tcp_client.py b/tools/testing/selftests/bpf/tcp_client.py index 481dccdf140c..7f8200a8702b 100755 --- a/tools/testing/selftests/bpf/tcp_client.py +++ b/tools/testing/selftests/bpf/tcp_client.py | |||
@@ -1,4 +1,4 @@ | |||
1 | #!/usr/bin/env python2 | 1 | #!/usr/bin/env python3 |
2 | # | 2 | # |
3 | # SPDX-License-Identifier: GPL-2.0 | 3 | # SPDX-License-Identifier: GPL-2.0 |
4 | # | 4 | # |
@@ -9,11 +9,11 @@ import subprocess | |||
9 | import select | 9 | import select |
10 | 10 | ||
11 | def read(sock, n): | 11 | def read(sock, n): |
12 | buf = '' | 12 | buf = b'' |
13 | while len(buf) < n: | 13 | while len(buf) < n: |
14 | rem = n - len(buf) | 14 | rem = n - len(buf) |
15 | try: s = sock.recv(rem) | 15 | try: s = sock.recv(rem) |
16 | except (socket.error), e: return '' | 16 | except (socket.error) as e: return b'' |
17 | buf += s | 17 | buf += s |
18 | return buf | 18 | return buf |
19 | 19 | ||
@@ -22,7 +22,7 @@ def send(sock, s): | |||
22 | count = 0 | 22 | count = 0 |
23 | while count < total: | 23 | while count < total: |
24 | try: n = sock.send(s) | 24 | try: n = sock.send(s) |
25 | except (socket.error), e: n = 0 | 25 | except (socket.error) as e: n = 0 |
26 | if n == 0: | 26 | if n == 0: |
27 | return count; | 27 | return count; |
28 | count += n | 28 | count += n |
@@ -39,10 +39,10 @@ try: | |||
39 | except socket.error as e: | 39 | except socket.error as e: |
40 | sys.exit(1) | 40 | sys.exit(1) |
41 | 41 | ||
42 | buf = '' | 42 | buf = b'' |
43 | n = 0 | 43 | n = 0 |
44 | while n < 1000: | 44 | while n < 1000: |
45 | buf += '+' | 45 | buf += b'+' |
46 | n += 1 | 46 | n += 1 |
47 | 47 | ||
48 | sock.settimeout(1); | 48 | sock.settimeout(1); |
diff --git a/tools/testing/selftests/bpf/tcp_server.py b/tools/testing/selftests/bpf/tcp_server.py index bc454d7d0be2..b39903fca4c8 100755 --- a/tools/testing/selftests/bpf/tcp_server.py +++ b/tools/testing/selftests/bpf/tcp_server.py | |||
@@ -1,4 +1,4 @@ | |||
1 | #!/usr/bin/env python2 | 1 | #!/usr/bin/env python3 |
2 | # | 2 | # |
3 | # SPDX-License-Identifier: GPL-2.0 | 3 | # SPDX-License-Identifier: GPL-2.0 |
4 | # | 4 | # |
@@ -9,11 +9,11 @@ import subprocess | |||
9 | import select | 9 | import select |
10 | 10 | ||
11 | def read(sock, n): | 11 | def read(sock, n): |
12 | buf = '' | 12 | buf = b'' |
13 | while len(buf) < n: | 13 | while len(buf) < n: |
14 | rem = n - len(buf) | 14 | rem = n - len(buf) |
15 | try: s = sock.recv(rem) | 15 | try: s = sock.recv(rem) |
16 | except (socket.error), e: return '' | 16 | except (socket.error) as e: return b'' |
17 | buf += s | 17 | buf += s |
18 | return buf | 18 | return buf |
19 | 19 | ||
@@ -22,7 +22,7 @@ def send(sock, s): | |||
22 | count = 0 | 22 | count = 0 |
23 | while count < total: | 23 | while count < total: |
24 | try: n = sock.send(s) | 24 | try: n = sock.send(s) |
25 | except (socket.error), e: n = 0 | 25 | except (socket.error) as e: n = 0 |
26 | if n == 0: | 26 | if n == 0: |
27 | return count; | 27 | return count; |
28 | count += n | 28 | count += n |
@@ -43,7 +43,7 @@ host = socket.gethostname() | |||
43 | 43 | ||
44 | try: serverSocket.bind((host, 0)) | 44 | try: serverSocket.bind((host, 0)) |
45 | except socket.error as msg: | 45 | except socket.error as msg: |
46 | print 'bind fails: ', msg | 46 | print('bind fails: ' + str(msg)) |
47 | 47 | ||
48 | sn = serverSocket.getsockname() | 48 | sn = serverSocket.getsockname() |
49 | serverPort = sn[1] | 49 | serverPort = sn[1] |
@@ -51,10 +51,10 @@ serverPort = sn[1] | |||
51 | cmdStr = ("./tcp_client.py %d &") % (serverPort) | 51 | cmdStr = ("./tcp_client.py %d &") % (serverPort) |
52 | os.system(cmdStr) | 52 | os.system(cmdStr) |
53 | 53 | ||
54 | buf = '' | 54 | buf = b'' |
55 | n = 0 | 55 | n = 0 |
56 | while n < 500: | 56 | while n < 500: |
57 | buf += '.' | 57 | buf += b'.' |
58 | n += 1 | 58 | n += 1 |
59 | 59 | ||
60 | serverSocket.listen(MAX_PORTS) | 60 | serverSocket.listen(MAX_PORTS) |
@@ -79,5 +79,5 @@ while True: | |||
79 | serverSocket.close() | 79 | serverSocket.close() |
80 | sys.exit(0) | 80 | sys.exit(0) |
81 | else: | 81 | else: |
82 | print 'Select timeout!' | 82 | print('Select timeout!') |
83 | sys.exit(1) | 83 | sys.exit(1) |
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c index 6b1b302310fe..5f377ec53f2f 100644 --- a/tools/testing/selftests/bpf/test_align.c +++ b/tools/testing/selftests/bpf/test_align.c | |||
@@ -18,10 +18,7 @@ | |||
18 | 18 | ||
19 | #include "../../../include/linux/filter.h" | 19 | #include "../../../include/linux/filter.h" |
20 | #include "bpf_rlimit.h" | 20 | #include "bpf_rlimit.h" |
21 | 21 | #include "bpf_util.h" | |
22 | #ifndef ARRAY_SIZE | ||
23 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
24 | #endif | ||
25 | 22 | ||
26 | #define MAX_INSNS 512 | 23 | #define MAX_INSNS 512 |
27 | #define MAX_MATCHES 16 | 24 | #define MAX_MATCHES 16 |
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c index ffdd27737c9e..6b5cfeb7a9cc 100644 --- a/tools/testing/selftests/bpf/test_btf.c +++ b/tools/testing/selftests/bpf/test_btf.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <bpf/btf.h> | 19 | #include <bpf/btf.h> |
20 | 20 | ||
21 | #include "bpf_rlimit.h" | 21 | #include "bpf_rlimit.h" |
22 | #include "bpf_util.h" | ||
22 | 23 | ||
23 | static uint32_t pass_cnt; | 24 | static uint32_t pass_cnt; |
24 | static uint32_t error_cnt; | 25 | static uint32_t error_cnt; |
@@ -93,10 +94,6 @@ static int __base_pr(const char *format, ...) | |||
93 | #define MAX_NR_RAW_TYPES 1024 | 94 | #define MAX_NR_RAW_TYPES 1024 |
94 | #define BTF_LOG_BUF_SIZE 65535 | 95 | #define BTF_LOG_BUF_SIZE 65535 |
95 | 96 | ||
96 | #ifndef ARRAY_SIZE | ||
97 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
98 | #endif | ||
99 | |||
100 | static struct args { | 97 | static struct args { |
101 | unsigned int raw_test_num; | 98 | unsigned int raw_test_num; |
102 | unsigned int file_test_num; | 99 | unsigned int file_test_num; |
@@ -131,6 +128,8 @@ struct btf_raw_test { | |||
131 | __u32 max_entries; | 128 | __u32 max_entries; |
132 | bool btf_load_err; | 129 | bool btf_load_err; |
133 | bool map_create_err; | 130 | bool map_create_err; |
131 | bool ordered_map; | ||
132 | bool lossless_map; | ||
134 | int hdr_len_delta; | 133 | int hdr_len_delta; |
135 | int type_off_delta; | 134 | int type_off_delta; |
136 | int str_off_delta; | 135 | int str_off_delta; |
@@ -2093,8 +2092,7 @@ struct pprint_mapv { | |||
2093 | } aenum; | 2092 | } aenum; |
2094 | }; | 2093 | }; |
2095 | 2094 | ||
2096 | static struct btf_raw_test pprint_test = { | 2095 | static struct btf_raw_test pprint_test_template = { |
2097 | .descr = "BTF pretty print test #1", | ||
2098 | .raw_types = { | 2096 | .raw_types = { |
2099 | /* unsighed char */ /* [1] */ | 2097 | /* unsighed char */ /* [1] */ |
2100 | BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), | 2098 | BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), |
@@ -2146,8 +2144,6 @@ static struct btf_raw_test pprint_test = { | |||
2146 | }, | 2144 | }, |
2147 | .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum", | 2145 | .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum", |
2148 | .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"), | 2146 | .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"), |
2149 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
2150 | .map_name = "pprint_test", | ||
2151 | .key_size = sizeof(unsigned int), | 2147 | .key_size = sizeof(unsigned int), |
2152 | .value_size = sizeof(struct pprint_mapv), | 2148 | .value_size = sizeof(struct pprint_mapv), |
2153 | .key_type_id = 3, /* unsigned int */ | 2149 | .key_type_id = 3, /* unsigned int */ |
@@ -2155,6 +2151,40 @@ static struct btf_raw_test pprint_test = { | |||
2155 | .max_entries = 128 * 1024, | 2151 | .max_entries = 128 * 1024, |
2156 | }; | 2152 | }; |
2157 | 2153 | ||
2154 | static struct btf_pprint_test_meta { | ||
2155 | const char *descr; | ||
2156 | enum bpf_map_type map_type; | ||
2157 | const char *map_name; | ||
2158 | bool ordered_map; | ||
2159 | bool lossless_map; | ||
2160 | } pprint_tests_meta[] = { | ||
2161 | { | ||
2162 | .descr = "BTF pretty print array", | ||
2163 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
2164 | .map_name = "pprint_test_array", | ||
2165 | .ordered_map = true, | ||
2166 | .lossless_map = true, | ||
2167 | }, | ||
2168 | |||
2169 | { | ||
2170 | .descr = "BTF pretty print hash", | ||
2171 | .map_type = BPF_MAP_TYPE_HASH, | ||
2172 | .map_name = "pprint_test_hash", | ||
2173 | .ordered_map = false, | ||
2174 | .lossless_map = true, | ||
2175 | }, | ||
2176 | |||
2177 | { | ||
2178 | .descr = "BTF pretty print lru hash", | ||
2179 | .map_type = BPF_MAP_TYPE_LRU_HASH, | ||
2180 | .map_name = "pprint_test_lru_hash", | ||
2181 | .ordered_map = false, | ||
2182 | .lossless_map = false, | ||
2183 | }, | ||
2184 | |||
2185 | }; | ||
2186 | |||
2187 | |||
2158 | static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i) | 2188 | static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i) |
2159 | { | 2189 | { |
2160 | v->ui32 = i; | 2190 | v->ui32 = i; |
@@ -2166,10 +2196,12 @@ static void set_pprint_mapv(struct pprint_mapv *v, uint32_t i) | |||
2166 | v->aenum = i & 0x03; | 2196 | v->aenum = i & 0x03; |
2167 | } | 2197 | } |
2168 | 2198 | ||
2169 | static int test_pprint(void) | 2199 | static int do_test_pprint(void) |
2170 | { | 2200 | { |
2171 | const struct btf_raw_test *test = &pprint_test; | 2201 | const struct btf_raw_test *test = &pprint_test_template; |
2172 | struct bpf_create_map_attr create_attr = {}; | 2202 | struct bpf_create_map_attr create_attr = {}; |
2203 | unsigned int key, nr_read_elems; | ||
2204 | bool ordered_map, lossless_map; | ||
2173 | int map_fd = -1, btf_fd = -1; | 2205 | int map_fd = -1, btf_fd = -1; |
2174 | struct pprint_mapv mapv = {}; | 2206 | struct pprint_mapv mapv = {}; |
2175 | unsigned int raw_btf_size; | 2207 | unsigned int raw_btf_size; |
@@ -2178,7 +2210,6 @@ static int test_pprint(void) | |||
2178 | char pin_path[255]; | 2210 | char pin_path[255]; |
2179 | size_t line_len = 0; | 2211 | size_t line_len = 0; |
2180 | char *line = NULL; | 2212 | char *line = NULL; |
2181 | unsigned int key; | ||
2182 | uint8_t *raw_btf; | 2213 | uint8_t *raw_btf; |
2183 | ssize_t nread; | 2214 | ssize_t nread; |
2184 | int err, ret; | 2215 | int err, ret; |
@@ -2251,14 +2282,18 @@ static int test_pprint(void) | |||
2251 | goto done; | 2282 | goto done; |
2252 | } | 2283 | } |
2253 | 2284 | ||
2254 | key = 0; | 2285 | nr_read_elems = 0; |
2286 | ordered_map = test->ordered_map; | ||
2287 | lossless_map = test->lossless_map; | ||
2255 | do { | 2288 | do { |
2256 | ssize_t nexpected_line; | 2289 | ssize_t nexpected_line; |
2290 | unsigned int next_key; | ||
2257 | 2291 | ||
2258 | set_pprint_mapv(&mapv, key); | 2292 | next_key = ordered_map ? nr_read_elems : atoi(line); |
2293 | set_pprint_mapv(&mapv, next_key); | ||
2259 | nexpected_line = snprintf(expected_line, sizeof(expected_line), | 2294 | nexpected_line = snprintf(expected_line, sizeof(expected_line), |
2260 | "%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n", | 2295 | "%u: {%u,0,%d,0x%x,0x%x,0x%x,{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s}\n", |
2261 | key, | 2296 | next_key, |
2262 | mapv.ui32, mapv.si32, | 2297 | mapv.ui32, mapv.si32, |
2263 | mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b, | 2298 | mapv.unused_bits2a, mapv.bits28, mapv.unused_bits2b, |
2264 | mapv.ui64, | 2299 | mapv.ui64, |
@@ -2281,11 +2316,12 @@ static int test_pprint(void) | |||
2281 | } | 2316 | } |
2282 | 2317 | ||
2283 | nread = getline(&line, &line_len, pin_file); | 2318 | nread = getline(&line, &line_len, pin_file); |
2284 | } while (++key < test->max_entries && nread > 0); | 2319 | } while (++nr_read_elems < test->max_entries && nread > 0); |
2285 | 2320 | ||
2286 | if (CHECK(key < test->max_entries, | 2321 | if (lossless_map && |
2287 | "Unexpected EOF. key:%u test->max_entries:%u", | 2322 | CHECK(nr_read_elems < test->max_entries, |
2288 | key, test->max_entries)) { | 2323 | "Unexpected EOF. nr_read_elems:%u test->max_entries:%u", |
2324 | nr_read_elems, test->max_entries)) { | ||
2289 | err = -1; | 2325 | err = -1; |
2290 | goto done; | 2326 | goto done; |
2291 | } | 2327 | } |
@@ -2314,6 +2350,24 @@ done: | |||
2314 | return err; | 2350 | return err; |
2315 | } | 2351 | } |
2316 | 2352 | ||
2353 | static int test_pprint(void) | ||
2354 | { | ||
2355 | unsigned int i; | ||
2356 | int err = 0; | ||
2357 | |||
2358 | for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) { | ||
2359 | pprint_test_template.descr = pprint_tests_meta[i].descr; | ||
2360 | pprint_test_template.map_type = pprint_tests_meta[i].map_type; | ||
2361 | pprint_test_template.map_name = pprint_tests_meta[i].map_name; | ||
2362 | pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map; | ||
2363 | pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map; | ||
2364 | |||
2365 | err |= count_result(do_test_pprint()); | ||
2366 | } | ||
2367 | |||
2368 | return err; | ||
2369 | } | ||
2370 | |||
2317 | static void usage(const char *cmd) | 2371 | static void usage(const char *cmd) |
2318 | { | 2372 | { |
2319 | fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n", | 2373 | fprintf(stderr, "Usage: %s [-l] [[-r test_num (1 - %zu)] | [-g test_num (1 - %zu)] | [-f test_num (1 - %zu)] | [-p]]\n", |
@@ -2409,7 +2463,7 @@ int main(int argc, char **argv) | |||
2409 | err |= test_file(); | 2463 | err |= test_file(); |
2410 | 2464 | ||
2411 | if (args.pprint_test) | 2465 | if (args.pprint_test) |
2412 | err |= count_result(test_pprint()); | 2466 | err |= test_pprint(); |
2413 | 2467 | ||
2414 | if (args.raw_test || args.get_info_test || args.file_test || | 2468 | if (args.raw_test || args.get_info_test || args.file_test || |
2415 | args.pprint_test) | 2469 | args.pprint_test) |
diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c new file mode 100644 index 000000000000..dc83fb2d3f27 --- /dev/null +++ b/tools/testing/selftests/bpf/test_cgroup_storage.c | |||
@@ -0,0 +1,130 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include <assert.h> | ||
3 | #include <bpf/bpf.h> | ||
4 | #include <linux/filter.h> | ||
5 | #include <stdio.h> | ||
6 | #include <stdlib.h> | ||
7 | |||
8 | #include "cgroup_helpers.h" | ||
9 | |||
10 | char bpf_log_buf[BPF_LOG_BUF_SIZE]; | ||
11 | |||
12 | #define TEST_CGROUP "/test-bpf-cgroup-storage-buf/" | ||
13 | |||
14 | int main(int argc, char **argv) | ||
15 | { | ||
16 | struct bpf_insn prog[] = { | ||
17 | BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */ | ||
18 | BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */ | ||
19 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
20 | BPF_FUNC_get_local_storage), | ||
21 | BPF_MOV64_IMM(BPF_REG_1, 1), | ||
22 | BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_1, 0), | ||
23 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), | ||
24 | BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x1), | ||
25 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), | ||
26 | BPF_EXIT_INSN(), | ||
27 | }; | ||
28 | size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn); | ||
29 | int error = EXIT_FAILURE; | ||
30 | int map_fd, prog_fd, cgroup_fd; | ||
31 | struct bpf_cgroup_storage_key key; | ||
32 | unsigned long long value; | ||
33 | |||
34 | map_fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE, sizeof(key), | ||
35 | sizeof(value), 0, 0); | ||
36 | if (map_fd < 0) { | ||
37 | printf("Failed to create map: %s\n", strerror(errno)); | ||
38 | goto out; | ||
39 | } | ||
40 | |||
41 | prog[0].imm = map_fd; | ||
42 | prog_fd = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB, | ||
43 | prog, insns_cnt, "GPL", 0, | ||
44 | bpf_log_buf, BPF_LOG_BUF_SIZE); | ||
45 | if (prog_fd < 0) { | ||
46 | printf("Failed to load bpf program: %s\n", bpf_log_buf); | ||
47 | goto out; | ||
48 | } | ||
49 | |||
50 | if (setup_cgroup_environment()) { | ||
51 | printf("Failed to setup cgroup environment\n"); | ||
52 | goto err; | ||
53 | } | ||
54 | |||
55 | /* Create a cgroup, get fd, and join it */ | ||
56 | cgroup_fd = create_and_get_cgroup(TEST_CGROUP); | ||
57 | if (!cgroup_fd) { | ||
58 | printf("Failed to create test cgroup\n"); | ||
59 | goto err; | ||
60 | } | ||
61 | |||
62 | if (join_cgroup(TEST_CGROUP)) { | ||
63 | printf("Failed to join cgroup\n"); | ||
64 | goto err; | ||
65 | } | ||
66 | |||
67 | /* Attach the bpf program */ | ||
68 | if (bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_INET_EGRESS, 0)) { | ||
69 | printf("Failed to attach bpf program\n"); | ||
70 | goto err; | ||
71 | } | ||
72 | |||
73 | if (bpf_map_get_next_key(map_fd, NULL, &key)) { | ||
74 | printf("Failed to get the first key in cgroup storage\n"); | ||
75 | goto err; | ||
76 | } | ||
77 | |||
78 | if (bpf_map_lookup_elem(map_fd, &key, &value)) { | ||
79 | printf("Failed to lookup cgroup storage\n"); | ||
80 | goto err; | ||
81 | } | ||
82 | |||
83 | /* Every second packet should be dropped */ | ||
84 | assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0); | ||
85 | assert(system("ping localhost -c 1 -W 1 -q > /dev/null")); | ||
86 | assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0); | ||
87 | |||
88 | /* Check the counter in the cgroup local storage */ | ||
89 | if (bpf_map_lookup_elem(map_fd, &key, &value)) { | ||
90 | printf("Failed to lookup cgroup storage\n"); | ||
91 | goto err; | ||
92 | } | ||
93 | |||
94 | if (value != 3) { | ||
95 | printf("Unexpected data in the cgroup storage: %llu\n", value); | ||
96 | goto err; | ||
97 | } | ||
98 | |||
99 | /* Bump the counter in the cgroup local storage */ | ||
100 | value++; | ||
101 | if (bpf_map_update_elem(map_fd, &key, &value, 0)) { | ||
102 | printf("Failed to update the data in the cgroup storage\n"); | ||
103 | goto err; | ||
104 | } | ||
105 | |||
106 | /* Every second packet should be dropped */ | ||
107 | assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0); | ||
108 | assert(system("ping localhost -c 1 -W 1 -q > /dev/null")); | ||
109 | assert(system("ping localhost -c 1 -W 1 -q > /dev/null") == 0); | ||
110 | |||
111 | /* Check the final value of the counter in the cgroup local storage */ | ||
112 | if (bpf_map_lookup_elem(map_fd, &key, &value)) { | ||
113 | printf("Failed to lookup the cgroup storage\n"); | ||
114 | goto err; | ||
115 | } | ||
116 | |||
117 | if (value != 7) { | ||
118 | printf("Unexpected data in the cgroup storage: %llu\n", value); | ||
119 | goto err; | ||
120 | } | ||
121 | |||
122 | error = 0; | ||
123 | printf("test_cgroup_storage:PASS\n"); | ||
124 | |||
125 | err: | ||
126 | cleanup_cgroup_environment(); | ||
127 | |||
128 | out: | ||
129 | return error; | ||
130 | } | ||
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index 6c253343a6f9..6f54f84144a0 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c | |||
@@ -17,7 +17,8 @@ | |||
17 | #include <stdlib.h> | 17 | #include <stdlib.h> |
18 | 18 | ||
19 | #include <sys/wait.h> | 19 | #include <sys/wait.h> |
20 | 20 | #include <sys/socket.h> | |
21 | #include <netinet/in.h> | ||
21 | #include <linux/bpf.h> | 22 | #include <linux/bpf.h> |
22 | 23 | ||
23 | #include <bpf/bpf.h> | 24 | #include <bpf/bpf.h> |
@@ -26,8 +27,21 @@ | |||
26 | #include "bpf_util.h" | 27 | #include "bpf_util.h" |
27 | #include "bpf_rlimit.h" | 28 | #include "bpf_rlimit.h" |
28 | 29 | ||
30 | #ifndef ENOTSUPP | ||
31 | #define ENOTSUPP 524 | ||
32 | #endif | ||
33 | |||
29 | static int map_flags; | 34 | static int map_flags; |
30 | 35 | ||
36 | #define CHECK(condition, tag, format...) ({ \ | ||
37 | int __ret = !!(condition); \ | ||
38 | if (__ret) { \ | ||
39 | printf("%s(%d):FAIL:%s ", __func__, __LINE__, tag); \ | ||
40 | printf(format); \ | ||
41 | exit(-1); \ | ||
42 | } \ | ||
43 | }) | ||
44 | |||
31 | static void test_hashmap(int task, void *data) | 45 | static void test_hashmap(int task, void *data) |
32 | { | 46 | { |
33 | long long key, next_key, first_key, value; | 47 | long long key, next_key, first_key, value; |
@@ -1150,6 +1164,250 @@ static void test_map_wronly(void) | |||
1150 | assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == EPERM); | 1164 | assert(bpf_map_get_next_key(fd, &key, &value) == -1 && errno == EPERM); |
1151 | } | 1165 | } |
1152 | 1166 | ||
1167 | static void prepare_reuseport_grp(int type, int map_fd, | ||
1168 | __s64 *fds64, __u64 *sk_cookies, | ||
1169 | unsigned int n) | ||
1170 | { | ||
1171 | socklen_t optlen, addrlen; | ||
1172 | struct sockaddr_in6 s6; | ||
1173 | const __u32 index0 = 0; | ||
1174 | const int optval = 1; | ||
1175 | unsigned int i; | ||
1176 | u64 sk_cookie; | ||
1177 | __s64 fd64; | ||
1178 | int err; | ||
1179 | |||
1180 | s6.sin6_family = AF_INET6; | ||
1181 | s6.sin6_addr = in6addr_any; | ||
1182 | s6.sin6_port = 0; | ||
1183 | addrlen = sizeof(s6); | ||
1184 | optlen = sizeof(sk_cookie); | ||
1185 | |||
1186 | for (i = 0; i < n; i++) { | ||
1187 | fd64 = socket(AF_INET6, type, 0); | ||
1188 | CHECK(fd64 == -1, "socket()", | ||
1189 | "sock_type:%d fd64:%lld errno:%d\n", | ||
1190 | type, fd64, errno); | ||
1191 | |||
1192 | err = setsockopt(fd64, SOL_SOCKET, SO_REUSEPORT, | ||
1193 | &optval, sizeof(optval)); | ||
1194 | CHECK(err == -1, "setsockopt(SO_REUSEPORT)", | ||
1195 | "err:%d errno:%d\n", err, errno); | ||
1196 | |||
1197 | /* reuseport_array does not allow unbound sk */ | ||
1198 | err = bpf_map_update_elem(map_fd, &index0, &fd64, | ||
1199 | BPF_ANY); | ||
1200 | CHECK(err != -1 || errno != EINVAL, | ||
1201 | "reuseport array update unbound sk", | ||
1202 | "sock_type:%d err:%d errno:%d\n", | ||
1203 | type, err, errno); | ||
1204 | |||
1205 | err = bind(fd64, (struct sockaddr *)&s6, sizeof(s6)); | ||
1206 | CHECK(err == -1, "bind()", | ||
1207 | "sock_type:%d err:%d errno:%d\n", type, err, errno); | ||
1208 | |||
1209 | if (i == 0) { | ||
1210 | err = getsockname(fd64, (struct sockaddr *)&s6, | ||
1211 | &addrlen); | ||
1212 | CHECK(err == -1, "getsockname()", | ||
1213 | "sock_type:%d err:%d errno:%d\n", | ||
1214 | type, err, errno); | ||
1215 | } | ||
1216 | |||
1217 | err = getsockopt(fd64, SOL_SOCKET, SO_COOKIE, &sk_cookie, | ||
1218 | &optlen); | ||
1219 | CHECK(err == -1, "getsockopt(SO_COOKIE)", | ||
1220 | "sock_type:%d err:%d errno:%d\n", type, err, errno); | ||
1221 | |||
1222 | if (type == SOCK_STREAM) { | ||
1223 | /* | ||
1224 | * reuseport_array does not allow | ||
1225 | * non-listening tcp sk. | ||
1226 | */ | ||
1227 | err = bpf_map_update_elem(map_fd, &index0, &fd64, | ||
1228 | BPF_ANY); | ||
1229 | CHECK(err != -1 || errno != EINVAL, | ||
1230 | "reuseport array update non-listening sk", | ||
1231 | "sock_type:%d err:%d errno:%d\n", | ||
1232 | type, err, errno); | ||
1233 | err = listen(fd64, 0); | ||
1234 | CHECK(err == -1, "listen()", | ||
1235 | "sock_type:%d, err:%d errno:%d\n", | ||
1236 | type, err, errno); | ||
1237 | } | ||
1238 | |||
1239 | fds64[i] = fd64; | ||
1240 | sk_cookies[i] = sk_cookie; | ||
1241 | } | ||
1242 | } | ||
1243 | |||
1244 | static void test_reuseport_array(void) | ||
1245 | { | ||
1246 | #define REUSEPORT_FD_IDX(err, last) ({ (err) ? last : !last; }) | ||
1247 | |||
1248 | const __u32 array_size = 4, index0 = 0, index3 = 3; | ||
1249 | int types[2] = { SOCK_STREAM, SOCK_DGRAM }, type; | ||
1250 | __u64 grpa_cookies[2], sk_cookie, map_cookie; | ||
1251 | __s64 grpa_fds64[2] = { -1, -1 }, fd64 = -1; | ||
1252 | const __u32 bad_index = array_size; | ||
1253 | int map_fd, err, t, f; | ||
1254 | __u32 fds_idx = 0; | ||
1255 | int fd; | ||
1256 | |||
1257 | map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, | ||
1258 | sizeof(__u32), sizeof(__u64), array_size, 0); | ||
1259 | CHECK(map_fd == -1, "reuseport array create", | ||
1260 | "map_fd:%d, errno:%d\n", map_fd, errno); | ||
1261 | |||
1262 | /* Test lookup/update/delete with invalid index */ | ||
1263 | err = bpf_map_delete_elem(map_fd, &bad_index); | ||
1264 | CHECK(err != -1 || errno != E2BIG, "reuseport array del >=max_entries", | ||
1265 | "err:%d errno:%d\n", err, errno); | ||
1266 | |||
1267 | err = bpf_map_update_elem(map_fd, &bad_index, &fd64, BPF_ANY); | ||
1268 | CHECK(err != -1 || errno != E2BIG, | ||
1269 | "reuseport array update >=max_entries", | ||
1270 | "err:%d errno:%d\n", err, errno); | ||
1271 | |||
1272 | err = bpf_map_lookup_elem(map_fd, &bad_index, &map_cookie); | ||
1273 | CHECK(err != -1 || errno != ENOENT, | ||
1274 | "reuseport array update >=max_entries", | ||
1275 | "err:%d errno:%d\n", err, errno); | ||
1276 | |||
1277 | /* Test lookup/delete non existence elem */ | ||
1278 | err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie); | ||
1279 | CHECK(err != -1 || errno != ENOENT, | ||
1280 | "reuseport array lookup not-exist elem", | ||
1281 | "err:%d errno:%d\n", err, errno); | ||
1282 | err = bpf_map_delete_elem(map_fd, &index3); | ||
1283 | CHECK(err != -1 || errno != ENOENT, | ||
1284 | "reuseport array del not-exist elem", | ||
1285 | "err:%d errno:%d\n", err, errno); | ||
1286 | |||
1287 | for (t = 0; t < ARRAY_SIZE(types); t++) { | ||
1288 | type = types[t]; | ||
1289 | |||
1290 | prepare_reuseport_grp(type, map_fd, grpa_fds64, | ||
1291 | grpa_cookies, ARRAY_SIZE(grpa_fds64)); | ||
1292 | |||
1293 | /* Test BPF_* update flags */ | ||
1294 | /* BPF_EXIST failure case */ | ||
1295 | err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx], | ||
1296 | BPF_EXIST); | ||
1297 | CHECK(err != -1 || errno != ENOENT, | ||
1298 | "reuseport array update empty elem BPF_EXIST", | ||
1299 | "sock_type:%d err:%d errno:%d\n", | ||
1300 | type, err, errno); | ||
1301 | fds_idx = REUSEPORT_FD_IDX(err, fds_idx); | ||
1302 | |||
1303 | /* BPF_NOEXIST success case */ | ||
1304 | err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx], | ||
1305 | BPF_NOEXIST); | ||
1306 | CHECK(err == -1, | ||
1307 | "reuseport array update empty elem BPF_NOEXIST", | ||
1308 | "sock_type:%d err:%d errno:%d\n", | ||
1309 | type, err, errno); | ||
1310 | fds_idx = REUSEPORT_FD_IDX(err, fds_idx); | ||
1311 | |||
1312 | /* BPF_EXIST success case. */ | ||
1313 | err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx], | ||
1314 | BPF_EXIST); | ||
1315 | CHECK(err == -1, | ||
1316 | "reuseport array update same elem BPF_EXIST", | ||
1317 | "sock_type:%d err:%d errno:%d\n", type, err, errno); | ||
1318 | fds_idx = REUSEPORT_FD_IDX(err, fds_idx); | ||
1319 | |||
1320 | /* BPF_NOEXIST failure case */ | ||
1321 | err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx], | ||
1322 | BPF_NOEXIST); | ||
1323 | CHECK(err != -1 || errno != EEXIST, | ||
1324 | "reuseport array update non-empty elem BPF_NOEXIST", | ||
1325 | "sock_type:%d err:%d errno:%d\n", | ||
1326 | type, err, errno); | ||
1327 | fds_idx = REUSEPORT_FD_IDX(err, fds_idx); | ||
1328 | |||
1329 | /* BPF_ANY case (always succeed) */ | ||
1330 | err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx], | ||
1331 | BPF_ANY); | ||
1332 | CHECK(err == -1, | ||
1333 | "reuseport array update same sk with BPF_ANY", | ||
1334 | "sock_type:%d err:%d errno:%d\n", type, err, errno); | ||
1335 | |||
1336 | fd64 = grpa_fds64[fds_idx]; | ||
1337 | sk_cookie = grpa_cookies[fds_idx]; | ||
1338 | |||
1339 | /* The same sk cannot be added to reuseport_array twice */ | ||
1340 | err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_ANY); | ||
1341 | CHECK(err != -1 || errno != EBUSY, | ||
1342 | "reuseport array update same sk with same index", | ||
1343 | "sock_type:%d err:%d errno:%d\n", | ||
1344 | type, err, errno); | ||
1345 | |||
1346 | err = bpf_map_update_elem(map_fd, &index0, &fd64, BPF_ANY); | ||
1347 | CHECK(err != -1 || errno != EBUSY, | ||
1348 | "reuseport array update same sk with different index", | ||
1349 | "sock_type:%d err:%d errno:%d\n", | ||
1350 | type, err, errno); | ||
1351 | |||
1352 | /* Test delete elem */ | ||
1353 | err = bpf_map_delete_elem(map_fd, &index3); | ||
1354 | CHECK(err == -1, "reuseport array delete sk", | ||
1355 | "sock_type:%d err:%d errno:%d\n", | ||
1356 | type, err, errno); | ||
1357 | |||
1358 | /* Add it back with BPF_NOEXIST */ | ||
1359 | err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST); | ||
1360 | CHECK(err == -1, | ||
1361 | "reuseport array re-add with BPF_NOEXIST after del", | ||
1362 | "sock_type:%d err:%d errno:%d\n", type, err, errno); | ||
1363 | |||
1364 | /* Test cookie */ | ||
1365 | err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie); | ||
1366 | CHECK(err == -1 || sk_cookie != map_cookie, | ||
1367 | "reuseport array lookup re-added sk", | ||
1368 | "sock_type:%d err:%d errno:%d sk_cookie:0x%llx map_cookie:0x%llxn", | ||
1369 | type, err, errno, sk_cookie, map_cookie); | ||
1370 | |||
1371 | /* Test elem removed by close() */ | ||
1372 | for (f = 0; f < ARRAY_SIZE(grpa_fds64); f++) | ||
1373 | close(grpa_fds64[f]); | ||
1374 | err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie); | ||
1375 | CHECK(err != -1 || errno != ENOENT, | ||
1376 | "reuseport array lookup after close()", | ||
1377 | "sock_type:%d err:%d errno:%d\n", | ||
1378 | type, err, errno); | ||
1379 | } | ||
1380 | |||
1381 | /* Test SOCK_RAW */ | ||
1382 | fd64 = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP); | ||
1383 | CHECK(fd64 == -1, "socket(SOCK_RAW)", "err:%d errno:%d\n", | ||
1384 | err, errno); | ||
1385 | err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST); | ||
1386 | CHECK(err != -1 || errno != ENOTSUPP, "reuseport array update SOCK_RAW", | ||
1387 | "err:%d errno:%d\n", err, errno); | ||
1388 | close(fd64); | ||
1389 | |||
1390 | /* Close the 64 bit value map */ | ||
1391 | close(map_fd); | ||
1392 | |||
1393 | /* Test 32 bit fd */ | ||
1394 | map_fd = bpf_create_map(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, | ||
1395 | sizeof(__u32), sizeof(__u32), array_size, 0); | ||
1396 | CHECK(map_fd == -1, "reuseport array create", | ||
1397 | "map_fd:%d, errno:%d\n", map_fd, errno); | ||
1398 | prepare_reuseport_grp(SOCK_STREAM, map_fd, &fd64, &sk_cookie, 1); | ||
1399 | fd = fd64; | ||
1400 | err = bpf_map_update_elem(map_fd, &index3, &fd, BPF_NOEXIST); | ||
1401 | CHECK(err == -1, "reuseport array update 32 bit fd", | ||
1402 | "err:%d errno:%d\n", err, errno); | ||
1403 | err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie); | ||
1404 | CHECK(err != -1 || errno != ENOSPC, | ||
1405 | "reuseport array lookup 32 bit fd", | ||
1406 | "err:%d errno:%d\n", err, errno); | ||
1407 | close(fd); | ||
1408 | close(map_fd); | ||
1409 | } | ||
1410 | |||
1153 | static void run_all_tests(void) | 1411 | static void run_all_tests(void) |
1154 | { | 1412 | { |
1155 | test_hashmap(0, NULL); | 1413 | test_hashmap(0, NULL); |
@@ -1170,6 +1428,8 @@ static void run_all_tests(void) | |||
1170 | 1428 | ||
1171 | test_map_rdonly(); | 1429 | test_map_rdonly(); |
1172 | test_map_wronly(); | 1430 | test_map_wronly(); |
1431 | |||
1432 | test_reuseport_array(); | ||
1173 | } | 1433 | } |
1174 | 1434 | ||
1175 | int main(void) | 1435 | int main(void) |
diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py index be800d0e7a84..d59642e70f56 100755 --- a/tools/testing/selftests/bpf/test_offload.py +++ b/tools/testing/selftests/bpf/test_offload.py | |||
@@ -158,8 +158,9 @@ def tool(name, args, flags, JSON=True, ns="", fail=True, include_stderr=False): | |||
158 | else: | 158 | else: |
159 | return ret, out | 159 | return ret, out |
160 | 160 | ||
161 | def bpftool(args, JSON=True, ns="", fail=True): | 161 | def bpftool(args, JSON=True, ns="", fail=True, include_stderr=False): |
162 | return tool("bpftool", args, {"json":"-p"}, JSON=JSON, ns=ns, fail=fail) | 162 | return tool("bpftool", args, {"json":"-p"}, JSON=JSON, ns=ns, |
163 | fail=fail, include_stderr=include_stderr) | ||
163 | 164 | ||
164 | def bpftool_prog_list(expected=None, ns=""): | 165 | def bpftool_prog_list(expected=None, ns=""): |
165 | _, progs = bpftool("prog show", JSON=True, ns=ns, fail=True) | 166 | _, progs = bpftool("prog show", JSON=True, ns=ns, fail=True) |
@@ -201,6 +202,21 @@ def bpftool_map_list_wait(expected=0, n_retry=20): | |||
201 | time.sleep(0.05) | 202 | time.sleep(0.05) |
202 | raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps)) | 203 | raise Exception("Time out waiting for map counts to stabilize want %d, have %d" % (expected, nmaps)) |
203 | 204 | ||
205 | def bpftool_prog_load(sample, file_name, maps=[], prog_type="xdp", dev=None, | ||
206 | fail=True, include_stderr=False): | ||
207 | args = "prog load %s %s" % (os.path.join(bpf_test_dir, sample), file_name) | ||
208 | if prog_type is not None: | ||
209 | args += " type " + prog_type | ||
210 | if dev is not None: | ||
211 | args += " dev " + dev | ||
212 | if len(maps): | ||
213 | args += " map " + " map ".join(maps) | ||
214 | |||
215 | res = bpftool(args, fail=fail, include_stderr=include_stderr) | ||
216 | if res[0] == 0: | ||
217 | files.append(file_name) | ||
218 | return res | ||
219 | |||
204 | def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False): | 220 | def ip(args, force=False, JSON=True, ns="", fail=True, include_stderr=False): |
205 | if force: | 221 | if force: |
206 | args = "-force " + args | 222 | args = "-force " + args |
@@ -307,21 +323,25 @@ class NetdevSim: | |||
307 | Class for netdevsim netdevice and its attributes. | 323 | Class for netdevsim netdevice and its attributes. |
308 | """ | 324 | """ |
309 | 325 | ||
310 | def __init__(self): | 326 | def __init__(self, link=None): |
327 | self.link = link | ||
328 | |||
311 | self.dev = self._netdevsim_create() | 329 | self.dev = self._netdevsim_create() |
312 | devs.append(self) | 330 | devs.append(self) |
313 | 331 | ||
314 | self.ns = "" | 332 | self.ns = "" |
315 | 333 | ||
316 | self.dfs_dir = '/sys/kernel/debug/netdevsim/%s' % (self.dev['ifname']) | 334 | self.dfs_dir = '/sys/kernel/debug/netdevsim/%s' % (self.dev['ifname']) |
335 | self.sdev_dir = self.dfs_dir + '/sdev/' | ||
317 | self.dfs_refresh() | 336 | self.dfs_refresh() |
318 | 337 | ||
319 | def __getitem__(self, key): | 338 | def __getitem__(self, key): |
320 | return self.dev[key] | 339 | return self.dev[key] |
321 | 340 | ||
322 | def _netdevsim_create(self): | 341 | def _netdevsim_create(self): |
342 | link = "" if self.link is None else "link " + self.link.dev['ifname'] | ||
323 | _, old = ip("link show") | 343 | _, old = ip("link show") |
324 | ip("link add sim%d type netdevsim") | 344 | ip("link add sim%d {link} type netdevsim".format(link=link)) |
325 | _, new = ip("link show") | 345 | _, new = ip("link show") |
326 | 346 | ||
327 | for dev in new: | 347 | for dev in new: |
@@ -339,13 +359,18 @@ class NetdevSim: | |||
339 | self.dfs = DebugfsDir(self.dfs_dir) | 359 | self.dfs = DebugfsDir(self.dfs_dir) |
340 | return self.dfs | 360 | return self.dfs |
341 | 361 | ||
362 | def dfs_read(self, f): | ||
363 | path = os.path.join(self.dfs_dir, f) | ||
364 | _, data = cmd('cat %s' % (path)) | ||
365 | return data.strip() | ||
366 | |||
342 | def dfs_num_bound_progs(self): | 367 | def dfs_num_bound_progs(self): |
343 | path = os.path.join(self.dfs_dir, "bpf_bound_progs") | 368 | path = os.path.join(self.sdev_dir, "bpf_bound_progs") |
344 | _, progs = cmd('ls %s' % (path)) | 369 | _, progs = cmd('ls %s' % (path)) |
345 | return len(progs.split()) | 370 | return len(progs.split()) |
346 | 371 | ||
347 | def dfs_get_bound_progs(self, expected): | 372 | def dfs_get_bound_progs(self, expected): |
348 | progs = DebugfsDir(os.path.join(self.dfs_dir, "bpf_bound_progs")) | 373 | progs = DebugfsDir(os.path.join(self.sdev_dir, "bpf_bound_progs")) |
349 | if expected is not None: | 374 | if expected is not None: |
350 | if len(progs) != expected: | 375 | if len(progs) != expected: |
351 | fail(True, "%d BPF programs bound, expected %d" % | 376 | fail(True, "%d BPF programs bound, expected %d" % |
@@ -547,11 +572,11 @@ def check_extack(output, reference, args): | |||
547 | if skip_extack: | 572 | if skip_extack: |
548 | return | 573 | return |
549 | lines = output.split("\n") | 574 | lines = output.split("\n") |
550 | comp = len(lines) >= 2 and lines[1] == reference | 575 | comp = len(lines) >= 2 and lines[1] == 'Error: ' + reference |
551 | fail(not comp, "Missing or incorrect netlink extack message") | 576 | fail(not comp, "Missing or incorrect netlink extack message") |
552 | 577 | ||
553 | def check_extack_nsim(output, reference, args): | 578 | def check_extack_nsim(output, reference, args): |
554 | check_extack(output, "Error: netdevsim: " + reference, args) | 579 | check_extack(output, "netdevsim: " + reference, args) |
555 | 580 | ||
556 | def check_no_extack(res, needle): | 581 | def check_no_extack(res, needle): |
557 | fail((res[1] + res[2]).count(needle) or (res[1] + res[2]).count("Warning:"), | 582 | fail((res[1] + res[2]).count(needle) or (res[1] + res[2]).count("Warning:"), |
@@ -654,7 +679,7 @@ try: | |||
654 | ret, _, err = sim.cls_bpf_add_filter(obj, skip_sw=True, | 679 | ret, _, err = sim.cls_bpf_add_filter(obj, skip_sw=True, |
655 | fail=False, include_stderr=True) | 680 | fail=False, include_stderr=True) |
656 | fail(ret == 0, "TC filter loaded without enabling TC offloads") | 681 | fail(ret == 0, "TC filter loaded without enabling TC offloads") |
657 | check_extack(err, "Error: TC offload is disabled on net device.", args) | 682 | check_extack(err, "TC offload is disabled on net device.", args) |
658 | sim.wait_for_flush() | 683 | sim.wait_for_flush() |
659 | 684 | ||
660 | sim.set_ethtool_tc_offloads(True) | 685 | sim.set_ethtool_tc_offloads(True) |
@@ -694,7 +719,7 @@ try: | |||
694 | skip_sw=True, | 719 | skip_sw=True, |
695 | fail=False, include_stderr=True) | 720 | fail=False, include_stderr=True) |
696 | fail(ret == 0, "Offloaded a filter to chain other than 0") | 721 | fail(ret == 0, "Offloaded a filter to chain other than 0") |
697 | check_extack(err, "Error: Driver supports only offload of chain 0.", args) | 722 | check_extack(err, "Driver supports only offload of chain 0.", args) |
698 | sim.tc_flush_filters() | 723 | sim.tc_flush_filters() |
699 | 724 | ||
700 | start_test("Test TC replace...") | 725 | start_test("Test TC replace...") |
@@ -814,24 +839,20 @@ try: | |||
814 | "Device parameters reported for non-offloaded program") | 839 | "Device parameters reported for non-offloaded program") |
815 | 840 | ||
816 | start_test("Test XDP prog replace with bad flags...") | 841 | start_test("Test XDP prog replace with bad flags...") |
817 | ret, _, err = sim.set_xdp(obj, "offload", force=True, | 842 | ret, _, err = sim.set_xdp(obj, "generic", force=True, |
818 | fail=False, include_stderr=True) | 843 | fail=False, include_stderr=True) |
819 | fail(ret == 0, "Replaced XDP program with a program in different mode") | 844 | fail(ret == 0, "Replaced XDP program with a program in different mode") |
820 | check_extack_nsim(err, "program loaded with different flags.", args) | 845 | fail(err.count("File exists") != 1, "Replaced driver XDP with generic") |
821 | ret, _, err = sim.set_xdp(obj, "", force=True, | 846 | ret, _, err = sim.set_xdp(obj, "", force=True, |
822 | fail=False, include_stderr=True) | 847 | fail=False, include_stderr=True) |
823 | fail(ret == 0, "Replaced XDP program with a program in different mode") | 848 | fail(ret == 0, "Replaced XDP program with a program in different mode") |
824 | check_extack_nsim(err, "program loaded with different flags.", args) | 849 | check_extack(err, "program loaded with different flags.", args) |
825 | 850 | ||
826 | start_test("Test XDP prog remove with bad flags...") | 851 | start_test("Test XDP prog remove with bad flags...") |
827 | ret, _, err = sim.unset_xdp("offload", force=True, | ||
828 | fail=False, include_stderr=True) | ||
829 | fail(ret == 0, "Removed program with a bad mode mode") | ||
830 | check_extack_nsim(err, "program loaded with different flags.", args) | ||
831 | ret, _, err = sim.unset_xdp("", force=True, | 852 | ret, _, err = sim.unset_xdp("", force=True, |
832 | fail=False, include_stderr=True) | 853 | fail=False, include_stderr=True) |
833 | fail(ret == 0, "Removed program with a bad mode mode") | 854 | fail(ret == 0, "Removed program with a bad mode") |
834 | check_extack_nsim(err, "program loaded with different flags.", args) | 855 | check_extack(err, "program loaded with different flags.", args) |
835 | 856 | ||
836 | start_test("Test MTU restrictions...") | 857 | start_test("Test MTU restrictions...") |
837 | ret, _ = sim.set_mtu(9000, fail=False) | 858 | ret, _ = sim.set_mtu(9000, fail=False) |
@@ -846,6 +867,25 @@ try: | |||
846 | sim.set_mtu(1500) | 867 | sim.set_mtu(1500) |
847 | 868 | ||
848 | sim.wait_for_flush() | 869 | sim.wait_for_flush() |
870 | start_test("Test non-offload XDP attaching to HW...") | ||
871 | bpftool_prog_load("sample_ret0.o", "/sys/fs/bpf/nooffload") | ||
872 | nooffload = bpf_pinned("/sys/fs/bpf/nooffload") | ||
873 | ret, _, err = sim.set_xdp(nooffload, "offload", | ||
874 | fail=False, include_stderr=True) | ||
875 | fail(ret == 0, "attached non-offloaded XDP program to HW") | ||
876 | check_extack_nsim(err, "xdpoffload of non-bound program.", args) | ||
877 | rm("/sys/fs/bpf/nooffload") | ||
878 | |||
879 | start_test("Test offload XDP attaching to drv...") | ||
880 | bpftool_prog_load("sample_ret0.o", "/sys/fs/bpf/offload", | ||
881 | dev=sim['ifname']) | ||
882 | offload = bpf_pinned("/sys/fs/bpf/offload") | ||
883 | ret, _, err = sim.set_xdp(offload, "drv", fail=False, include_stderr=True) | ||
884 | fail(ret == 0, "attached offloaded XDP program to drv") | ||
885 | check_extack(err, "using device-bound program without HW_MODE flag is not supported.", args) | ||
886 | rm("/sys/fs/bpf/offload") | ||
887 | sim.wait_for_flush() | ||
888 | |||
849 | start_test("Test XDP offload...") | 889 | start_test("Test XDP offload...") |
850 | _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True) | 890 | _, _, err = sim.set_xdp(obj, "offload", verbose=True, include_stderr=True) |
851 | ipl = sim.ip_link_show(xdp=True) | 891 | ipl = sim.ip_link_show(xdp=True) |
@@ -891,6 +931,60 @@ try: | |||
891 | rm(pin_file) | 931 | rm(pin_file) |
892 | bpftool_prog_list_wait(expected=0) | 932 | bpftool_prog_list_wait(expected=0) |
893 | 933 | ||
934 | start_test("Test multi-attachment XDP - attach...") | ||
935 | sim.set_xdp(obj, "offload") | ||
936 | xdp = sim.ip_link_show(xdp=True)["xdp"] | ||
937 | offloaded = sim.dfs_read("bpf_offloaded_id") | ||
938 | fail("prog" not in xdp, "Base program not reported in single program mode") | ||
939 | fail(len(ipl["xdp"]["attached"]) != 1, | ||
940 | "Wrong attached program count with one program") | ||
941 | |||
942 | sim.set_xdp(obj, "") | ||
943 | two_xdps = sim.ip_link_show(xdp=True)["xdp"] | ||
944 | offloaded2 = sim.dfs_read("bpf_offloaded_id") | ||
945 | |||
946 | fail(two_xdps["mode"] != 4, "Bad mode reported with multiple programs") | ||
947 | fail("prog" in two_xdps, "Base program reported in multi program mode") | ||
948 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
949 | "Offload program not reported after driver activated") | ||
950 | fail(len(two_xdps["attached"]) != 2, | ||
951 | "Wrong attached program count with two programs") | ||
952 | fail(two_xdps["attached"][0]["prog"]["id"] == | ||
953 | two_xdps["attached"][1]["prog"]["id"], | ||
954 | "offloaded and drv programs have the same id") | ||
955 | fail(offloaded != offloaded2, | ||
956 | "offload ID changed after loading driver program") | ||
957 | |||
958 | start_test("Test multi-attachment XDP - replace...") | ||
959 | ret, _, err = sim.set_xdp(obj, "offload", fail=False, include_stderr=True) | ||
960 | fail(err.count("busy") != 1, "Replaced one of programs without -force") | ||
961 | |||
962 | start_test("Test multi-attachment XDP - detach...") | ||
963 | ret, _, err = sim.unset_xdp("drv", force=True, | ||
964 | fail=False, include_stderr=True) | ||
965 | fail(ret == 0, "Removed program with a bad mode") | ||
966 | check_extack(err, "program loaded with different flags.", args) | ||
967 | |||
968 | sim.unset_xdp("offload") | ||
969 | xdp = sim.ip_link_show(xdp=True)["xdp"] | ||
970 | offloaded = sim.dfs_read("bpf_offloaded_id") | ||
971 | |||
972 | fail(xdp["mode"] != 1, "Bad mode reported after multiple programs") | ||
973 | fail("prog" not in xdp, | ||
974 | "Base program not reported after multi program mode") | ||
975 | fail(xdp["attached"][0] not in two_xdps["attached"], | ||
976 | "Offload program not reported after driver activated") | ||
977 | fail(len(ipl["xdp"]["attached"]) != 1, | ||
978 | "Wrong attached program count with remaining programs") | ||
979 | fail(offloaded != "0", "offload ID reported with only driver program left") | ||
980 | |||
981 | start_test("Test multi-attachment XDP - device remove...") | ||
982 | sim.set_xdp(obj, "offload") | ||
983 | sim.remove() | ||
984 | |||
985 | sim = NetdevSim() | ||
986 | sim.set_ethtool_tc_offloads(True) | ||
987 | |||
894 | start_test("Test mixing of TC and XDP...") | 988 | start_test("Test mixing of TC and XDP...") |
895 | sim.tc_add_ingress() | 989 | sim.tc_add_ingress() |
896 | sim.set_xdp(obj, "offload") | 990 | sim.set_xdp(obj, "offload") |
@@ -1085,6 +1179,106 @@ try: | |||
1085 | fail(ret == 0, | 1179 | fail(ret == 0, |
1086 | "netdevsim didn't refuse to create a map with offload disabled") | 1180 | "netdevsim didn't refuse to create a map with offload disabled") |
1087 | 1181 | ||
1182 | sim.remove() | ||
1183 | |||
1184 | start_test("Test multi-dev ASIC program reuse...") | ||
1185 | simA = NetdevSim() | ||
1186 | simB1 = NetdevSim() | ||
1187 | simB2 = NetdevSim(link=simB1) | ||
1188 | simB3 = NetdevSim(link=simB1) | ||
1189 | sims = (simA, simB1, simB2, simB3) | ||
1190 | simB = (simB1, simB2, simB3) | ||
1191 | |||
1192 | bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimA", | ||
1193 | dev=simA['ifname']) | ||
1194 | progA = bpf_pinned("/sys/fs/bpf/nsimA") | ||
1195 | bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB", | ||
1196 | dev=simB1['ifname']) | ||
1197 | progB = bpf_pinned("/sys/fs/bpf/nsimB") | ||
1198 | |||
1199 | simA.set_xdp(progA, "offload", JSON=False) | ||
1200 | for d in simB: | ||
1201 | d.set_xdp(progB, "offload", JSON=False) | ||
1202 | |||
1203 | start_test("Test multi-dev ASIC cross-dev replace...") | ||
1204 | ret, _ = simA.set_xdp(progB, "offload", force=True, JSON=False, fail=False) | ||
1205 | fail(ret == 0, "cross-ASIC program allowed") | ||
1206 | for d in simB: | ||
1207 | ret, _ = d.set_xdp(progA, "offload", force=True, JSON=False, fail=False) | ||
1208 | fail(ret == 0, "cross-ASIC program allowed") | ||
1209 | |||
1210 | start_test("Test multi-dev ASIC cross-dev install...") | ||
1211 | for d in sims: | ||
1212 | d.unset_xdp("offload") | ||
1213 | |||
1214 | ret, _, err = simA.set_xdp(progB, "offload", force=True, JSON=False, | ||
1215 | fail=False, include_stderr=True) | ||
1216 | fail(ret == 0, "cross-ASIC program allowed") | ||
1217 | check_extack_nsim(err, "program bound to different dev.", args) | ||
1218 | for d in simB: | ||
1219 | ret, _, err = d.set_xdp(progA, "offload", force=True, JSON=False, | ||
1220 | fail=False, include_stderr=True) | ||
1221 | fail(ret == 0, "cross-ASIC program allowed") | ||
1222 | check_extack_nsim(err, "program bound to different dev.", args) | ||
1223 | |||
1224 | start_test("Test multi-dev ASIC cross-dev map reuse...") | ||
1225 | |||
1226 | mapA = bpftool("prog show %s" % (progA))[1]["map_ids"][0] | ||
1227 | mapB = bpftool("prog show %s" % (progB))[1]["map_ids"][0] | ||
1228 | |||
1229 | ret, _ = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB_", | ||
1230 | dev=simB3['ifname'], | ||
1231 | maps=["idx 0 id %d" % (mapB)], | ||
1232 | fail=False) | ||
1233 | fail(ret != 0, "couldn't reuse a map on the same ASIC") | ||
1234 | rm("/sys/fs/bpf/nsimB_") | ||
1235 | |||
1236 | ret, _, err = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimA_", | ||
1237 | dev=simA['ifname'], | ||
1238 | maps=["idx 0 id %d" % (mapB)], | ||
1239 | fail=False, include_stderr=True) | ||
1240 | fail(ret == 0, "could reuse a map on a different ASIC") | ||
1241 | fail(err.count("offload device mismatch between prog and map") == 0, | ||
1242 | "error message missing for cross-ASIC map") | ||
1243 | |||
1244 | ret, _, err = bpftool_prog_load("sample_map_ret0.o", "/sys/fs/bpf/nsimB_", | ||
1245 | dev=simB1['ifname'], | ||
1246 | maps=["idx 0 id %d" % (mapA)], | ||
1247 | fail=False, include_stderr=True) | ||
1248 | fail(ret == 0, "could reuse a map on a different ASIC") | ||
1249 | fail(err.count("offload device mismatch between prog and map") == 0, | ||
1250 | "error message missing for cross-ASIC map") | ||
1251 | |||
1252 | start_test("Test multi-dev ASIC cross-dev destruction...") | ||
1253 | bpftool_prog_list_wait(expected=2) | ||
1254 | |||
1255 | simA.remove() | ||
1256 | bpftool_prog_list_wait(expected=1) | ||
1257 | |||
1258 | ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"] | ||
1259 | fail(ifnameB != simB1['ifname'], "program not bound to originial device") | ||
1260 | simB1.remove() | ||
1261 | bpftool_prog_list_wait(expected=1) | ||
1262 | |||
1263 | start_test("Test multi-dev ASIC cross-dev destruction - move...") | ||
1264 | ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"] | ||
1265 | fail(ifnameB not in (simB2['ifname'], simB3['ifname']), | ||
1266 | "program not bound to remaining devices") | ||
1267 | |||
1268 | simB2.remove() | ||
1269 | ifnameB = bpftool("prog show %s" % (progB))[1]["dev"]["ifname"] | ||
1270 | fail(ifnameB != simB3['ifname'], "program not bound to remaining device") | ||
1271 | |||
1272 | simB3.remove() | ||
1273 | bpftool_prog_list_wait(expected=0) | ||
1274 | |||
1275 | start_test("Test multi-dev ASIC cross-dev destruction - orphaned...") | ||
1276 | ret, out = bpftool("prog show %s" % (progB), fail=False) | ||
1277 | fail(ret == 0, "got information about orphaned program") | ||
1278 | fail("error" not in out, "no error reported for get info on orphaned") | ||
1279 | fail(out["error"] != "can't get prog info: No such device", | ||
1280 | "wrong error for get info on orphaned") | ||
1281 | |||
1088 | print("%s: OK" % (os.path.basename(__file__))) | 1282 | print("%s: OK" % (os.path.basename(__file__))) |
1089 | 1283 | ||
1090 | finally: | 1284 | finally: |
diff --git a/tools/testing/selftests/bpf/test_select_reuseport.c b/tools/testing/selftests/bpf/test_select_reuseport.c new file mode 100644 index 000000000000..75646d9b34aa --- /dev/null +++ b/tools/testing/selftests/bpf/test_select_reuseport.c | |||
@@ -0,0 +1,688 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* Copyright (c) 2018 Facebook */ | ||
3 | |||
4 | #include <stdlib.h> | ||
5 | #include <unistd.h> | ||
6 | #include <stdbool.h> | ||
7 | #include <string.h> | ||
8 | #include <errno.h> | ||
9 | #include <assert.h> | ||
10 | #include <fcntl.h> | ||
11 | #include <linux/bpf.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/if_ether.h> | ||
15 | #include <sys/types.h> | ||
16 | #include <sys/epoll.h> | ||
17 | #include <sys/socket.h> | ||
18 | #include <netinet/in.h> | ||
19 | #include <bpf/bpf.h> | ||
20 | #include <bpf/libbpf.h> | ||
21 | #include "bpf_rlimit.h" | ||
22 | #include "bpf_util.h" | ||
23 | #include "test_select_reuseport_common.h" | ||
24 | |||
25 | #define MIN_TCPHDR_LEN 20 | ||
26 | #define UDPHDR_LEN 8 | ||
27 | |||
28 | #define TCP_SYNCOOKIE_SYSCTL "/proc/sys/net/ipv4/tcp_syncookies" | ||
29 | #define TCP_FO_SYSCTL "/proc/sys/net/ipv4/tcp_fastopen" | ||
30 | #define REUSEPORT_ARRAY_SIZE 32 | ||
31 | |||
32 | static int result_map, tmp_index_ovr_map, linum_map, data_check_map; | ||
33 | static enum result expected_results[NR_RESULTS]; | ||
34 | static int sk_fds[REUSEPORT_ARRAY_SIZE]; | ||
35 | static int reuseport_array, outer_map; | ||
36 | static int select_by_skb_data_prog; | ||
37 | static int saved_tcp_syncookie; | ||
38 | static struct bpf_object *obj; | ||
39 | static int saved_tcp_fo; | ||
40 | static __u32 index_zero; | ||
41 | static int epfd; | ||
42 | |||
43 | static union sa46 { | ||
44 | struct sockaddr_in6 v6; | ||
45 | struct sockaddr_in v4; | ||
46 | sa_family_t family; | ||
47 | } srv_sa; | ||
48 | |||
49 | #define CHECK(condition, tag, format...) ({ \ | ||
50 | int __ret = !!(condition); \ | ||
51 | if (__ret) { \ | ||
52 | printf("%s(%d):FAIL:%s ", __func__, __LINE__, tag); \ | ||
53 | printf(format); \ | ||
54 | exit(-1); \ | ||
55 | } \ | ||
56 | }) | ||
57 | |||
58 | static void create_maps(void) | ||
59 | { | ||
60 | struct bpf_create_map_attr attr = {}; | ||
61 | |||
62 | /* Creating reuseport_array */ | ||
63 | attr.name = "reuseport_array"; | ||
64 | attr.map_type = BPF_MAP_TYPE_REUSEPORT_SOCKARRAY; | ||
65 | attr.key_size = sizeof(__u32); | ||
66 | attr.value_size = sizeof(__u32); | ||
67 | attr.max_entries = REUSEPORT_ARRAY_SIZE; | ||
68 | |||
69 | reuseport_array = bpf_create_map_xattr(&attr); | ||
70 | CHECK(reuseport_array == -1, "creating reuseport_array", | ||
71 | "reuseport_array:%d errno:%d\n", reuseport_array, errno); | ||
72 | |||
73 | /* Creating outer_map */ | ||
74 | attr.name = "outer_map"; | ||
75 | attr.map_type = BPF_MAP_TYPE_ARRAY_OF_MAPS; | ||
76 | attr.key_size = sizeof(__u32); | ||
77 | attr.value_size = sizeof(__u32); | ||
78 | attr.max_entries = 1; | ||
79 | attr.inner_map_fd = reuseport_array; | ||
80 | outer_map = bpf_create_map_xattr(&attr); | ||
81 | CHECK(outer_map == -1, "creating outer_map", | ||
82 | "outer_map:%d errno:%d\n", outer_map, errno); | ||
83 | } | ||
84 | |||
85 | static void prepare_bpf_obj(void) | ||
86 | { | ||
87 | struct bpf_program *prog; | ||
88 | struct bpf_map *map; | ||
89 | int err; | ||
90 | struct bpf_object_open_attr attr = { | ||
91 | .file = "test_select_reuseport_kern.o", | ||
92 | .prog_type = BPF_PROG_TYPE_SK_REUSEPORT, | ||
93 | }; | ||
94 | |||
95 | obj = bpf_object__open_xattr(&attr); | ||
96 | CHECK(IS_ERR_OR_NULL(obj), "open test_select_reuseport_kern.o", | ||
97 | "obj:%p PTR_ERR(obj):%ld\n", obj, PTR_ERR(obj)); | ||
98 | |||
99 | prog = bpf_program__next(NULL, obj); | ||
100 | CHECK(!prog, "get first bpf_program", "!prog\n"); | ||
101 | bpf_program__set_type(prog, attr.prog_type); | ||
102 | |||
103 | map = bpf_object__find_map_by_name(obj, "outer_map"); | ||
104 | CHECK(!map, "find outer_map", "!map\n"); | ||
105 | err = bpf_map__reuse_fd(map, outer_map); | ||
106 | CHECK(err, "reuse outer_map", "err:%d\n", err); | ||
107 | |||
108 | err = bpf_object__load(obj); | ||
109 | CHECK(err, "load bpf_object", "err:%d\n", err); | ||
110 | |||
111 | select_by_skb_data_prog = bpf_program__fd(prog); | ||
112 | CHECK(select_by_skb_data_prog == -1, "get prog fd", | ||
113 | "select_by_skb_data_prog:%d\n", select_by_skb_data_prog); | ||
114 | |||
115 | map = bpf_object__find_map_by_name(obj, "result_map"); | ||
116 | CHECK(!map, "find result_map", "!map\n"); | ||
117 | result_map = bpf_map__fd(map); | ||
118 | CHECK(result_map == -1, "get result_map fd", | ||
119 | "result_map:%d\n", result_map); | ||
120 | |||
121 | map = bpf_object__find_map_by_name(obj, "tmp_index_ovr_map"); | ||
122 | CHECK(!map, "find tmp_index_ovr_map", "!map\n"); | ||
123 | tmp_index_ovr_map = bpf_map__fd(map); | ||
124 | CHECK(tmp_index_ovr_map == -1, "get tmp_index_ovr_map fd", | ||
125 | "tmp_index_ovr_map:%d\n", tmp_index_ovr_map); | ||
126 | |||
127 | map = bpf_object__find_map_by_name(obj, "linum_map"); | ||
128 | CHECK(!map, "find linum_map", "!map\n"); | ||
129 | linum_map = bpf_map__fd(map); | ||
130 | CHECK(linum_map == -1, "get linum_map fd", | ||
131 | "linum_map:%d\n", linum_map); | ||
132 | |||
133 | map = bpf_object__find_map_by_name(obj, "data_check_map"); | ||
134 | CHECK(!map, "find data_check_map", "!map\n"); | ||
135 | data_check_map = bpf_map__fd(map); | ||
136 | CHECK(data_check_map == -1, "get data_check_map fd", | ||
137 | "data_check_map:%d\n", data_check_map); | ||
138 | } | ||
139 | |||
140 | static void sa46_init_loopback(union sa46 *sa, sa_family_t family) | ||
141 | { | ||
142 | memset(sa, 0, sizeof(*sa)); | ||
143 | sa->family = family; | ||
144 | if (sa->family == AF_INET6) | ||
145 | sa->v6.sin6_addr = in6addr_loopback; | ||
146 | else | ||
147 | sa->v4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | ||
148 | } | ||
149 | |||
150 | static void sa46_init_inany(union sa46 *sa, sa_family_t family) | ||
151 | { | ||
152 | memset(sa, 0, sizeof(*sa)); | ||
153 | sa->family = family; | ||
154 | if (sa->family == AF_INET6) | ||
155 | sa->v6.sin6_addr = in6addr_any; | ||
156 | else | ||
157 | sa->v4.sin_addr.s_addr = INADDR_ANY; | ||
158 | } | ||
159 | |||
160 | static int read_int_sysctl(const char *sysctl) | ||
161 | { | ||
162 | char buf[16]; | ||
163 | int fd, ret; | ||
164 | |||
165 | fd = open(sysctl, 0); | ||
166 | CHECK(fd == -1, "open(sysctl)", "sysctl:%s fd:%d errno:%d\n", | ||
167 | sysctl, fd, errno); | ||
168 | |||
169 | ret = read(fd, buf, sizeof(buf)); | ||
170 | CHECK(ret <= 0, "read(sysctl)", "sysctl:%s ret:%d errno:%d\n", | ||
171 | sysctl, ret, errno); | ||
172 | close(fd); | ||
173 | |||
174 | return atoi(buf); | ||
175 | } | ||
176 | |||
177 | static void write_int_sysctl(const char *sysctl, int v) | ||
178 | { | ||
179 | int fd, ret, size; | ||
180 | char buf[16]; | ||
181 | |||
182 | fd = open(sysctl, O_RDWR); | ||
183 | CHECK(fd == -1, "open(sysctl)", "sysctl:%s fd:%d errno:%d\n", | ||
184 | sysctl, fd, errno); | ||
185 | |||
186 | size = snprintf(buf, sizeof(buf), "%d", v); | ||
187 | ret = write(fd, buf, size); | ||
188 | CHECK(ret != size, "write(sysctl)", | ||
189 | "sysctl:%s ret:%d size:%d errno:%d\n", sysctl, ret, size, errno); | ||
190 | close(fd); | ||
191 | } | ||
192 | |||
193 | static void restore_sysctls(void) | ||
194 | { | ||
195 | write_int_sysctl(TCP_FO_SYSCTL, saved_tcp_fo); | ||
196 | write_int_sysctl(TCP_SYNCOOKIE_SYSCTL, saved_tcp_syncookie); | ||
197 | } | ||
198 | |||
199 | static void enable_fastopen(void) | ||
200 | { | ||
201 | int fo; | ||
202 | |||
203 | fo = read_int_sysctl(TCP_FO_SYSCTL); | ||
204 | write_int_sysctl(TCP_FO_SYSCTL, fo | 7); | ||
205 | } | ||
206 | |||
207 | static void enable_syncookie(void) | ||
208 | { | ||
209 | write_int_sysctl(TCP_SYNCOOKIE_SYSCTL, 2); | ||
210 | } | ||
211 | |||
212 | static void disable_syncookie(void) | ||
213 | { | ||
214 | write_int_sysctl(TCP_SYNCOOKIE_SYSCTL, 0); | ||
215 | } | ||
216 | |||
217 | static __u32 get_linum(void) | ||
218 | { | ||
219 | __u32 linum; | ||
220 | int err; | ||
221 | |||
222 | err = bpf_map_lookup_elem(linum_map, &index_zero, &linum); | ||
223 | CHECK(err == -1, "lookup_elem(linum_map)", "err:%d errno:%d\n", | ||
224 | err, errno); | ||
225 | |||
226 | return linum; | ||
227 | } | ||
228 | |||
229 | static void check_data(int type, sa_family_t family, const struct cmd *cmd, | ||
230 | int cli_fd) | ||
231 | { | ||
232 | struct data_check expected = {}, result; | ||
233 | union sa46 cli_sa; | ||
234 | socklen_t addrlen; | ||
235 | int err; | ||
236 | |||
237 | addrlen = sizeof(cli_sa); | ||
238 | err = getsockname(cli_fd, (struct sockaddr *)&cli_sa, | ||
239 | &addrlen); | ||
240 | CHECK(err == -1, "getsockname(cli_fd)", "err:%d errno:%d\n", | ||
241 | err, errno); | ||
242 | |||
243 | err = bpf_map_lookup_elem(data_check_map, &index_zero, &result); | ||
244 | CHECK(err == -1, "lookup_elem(data_check_map)", "err:%d errno:%d\n", | ||
245 | err, errno); | ||
246 | |||
247 | if (type == SOCK_STREAM) { | ||
248 | expected.len = MIN_TCPHDR_LEN; | ||
249 | expected.ip_protocol = IPPROTO_TCP; | ||
250 | } else { | ||
251 | expected.len = UDPHDR_LEN; | ||
252 | expected.ip_protocol = IPPROTO_UDP; | ||
253 | } | ||
254 | |||
255 | if (family == AF_INET6) { | ||
256 | expected.eth_protocol = htons(ETH_P_IPV6); | ||
257 | expected.bind_inany = !srv_sa.v6.sin6_addr.s6_addr32[3] && | ||
258 | !srv_sa.v6.sin6_addr.s6_addr32[2] && | ||
259 | !srv_sa.v6.sin6_addr.s6_addr32[1] && | ||
260 | !srv_sa.v6.sin6_addr.s6_addr32[0]; | ||
261 | |||
262 | memcpy(&expected.skb_addrs[0], cli_sa.v6.sin6_addr.s6_addr32, | ||
263 | sizeof(cli_sa.v6.sin6_addr)); | ||
264 | memcpy(&expected.skb_addrs[4], &in6addr_loopback, | ||
265 | sizeof(in6addr_loopback)); | ||
266 | expected.skb_ports[0] = cli_sa.v6.sin6_port; | ||
267 | expected.skb_ports[1] = srv_sa.v6.sin6_port; | ||
268 | } else { | ||
269 | expected.eth_protocol = htons(ETH_P_IP); | ||
270 | expected.bind_inany = !srv_sa.v4.sin_addr.s_addr; | ||
271 | |||
272 | expected.skb_addrs[0] = cli_sa.v4.sin_addr.s_addr; | ||
273 | expected.skb_addrs[1] = htonl(INADDR_LOOPBACK); | ||
274 | expected.skb_ports[0] = cli_sa.v4.sin_port; | ||
275 | expected.skb_ports[1] = srv_sa.v4.sin_port; | ||
276 | } | ||
277 | |||
278 | if (memcmp(&result, &expected, offsetof(struct data_check, | ||
279 | equal_check_end))) { | ||
280 | printf("unexpected data_check\n"); | ||
281 | printf(" result: (0x%x, %u, %u)\n", | ||
282 | result.eth_protocol, result.ip_protocol, | ||
283 | result.bind_inany); | ||
284 | printf("expected: (0x%x, %u, %u)\n", | ||
285 | expected.eth_protocol, expected.ip_protocol, | ||
286 | expected.bind_inany); | ||
287 | CHECK(1, "data_check result != expected", | ||
288 | "bpf_prog_linum:%u\n", get_linum()); | ||
289 | } | ||
290 | |||
291 | CHECK(!result.hash, "data_check result.hash empty", | ||
292 | "result.hash:%u", result.hash); | ||
293 | |||
294 | expected.len += cmd ? sizeof(*cmd) : 0; | ||
295 | if (type == SOCK_STREAM) | ||
296 | CHECK(expected.len > result.len, "expected.len > result.len", | ||
297 | "expected.len:%u result.len:%u bpf_prog_linum:%u\n", | ||
298 | expected.len, result.len, get_linum()); | ||
299 | else | ||
300 | CHECK(expected.len != result.len, "expected.len != result.len", | ||
301 | "expected.len:%u result.len:%u bpf_prog_linum:%u\n", | ||
302 | expected.len, result.len, get_linum()); | ||
303 | } | ||
304 | |||
305 | static void check_results(void) | ||
306 | { | ||
307 | __u32 results[NR_RESULTS]; | ||
308 | __u32 i, broken = 0; | ||
309 | int err; | ||
310 | |||
311 | for (i = 0; i < NR_RESULTS; i++) { | ||
312 | err = bpf_map_lookup_elem(result_map, &i, &results[i]); | ||
313 | CHECK(err == -1, "lookup_elem(result_map)", | ||
314 | "i:%u err:%d errno:%d\n", i, err, errno); | ||
315 | } | ||
316 | |||
317 | for (i = 0; i < NR_RESULTS; i++) { | ||
318 | if (results[i] != expected_results[i]) { | ||
319 | broken = i; | ||
320 | break; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | if (i == NR_RESULTS) | ||
325 | return; | ||
326 | |||
327 | printf("unexpected result\n"); | ||
328 | printf(" result: ["); | ||
329 | printf("%u", results[0]); | ||
330 | for (i = 1; i < NR_RESULTS; i++) | ||
331 | printf(", %u", results[i]); | ||
332 | printf("]\n"); | ||
333 | |||
334 | printf("expected: ["); | ||
335 | printf("%u", expected_results[0]); | ||
336 | for (i = 1; i < NR_RESULTS; i++) | ||
337 | printf(", %u", expected_results[i]); | ||
338 | printf("]\n"); | ||
339 | |||
340 | CHECK(expected_results[broken] != results[broken], | ||
341 | "unexpected result", | ||
342 | "expected_results[%u] != results[%u] bpf_prog_linum:%u\n", | ||
343 | broken, broken, get_linum()); | ||
344 | } | ||
345 | |||
346 | static int send_data(int type, sa_family_t family, void *data, size_t len, | ||
347 | enum result expected) | ||
348 | { | ||
349 | union sa46 cli_sa; | ||
350 | int fd, err; | ||
351 | |||
352 | fd = socket(family, type, 0); | ||
353 | CHECK(fd == -1, "socket()", "fd:%d errno:%d\n", fd, errno); | ||
354 | |||
355 | sa46_init_loopback(&cli_sa, family); | ||
356 | err = bind(fd, (struct sockaddr *)&cli_sa, sizeof(cli_sa)); | ||
357 | CHECK(fd == -1, "bind(cli_sa)", "err:%d errno:%d\n", err, errno); | ||
358 | |||
359 | err = sendto(fd, data, len, MSG_FASTOPEN, (struct sockaddr *)&srv_sa, | ||
360 | sizeof(srv_sa)); | ||
361 | CHECK(err != len && expected >= PASS, | ||
362 | "sendto()", "family:%u err:%d errno:%d expected:%d\n", | ||
363 | family, err, errno, expected); | ||
364 | |||
365 | return fd; | ||
366 | } | ||
367 | |||
368 | static void do_test(int type, sa_family_t family, struct cmd *cmd, | ||
369 | enum result expected) | ||
370 | { | ||
371 | int nev, srv_fd, cli_fd; | ||
372 | struct epoll_event ev; | ||
373 | struct cmd rcv_cmd; | ||
374 | ssize_t nread; | ||
375 | |||
376 | cli_fd = send_data(type, family, cmd, cmd ? sizeof(*cmd) : 0, | ||
377 | expected); | ||
378 | nev = epoll_wait(epfd, &ev, 1, expected >= PASS ? 5 : 0); | ||
379 | CHECK((nev <= 0 && expected >= PASS) || | ||
380 | (nev > 0 && expected < PASS), | ||
381 | "nev <> expected", | ||
382 | "nev:%d expected:%d type:%d family:%d data:(%d, %d)\n", | ||
383 | nev, expected, type, family, | ||
384 | cmd ? cmd->reuseport_index : -1, | ||
385 | cmd ? cmd->pass_on_failure : -1); | ||
386 | check_results(); | ||
387 | check_data(type, family, cmd, cli_fd); | ||
388 | |||
389 | if (expected < PASS) | ||
390 | return; | ||
391 | |||
392 | CHECK(expected != PASS_ERR_SK_SELECT_REUSEPORT && | ||
393 | cmd->reuseport_index != ev.data.u32, | ||
394 | "check cmd->reuseport_index", | ||
395 | "cmd:(%u, %u) ev.data.u32:%u\n", | ||
396 | cmd->pass_on_failure, cmd->reuseport_index, ev.data.u32); | ||
397 | |||
398 | srv_fd = sk_fds[ev.data.u32]; | ||
399 | if (type == SOCK_STREAM) { | ||
400 | int new_fd = accept(srv_fd, NULL, 0); | ||
401 | |||
402 | CHECK(new_fd == -1, "accept(srv_fd)", | ||
403 | "ev.data.u32:%u new_fd:%d errno:%d\n", | ||
404 | ev.data.u32, new_fd, errno); | ||
405 | |||
406 | nread = recv(new_fd, &rcv_cmd, sizeof(rcv_cmd), MSG_DONTWAIT); | ||
407 | CHECK(nread != sizeof(rcv_cmd), | ||
408 | "recv(new_fd)", | ||
409 | "ev.data.u32:%u nread:%zd sizeof(rcv_cmd):%zu errno:%d\n", | ||
410 | ev.data.u32, nread, sizeof(rcv_cmd), errno); | ||
411 | |||
412 | close(new_fd); | ||
413 | } else { | ||
414 | nread = recv(srv_fd, &rcv_cmd, sizeof(rcv_cmd), MSG_DONTWAIT); | ||
415 | CHECK(nread != sizeof(rcv_cmd), | ||
416 | "recv(sk_fds)", | ||
417 | "ev.data.u32:%u nread:%zd sizeof(rcv_cmd):%zu errno:%d\n", | ||
418 | ev.data.u32, nread, sizeof(rcv_cmd), errno); | ||
419 | } | ||
420 | |||
421 | close(cli_fd); | ||
422 | } | ||
423 | |||
424 | static void test_err_inner_map(int type, sa_family_t family) | ||
425 | { | ||
426 | struct cmd cmd = { | ||
427 | .reuseport_index = 0, | ||
428 | .pass_on_failure = 0, | ||
429 | }; | ||
430 | |||
431 | printf("%s: ", __func__); | ||
432 | expected_results[DROP_ERR_INNER_MAP]++; | ||
433 | do_test(type, family, &cmd, DROP_ERR_INNER_MAP); | ||
434 | printf("OK\n"); | ||
435 | } | ||
436 | |||
437 | static void test_err_skb_data(int type, sa_family_t family) | ||
438 | { | ||
439 | printf("%s: ", __func__); | ||
440 | expected_results[DROP_ERR_SKB_DATA]++; | ||
441 | do_test(type, family, NULL, DROP_ERR_SKB_DATA); | ||
442 | printf("OK\n"); | ||
443 | } | ||
444 | |||
445 | static void test_err_sk_select_port(int type, sa_family_t family) | ||
446 | { | ||
447 | struct cmd cmd = { | ||
448 | .reuseport_index = REUSEPORT_ARRAY_SIZE, | ||
449 | .pass_on_failure = 0, | ||
450 | }; | ||
451 | |||
452 | printf("%s: ", __func__); | ||
453 | expected_results[DROP_ERR_SK_SELECT_REUSEPORT]++; | ||
454 | do_test(type, family, &cmd, DROP_ERR_SK_SELECT_REUSEPORT); | ||
455 | printf("OK\n"); | ||
456 | } | ||
457 | |||
458 | static void test_pass(int type, sa_family_t family) | ||
459 | { | ||
460 | struct cmd cmd; | ||
461 | int i; | ||
462 | |||
463 | printf("%s: ", __func__); | ||
464 | cmd.pass_on_failure = 0; | ||
465 | for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++) { | ||
466 | expected_results[PASS]++; | ||
467 | cmd.reuseport_index = i; | ||
468 | do_test(type, family, &cmd, PASS); | ||
469 | } | ||
470 | printf("OK\n"); | ||
471 | } | ||
472 | |||
473 | static void test_syncookie(int type, sa_family_t family) | ||
474 | { | ||
475 | int err, tmp_index = 1; | ||
476 | struct cmd cmd = { | ||
477 | .reuseport_index = 0, | ||
478 | .pass_on_failure = 0, | ||
479 | }; | ||
480 | |||
481 | if (type != SOCK_STREAM) | ||
482 | return; | ||
483 | |||
484 | printf("%s: ", __func__); | ||
485 | /* | ||
486 | * +1 for TCP-SYN and | ||
487 | * +1 for the TCP-ACK (ack the syncookie) | ||
488 | */ | ||
489 | expected_results[PASS] += 2; | ||
490 | enable_syncookie(); | ||
491 | /* | ||
492 | * Simulate TCP-SYN and TCP-ACK are handled by two different sk: | ||
493 | * TCP-SYN: select sk_fds[tmp_index = 1] tmp_index is from the | ||
494 | * tmp_index_ovr_map | ||
495 | * TCP-ACK: select sk_fds[reuseport_index = 0] reuseport_index | ||
496 | * is from the cmd.reuseport_index | ||
497 | */ | ||
498 | err = bpf_map_update_elem(tmp_index_ovr_map, &index_zero, | ||
499 | &tmp_index, BPF_ANY); | ||
500 | CHECK(err == -1, "update_elem(tmp_index_ovr_map, 0, 1)", | ||
501 | "err:%d errno:%d\n", err, errno); | ||
502 | do_test(type, family, &cmd, PASS); | ||
503 | err = bpf_map_lookup_elem(tmp_index_ovr_map, &index_zero, | ||
504 | &tmp_index); | ||
505 | CHECK(err == -1 || tmp_index != -1, | ||
506 | "lookup_elem(tmp_index_ovr_map)", | ||
507 | "err:%d errno:%d tmp_index:%d\n", | ||
508 | err, errno, tmp_index); | ||
509 | disable_syncookie(); | ||
510 | printf("OK\n"); | ||
511 | } | ||
512 | |||
513 | static void test_pass_on_err(int type, sa_family_t family) | ||
514 | { | ||
515 | struct cmd cmd = { | ||
516 | .reuseport_index = REUSEPORT_ARRAY_SIZE, | ||
517 | .pass_on_failure = 1, | ||
518 | }; | ||
519 | |||
520 | printf("%s: ", __func__); | ||
521 | expected_results[PASS_ERR_SK_SELECT_REUSEPORT] += 1; | ||
522 | do_test(type, family, &cmd, PASS_ERR_SK_SELECT_REUSEPORT); | ||
523 | printf("OK\n"); | ||
524 | } | ||
525 | |||
526 | static void prepare_sk_fds(int type, sa_family_t family, bool inany) | ||
527 | { | ||
528 | const int first = REUSEPORT_ARRAY_SIZE - 1; | ||
529 | int i, err, optval = 1; | ||
530 | struct epoll_event ev; | ||
531 | socklen_t addrlen; | ||
532 | |||
533 | if (inany) | ||
534 | sa46_init_inany(&srv_sa, family); | ||
535 | else | ||
536 | sa46_init_loopback(&srv_sa, family); | ||
537 | addrlen = sizeof(srv_sa); | ||
538 | |||
539 | /* | ||
540 | * The sk_fds[] is filled from the back such that the order | ||
541 | * is exactly opposite to the (struct sock_reuseport *)reuse->socks[]. | ||
542 | */ | ||
543 | for (i = first; i >= 0; i--) { | ||
544 | sk_fds[i] = socket(family, type, 0); | ||
545 | CHECK(sk_fds[i] == -1, "socket()", "sk_fds[%d]:%d errno:%d\n", | ||
546 | i, sk_fds[i], errno); | ||
547 | err = setsockopt(sk_fds[i], SOL_SOCKET, SO_REUSEPORT, | ||
548 | &optval, sizeof(optval)); | ||
549 | CHECK(err == -1, "setsockopt(SO_REUSEPORT)", | ||
550 | "sk_fds[%d] err:%d errno:%d\n", | ||
551 | i, err, errno); | ||
552 | |||
553 | if (i == first) { | ||
554 | err = setsockopt(sk_fds[i], SOL_SOCKET, | ||
555 | SO_ATTACH_REUSEPORT_EBPF, | ||
556 | &select_by_skb_data_prog, | ||
557 | sizeof(select_by_skb_data_prog)); | ||
558 | CHECK(err == -1, "setsockopt(SO_ATTACH_REUEPORT_EBPF)", | ||
559 | "err:%d errno:%d\n", err, errno); | ||
560 | } | ||
561 | |||
562 | err = bind(sk_fds[i], (struct sockaddr *)&srv_sa, addrlen); | ||
563 | CHECK(err == -1, "bind()", "sk_fds[%d] err:%d errno:%d\n", | ||
564 | i, err, errno); | ||
565 | |||
566 | if (type == SOCK_STREAM) { | ||
567 | err = listen(sk_fds[i], 10); | ||
568 | CHECK(err == -1, "listen()", | ||
569 | "sk_fds[%d] err:%d errno:%d\n", | ||
570 | i, err, errno); | ||
571 | } | ||
572 | |||
573 | err = bpf_map_update_elem(reuseport_array, &i, &sk_fds[i], | ||
574 | BPF_NOEXIST); | ||
575 | CHECK(err == -1, "update_elem(reuseport_array)", | ||
576 | "sk_fds[%d] err:%d errno:%d\n", i, err, errno); | ||
577 | |||
578 | if (i == first) { | ||
579 | socklen_t addrlen = sizeof(srv_sa); | ||
580 | |||
581 | err = getsockname(sk_fds[i], (struct sockaddr *)&srv_sa, | ||
582 | &addrlen); | ||
583 | CHECK(err == -1, "getsockname()", | ||
584 | "sk_fds[%d] err:%d errno:%d\n", i, err, errno); | ||
585 | } | ||
586 | } | ||
587 | |||
588 | epfd = epoll_create(1); | ||
589 | CHECK(epfd == -1, "epoll_create(1)", | ||
590 | "epfd:%d errno:%d\n", epfd, errno); | ||
591 | |||
592 | ev.events = EPOLLIN; | ||
593 | for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++) { | ||
594 | ev.data.u32 = i; | ||
595 | err = epoll_ctl(epfd, EPOLL_CTL_ADD, sk_fds[i], &ev); | ||
596 | CHECK(err, "epoll_ctl(EPOLL_CTL_ADD)", "sk_fds[%d]\n", i); | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static void setup_per_test(int type, unsigned short family, bool inany) | ||
601 | { | ||
602 | int ovr = -1, err; | ||
603 | |||
604 | prepare_sk_fds(type, family, inany); | ||
605 | err = bpf_map_update_elem(tmp_index_ovr_map, &index_zero, &ovr, | ||
606 | BPF_ANY); | ||
607 | CHECK(err == -1, "update_elem(tmp_index_ovr_map, 0, -1)", | ||
608 | "err:%d errno:%d\n", err, errno); | ||
609 | } | ||
610 | |||
611 | static void cleanup_per_test(void) | ||
612 | { | ||
613 | int i, err; | ||
614 | |||
615 | for (i = 0; i < REUSEPORT_ARRAY_SIZE; i++) | ||
616 | close(sk_fds[i]); | ||
617 | close(epfd); | ||
618 | |||
619 | err = bpf_map_delete_elem(outer_map, &index_zero); | ||
620 | CHECK(err == -1, "delete_elem(outer_map)", | ||
621 | "err:%d errno:%d\n", err, errno); | ||
622 | } | ||
623 | |||
624 | static void cleanup(void) | ||
625 | { | ||
626 | close(outer_map); | ||
627 | close(reuseport_array); | ||
628 | bpf_object__close(obj); | ||
629 | } | ||
630 | |||
631 | static void test_all(void) | ||
632 | { | ||
633 | /* Extra SOCK_STREAM to test bind_inany==true */ | ||
634 | const int types[] = { SOCK_STREAM, SOCK_DGRAM, SOCK_STREAM }; | ||
635 | const char * const type_strings[] = { "TCP", "UDP", "TCP" }; | ||
636 | const char * const family_strings[] = { "IPv6", "IPv4" }; | ||
637 | const unsigned short families[] = { AF_INET6, AF_INET }; | ||
638 | const bool bind_inany[] = { false, false, true }; | ||
639 | int t, f, err; | ||
640 | |||
641 | for (f = 0; f < ARRAY_SIZE(families); f++) { | ||
642 | unsigned short family = families[f]; | ||
643 | |||
644 | for (t = 0; t < ARRAY_SIZE(types); t++) { | ||
645 | bool inany = bind_inany[t]; | ||
646 | int type = types[t]; | ||
647 | |||
648 | printf("######## %s/%s %s ########\n", | ||
649 | family_strings[f], type_strings[t], | ||
650 | inany ? " INANY " : "LOOPBACK"); | ||
651 | |||
652 | setup_per_test(type, family, inany); | ||
653 | |||
654 | test_err_inner_map(type, family); | ||
655 | |||
656 | /* Install reuseport_array to the outer_map */ | ||
657 | err = bpf_map_update_elem(outer_map, &index_zero, | ||
658 | &reuseport_array, BPF_ANY); | ||
659 | CHECK(err == -1, "update_elem(outer_map)", | ||
660 | "err:%d errno:%d\n", err, errno); | ||
661 | |||
662 | test_err_skb_data(type, family); | ||
663 | test_err_sk_select_port(type, family); | ||
664 | test_pass(type, family); | ||
665 | test_syncookie(type, family); | ||
666 | test_pass_on_err(type, family); | ||
667 | |||
668 | cleanup_per_test(); | ||
669 | printf("\n"); | ||
670 | } | ||
671 | } | ||
672 | } | ||
673 | |||
674 | int main(int argc, const char **argv) | ||
675 | { | ||
676 | create_maps(); | ||
677 | prepare_bpf_obj(); | ||
678 | saved_tcp_fo = read_int_sysctl(TCP_FO_SYSCTL); | ||
679 | saved_tcp_syncookie = read_int_sysctl(TCP_SYNCOOKIE_SYSCTL); | ||
680 | enable_fastopen(); | ||
681 | disable_syncookie(); | ||
682 | atexit(restore_sysctls); | ||
683 | |||
684 | test_all(); | ||
685 | |||
686 | cleanup(); | ||
687 | return 0; | ||
688 | } | ||
diff --git a/tools/testing/selftests/bpf/test_select_reuseport_common.h b/tools/testing/selftests/bpf/test_select_reuseport_common.h new file mode 100644 index 000000000000..08eb2a9f145f --- /dev/null +++ b/tools/testing/selftests/bpf/test_select_reuseport_common.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* Copyright (c) 2018 Facebook */ | ||
3 | |||
4 | #ifndef __TEST_SELECT_REUSEPORT_COMMON_H | ||
5 | #define __TEST_SELECT_REUSEPORT_COMMON_H | ||
6 | |||
7 | #include <linux/types.h> | ||
8 | |||
9 | enum result { | ||
10 | DROP_ERR_INNER_MAP, | ||
11 | DROP_ERR_SKB_DATA, | ||
12 | DROP_ERR_SK_SELECT_REUSEPORT, | ||
13 | DROP_MISC, | ||
14 | PASS, | ||
15 | PASS_ERR_SK_SELECT_REUSEPORT, | ||
16 | NR_RESULTS, | ||
17 | }; | ||
18 | |||
19 | struct cmd { | ||
20 | __u32 reuseport_index; | ||
21 | __u32 pass_on_failure; | ||
22 | }; | ||
23 | |||
24 | struct data_check { | ||
25 | __u32 ip_protocol; | ||
26 | __u32 skb_addrs[8]; | ||
27 | __u16 skb_ports[2]; | ||
28 | __u16 eth_protocol; | ||
29 | __u8 bind_inany; | ||
30 | __u8 equal_check_end[0]; | ||
31 | |||
32 | __u32 len; | ||
33 | __u32 hash; | ||
34 | }; | ||
35 | |||
36 | #endif | ||
diff --git a/tools/testing/selftests/bpf/test_select_reuseport_kern.c b/tools/testing/selftests/bpf/test_select_reuseport_kern.c new file mode 100644 index 000000000000..5b54ec637ada --- /dev/null +++ b/tools/testing/selftests/bpf/test_select_reuseport_kern.c | |||
@@ -0,0 +1,180 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* Copyright (c) 2018 Facebook */ | ||
3 | |||
4 | #include <stdlib.h> | ||
5 | #include <linux/in.h> | ||
6 | #include <linux/ip.h> | ||
7 | #include <linux/ipv6.h> | ||
8 | #include <linux/tcp.h> | ||
9 | #include <linux/udp.h> | ||
10 | #include <linux/bpf.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/if_ether.h> | ||
13 | |||
14 | #include "bpf_endian.h" | ||
15 | #include "bpf_helpers.h" | ||
16 | #include "test_select_reuseport_common.h" | ||
17 | |||
18 | int _version SEC("version") = 1; | ||
19 | |||
20 | #ifndef offsetof | ||
21 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | ||
22 | #endif | ||
23 | |||
24 | struct bpf_map_def SEC("maps") outer_map = { | ||
25 | .type = BPF_MAP_TYPE_ARRAY_OF_MAPS, | ||
26 | .key_size = sizeof(__u32), | ||
27 | .value_size = sizeof(__u32), | ||
28 | .max_entries = 1, | ||
29 | }; | ||
30 | |||
31 | struct bpf_map_def SEC("maps") result_map = { | ||
32 | .type = BPF_MAP_TYPE_ARRAY, | ||
33 | .key_size = sizeof(__u32), | ||
34 | .value_size = sizeof(__u32), | ||
35 | .max_entries = NR_RESULTS, | ||
36 | }; | ||
37 | |||
38 | struct bpf_map_def SEC("maps") tmp_index_ovr_map = { | ||
39 | .type = BPF_MAP_TYPE_ARRAY, | ||
40 | .key_size = sizeof(__u32), | ||
41 | .value_size = sizeof(int), | ||
42 | .max_entries = 1, | ||
43 | }; | ||
44 | |||
45 | struct bpf_map_def SEC("maps") linum_map = { | ||
46 | .type = BPF_MAP_TYPE_ARRAY, | ||
47 | .key_size = sizeof(__u32), | ||
48 | .value_size = sizeof(__u32), | ||
49 | .max_entries = 1, | ||
50 | }; | ||
51 | |||
52 | struct bpf_map_def SEC("maps") data_check_map = { | ||
53 | .type = BPF_MAP_TYPE_ARRAY, | ||
54 | .key_size = sizeof(__u32), | ||
55 | .value_size = sizeof(struct data_check), | ||
56 | .max_entries = 1, | ||
57 | }; | ||
58 | |||
59 | #define GOTO_DONE(_result) ({ \ | ||
60 | result = (_result); \ | ||
61 | linum = __LINE__; \ | ||
62 | goto done; \ | ||
63 | }) | ||
64 | |||
65 | SEC("select_by_skb_data") | ||
66 | int _select_by_skb_data(struct sk_reuseport_md *reuse_md) | ||
67 | { | ||
68 | __u32 linum, index = 0, flags = 0, index_zero = 0; | ||
69 | __u32 *result_cnt, *linum_value; | ||
70 | struct data_check data_check = {}; | ||
71 | struct cmd *cmd, cmd_copy; | ||
72 | void *data, *data_end; | ||
73 | void *reuseport_array; | ||
74 | enum result result; | ||
75 | int *index_ovr; | ||
76 | int err; | ||
77 | |||
78 | data = reuse_md->data; | ||
79 | data_end = reuse_md->data_end; | ||
80 | data_check.len = reuse_md->len; | ||
81 | data_check.eth_protocol = reuse_md->eth_protocol; | ||
82 | data_check.ip_protocol = reuse_md->ip_protocol; | ||
83 | data_check.hash = reuse_md->hash; | ||
84 | data_check.bind_inany = reuse_md->bind_inany; | ||
85 | if (data_check.eth_protocol == bpf_htons(ETH_P_IP)) { | ||
86 | if (bpf_skb_load_bytes_relative(reuse_md, | ||
87 | offsetof(struct iphdr, saddr), | ||
88 | data_check.skb_addrs, 8, | ||
89 | BPF_HDR_START_NET)) | ||
90 | GOTO_DONE(DROP_MISC); | ||
91 | } else { | ||
92 | if (bpf_skb_load_bytes_relative(reuse_md, | ||
93 | offsetof(struct ipv6hdr, saddr), | ||
94 | data_check.skb_addrs, 32, | ||
95 | BPF_HDR_START_NET)) | ||
96 | GOTO_DONE(DROP_MISC); | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * The ip_protocol could be a compile time decision | ||
101 | * if the bpf_prog.o is dedicated to either TCP or | ||
102 | * UDP. | ||
103 | * | ||
104 | * Otherwise, reuse_md->ip_protocol or | ||
105 | * the protocol field in the iphdr can be used. | ||
106 | */ | ||
107 | if (data_check.ip_protocol == IPPROTO_TCP) { | ||
108 | struct tcphdr *th = data; | ||
109 | |||
110 | if (th + 1 > data_end) | ||
111 | GOTO_DONE(DROP_MISC); | ||
112 | |||
113 | data_check.skb_ports[0] = th->source; | ||
114 | data_check.skb_ports[1] = th->dest; | ||
115 | |||
116 | if ((th->doff << 2) + sizeof(*cmd) > data_check.len) | ||
117 | GOTO_DONE(DROP_ERR_SKB_DATA); | ||
118 | if (bpf_skb_load_bytes(reuse_md, th->doff << 2, &cmd_copy, | ||
119 | sizeof(cmd_copy))) | ||
120 | GOTO_DONE(DROP_MISC); | ||
121 | cmd = &cmd_copy; | ||
122 | } else if (data_check.ip_protocol == IPPROTO_UDP) { | ||
123 | struct udphdr *uh = data; | ||
124 | |||
125 | if (uh + 1 > data_end) | ||
126 | GOTO_DONE(DROP_MISC); | ||
127 | |||
128 | data_check.skb_ports[0] = uh->source; | ||
129 | data_check.skb_ports[1] = uh->dest; | ||
130 | |||
131 | if (sizeof(struct udphdr) + sizeof(*cmd) > data_check.len) | ||
132 | GOTO_DONE(DROP_ERR_SKB_DATA); | ||
133 | if (data + sizeof(struct udphdr) + sizeof(*cmd) > data_end) { | ||
134 | if (bpf_skb_load_bytes(reuse_md, sizeof(struct udphdr), | ||
135 | &cmd_copy, sizeof(cmd_copy))) | ||
136 | GOTO_DONE(DROP_MISC); | ||
137 | cmd = &cmd_copy; | ||
138 | } else { | ||
139 | cmd = data + sizeof(struct udphdr); | ||
140 | } | ||
141 | } else { | ||
142 | GOTO_DONE(DROP_MISC); | ||
143 | } | ||
144 | |||
145 | reuseport_array = bpf_map_lookup_elem(&outer_map, &index_zero); | ||
146 | if (!reuseport_array) | ||
147 | GOTO_DONE(DROP_ERR_INNER_MAP); | ||
148 | |||
149 | index = cmd->reuseport_index; | ||
150 | index_ovr = bpf_map_lookup_elem(&tmp_index_ovr_map, &index_zero); | ||
151 | if (!index_ovr) | ||
152 | GOTO_DONE(DROP_MISC); | ||
153 | |||
154 | if (*index_ovr != -1) { | ||
155 | index = *index_ovr; | ||
156 | *index_ovr = -1; | ||
157 | } | ||
158 | err = bpf_sk_select_reuseport(reuse_md, reuseport_array, &index, | ||
159 | flags); | ||
160 | if (!err) | ||
161 | GOTO_DONE(PASS); | ||
162 | |||
163 | if (cmd->pass_on_failure) | ||
164 | GOTO_DONE(PASS_ERR_SK_SELECT_REUSEPORT); | ||
165 | else | ||
166 | GOTO_DONE(DROP_ERR_SK_SELECT_REUSEPORT); | ||
167 | |||
168 | done: | ||
169 | result_cnt = bpf_map_lookup_elem(&result_map, &result); | ||
170 | if (!result_cnt) | ||
171 | return SK_DROP; | ||
172 | |||
173 | bpf_map_update_elem(&linum_map, &index_zero, &linum, BPF_ANY); | ||
174 | bpf_map_update_elem(&data_check_map, &index_zero, &data_check, BPF_ANY); | ||
175 | |||
176 | (*result_cnt)++; | ||
177 | return result < PASS ? SK_DROP : SK_PASS; | ||
178 | } | ||
179 | |||
180 | char _license[] SEC("license") = "GPL"; | ||
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id.sh b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh new file mode 100755 index 000000000000..42544a969abc --- /dev/null +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh | |||
@@ -0,0 +1,62 @@ | |||
1 | #!/bin/sh | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | # Copyright (c) 2018 Facebook | ||
4 | |||
5 | set -eu | ||
6 | |||
7 | wait_for_ip() | ||
8 | { | ||
9 | local _i | ||
10 | echo -n "Wait for testing link-local IP to become available " | ||
11 | for _i in $(seq ${MAX_PING_TRIES}); do | ||
12 | echo -n "." | ||
13 | if ping -6 -q -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then | ||
14 | echo " OK" | ||
15 | return | ||
16 | fi | ||
17 | sleep 1 | ||
18 | done | ||
19 | echo 1>&2 "ERROR: Timeout waiting for test IP to become available." | ||
20 | exit 1 | ||
21 | } | ||
22 | |||
23 | setup() | ||
24 | { | ||
25 | # Create testing interfaces not to interfere with current environment. | ||
26 | ip link add dev ${TEST_IF} type veth peer name ${TEST_IF_PEER} | ||
27 | ip link set ${TEST_IF} up | ||
28 | ip link set ${TEST_IF_PEER} up | ||
29 | |||
30 | wait_for_ip | ||
31 | |||
32 | tc qdisc add dev ${TEST_IF} clsact | ||
33 | tc filter add dev ${TEST_IF} egress bpf obj ${BPF_PROG_OBJ} \ | ||
34 | sec ${BPF_PROG_SECTION} da | ||
35 | |||
36 | BPF_PROG_ID=$(tc filter show dev ${TEST_IF} egress | \ | ||
37 | awk '/ id / {sub(/.* id /, "", $0); print($1)}') | ||
38 | } | ||
39 | |||
40 | cleanup() | ||
41 | { | ||
42 | ip link del ${TEST_IF} 2>/dev/null || : | ||
43 | ip link del ${TEST_IF_PEER} 2>/dev/null || : | ||
44 | } | ||
45 | |||
46 | main() | ||
47 | { | ||
48 | trap cleanup EXIT 2 3 6 15 | ||
49 | setup | ||
50 | ${PROG} ${TEST_IF} ${BPF_PROG_ID} | ||
51 | } | ||
52 | |||
53 | DIR=$(dirname $0) | ||
54 | TEST_IF="test_cgid_1" | ||
55 | TEST_IF_PEER="test_cgid_2" | ||
56 | MAX_PING_TRIES=5 | ||
57 | BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o" | ||
58 | BPF_PROG_SECTION="cgroup_id_logger" | ||
59 | BPF_PROG_ID=0 | ||
60 | PROG="${DIR}/test_skb_cgroup_id_user" | ||
61 | |||
62 | main | ||
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c new file mode 100644 index 000000000000..68cf9829f5a7 --- /dev/null +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c | |||
@@ -0,0 +1,47 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (c) 2018 Facebook | ||
3 | |||
4 | #include <linux/bpf.h> | ||
5 | #include <linux/pkt_cls.h> | ||
6 | |||
7 | #include <string.h> | ||
8 | |||
9 | #include "bpf_helpers.h" | ||
10 | |||
11 | #define NUM_CGROUP_LEVELS 4 | ||
12 | |||
13 | struct bpf_map_def SEC("maps") cgroup_ids = { | ||
14 | .type = BPF_MAP_TYPE_ARRAY, | ||
15 | .key_size = sizeof(__u32), | ||
16 | .value_size = sizeof(__u64), | ||
17 | .max_entries = NUM_CGROUP_LEVELS, | ||
18 | }; | ||
19 | |||
20 | static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level) | ||
21 | { | ||
22 | __u64 id; | ||
23 | |||
24 | /* [1] &level passed to external function that may change it, it's | ||
25 | * incompatible with loop unroll. | ||
26 | */ | ||
27 | id = bpf_skb_ancestor_cgroup_id(skb, level); | ||
28 | bpf_map_update_elem(&cgroup_ids, &level, &id, 0); | ||
29 | } | ||
30 | |||
31 | SEC("cgroup_id_logger") | ||
32 | int log_cgroup_id(struct __sk_buff *skb) | ||
33 | { | ||
34 | /* Loop unroll can't be used here due to [1]. Unrolling manually. | ||
35 | * Number of calls should be in sync with NUM_CGROUP_LEVELS. | ||
36 | */ | ||
37 | log_nth_level(skb, 0); | ||
38 | log_nth_level(skb, 1); | ||
39 | log_nth_level(skb, 2); | ||
40 | log_nth_level(skb, 3); | ||
41 | |||
42 | return TC_ACT_OK; | ||
43 | } | ||
44 | |||
45 | int _version SEC("version") = 1; | ||
46 | |||
47 | char _license[] SEC("license") = "GPL"; | ||
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c new file mode 100644 index 000000000000..c121cc59f314 --- /dev/null +++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c | |||
@@ -0,0 +1,187 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (c) 2018 Facebook | ||
3 | |||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | #include <unistd.h> | ||
7 | |||
8 | #include <arpa/inet.h> | ||
9 | #include <net/if.h> | ||
10 | #include <netinet/in.h> | ||
11 | #include <sys/socket.h> | ||
12 | #include <sys/types.h> | ||
13 | |||
14 | |||
15 | #include <bpf/bpf.h> | ||
16 | #include <bpf/libbpf.h> | ||
17 | |||
18 | #include "bpf_rlimit.h" | ||
19 | #include "cgroup_helpers.h" | ||
20 | |||
21 | #define CGROUP_PATH "/skb_cgroup_test" | ||
22 | #define NUM_CGROUP_LEVELS 4 | ||
23 | |||
24 | /* RFC 4291, Section 2.7.1 */ | ||
25 | #define LINKLOCAL_MULTICAST "ff02::1" | ||
26 | |||
27 | static int mk_dst_addr(const char *ip, const char *iface, | ||
28 | struct sockaddr_in6 *dst) | ||
29 | { | ||
30 | memset(dst, 0, sizeof(*dst)); | ||
31 | |||
32 | dst->sin6_family = AF_INET6; | ||
33 | dst->sin6_port = htons(1025); | ||
34 | |||
35 | if (inet_pton(AF_INET6, ip, &dst->sin6_addr) != 1) { | ||
36 | log_err("Invalid IPv6: %s", ip); | ||
37 | return -1; | ||
38 | } | ||
39 | |||
40 | dst->sin6_scope_id = if_nametoindex(iface); | ||
41 | if (!dst->sin6_scope_id) { | ||
42 | log_err("Failed to get index of iface: %s", iface); | ||
43 | return -1; | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int send_packet(const char *iface) | ||
50 | { | ||
51 | struct sockaddr_in6 dst; | ||
52 | char msg[] = "msg"; | ||
53 | int err = 0; | ||
54 | int fd = -1; | ||
55 | |||
56 | if (mk_dst_addr(LINKLOCAL_MULTICAST, iface, &dst)) | ||
57 | goto err; | ||
58 | |||
59 | fd = socket(AF_INET6, SOCK_DGRAM, 0); | ||
60 | if (fd == -1) { | ||
61 | log_err("Failed to create UDP socket"); | ||
62 | goto err; | ||
63 | } | ||
64 | |||
65 | if (sendto(fd, &msg, sizeof(msg), 0, (const struct sockaddr *)&dst, | ||
66 | sizeof(dst)) == -1) { | ||
67 | log_err("Failed to send datagram"); | ||
68 | goto err; | ||
69 | } | ||
70 | |||
71 | goto out; | ||
72 | err: | ||
73 | err = -1; | ||
74 | out: | ||
75 | if (fd >= 0) | ||
76 | close(fd); | ||
77 | return err; | ||
78 | } | ||
79 | |||
80 | int get_map_fd_by_prog_id(int prog_id) | ||
81 | { | ||
82 | struct bpf_prog_info info = {}; | ||
83 | __u32 info_len = sizeof(info); | ||
84 | __u32 map_ids[1]; | ||
85 | int prog_fd = -1; | ||
86 | int map_fd = -1; | ||
87 | |||
88 | prog_fd = bpf_prog_get_fd_by_id(prog_id); | ||
89 | if (prog_fd < 0) { | ||
90 | log_err("Failed to get fd by prog id %d", prog_id); | ||
91 | goto err; | ||
92 | } | ||
93 | |||
94 | info.nr_map_ids = 1; | ||
95 | info.map_ids = (__u64) (unsigned long) map_ids; | ||
96 | |||
97 | if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) { | ||
98 | log_err("Failed to get info by prog fd %d", prog_fd); | ||
99 | goto err; | ||
100 | } | ||
101 | |||
102 | if (!info.nr_map_ids) { | ||
103 | log_err("No maps found for prog fd %d", prog_fd); | ||
104 | goto err; | ||
105 | } | ||
106 | |||
107 | map_fd = bpf_map_get_fd_by_id(map_ids[0]); | ||
108 | if (map_fd < 0) | ||
109 | log_err("Failed to get fd by map id %d", map_ids[0]); | ||
110 | err: | ||
111 | if (prog_fd >= 0) | ||
112 | close(prog_fd); | ||
113 | return map_fd; | ||
114 | } | ||
115 | |||
116 | int check_ancestor_cgroup_ids(int prog_id) | ||
117 | { | ||
118 | __u64 actual_ids[NUM_CGROUP_LEVELS], expected_ids[NUM_CGROUP_LEVELS]; | ||
119 | __u32 level; | ||
120 | int err = 0; | ||
121 | int map_fd; | ||
122 | |||
123 | expected_ids[0] = 0x100000001; /* root cgroup */ | ||
124 | expected_ids[1] = get_cgroup_id(""); | ||
125 | expected_ids[2] = get_cgroup_id(CGROUP_PATH); | ||
126 | expected_ids[3] = 0; /* non-existent cgroup */ | ||
127 | |||
128 | map_fd = get_map_fd_by_prog_id(prog_id); | ||
129 | if (map_fd < 0) | ||
130 | goto err; | ||
131 | |||
132 | for (level = 0; level < NUM_CGROUP_LEVELS; ++level) { | ||
133 | if (bpf_map_lookup_elem(map_fd, &level, &actual_ids[level])) { | ||
134 | log_err("Failed to lookup key %d", level); | ||
135 | goto err; | ||
136 | } | ||
137 | if (actual_ids[level] != expected_ids[level]) { | ||
138 | log_err("%llx (actual) != %llx (expected), level: %u\n", | ||
139 | actual_ids[level], expected_ids[level], level); | ||
140 | goto err; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | goto out; | ||
145 | err: | ||
146 | err = -1; | ||
147 | out: | ||
148 | if (map_fd >= 0) | ||
149 | close(map_fd); | ||
150 | return err; | ||
151 | } | ||
152 | |||
153 | int main(int argc, char **argv) | ||
154 | { | ||
155 | int cgfd = -1; | ||
156 | int err = 0; | ||
157 | |||
158 | if (argc < 3) { | ||
159 | fprintf(stderr, "Usage: %s iface prog_id\n", argv[0]); | ||
160 | exit(EXIT_FAILURE); | ||
161 | } | ||
162 | |||
163 | if (setup_cgroup_environment()) | ||
164 | goto err; | ||
165 | |||
166 | cgfd = create_and_get_cgroup(CGROUP_PATH); | ||
167 | if (!cgfd) | ||
168 | goto err; | ||
169 | |||
170 | if (join_cgroup(CGROUP_PATH)) | ||
171 | goto err; | ||
172 | |||
173 | if (send_packet(argv[1])) | ||
174 | goto err; | ||
175 | |||
176 | if (check_ancestor_cgroup_ids(atoi(argv[2]))) | ||
177 | goto err; | ||
178 | |||
179 | goto out; | ||
180 | err: | ||
181 | err = -1; | ||
182 | out: | ||
183 | close(cgfd); | ||
184 | cleanup_cgroup_environment(); | ||
185 | printf("[%s]\n", err ? "FAIL" : "PASS"); | ||
186 | return err; | ||
187 | } | ||
diff --git a/tools/testing/selftests/bpf/test_sock.c b/tools/testing/selftests/bpf/test_sock.c index f4d99fabc56d..b8ebe2f58074 100644 --- a/tools/testing/selftests/bpf/test_sock.c +++ b/tools/testing/selftests/bpf/test_sock.c | |||
@@ -14,10 +14,7 @@ | |||
14 | 14 | ||
15 | #include "cgroup_helpers.h" | 15 | #include "cgroup_helpers.h" |
16 | #include "bpf_rlimit.h" | 16 | #include "bpf_rlimit.h" |
17 | 17 | #include "bpf_util.h" | |
18 | #ifndef ARRAY_SIZE | ||
19 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
20 | #endif | ||
21 | 18 | ||
22 | #define CG_PATH "/foo" | 19 | #define CG_PATH "/foo" |
23 | #define MAX_INSNS 512 | 20 | #define MAX_INSNS 512 |
diff --git a/tools/testing/selftests/bpf/test_sock_addr.c b/tools/testing/selftests/bpf/test_sock_addr.c index a5e76b9219b9..aeeb76a54d63 100644 --- a/tools/testing/selftests/bpf/test_sock_addr.c +++ b/tools/testing/selftests/bpf/test_sock_addr.c | |||
@@ -20,15 +20,12 @@ | |||
20 | 20 | ||
21 | #include "cgroup_helpers.h" | 21 | #include "cgroup_helpers.h" |
22 | #include "bpf_rlimit.h" | 22 | #include "bpf_rlimit.h" |
23 | #include "bpf_util.h" | ||
23 | 24 | ||
24 | #ifndef ENOTSUPP | 25 | #ifndef ENOTSUPP |
25 | # define ENOTSUPP 524 | 26 | # define ENOTSUPP 524 |
26 | #endif | 27 | #endif |
27 | 28 | ||
28 | #ifndef ARRAY_SIZE | ||
29 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
30 | #endif | ||
31 | |||
32 | #define CG_PATH "/foo" | 29 | #define CG_PATH "/foo" |
33 | #define CONNECT4_PROG_PATH "./connect4_prog.o" | 30 | #define CONNECT4_PROG_PATH "./connect4_prog.o" |
34 | #define CONNECT6_PROG_PATH "./connect6_prog.o" | 31 | #define CONNECT6_PROG_PATH "./connect6_prog.o" |
@@ -998,8 +995,9 @@ int init_pktinfo(int domain, struct cmsghdr *cmsg) | |||
998 | return 0; | 995 | return 0; |
999 | } | 996 | } |
1000 | 997 | ||
1001 | static int sendmsg_to_server(const struct sockaddr_storage *addr, | 998 | static int sendmsg_to_server(int type, const struct sockaddr_storage *addr, |
1002 | socklen_t addr_len, int set_cmsg, int *syscall_err) | 999 | socklen_t addr_len, int set_cmsg, int flags, |
1000 | int *syscall_err) | ||
1003 | { | 1001 | { |
1004 | union { | 1002 | union { |
1005 | char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; | 1003 | char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; |
@@ -1022,7 +1020,7 @@ static int sendmsg_to_server(const struct sockaddr_storage *addr, | |||
1022 | goto err; | 1020 | goto err; |
1023 | } | 1021 | } |
1024 | 1022 | ||
1025 | fd = socket(domain, SOCK_DGRAM, 0); | 1023 | fd = socket(domain, type, 0); |
1026 | if (fd == -1) { | 1024 | if (fd == -1) { |
1027 | log_err("Failed to create client socket"); | 1025 | log_err("Failed to create client socket"); |
1028 | goto err; | 1026 | goto err; |
@@ -1052,7 +1050,7 @@ static int sendmsg_to_server(const struct sockaddr_storage *addr, | |||
1052 | } | 1050 | } |
1053 | } | 1051 | } |
1054 | 1052 | ||
1055 | if (sendmsg(fd, &hdr, 0) != sizeof(data)) { | 1053 | if (sendmsg(fd, &hdr, flags) != sizeof(data)) { |
1056 | log_err("Fail to send message to server"); | 1054 | log_err("Fail to send message to server"); |
1057 | *syscall_err = errno; | 1055 | *syscall_err = errno; |
1058 | goto err; | 1056 | goto err; |
@@ -1066,6 +1064,15 @@ out: | |||
1066 | return fd; | 1064 | return fd; |
1067 | } | 1065 | } |
1068 | 1066 | ||
1067 | static int fastconnect_to_server(const struct sockaddr_storage *addr, | ||
1068 | socklen_t addr_len) | ||
1069 | { | ||
1070 | int sendmsg_err; | ||
1071 | |||
1072 | return sendmsg_to_server(SOCK_STREAM, addr, addr_len, /*set_cmsg*/0, | ||
1073 | MSG_FASTOPEN, &sendmsg_err); | ||
1074 | } | ||
1075 | |||
1069 | static int recvmsg_from_client(int sockfd, struct sockaddr_storage *src_addr) | 1076 | static int recvmsg_from_client(int sockfd, struct sockaddr_storage *src_addr) |
1070 | { | 1077 | { |
1071 | struct timeval tv; | 1078 | struct timeval tv; |
@@ -1185,6 +1192,20 @@ static int run_connect_test_case(const struct sock_addr_test *test) | |||
1185 | if (cmp_local_ip(clientfd, &expected_src_addr)) | 1192 | if (cmp_local_ip(clientfd, &expected_src_addr)) |
1186 | goto err; | 1193 | goto err; |
1187 | 1194 | ||
1195 | if (test->type == SOCK_STREAM) { | ||
1196 | /* Test TCP Fast Open scenario */ | ||
1197 | clientfd = fastconnect_to_server(&requested_addr, addr_len); | ||
1198 | if (clientfd == -1) | ||
1199 | goto err; | ||
1200 | |||
1201 | /* Make sure src and dst addrs were overridden properly */ | ||
1202 | if (cmp_peer_addr(clientfd, &expected_addr)) | ||
1203 | goto err; | ||
1204 | |||
1205 | if (cmp_local_ip(clientfd, &expected_src_addr)) | ||
1206 | goto err; | ||
1207 | } | ||
1208 | |||
1188 | goto out; | 1209 | goto out; |
1189 | err: | 1210 | err: |
1190 | err = -1; | 1211 | err = -1; |
@@ -1222,8 +1243,9 @@ static int run_sendmsg_test_case(const struct sock_addr_test *test) | |||
1222 | if (clientfd >= 0) | 1243 | if (clientfd >= 0) |
1223 | close(clientfd); | 1244 | close(clientfd); |
1224 | 1245 | ||
1225 | clientfd = sendmsg_to_server(&requested_addr, addr_len, | 1246 | clientfd = sendmsg_to_server(test->type, &requested_addr, |
1226 | set_cmsg, &err); | 1247 | addr_len, set_cmsg, /*flags*/0, |
1248 | &err); | ||
1227 | if (err) | 1249 | if (err) |
1228 | goto out; | 1250 | goto out; |
1229 | else if (clientfd == -1) | 1251 | else if (clientfd == -1) |
diff --git a/tools/testing/selftests/bpf/test_socket_cookie.c b/tools/testing/selftests/bpf/test_socket_cookie.c new file mode 100644 index 000000000000..68e108e4687a --- /dev/null +++ b/tools/testing/selftests/bpf/test_socket_cookie.c | |||
@@ -0,0 +1,225 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (c) 2018 Facebook | ||
3 | |||
4 | #include <string.h> | ||
5 | #include <unistd.h> | ||
6 | |||
7 | #include <arpa/inet.h> | ||
8 | #include <netinet/in.h> | ||
9 | #include <sys/types.h> | ||
10 | #include <sys/socket.h> | ||
11 | |||
12 | #include <bpf/bpf.h> | ||
13 | #include <bpf/libbpf.h> | ||
14 | |||
15 | #include "bpf_rlimit.h" | ||
16 | #include "cgroup_helpers.h" | ||
17 | |||
18 | #define CG_PATH "/foo" | ||
19 | #define SOCKET_COOKIE_PROG "./socket_cookie_prog.o" | ||
20 | |||
21 | static int start_server(void) | ||
22 | { | ||
23 | struct sockaddr_in6 addr; | ||
24 | int fd; | ||
25 | |||
26 | fd = socket(AF_INET6, SOCK_STREAM, 0); | ||
27 | if (fd == -1) { | ||
28 | log_err("Failed to create server socket"); | ||
29 | goto out; | ||
30 | } | ||
31 | |||
32 | memset(&addr, 0, sizeof(addr)); | ||
33 | addr.sin6_family = AF_INET6; | ||
34 | addr.sin6_addr = in6addr_loopback; | ||
35 | addr.sin6_port = 0; | ||
36 | |||
37 | if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) == -1) { | ||
38 | log_err("Failed to bind server socket"); | ||
39 | goto close_out; | ||
40 | } | ||
41 | |||
42 | if (listen(fd, 128) == -1) { | ||
43 | log_err("Failed to listen on server socket"); | ||
44 | goto close_out; | ||
45 | } | ||
46 | |||
47 | goto out; | ||
48 | |||
49 | close_out: | ||
50 | close(fd); | ||
51 | fd = -1; | ||
52 | out: | ||
53 | return fd; | ||
54 | } | ||
55 | |||
56 | static int connect_to_server(int server_fd) | ||
57 | { | ||
58 | struct sockaddr_storage addr; | ||
59 | socklen_t len = sizeof(addr); | ||
60 | int fd; | ||
61 | |||
62 | fd = socket(AF_INET6, SOCK_STREAM, 0); | ||
63 | if (fd == -1) { | ||
64 | log_err("Failed to create client socket"); | ||
65 | goto out; | ||
66 | } | ||
67 | |||
68 | if (getsockname(server_fd, (struct sockaddr *)&addr, &len)) { | ||
69 | log_err("Failed to get server addr"); | ||
70 | goto close_out; | ||
71 | } | ||
72 | |||
73 | if (connect(fd, (const struct sockaddr *)&addr, len) == -1) { | ||
74 | log_err("Fail to connect to server"); | ||
75 | goto close_out; | ||
76 | } | ||
77 | |||
78 | goto out; | ||
79 | |||
80 | close_out: | ||
81 | close(fd); | ||
82 | fd = -1; | ||
83 | out: | ||
84 | return fd; | ||
85 | } | ||
86 | |||
87 | static int validate_map(struct bpf_map *map, int client_fd) | ||
88 | { | ||
89 | __u32 cookie_expected_value; | ||
90 | struct sockaddr_in6 addr; | ||
91 | socklen_t len = sizeof(addr); | ||
92 | __u32 cookie_value; | ||
93 | __u64 cookie_key; | ||
94 | int err = 0; | ||
95 | int map_fd; | ||
96 | |||
97 | if (!map) { | ||
98 | log_err("Map not found in BPF object"); | ||
99 | goto err; | ||
100 | } | ||
101 | |||
102 | map_fd = bpf_map__fd(map); | ||
103 | |||
104 | err = bpf_map_get_next_key(map_fd, NULL, &cookie_key); | ||
105 | if (err) { | ||
106 | log_err("Can't get cookie key from map"); | ||
107 | goto out; | ||
108 | } | ||
109 | |||
110 | err = bpf_map_lookup_elem(map_fd, &cookie_key, &cookie_value); | ||
111 | if (err) { | ||
112 | log_err("Can't get cookie value from map"); | ||
113 | goto out; | ||
114 | } | ||
115 | |||
116 | err = getsockname(client_fd, (struct sockaddr *)&addr, &len); | ||
117 | if (err) { | ||
118 | log_err("Can't get client local addr"); | ||
119 | goto out; | ||
120 | } | ||
121 | |||
122 | cookie_expected_value = (ntohs(addr.sin6_port) << 8) | 0xFF; | ||
123 | if (cookie_value != cookie_expected_value) { | ||
124 | log_err("Unexpected value in map: %x != %x", cookie_value, | ||
125 | cookie_expected_value); | ||
126 | goto err; | ||
127 | } | ||
128 | |||
129 | goto out; | ||
130 | err: | ||
131 | err = -1; | ||
132 | out: | ||
133 | return err; | ||
134 | } | ||
135 | |||
136 | static int run_test(int cgfd) | ||
137 | { | ||
138 | enum bpf_attach_type attach_type; | ||
139 | struct bpf_prog_load_attr attr; | ||
140 | struct bpf_program *prog; | ||
141 | struct bpf_object *pobj; | ||
142 | const char *prog_name; | ||
143 | int server_fd = -1; | ||
144 | int client_fd = -1; | ||
145 | int prog_fd = -1; | ||
146 | int err = 0; | ||
147 | |||
148 | memset(&attr, 0, sizeof(attr)); | ||
149 | attr.file = SOCKET_COOKIE_PROG; | ||
150 | attr.prog_type = BPF_PROG_TYPE_UNSPEC; | ||
151 | |||
152 | err = bpf_prog_load_xattr(&attr, &pobj, &prog_fd); | ||
153 | if (err) { | ||
154 | log_err("Failed to load %s", attr.file); | ||
155 | goto out; | ||
156 | } | ||
157 | |||
158 | bpf_object__for_each_program(prog, pobj) { | ||
159 | prog_name = bpf_program__title(prog, /*needs_copy*/ false); | ||
160 | |||
161 | if (strcmp(prog_name, "cgroup/connect6") == 0) { | ||
162 | attach_type = BPF_CGROUP_INET6_CONNECT; | ||
163 | } else if (strcmp(prog_name, "sockops") == 0) { | ||
164 | attach_type = BPF_CGROUP_SOCK_OPS; | ||
165 | } else { | ||
166 | log_err("Unexpected prog: %s", prog_name); | ||
167 | goto err; | ||
168 | } | ||
169 | |||
170 | err = bpf_prog_attach(bpf_program__fd(prog), cgfd, attach_type, | ||
171 | BPF_F_ALLOW_OVERRIDE); | ||
172 | if (err) { | ||
173 | log_err("Failed to attach prog %s", prog_name); | ||
174 | goto out; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | server_fd = start_server(); | ||
179 | if (server_fd == -1) | ||
180 | goto err; | ||
181 | |||
182 | client_fd = connect_to_server(server_fd); | ||
183 | if (client_fd == -1) | ||
184 | goto err; | ||
185 | |||
186 | if (validate_map(bpf_map__next(NULL, pobj), client_fd)) | ||
187 | goto err; | ||
188 | |||
189 | goto out; | ||
190 | err: | ||
191 | err = -1; | ||
192 | out: | ||
193 | close(client_fd); | ||
194 | close(server_fd); | ||
195 | bpf_object__close(pobj); | ||
196 | printf("%s\n", err ? "FAILED" : "PASSED"); | ||
197 | return err; | ||
198 | } | ||
199 | |||
200 | int main(int argc, char **argv) | ||
201 | { | ||
202 | int cgfd = -1; | ||
203 | int err = 0; | ||
204 | |||
205 | if (setup_cgroup_environment()) | ||
206 | goto err; | ||
207 | |||
208 | cgfd = create_and_get_cgroup(CG_PATH); | ||
209 | if (!cgfd) | ||
210 | goto err; | ||
211 | |||
212 | if (join_cgroup(CG_PATH)) | ||
213 | goto err; | ||
214 | |||
215 | if (run_test(cgfd)) | ||
216 | goto err; | ||
217 | |||
218 | goto out; | ||
219 | err: | ||
220 | err = -1; | ||
221 | out: | ||
222 | close(cgfd); | ||
223 | cleanup_cgroup_environment(); | ||
224 | return err; | ||
225 | } | ||
diff --git a/tools/testing/selftests/bpf/test_tcpbpf.h b/tools/testing/selftests/bpf/test_tcpbpf.h index 2fe43289943c..7bcfa6207005 100644 --- a/tools/testing/selftests/bpf/test_tcpbpf.h +++ b/tools/testing/selftests/bpf/test_tcpbpf.h | |||
@@ -12,5 +12,6 @@ struct tcpbpf_globals { | |||
12 | __u32 good_cb_test_rv; | 12 | __u32 good_cb_test_rv; |
13 | __u64 bytes_received; | 13 | __u64 bytes_received; |
14 | __u64 bytes_acked; | 14 | __u64 bytes_acked; |
15 | __u32 num_listen; | ||
15 | }; | 16 | }; |
16 | #endif | 17 | #endif |
diff --git a/tools/testing/selftests/bpf/test_tcpbpf_kern.c b/tools/testing/selftests/bpf/test_tcpbpf_kern.c index 3e645ee41ed5..4b7fd540cea9 100644 --- a/tools/testing/selftests/bpf/test_tcpbpf_kern.c +++ b/tools/testing/selftests/bpf/test_tcpbpf_kern.c | |||
@@ -96,15 +96,22 @@ int bpf_testcb(struct bpf_sock_ops *skops) | |||
96 | if (!gp) | 96 | if (!gp) |
97 | break; | 97 | break; |
98 | g = *gp; | 98 | g = *gp; |
99 | g.total_retrans = skops->total_retrans; | 99 | if (skops->args[0] == BPF_TCP_LISTEN) { |
100 | g.data_segs_in = skops->data_segs_in; | 100 | g.num_listen++; |
101 | g.data_segs_out = skops->data_segs_out; | 101 | } else { |
102 | g.bytes_received = skops->bytes_received; | 102 | g.total_retrans = skops->total_retrans; |
103 | g.bytes_acked = skops->bytes_acked; | 103 | g.data_segs_in = skops->data_segs_in; |
104 | g.data_segs_out = skops->data_segs_out; | ||
105 | g.bytes_received = skops->bytes_received; | ||
106 | g.bytes_acked = skops->bytes_acked; | ||
107 | } | ||
104 | bpf_map_update_elem(&global_map, &key, &g, | 108 | bpf_map_update_elem(&global_map, &key, &g, |
105 | BPF_ANY); | 109 | BPF_ANY); |
106 | } | 110 | } |
107 | break; | 111 | break; |
112 | case BPF_SOCK_OPS_TCP_LISTEN_CB: | ||
113 | bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); | ||
114 | break; | ||
108 | default: | 115 | default: |
109 | rv = -1; | 116 | rv = -1; |
110 | } | 117 | } |
diff --git a/tools/testing/selftests/bpf/test_tcpbpf_user.c b/tools/testing/selftests/bpf/test_tcpbpf_user.c index 84ab5163c828..a275c2971376 100644 --- a/tools/testing/selftests/bpf/test_tcpbpf_user.c +++ b/tools/testing/selftests/bpf/test_tcpbpf_user.c | |||
@@ -1,27 +1,59 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <inttypes.h> | ||
2 | #include <stdio.h> | 3 | #include <stdio.h> |
3 | #include <stdlib.h> | 4 | #include <stdlib.h> |
4 | #include <stdio.h> | ||
5 | #include <unistd.h> | 5 | #include <unistd.h> |
6 | #include <errno.h> | 6 | #include <errno.h> |
7 | #include <signal.h> | ||
8 | #include <string.h> | 7 | #include <string.h> |
9 | #include <assert.h> | ||
10 | #include <linux/perf_event.h> | ||
11 | #include <linux/ptrace.h> | ||
12 | #include <linux/bpf.h> | 8 | #include <linux/bpf.h> |
13 | #include <sys/ioctl.h> | ||
14 | #include <sys/time.h> | ||
15 | #include <sys/types.h> | 9 | #include <sys/types.h> |
16 | #include <sys/stat.h> | ||
17 | #include <fcntl.h> | ||
18 | #include <bpf/bpf.h> | 10 | #include <bpf/bpf.h> |
19 | #include <bpf/libbpf.h> | 11 | #include <bpf/libbpf.h> |
20 | #include "bpf_util.h" | 12 | |
21 | #include "bpf_rlimit.h" | 13 | #include "bpf_rlimit.h" |
22 | #include <linux/perf_event.h> | 14 | #include "bpf_util.h" |
15 | #include "cgroup_helpers.h" | ||
16 | |||
23 | #include "test_tcpbpf.h" | 17 | #include "test_tcpbpf.h" |
24 | 18 | ||
19 | #define EXPECT_EQ(expected, actual, fmt) \ | ||
20 | do { \ | ||
21 | if ((expected) != (actual)) { \ | ||
22 | printf(" Value of: " #actual "\n" \ | ||
23 | " Actual: %" fmt "\n" \ | ||
24 | " Expected: %" fmt "\n", \ | ||
25 | (actual), (expected)); \ | ||
26 | goto err; \ | ||
27 | } \ | ||
28 | } while (0) | ||
29 | |||
30 | int verify_result(const struct tcpbpf_globals *result) | ||
31 | { | ||
32 | __u32 expected_events; | ||
33 | |||
34 | expected_events = ((1 << BPF_SOCK_OPS_TIMEOUT_INIT) | | ||
35 | (1 << BPF_SOCK_OPS_RWND_INIT) | | ||
36 | (1 << BPF_SOCK_OPS_TCP_CONNECT_CB) | | ||
37 | (1 << BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB) | | ||
38 | (1 << BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) | | ||
39 | (1 << BPF_SOCK_OPS_NEEDS_ECN) | | ||
40 | (1 << BPF_SOCK_OPS_STATE_CB) | | ||
41 | (1 << BPF_SOCK_OPS_TCP_LISTEN_CB)); | ||
42 | |||
43 | EXPECT_EQ(expected_events, result->event_map, "#" PRIx32); | ||
44 | EXPECT_EQ(501ULL, result->bytes_received, "llu"); | ||
45 | EXPECT_EQ(1002ULL, result->bytes_acked, "llu"); | ||
46 | EXPECT_EQ(1, result->data_segs_in, PRIu32); | ||
47 | EXPECT_EQ(1, result->data_segs_out, PRIu32); | ||
48 | EXPECT_EQ(0x80, result->bad_cb_test_rv, PRIu32); | ||
49 | EXPECT_EQ(0, result->good_cb_test_rv, PRIu32); | ||
50 | EXPECT_EQ(1, result->num_listen, PRIu32); | ||
51 | |||
52 | return 0; | ||
53 | err: | ||
54 | return -1; | ||
55 | } | ||
56 | |||
25 | static int bpf_find_map(const char *test, struct bpf_object *obj, | 57 | static int bpf_find_map(const char *test, struct bpf_object *obj, |
26 | const char *name) | 58 | const char *name) |
27 | { | 59 | { |
@@ -35,42 +67,28 @@ static int bpf_find_map(const char *test, struct bpf_object *obj, | |||
35 | return bpf_map__fd(map); | 67 | return bpf_map__fd(map); |
36 | } | 68 | } |
37 | 69 | ||
38 | #define SYSTEM(CMD) \ | ||
39 | do { \ | ||
40 | if (system(CMD)) { \ | ||
41 | printf("system(%s) FAILS!\n", CMD); \ | ||
42 | } \ | ||
43 | } while (0) | ||
44 | |||
45 | int main(int argc, char **argv) | 70 | int main(int argc, char **argv) |
46 | { | 71 | { |
47 | const char *file = "test_tcpbpf_kern.o"; | 72 | const char *file = "test_tcpbpf_kern.o"; |
48 | struct tcpbpf_globals g = {0}; | 73 | struct tcpbpf_globals g = {0}; |
49 | int cg_fd, prog_fd, map_fd; | 74 | const char *cg_path = "/foo"; |
50 | bool debug_flag = false; | ||
51 | int error = EXIT_FAILURE; | 75 | int error = EXIT_FAILURE; |
52 | struct bpf_object *obj; | 76 | struct bpf_object *obj; |
53 | char cmd[100], *dir; | 77 | int prog_fd, map_fd; |
54 | struct stat buffer; | 78 | int cg_fd = -1; |
55 | __u32 key = 0; | 79 | __u32 key = 0; |
56 | int pid; | ||
57 | int rv; | 80 | int rv; |
58 | 81 | ||
59 | if (argc > 1 && strcmp(argv[1], "-d") == 0) | 82 | if (setup_cgroup_environment()) |
60 | debug_flag = true; | 83 | goto err; |
61 | 84 | ||
62 | dir = "/tmp/cgroupv2/foo"; | 85 | cg_fd = create_and_get_cgroup(cg_path); |
86 | if (!cg_fd) | ||
87 | goto err; | ||
63 | 88 | ||
64 | if (stat(dir, &buffer) != 0) { | 89 | if (join_cgroup(cg_path)) |
65 | SYSTEM("mkdir -p /tmp/cgroupv2"); | 90 | goto err; |
66 | SYSTEM("mount -t cgroup2 none /tmp/cgroupv2"); | ||
67 | SYSTEM("mkdir -p /tmp/cgroupv2/foo"); | ||
68 | } | ||
69 | pid = (int) getpid(); | ||
70 | sprintf(cmd, "echo %d >> /tmp/cgroupv2/foo/cgroup.procs", pid); | ||
71 | SYSTEM(cmd); | ||
72 | 91 | ||
73 | cg_fd = open(dir, O_DIRECTORY, O_RDONLY); | ||
74 | if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { | 92 | if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { |
75 | printf("FAILED: load_bpf_file failed for: %s\n", file); | 93 | printf("FAILED: load_bpf_file failed for: %s\n", file); |
76 | goto err; | 94 | goto err; |
@@ -83,7 +101,10 @@ int main(int argc, char **argv) | |||
83 | goto err; | 101 | goto err; |
84 | } | 102 | } |
85 | 103 | ||
86 | SYSTEM("./tcp_server.py"); | 104 | if (system("./tcp_server.py")) { |
105 | printf("FAILED: TCP server\n"); | ||
106 | goto err; | ||
107 | } | ||
87 | 108 | ||
88 | map_fd = bpf_find_map(__func__, obj, "global_map"); | 109 | map_fd = bpf_find_map(__func__, obj, "global_map"); |
89 | if (map_fd < 0) | 110 | if (map_fd < 0) |
@@ -95,34 +116,16 @@ int main(int argc, char **argv) | |||
95 | goto err; | 116 | goto err; |
96 | } | 117 | } |
97 | 118 | ||
98 | if (g.bytes_received != 501 || g.bytes_acked != 1002 || | 119 | if (verify_result(&g)) { |
99 | g.data_segs_in != 1 || g.data_segs_out != 1 || | ||
100 | (g.event_map ^ 0x47e) != 0 || g.bad_cb_test_rv != 0x80 || | ||
101 | g.good_cb_test_rv != 0) { | ||
102 | printf("FAILED: Wrong stats\n"); | 120 | printf("FAILED: Wrong stats\n"); |
103 | if (debug_flag) { | ||
104 | printf("\n"); | ||
105 | printf("bytes_received: %d (expecting 501)\n", | ||
106 | (int)g.bytes_received); | ||
107 | printf("bytes_acked: %d (expecting 1002)\n", | ||
108 | (int)g.bytes_acked); | ||
109 | printf("data_segs_in: %d (expecting 1)\n", | ||
110 | g.data_segs_in); | ||
111 | printf("data_segs_out: %d (expecting 1)\n", | ||
112 | g.data_segs_out); | ||
113 | printf("event_map: 0x%x (at least 0x47e)\n", | ||
114 | g.event_map); | ||
115 | printf("bad_cb_test_rv: 0x%x (expecting 0x80)\n", | ||
116 | g.bad_cb_test_rv); | ||
117 | printf("good_cb_test_rv:0x%x (expecting 0)\n", | ||
118 | g.good_cb_test_rv); | ||
119 | } | ||
120 | goto err; | 121 | goto err; |
121 | } | 122 | } |
123 | |||
122 | printf("PASSED!\n"); | 124 | printf("PASSED!\n"); |
123 | error = 0; | 125 | error = 0; |
124 | err: | 126 | err: |
125 | bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); | 127 | bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); |
128 | close(cg_fd); | ||
129 | cleanup_cgroup_environment(); | ||
126 | return error; | 130 | return error; |
127 | |||
128 | } | 131 | } |
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 41106d9d5cc7..67c412d19c09 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -42,15 +42,12 @@ | |||
42 | #endif | 42 | #endif |
43 | #include "bpf_rlimit.h" | 43 | #include "bpf_rlimit.h" |
44 | #include "bpf_rand.h" | 44 | #include "bpf_rand.h" |
45 | #include "bpf_util.h" | ||
45 | #include "../../../include/linux/filter.h" | 46 | #include "../../../include/linux/filter.h" |
46 | 47 | ||
47 | #ifndef ARRAY_SIZE | ||
48 | # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
49 | #endif | ||
50 | |||
51 | #define MAX_INSNS BPF_MAXINSNS | 48 | #define MAX_INSNS BPF_MAXINSNS |
52 | #define MAX_FIXUPS 8 | 49 | #define MAX_FIXUPS 8 |
53 | #define MAX_NR_MAPS 7 | 50 | #define MAX_NR_MAPS 8 |
54 | #define POINTER_VALUE 0xcafe4all | 51 | #define POINTER_VALUE 0xcafe4all |
55 | #define TEST_DATA_LEN 64 | 52 | #define TEST_DATA_LEN 64 |
56 | 53 | ||
@@ -70,6 +67,7 @@ struct bpf_test { | |||
70 | int fixup_prog1[MAX_FIXUPS]; | 67 | int fixup_prog1[MAX_FIXUPS]; |
71 | int fixup_prog2[MAX_FIXUPS]; | 68 | int fixup_prog2[MAX_FIXUPS]; |
72 | int fixup_map_in_map[MAX_FIXUPS]; | 69 | int fixup_map_in_map[MAX_FIXUPS]; |
70 | int fixup_cgroup_storage[MAX_FIXUPS]; | ||
73 | const char *errstr; | 71 | const char *errstr; |
74 | const char *errstr_unpriv; | 72 | const char *errstr_unpriv; |
75 | uint32_t retval; | 73 | uint32_t retval; |
@@ -4631,6 +4629,121 @@ static struct bpf_test tests[] = { | |||
4631 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 4629 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
4632 | }, | 4630 | }, |
4633 | { | 4631 | { |
4632 | "valid cgroup storage access", | ||
4633 | .insns = { | ||
4634 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
4635 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4636 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4637 | BPF_FUNC_get_local_storage), | ||
4638 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), | ||
4639 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), | ||
4640 | BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1), | ||
4641 | BPF_EXIT_INSN(), | ||
4642 | }, | ||
4643 | .fixup_cgroup_storage = { 1 }, | ||
4644 | .result = ACCEPT, | ||
4645 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4646 | }, | ||
4647 | { | ||
4648 | "invalid cgroup storage access 1", | ||
4649 | .insns = { | ||
4650 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
4651 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4652 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4653 | BPF_FUNC_get_local_storage), | ||
4654 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), | ||
4655 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), | ||
4656 | BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1), | ||
4657 | BPF_EXIT_INSN(), | ||
4658 | }, | ||
4659 | .fixup_map1 = { 1 }, | ||
4660 | .result = REJECT, | ||
4661 | .errstr = "cannot pass map_type 1 into func bpf_get_local_storage", | ||
4662 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4663 | }, | ||
4664 | { | ||
4665 | "invalid cgroup storage access 2", | ||
4666 | .insns = { | ||
4667 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
4668 | BPF_LD_MAP_FD(BPF_REG_1, 1), | ||
4669 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4670 | BPF_FUNC_get_local_storage), | ||
4671 | BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1), | ||
4672 | BPF_EXIT_INSN(), | ||
4673 | }, | ||
4674 | .result = REJECT, | ||
4675 | .errstr = "fd 1 is not pointing to valid bpf_map", | ||
4676 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4677 | }, | ||
4678 | { | ||
4679 | "invalid per-cgroup storage access 3", | ||
4680 | .insns = { | ||
4681 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
4682 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4683 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4684 | BPF_FUNC_get_local_storage), | ||
4685 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256), | ||
4686 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1), | ||
4687 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
4688 | BPF_EXIT_INSN(), | ||
4689 | }, | ||
4690 | .fixup_cgroup_storage = { 1 }, | ||
4691 | .result = REJECT, | ||
4692 | .errstr = "invalid access to map value, value_size=64 off=256 size=4", | ||
4693 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4694 | }, | ||
4695 | { | ||
4696 | "invalid cgroup storage access 4", | ||
4697 | .insns = { | ||
4698 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
4699 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4700 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4701 | BPF_FUNC_get_local_storage), | ||
4702 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2), | ||
4703 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), | ||
4704 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1), | ||
4705 | BPF_EXIT_INSN(), | ||
4706 | }, | ||
4707 | .fixup_cgroup_storage = { 1 }, | ||
4708 | .result = REJECT, | ||
4709 | .errstr = "invalid access to map value, value_size=64 off=-2 size=4", | ||
4710 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4711 | }, | ||
4712 | { | ||
4713 | "invalid cgroup storage access 5", | ||
4714 | .insns = { | ||
4715 | BPF_MOV64_IMM(BPF_REG_2, 7), | ||
4716 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4717 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4718 | BPF_FUNC_get_local_storage), | ||
4719 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), | ||
4720 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), | ||
4721 | BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1), | ||
4722 | BPF_EXIT_INSN(), | ||
4723 | }, | ||
4724 | .fixup_cgroup_storage = { 1 }, | ||
4725 | .result = REJECT, | ||
4726 | .errstr = "get_local_storage() doesn't support non-zero flags", | ||
4727 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4728 | }, | ||
4729 | { | ||
4730 | "invalid cgroup storage access 6", | ||
4731 | .insns = { | ||
4732 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_1), | ||
4733 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
4734 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | ||
4735 | BPF_FUNC_get_local_storage), | ||
4736 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), | ||
4737 | BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), | ||
4738 | BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1), | ||
4739 | BPF_EXIT_INSN(), | ||
4740 | }, | ||
4741 | .fixup_cgroup_storage = { 1 }, | ||
4742 | .result = REJECT, | ||
4743 | .errstr = "get_local_storage() doesn't support non-zero flags", | ||
4744 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | ||
4745 | }, | ||
4746 | { | ||
4634 | "multiple registers share map_lookup_elem result", | 4747 | "multiple registers share map_lookup_elem result", |
4635 | .insns = { | 4748 | .insns = { |
4636 | BPF_MOV64_IMM(BPF_REG_1, 10), | 4749 | BPF_MOV64_IMM(BPF_REG_1, 10), |
@@ -6997,7 +7110,7 @@ static struct bpf_test tests[] = { | |||
6997 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | 7110 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), |
6998 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | 7111 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, |
6999 | BPF_FUNC_map_lookup_elem), | 7112 | BPF_FUNC_map_lookup_elem), |
7000 | BPF_MOV64_REG(BPF_REG_0, 0), | 7113 | BPF_MOV64_IMM(BPF_REG_0, 0), |
7001 | BPF_EXIT_INSN(), | 7114 | BPF_EXIT_INSN(), |
7002 | }, | 7115 | }, |
7003 | .fixup_map_in_map = { 3 }, | 7116 | .fixup_map_in_map = { 3 }, |
@@ -7020,7 +7133,7 @@ static struct bpf_test tests[] = { | |||
7020 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), | 7133 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), |
7021 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | 7134 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, |
7022 | BPF_FUNC_map_lookup_elem), | 7135 | BPF_FUNC_map_lookup_elem), |
7023 | BPF_MOV64_REG(BPF_REG_0, 0), | 7136 | BPF_MOV64_IMM(BPF_REG_0, 0), |
7024 | BPF_EXIT_INSN(), | 7137 | BPF_EXIT_INSN(), |
7025 | }, | 7138 | }, |
7026 | .fixup_map_in_map = { 3 }, | 7139 | .fixup_map_in_map = { 3 }, |
@@ -7042,7 +7155,7 @@ static struct bpf_test tests[] = { | |||
7042 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | 7155 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), |
7043 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, | 7156 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, |
7044 | BPF_FUNC_map_lookup_elem), | 7157 | BPF_FUNC_map_lookup_elem), |
7045 | BPF_MOV64_REG(BPF_REG_0, 0), | 7158 | BPF_MOV64_IMM(BPF_REG_0, 0), |
7046 | BPF_EXIT_INSN(), | 7159 | BPF_EXIT_INSN(), |
7047 | }, | 7160 | }, |
7048 | .fixup_map_in_map = { 3 }, | 7161 | .fixup_map_in_map = { 3 }, |
@@ -12372,6 +12485,32 @@ static struct bpf_test tests[] = { | |||
12372 | .result = REJECT, | 12485 | .result = REJECT, |
12373 | .errstr = "variable ctx access var_off=(0x0; 0x4)", | 12486 | .errstr = "variable ctx access var_off=(0x0; 0x4)", |
12374 | }, | 12487 | }, |
12488 | { | ||
12489 | "mov64 src == dst", | ||
12490 | .insns = { | ||
12491 | BPF_MOV64_IMM(BPF_REG_2, 0), | ||
12492 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_2), | ||
12493 | // Check bounds are OK | ||
12494 | BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), | ||
12495 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
12496 | BPF_EXIT_INSN(), | ||
12497 | }, | ||
12498 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
12499 | .result = ACCEPT, | ||
12500 | }, | ||
12501 | { | ||
12502 | "mov64 src != dst", | ||
12503 | .insns = { | ||
12504 | BPF_MOV64_IMM(BPF_REG_3, 0), | ||
12505 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_3), | ||
12506 | // Check bounds are OK | ||
12507 | BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), | ||
12508 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
12509 | BPF_EXIT_INSN(), | ||
12510 | }, | ||
12511 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
12512 | .result = ACCEPT, | ||
12513 | }, | ||
12375 | }; | 12514 | }; |
12376 | 12515 | ||
12377 | static int probe_filter_length(const struct bpf_insn *fp) | 12516 | static int probe_filter_length(const struct bpf_insn *fp) |
@@ -12476,6 +12615,19 @@ static int create_map_in_map(void) | |||
12476 | return outer_map_fd; | 12615 | return outer_map_fd; |
12477 | } | 12616 | } |
12478 | 12617 | ||
12618 | static int create_cgroup_storage(void) | ||
12619 | { | ||
12620 | int fd; | ||
12621 | |||
12622 | fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE, | ||
12623 | sizeof(struct bpf_cgroup_storage_key), | ||
12624 | TEST_DATA_LEN, 0, 0); | ||
12625 | if (fd < 0) | ||
12626 | printf("Failed to create array '%s'!\n", strerror(errno)); | ||
12627 | |||
12628 | return fd; | ||
12629 | } | ||
12630 | |||
12479 | static char bpf_vlog[UINT_MAX >> 8]; | 12631 | static char bpf_vlog[UINT_MAX >> 8]; |
12480 | 12632 | ||
12481 | static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, | 12633 | static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, |
@@ -12488,6 +12640,7 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, | |||
12488 | int *fixup_prog1 = test->fixup_prog1; | 12640 | int *fixup_prog1 = test->fixup_prog1; |
12489 | int *fixup_prog2 = test->fixup_prog2; | 12641 | int *fixup_prog2 = test->fixup_prog2; |
12490 | int *fixup_map_in_map = test->fixup_map_in_map; | 12642 | int *fixup_map_in_map = test->fixup_map_in_map; |
12643 | int *fixup_cgroup_storage = test->fixup_cgroup_storage; | ||
12491 | 12644 | ||
12492 | if (test->fill_helper) | 12645 | if (test->fill_helper) |
12493 | test->fill_helper(test); | 12646 | test->fill_helper(test); |
@@ -12555,6 +12708,14 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog, | |||
12555 | fixup_map_in_map++; | 12708 | fixup_map_in_map++; |
12556 | } while (*fixup_map_in_map); | 12709 | } while (*fixup_map_in_map); |
12557 | } | 12710 | } |
12711 | |||
12712 | if (*fixup_cgroup_storage) { | ||
12713 | map_fds[7] = create_cgroup_storage(); | ||
12714 | do { | ||
12715 | prog[*fixup_cgroup_storage].imm = map_fds[7]; | ||
12716 | fixup_cgroup_storage++; | ||
12717 | } while (*fixup_cgroup_storage); | ||
12718 | } | ||
12558 | } | 12719 | } |
12559 | 12720 | ||
12560 | static void do_test_single(struct bpf_test *test, bool unpriv, | 12721 | static void do_test_single(struct bpf_test *test, bool unpriv, |
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c index 3868dcb63420..cabe2a3a3b30 100644 --- a/tools/testing/selftests/bpf/trace_helpers.c +++ b/tools/testing/selftests/bpf/trace_helpers.c | |||
@@ -88,7 +88,7 @@ static int page_size; | |||
88 | static int page_cnt = 8; | 88 | static int page_cnt = 8; |
89 | static struct perf_event_mmap_page *header; | 89 | static struct perf_event_mmap_page *header; |
90 | 90 | ||
91 | int perf_event_mmap(int fd) | 91 | int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header) |
92 | { | 92 | { |
93 | void *base; | 93 | void *base; |
94 | int mmap_size; | 94 | int mmap_size; |
@@ -102,10 +102,15 @@ int perf_event_mmap(int fd) | |||
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | 104 | ||
105 | header = base; | 105 | *header = base; |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | int perf_event_mmap(int fd) | ||
110 | { | ||
111 | return perf_event_mmap_header(fd, &header); | ||
112 | } | ||
113 | |||
109 | static int perf_event_poll(int fd) | 114 | static int perf_event_poll(int fd) |
110 | { | 115 | { |
111 | struct pollfd pfd = { .fd = fd, .events = POLLIN }; | 116 | struct pollfd pfd = { .fd = fd, .events = POLLIN }; |
@@ -163,3 +168,42 @@ int perf_event_poller(int fd, perf_event_print_fn output_fn) | |||
163 | 168 | ||
164 | return ret; | 169 | return ret; |
165 | } | 170 | } |
171 | |||
172 | int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers, | ||
173 | int num_fds, perf_event_print_fn output_fn) | ||
174 | { | ||
175 | enum bpf_perf_event_ret ret; | ||
176 | struct pollfd *pfds; | ||
177 | void *buf = NULL; | ||
178 | size_t len = 0; | ||
179 | int i; | ||
180 | |||
181 | pfds = calloc(num_fds, sizeof(*pfds)); | ||
182 | if (!pfds) | ||
183 | return LIBBPF_PERF_EVENT_ERROR; | ||
184 | |||
185 | for (i = 0; i < num_fds; i++) { | ||
186 | pfds[i].fd = fds[i]; | ||
187 | pfds[i].events = POLLIN; | ||
188 | } | ||
189 | |||
190 | for (;;) { | ||
191 | poll(pfds, num_fds, 1000); | ||
192 | for (i = 0; i < num_fds; i++) { | ||
193 | if (!pfds[i].revents) | ||
194 | continue; | ||
195 | |||
196 | ret = bpf_perf_event_read_simple(headers[i], | ||
197 | page_cnt * page_size, | ||
198 | page_size, &buf, &len, | ||
199 | bpf_perf_event_print, | ||
200 | output_fn); | ||
201 | if (ret != LIBBPF_PERF_EVENT_CONT) | ||
202 | break; | ||
203 | } | ||
204 | } | ||
205 | free(buf); | ||
206 | free(pfds); | ||
207 | |||
208 | return ret; | ||
209 | } | ||
diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h index 3b4bcf7f5084..18924f23db1b 100644 --- a/tools/testing/selftests/bpf/trace_helpers.h +++ b/tools/testing/selftests/bpf/trace_helpers.h | |||
@@ -3,6 +3,7 @@ | |||
3 | #define __TRACE_HELPER_H | 3 | #define __TRACE_HELPER_H |
4 | 4 | ||
5 | #include <libbpf.h> | 5 | #include <libbpf.h> |
6 | #include <linux/perf_event.h> | ||
6 | 7 | ||
7 | struct ksym { | 8 | struct ksym { |
8 | long addr; | 9 | long addr; |
@@ -16,6 +17,9 @@ long ksym_get_addr(const char *name); | |||
16 | typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size); | 17 | typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size); |
17 | 18 | ||
18 | int perf_event_mmap(int fd); | 19 | int perf_event_mmap(int fd); |
20 | int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header); | ||
19 | /* return LIBBPF_PERF_EVENT_DONE or LIBBPF_PERF_EVENT_ERROR */ | 21 | /* return LIBBPF_PERF_EVENT_DONE or LIBBPF_PERF_EVENT_ERROR */ |
20 | int perf_event_poller(int fd, perf_event_print_fn output_fn); | 22 | int perf_event_poller(int fd, perf_event_print_fn output_fn); |
23 | int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers, | ||
24 | int num_fds, perf_event_print_fn output_fn); | ||
21 | #endif | 25 | #endif |
diff --git a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh new file mode 100755 index 000000000000..76f1ab4898d9 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre.sh | |||
@@ -0,0 +1,217 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # This test uses standard topology for testing gretap. See | ||
5 | # ../../../net/forwarding/mirror_gre_topo_lib.sh for more details. | ||
6 | # | ||
7 | # Test offloading various features of offloading gretap mirrors specific to | ||
8 | # mlxsw. | ||
9 | |||
10 | lib_dir=$(dirname $0)/../../../net/forwarding | ||
11 | |||
12 | NUM_NETIFS=6 | ||
13 | source $lib_dir/lib.sh | ||
14 | source $lib_dir/mirror_lib.sh | ||
15 | source $lib_dir/mirror_gre_lib.sh | ||
16 | source $lib_dir/mirror_gre_topo_lib.sh | ||
17 | |||
18 | setup_keyful() | ||
19 | { | ||
20 | tunnel_create gt6-key ip6gretap 2001:db8:3::1 2001:db8:3::2 \ | ||
21 | ttl 100 tos inherit allow-localremote \ | ||
22 | key 1234 | ||
23 | |||
24 | tunnel_create h3-gt6-key ip6gretap 2001:db8:3::2 2001:db8:3::1 \ | ||
25 | key 1234 | ||
26 | ip link set h3-gt6-key vrf v$h3 | ||
27 | matchall_sink_create h3-gt6-key | ||
28 | |||
29 | ip address add dev $swp3 2001:db8:3::1/64 | ||
30 | ip address add dev $h3 2001:db8:3::2/64 | ||
31 | } | ||
32 | |||
33 | cleanup_keyful() | ||
34 | { | ||
35 | ip address del dev $h3 2001:db8:3::2/64 | ||
36 | ip address del dev $swp3 2001:db8:3::1/64 | ||
37 | |||
38 | tunnel_destroy h3-gt6-key | ||
39 | tunnel_destroy gt6-key | ||
40 | } | ||
41 | |||
42 | setup_soft() | ||
43 | { | ||
44 | # Set up a topology for testing underlay routes that point at an | ||
45 | # unsupported soft device. | ||
46 | |||
47 | tunnel_create gt6-soft ip6gretap 2001:db8:4::1 2001:db8:4::2 \ | ||
48 | ttl 100 tos inherit allow-localremote | ||
49 | |||
50 | tunnel_create h3-gt6-soft ip6gretap 2001:db8:4::2 2001:db8:4::1 | ||
51 | ip link set h3-gt6-soft vrf v$h3 | ||
52 | matchall_sink_create h3-gt6-soft | ||
53 | |||
54 | ip link add name v1 type veth peer name v2 | ||
55 | ip link set dev v1 up | ||
56 | ip address add dev v1 2001:db8:4::1/64 | ||
57 | |||
58 | ip link set dev v2 vrf v$h3 | ||
59 | ip link set dev v2 up | ||
60 | ip address add dev v2 2001:db8:4::2/64 | ||
61 | } | ||
62 | |||
63 | cleanup_soft() | ||
64 | { | ||
65 | ip link del dev v1 | ||
66 | |||
67 | tunnel_destroy h3-gt6-soft | ||
68 | tunnel_destroy gt6-soft | ||
69 | } | ||
70 | |||
71 | setup_prepare() | ||
72 | { | ||
73 | h1=${NETIFS[p1]} | ||
74 | swp1=${NETIFS[p2]} | ||
75 | |||
76 | swp2=${NETIFS[p3]} | ||
77 | h2=${NETIFS[p4]} | ||
78 | |||
79 | swp3=${NETIFS[p5]} | ||
80 | h3=${NETIFS[p6]} | ||
81 | |||
82 | vrf_prepare | ||
83 | mirror_gre_topo_create | ||
84 | |||
85 | ip address add dev $swp3 2001:db8:2::1/64 | ||
86 | ip address add dev $h3 2001:db8:2::2/64 | ||
87 | |||
88 | ip address add dev $swp3 192.0.2.129/28 | ||
89 | ip address add dev $h3 192.0.2.130/28 | ||
90 | |||
91 | setup_keyful | ||
92 | setup_soft | ||
93 | } | ||
94 | |||
95 | cleanup() | ||
96 | { | ||
97 | pre_cleanup | ||
98 | |||
99 | cleanup_soft | ||
100 | cleanup_keyful | ||
101 | |||
102 | ip address del dev $h3 2001:db8:2::2/64 | ||
103 | ip address del dev $swp3 2001:db8:2::1/64 | ||
104 | |||
105 | ip address del dev $h3 192.0.2.130/28 | ||
106 | ip address del dev $swp3 192.0.2.129/28 | ||
107 | |||
108 | mirror_gre_topo_destroy | ||
109 | vrf_cleanup | ||
110 | } | ||
111 | |||
112 | test_span_gre_ttl_inherit() | ||
113 | { | ||
114 | local tundev=$1; shift | ||
115 | local type=$1; shift | ||
116 | local what=$1; shift | ||
117 | |||
118 | RET=0 | ||
119 | |||
120 | ip link set dev $tundev type $type ttl inherit | ||
121 | mirror_install $swp1 ingress $tundev "matchall $tcflags" | ||
122 | fail_test_span_gre_dir $tundev ingress | ||
123 | |||
124 | ip link set dev $tundev type $type ttl 100 | ||
125 | |||
126 | quick_test_span_gre_dir $tundev ingress | ||
127 | mirror_uninstall $swp1 ingress | ||
128 | |||
129 | log_test "$what: no offload on TTL of inherit ($tcflags)" | ||
130 | } | ||
131 | |||
132 | test_span_gre_tos_fixed() | ||
133 | { | ||
134 | local tundev=$1; shift | ||
135 | local type=$1; shift | ||
136 | local what=$1; shift | ||
137 | |||
138 | RET=0 | ||
139 | |||
140 | ip link set dev $tundev type $type tos 0x10 | ||
141 | mirror_install $swp1 ingress $tundev "matchall $tcflags" | ||
142 | fail_test_span_gre_dir $tundev ingress | ||
143 | |||
144 | ip link set dev $tundev type $type tos inherit | ||
145 | quick_test_span_gre_dir $tundev ingress | ||
146 | mirror_uninstall $swp1 ingress | ||
147 | |||
148 | log_test "$what: no offload on a fixed TOS ($tcflags)" | ||
149 | } | ||
150 | |||
151 | test_span_failable() | ||
152 | { | ||
153 | local should_fail=$1; shift | ||
154 | local tundev=$1; shift | ||
155 | local what=$1; shift | ||
156 | |||
157 | RET=0 | ||
158 | |||
159 | mirror_install $swp1 ingress $tundev "matchall $tcflags" | ||
160 | if ((should_fail)); then | ||
161 | fail_test_span_gre_dir $tundev ingress | ||
162 | else | ||
163 | quick_test_span_gre_dir $tundev ingress | ||
164 | fi | ||
165 | mirror_uninstall $swp1 ingress | ||
166 | |||
167 | log_test "$what: should_fail=$should_fail ($tcflags)" | ||
168 | } | ||
169 | |||
170 | test_failable() | ||
171 | { | ||
172 | local should_fail=$1; shift | ||
173 | |||
174 | test_span_failable $should_fail gt6-key "mirror to keyful gretap" | ||
175 | test_span_failable $should_fail gt6-soft "mirror to gretap w/ soft underlay" | ||
176 | } | ||
177 | |||
178 | test_sw() | ||
179 | { | ||
180 | slow_path_trap_install $swp1 ingress | ||
181 | slow_path_trap_install $swp1 egress | ||
182 | |||
183 | test_failable 0 | ||
184 | |||
185 | slow_path_trap_uninstall $swp1 egress | ||
186 | slow_path_trap_uninstall $swp1 ingress | ||
187 | } | ||
188 | |||
189 | test_hw() | ||
190 | { | ||
191 | test_failable 1 | ||
192 | |||
193 | test_span_gre_tos_fixed gt4 gretap "mirror to gretap" | ||
194 | test_span_gre_tos_fixed gt6 ip6gretap "mirror to ip6gretap" | ||
195 | |||
196 | test_span_gre_ttl_inherit gt4 gretap "mirror to gretap" | ||
197 | test_span_gre_ttl_inherit gt6 ip6gretap "mirror to ip6gretap" | ||
198 | } | ||
199 | |||
200 | trap cleanup EXIT | ||
201 | |||
202 | setup_prepare | ||
203 | setup_wait | ||
204 | |||
205 | if ! tc_offload_check; then | ||
206 | check_err 1 "Could not test offloaded functionality" | ||
207 | log_test "mlxsw-specific tests for mirror to gretap" | ||
208 | exit | ||
209 | fi | ||
210 | |||
211 | tcflags="skip_hw" | ||
212 | test_sw | ||
213 | |||
214 | tcflags="skip_sw" | ||
215 | test_hw | ||
216 | |||
217 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh new file mode 100644 index 000000000000..6f3a70df63bc --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/mirror_gre_scale.sh | |||
@@ -0,0 +1,197 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | # Test offloading a number of mirrors-to-gretap. The test creates a number of | ||
4 | # tunnels. Then it adds one flower mirror for each of the tunnels, matching a | ||
5 | # given host IP. Then it generates traffic at each of the host IPs and checks | ||
6 | # that the traffic has been mirrored at the appropriate tunnel. | ||
7 | # | ||
8 | # +--------------------------+ +--------------------------+ | ||
9 | # | H1 | | H2 | | ||
10 | # | + $h1 | | $h2 + | | ||
11 | # | | 2001:db8:1:X::1/64 | | 2001:db8:1:X::2/64 | | | ||
12 | # +-----|--------------------+ +--------------------|-----+ | ||
13 | # | | | ||
14 | # +-----|-------------------------------------------------------------|-----+ | ||
15 | # | SW o--> mirrors | | | ||
16 | # | +---|-------------------------------------------------------------|---+ | | ||
17 | # | | + $swp1 BR $swp2 + | | | ||
18 | # | +---------------------------------------------------------------------+ | | ||
19 | # | | | ||
20 | # | + $swp3 + gt6-<X> (ip6gretap) | | ||
21 | # | | 2001:db8:2:X::1/64 : loc=2001:db8:2:X::1 | | ||
22 | # | | : rem=2001:db8:2:X::2 | | ||
23 | # | | : ttl=100 | | ||
24 | # | | : tos=inherit | | ||
25 | # | | : | | ||
26 | # +-----|--------------------------------:----------------------------------+ | ||
27 | # | : | ||
28 | # +-----|--------------------------------:----------------------------------+ | ||
29 | # | H3 + $h3 + h3-gt6-<X> (ip6gretap) | | ||
30 | # | 2001:db8:2:X::2/64 loc=2001:db8:2:X::2 | | ||
31 | # | rem=2001:db8:2:X::1 | | ||
32 | # | ttl=100 | | ||
33 | # | tos=inherit | | ||
34 | # | | | ||
35 | # +-------------------------------------------------------------------------+ | ||
36 | |||
37 | source ../../../../net/forwarding/mirror_lib.sh | ||
38 | |||
39 | MIRROR_NUM_NETIFS=6 | ||
40 | |||
41 | mirror_gre_ipv6_addr() | ||
42 | { | ||
43 | local net=$1; shift | ||
44 | local num=$1; shift | ||
45 | |||
46 | printf "2001:db8:%x:%x" $net $num | ||
47 | } | ||
48 | |||
49 | mirror_gre_tunnels_create() | ||
50 | { | ||
51 | local count=$1; shift | ||
52 | local should_fail=$1; shift | ||
53 | |||
54 | MIRROR_GRE_BATCH_FILE="$(mktemp)" | ||
55 | for ((i=0; i < count; ++i)); do | ||
56 | local match_dip=$(mirror_gre_ipv6_addr 1 $i)::2 | ||
57 | local htun=h3-gt6-$i | ||
58 | local tun=gt6-$i | ||
59 | |||
60 | ((mirror_gre_tunnels++)) | ||
61 | |||
62 | ip address add dev $h1 $(mirror_gre_ipv6_addr 1 $i)::1/64 | ||
63 | ip address add dev $h2 $(mirror_gre_ipv6_addr 1 $i)::2/64 | ||
64 | |||
65 | ip address add dev $swp3 $(mirror_gre_ipv6_addr 2 $i)::1/64 | ||
66 | ip address add dev $h3 $(mirror_gre_ipv6_addr 2 $i)::2/64 | ||
67 | |||
68 | tunnel_create $tun ip6gretap \ | ||
69 | $(mirror_gre_ipv6_addr 2 $i)::1 \ | ||
70 | $(mirror_gre_ipv6_addr 2 $i)::2 \ | ||
71 | ttl 100 tos inherit allow-localremote | ||
72 | |||
73 | tunnel_create $htun ip6gretap \ | ||
74 | $(mirror_gre_ipv6_addr 2 $i)::2 \ | ||
75 | $(mirror_gre_ipv6_addr 2 $i)::1 | ||
76 | ip link set $htun vrf v$h3 | ||
77 | matchall_sink_create $htun | ||
78 | |||
79 | cat >> $MIRROR_GRE_BATCH_FILE <<-EOF | ||
80 | filter add dev $swp1 ingress pref 1000 \ | ||
81 | protocol ipv6 \ | ||
82 | flower $tcflags dst_ip $match_dip \ | ||
83 | action mirred egress mirror dev $tun | ||
84 | EOF | ||
85 | done | ||
86 | |||
87 | tc -b $MIRROR_GRE_BATCH_FILE | ||
88 | check_err_fail $should_fail $? "Mirror rule insertion" | ||
89 | } | ||
90 | |||
91 | mirror_gre_tunnels_destroy() | ||
92 | { | ||
93 | local count=$1; shift | ||
94 | |||
95 | for ((i=0; i < count; ++i)); do | ||
96 | local htun=h3-gt6-$i | ||
97 | local tun=gt6-$i | ||
98 | |||
99 | ip address del dev $h3 $(mirror_gre_ipv6_addr 2 $i)::2/64 | ||
100 | ip address del dev $swp3 $(mirror_gre_ipv6_addr 2 $i)::1/64 | ||
101 | |||
102 | ip address del dev $h2 $(mirror_gre_ipv6_addr 1 $i)::2/64 | ||
103 | ip address del dev $h1 $(mirror_gre_ipv6_addr 1 $i)::1/64 | ||
104 | |||
105 | tunnel_destroy $htun | ||
106 | tunnel_destroy $tun | ||
107 | done | ||
108 | } | ||
109 | |||
110 | __mirror_gre_test() | ||
111 | { | ||
112 | local count=$1; shift | ||
113 | local should_fail=$1; shift | ||
114 | |||
115 | mirror_gre_tunnels_create $count $should_fail | ||
116 | if ((should_fail)); then | ||
117 | return | ||
118 | fi | ||
119 | |||
120 | sleep 5 | ||
121 | |||
122 | for ((i = 0; i < count; ++i)); do | ||
123 | local dip=$(mirror_gre_ipv6_addr 1 $i)::2 | ||
124 | local htun=h3-gt6-$i | ||
125 | local message | ||
126 | |||
127 | icmp6_capture_install $htun | ||
128 | mirror_test v$h1 "" $dip $htun 100 10 | ||
129 | icmp6_capture_uninstall $htun | ||
130 | done | ||
131 | } | ||
132 | |||
133 | mirror_gre_test() | ||
134 | { | ||
135 | local count=$1; shift | ||
136 | local should_fail=$1; shift | ||
137 | |||
138 | if ! tc_offload_check $TC_FLOWER_NUM_NETIFS; then | ||
139 | check_err 1 "Could not test offloaded functionality" | ||
140 | return | ||
141 | fi | ||
142 | |||
143 | tcflags="skip_sw" | ||
144 | __mirror_gre_test $count $should_fail | ||
145 | } | ||
146 | |||
147 | mirror_gre_setup_prepare() | ||
148 | { | ||
149 | h1=${NETIFS[p1]} | ||
150 | swp1=${NETIFS[p2]} | ||
151 | |||
152 | swp2=${NETIFS[p3]} | ||
153 | h2=${NETIFS[p4]} | ||
154 | |||
155 | swp3=${NETIFS[p5]} | ||
156 | h3=${NETIFS[p6]} | ||
157 | |||
158 | mirror_gre_tunnels=0 | ||
159 | |||
160 | vrf_prepare | ||
161 | |||
162 | simple_if_init $h1 | ||
163 | simple_if_init $h2 | ||
164 | simple_if_init $h3 | ||
165 | |||
166 | ip link add name br1 type bridge vlan_filtering 1 | ||
167 | ip link set dev br1 up | ||
168 | |||
169 | ip link set dev $swp1 master br1 | ||
170 | ip link set dev $swp1 up | ||
171 | tc qdisc add dev $swp1 clsact | ||
172 | |||
173 | ip link set dev $swp2 master br1 | ||
174 | ip link set dev $swp2 up | ||
175 | |||
176 | ip link set dev $swp3 up | ||
177 | } | ||
178 | |||
179 | mirror_gre_cleanup() | ||
180 | { | ||
181 | mirror_gre_tunnels_destroy $mirror_gre_tunnels | ||
182 | |||
183 | ip link set dev $swp3 down | ||
184 | |||
185 | ip link set dev $swp2 down | ||
186 | |||
187 | tc qdisc del dev $swp1 clsact | ||
188 | ip link set dev $swp1 down | ||
189 | |||
190 | ip link del dev br1 | ||
191 | |||
192 | simple_if_fini $h3 | ||
193 | simple_if_fini $h2 | ||
194 | simple_if_fini $h1 | ||
195 | |||
196 | vrf_cleanup | ||
197 | } | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh new file mode 100755 index 000000000000..1ca631d5aaba --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_bridge.sh | |||
@@ -0,0 +1,189 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for DSCP prioritization and rewrite. Packets ingress $swp1 with a DSCP | ||
5 | # tag and are prioritized according to the map at $swp1. They egress $swp2 and | ||
6 | # the DSCP value is updated to match the map at that interface. The updated DSCP | ||
7 | # tag is verified at $h2. | ||
8 | # | ||
9 | # ICMP responses are produced with the same DSCP tag that arrived at $h2. They | ||
10 | # go through prioritization at $swp2 and DSCP retagging at $swp1. The tag is | ||
11 | # verified at $h1--it should match the original tag. | ||
12 | # | ||
13 | # +----------------------+ +----------------------+ | ||
14 | # | H1 | | H2 | | ||
15 | # | + $h1 | | $h2 + | | ||
16 | # | | 192.0.2.1/28 | | 192.0.2.2/28 | | | ||
17 | # +----|-----------------+ +----------------|-----+ | ||
18 | # | | | ||
19 | # +----|----------------------------------------------------------------|-----+ | ||
20 | # | SW | | | | ||
21 | # | +-|----------------------------------------------------------------|-+ | | ||
22 | # | | + $swp1 BR $swp2 + | | | ||
23 | # | | APP=0,5,10 .. 7,5,17 APP=0,5,20 .. 7,5,27 | | | ||
24 | # | +--------------------------------------------------------------------+ | | ||
25 | # +---------------------------------------------------------------------------+ | ||
26 | |||
27 | ALL_TESTS=" | ||
28 | ping_ipv4 | ||
29 | test_dscp | ||
30 | " | ||
31 | |||
32 | lib_dir=$(dirname $0)/../../../net/forwarding | ||
33 | |||
34 | NUM_NETIFS=4 | ||
35 | source $lib_dir/lib.sh | ||
36 | |||
37 | h1_create() | ||
38 | { | ||
39 | local dscp; | ||
40 | |||
41 | simple_if_init $h1 192.0.2.1/28 | ||
42 | tc qdisc add dev $h1 clsact | ||
43 | dscp_capture_install $h1 10 | ||
44 | } | ||
45 | |||
46 | h1_destroy() | ||
47 | { | ||
48 | dscp_capture_uninstall $h1 10 | ||
49 | tc qdisc del dev $h1 clsact | ||
50 | simple_if_fini $h1 192.0.2.1/28 | ||
51 | } | ||
52 | |||
53 | h2_create() | ||
54 | { | ||
55 | simple_if_init $h2 192.0.2.2/28 | ||
56 | tc qdisc add dev $h2 clsact | ||
57 | dscp_capture_install $h2 20 | ||
58 | } | ||
59 | |||
60 | h2_destroy() | ||
61 | { | ||
62 | dscp_capture_uninstall $h2 20 | ||
63 | tc qdisc del dev $h2 clsact | ||
64 | simple_if_fini $h2 192.0.2.2/28 | ||
65 | } | ||
66 | |||
67 | dscp_map() | ||
68 | { | ||
69 | local base=$1; shift | ||
70 | |||
71 | for prio in {0..7}; do | ||
72 | echo app=$prio,5,$((base + prio)) | ||
73 | done | ||
74 | } | ||
75 | |||
76 | switch_create() | ||
77 | { | ||
78 | ip link add name br1 type bridge vlan_filtering 1 | ||
79 | ip link set dev br1 up | ||
80 | ip link set dev $swp1 master br1 | ||
81 | ip link set dev $swp1 up | ||
82 | ip link set dev $swp2 master br1 | ||
83 | ip link set dev $swp2 up | ||
84 | |||
85 | lldptool -T -i $swp1 -V APP $(dscp_map 10) >/dev/null | ||
86 | lldptool -T -i $swp2 -V APP $(dscp_map 20) >/dev/null | ||
87 | lldpad_app_wait_set $swp1 | ||
88 | lldpad_app_wait_set $swp2 | ||
89 | } | ||
90 | |||
91 | switch_destroy() | ||
92 | { | ||
93 | lldptool -T -i $swp2 -V APP -d $(dscp_map 20) >/dev/null | ||
94 | lldptool -T -i $swp1 -V APP -d $(dscp_map 10) >/dev/null | ||
95 | lldpad_app_wait_del | ||
96 | |||
97 | ip link set dev $swp2 nomaster | ||
98 | ip link set dev $swp1 nomaster | ||
99 | ip link del dev br1 | ||
100 | } | ||
101 | |||
102 | setup_prepare() | ||
103 | { | ||
104 | h1=${NETIFS[p1]} | ||
105 | swp1=${NETIFS[p2]} | ||
106 | |||
107 | swp2=${NETIFS[p3]} | ||
108 | h2=${NETIFS[p4]} | ||
109 | |||
110 | vrf_prepare | ||
111 | |||
112 | h1_create | ||
113 | h2_create | ||
114 | switch_create | ||
115 | } | ||
116 | |||
117 | cleanup() | ||
118 | { | ||
119 | pre_cleanup | ||
120 | |||
121 | switch_destroy | ||
122 | h2_destroy | ||
123 | h1_destroy | ||
124 | |||
125 | vrf_cleanup | ||
126 | } | ||
127 | |||
128 | ping_ipv4() | ||
129 | { | ||
130 | ping_test $h1 192.0.2.2 | ||
131 | } | ||
132 | |||
133 | dscp_ping_test() | ||
134 | { | ||
135 | local vrf_name=$1; shift | ||
136 | local sip=$1; shift | ||
137 | local dip=$1; shift | ||
138 | local prio=$1; shift | ||
139 | local dev_10=$1; shift | ||
140 | local dev_20=$1; shift | ||
141 | |||
142 | local dscp_10=$(((prio + 10) << 2)) | ||
143 | local dscp_20=$(((prio + 20) << 2)) | ||
144 | |||
145 | RET=0 | ||
146 | |||
147 | local -A t0s | ||
148 | eval "t0s=($(dscp_fetch_stats $dev_10 10) | ||
149 | $(dscp_fetch_stats $dev_20 20))" | ||
150 | |||
151 | ip vrf exec $vrf_name \ | ||
152 | ${PING} -Q $dscp_10 ${sip:+-I $sip} $dip \ | ||
153 | -c 10 -i 0.1 -w 2 &> /dev/null | ||
154 | |||
155 | local -A t1s | ||
156 | eval "t1s=($(dscp_fetch_stats $dev_10 10) | ||
157 | $(dscp_fetch_stats $dev_20 20))" | ||
158 | |||
159 | for key in ${!t0s[@]}; do | ||
160 | local expect | ||
161 | if ((key == prio+10 || key == prio+20)); then | ||
162 | expect=10 | ||
163 | else | ||
164 | expect=0 | ||
165 | fi | ||
166 | |||
167 | local delta=$((t1s[$key] - t0s[$key])) | ||
168 | ((expect == delta)) | ||
169 | check_err $? "DSCP $key: Expected to capture $expect packets, got $delta." | ||
170 | done | ||
171 | |||
172 | log_test "DSCP rewrite: $dscp_10-(prio $prio)-$dscp_20" | ||
173 | } | ||
174 | |||
175 | test_dscp() | ||
176 | { | ||
177 | for prio in {0..7}; do | ||
178 | dscp_ping_test v$h1 192.0.2.1 192.0.2.2 $prio $h1 $h2 | ||
179 | done | ||
180 | } | ||
181 | |||
182 | trap cleanup EXIT | ||
183 | |||
184 | setup_prepare | ||
185 | setup_wait | ||
186 | |||
187 | tests_run | ||
188 | |||
189 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh new file mode 100755 index 000000000000..281d90766e12 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/qos_dscp_router.sh | |||
@@ -0,0 +1,233 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for DSCP prioritization in the router. | ||
5 | # | ||
6 | # With ip_forward_update_priority disabled, the packets are expected to keep | ||
7 | # their DSCP (which in this test uses only values 0..7) intact as they are | ||
8 | # forwarded by the switch. That is verified at $h2. ICMP responses are formed | ||
9 | # with the same DSCP as the requests, and likewise pass through the switch | ||
10 | # intact, which is verified at $h1. | ||
11 | # | ||
12 | # With ip_forward_update_priority enabled, router reprioritizes the packets | ||
13 | # according to the table in reprioritize(). Thus, say, DSCP 7 maps to priority | ||
14 | # 4, which on egress maps back to DSCP 4. The response packet then gets | ||
15 | # reprioritized to 6, getting DSCP 6 on egress. | ||
16 | # | ||
17 | # +----------------------+ +----------------------+ | ||
18 | # | H1 | | H2 | | ||
19 | # | + $h1 | | $h2 + | | ||
20 | # | | 192.0.2.1/28 | | 192.0.2.18/28 | | | ||
21 | # +----|-----------------+ +----------------|-----+ | ||
22 | # | | | ||
23 | # +----|----------------------------------------------------------------|-----+ | ||
24 | # | SW | | | | ||
25 | # | + $swp1 $swp2 + | | ||
26 | # | 192.0.2.2/28 192.0.2.17/28 | | ||
27 | # | APP=0,5,0 .. 7,5,7 APP=0,5,0 .. 7,5,7 | | ||
28 | # +---------------------------------------------------------------------------+ | ||
29 | |||
30 | ALL_TESTS=" | ||
31 | ping_ipv4 | ||
32 | test_update | ||
33 | test_no_update | ||
34 | " | ||
35 | |||
36 | lib_dir=$(dirname $0)/../../../net/forwarding | ||
37 | |||
38 | NUM_NETIFS=4 | ||
39 | source $lib_dir/lib.sh | ||
40 | |||
41 | reprioritize() | ||
42 | { | ||
43 | local in=$1; shift | ||
44 | |||
45 | # This is based on rt_tos2priority in include/net/route.h. Assuming 1:1 | ||
46 | # mapping between priorities and TOS, it yields a new priority for a | ||
47 | # packet with ingress priority of $in. | ||
48 | local -a reprio=(0 0 2 2 6 6 4 4) | ||
49 | |||
50 | echo ${reprio[$in]} | ||
51 | } | ||
52 | |||
53 | h1_create() | ||
54 | { | ||
55 | local dscp; | ||
56 | |||
57 | simple_if_init $h1 192.0.2.1/28 | ||
58 | tc qdisc add dev $h1 clsact | ||
59 | dscp_capture_install $h1 0 | ||
60 | ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2 | ||
61 | } | ||
62 | |||
63 | h1_destroy() | ||
64 | { | ||
65 | ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2 | ||
66 | dscp_capture_uninstall $h1 0 | ||
67 | tc qdisc del dev $h1 clsact | ||
68 | simple_if_fini $h1 192.0.2.1/28 | ||
69 | } | ||
70 | |||
71 | h2_create() | ||
72 | { | ||
73 | simple_if_init $h2 192.0.2.18/28 | ||
74 | tc qdisc add dev $h2 clsact | ||
75 | dscp_capture_install $h2 0 | ||
76 | ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17 | ||
77 | } | ||
78 | |||
79 | h2_destroy() | ||
80 | { | ||
81 | ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17 | ||
82 | dscp_capture_uninstall $h2 0 | ||
83 | tc qdisc del dev $h2 clsact | ||
84 | simple_if_fini $h2 192.0.2.18/28 | ||
85 | } | ||
86 | |||
87 | dscp_map() | ||
88 | { | ||
89 | local base=$1; shift | ||
90 | |||
91 | for prio in {0..7}; do | ||
92 | echo app=$prio,5,$((base + prio)) | ||
93 | done | ||
94 | } | ||
95 | |||
96 | switch_create() | ||
97 | { | ||
98 | simple_if_init $swp1 192.0.2.2/28 | ||
99 | __simple_if_init $swp2 v$swp1 192.0.2.17/28 | ||
100 | |||
101 | lldptool -T -i $swp1 -V APP $(dscp_map 0) >/dev/null | ||
102 | lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null | ||
103 | lldpad_app_wait_set $swp1 | ||
104 | lldpad_app_wait_set $swp2 | ||
105 | } | ||
106 | |||
107 | switch_destroy() | ||
108 | { | ||
109 | lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null | ||
110 | lldptool -T -i $swp1 -V APP -d $(dscp_map 0) >/dev/null | ||
111 | lldpad_app_wait_del | ||
112 | |||
113 | __simple_if_fini $swp2 192.0.2.17/28 | ||
114 | simple_if_fini $swp1 192.0.2.2/28 | ||
115 | } | ||
116 | |||
117 | setup_prepare() | ||
118 | { | ||
119 | h1=${NETIFS[p1]} | ||
120 | swp1=${NETIFS[p2]} | ||
121 | |||
122 | swp2=${NETIFS[p3]} | ||
123 | h2=${NETIFS[p4]} | ||
124 | |||
125 | vrf_prepare | ||
126 | |||
127 | sysctl_set net.ipv4.ip_forward_update_priority 1 | ||
128 | h1_create | ||
129 | h2_create | ||
130 | switch_create | ||
131 | } | ||
132 | |||
133 | cleanup() | ||
134 | { | ||
135 | pre_cleanup | ||
136 | |||
137 | switch_destroy | ||
138 | h2_destroy | ||
139 | h1_destroy | ||
140 | sysctl_restore net.ipv4.ip_forward_update_priority | ||
141 | |||
142 | vrf_cleanup | ||
143 | } | ||
144 | |||
145 | ping_ipv4() | ||
146 | { | ||
147 | ping_test $h1 192.0.2.18 | ||
148 | } | ||
149 | |||
150 | dscp_ping_test() | ||
151 | { | ||
152 | local vrf_name=$1; shift | ||
153 | local sip=$1; shift | ||
154 | local dip=$1; shift | ||
155 | local prio=$1; shift | ||
156 | local reprio=$1; shift | ||
157 | local dev1=$1; shift | ||
158 | local dev2=$1; shift | ||
159 | |||
160 | local prio2=$($reprio $prio) # ICMP Request egress prio | ||
161 | local prio3=$($reprio $prio2) # ICMP Response egress prio | ||
162 | |||
163 | local dscp=$((prio << 2)) # ICMP Request ingress DSCP | ||
164 | local dscp2=$((prio2 << 2)) # ICMP Request egress DSCP | ||
165 | local dscp3=$((prio3 << 2)) # ICMP Response egress DSCP | ||
166 | |||
167 | RET=0 | ||
168 | |||
169 | eval "local -A dev1_t0s=($(dscp_fetch_stats $dev1 0))" | ||
170 | eval "local -A dev2_t0s=($(dscp_fetch_stats $dev2 0))" | ||
171 | |||
172 | ip vrf exec $vrf_name \ | ||
173 | ${PING} -Q $dscp ${sip:+-I $sip} $dip \ | ||
174 | -c 10 -i 0.1 -w 2 &> /dev/null | ||
175 | |||
176 | eval "local -A dev1_t1s=($(dscp_fetch_stats $dev1 0))" | ||
177 | eval "local -A dev2_t1s=($(dscp_fetch_stats $dev2 0))" | ||
178 | |||
179 | for i in {0..7}; do | ||
180 | local dscpi=$((i << 2)) | ||
181 | local expect2=0 | ||
182 | local expect3=0 | ||
183 | |||
184 | if ((i == prio2)); then | ||
185 | expect2=10 | ||
186 | fi | ||
187 | if ((i == prio3)); then | ||
188 | expect3=10 | ||
189 | fi | ||
190 | |||
191 | local delta=$((dev2_t1s[$i] - dev2_t0s[$i])) | ||
192 | ((expect2 == delta)) | ||
193 | check_err $? "DSCP $dscpi@$dev2: Expected to capture $expect2 packets, got $delta." | ||
194 | |||
195 | delta=$((dev1_t1s[$i] - dev1_t0s[$i])) | ||
196 | ((expect3 == delta)) | ||
197 | check_err $? "DSCP $dscpi@$dev1: Expected to capture $expect3 packets, got $delta." | ||
198 | done | ||
199 | |||
200 | log_test "DSCP rewrite: $dscp-(prio $prio2)-$dscp2-(prio $prio3)-$dscp3" | ||
201 | } | ||
202 | |||
203 | __test_update() | ||
204 | { | ||
205 | local update=$1; shift | ||
206 | local reprio=$1; shift | ||
207 | |||
208 | sysctl_restore net.ipv4.ip_forward_update_priority | ||
209 | sysctl_set net.ipv4.ip_forward_update_priority $update | ||
210 | |||
211 | for prio in {0..7}; do | ||
212 | dscp_ping_test v$h1 192.0.2.1 192.0.2.18 $prio $reprio $h1 $h2 | ||
213 | done | ||
214 | } | ||
215 | |||
216 | test_update() | ||
217 | { | ||
218 | __test_update 1 reprioritize | ||
219 | } | ||
220 | |||
221 | test_no_update() | ||
222 | { | ||
223 | __test_update 0 echo | ||
224 | } | ||
225 | |||
226 | trap cleanup EXIT | ||
227 | |||
228 | setup_prepare | ||
229 | setup_wait | ||
230 | |||
231 | tests_run | ||
232 | |||
233 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh new file mode 100644 index 000000000000..d231649b4f01 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/router_scale.sh | |||
@@ -0,0 +1,167 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | ROUTER_NUM_NETIFS=4 | ||
5 | |||
6 | router_h1_create() | ||
7 | { | ||
8 | simple_if_init $h1 192.0.1.1/24 | ||
9 | ip route add 193.0.0.0/8 via 192.0.1.2 dev $h1 | ||
10 | } | ||
11 | |||
12 | router_h1_destroy() | ||
13 | { | ||
14 | ip route del 193.0.0.0/8 via 192.0.1.2 dev $h1 | ||
15 | simple_if_fini $h1 192.0.1.1/24 | ||
16 | } | ||
17 | |||
18 | router_h2_create() | ||
19 | { | ||
20 | simple_if_init $h2 192.0.2.1/24 | ||
21 | tc qdisc add dev $h2 handle ffff: ingress | ||
22 | } | ||
23 | |||
24 | router_h2_destroy() | ||
25 | { | ||
26 | tc qdisc del dev $h2 handle ffff: ingress | ||
27 | simple_if_fini $h2 192.0.2.1/24 | ||
28 | } | ||
29 | |||
30 | router_create() | ||
31 | { | ||
32 | ip link set dev $rp1 up | ||
33 | ip link set dev $rp2 up | ||
34 | |||
35 | ip address add 192.0.1.2/24 dev $rp1 | ||
36 | ip address add 192.0.2.2/24 dev $rp2 | ||
37 | } | ||
38 | |||
39 | router_destroy() | ||
40 | { | ||
41 | ip address del 192.0.2.2/24 dev $rp2 | ||
42 | ip address del 192.0.1.2/24 dev $rp1 | ||
43 | |||
44 | ip link set dev $rp2 down | ||
45 | ip link set dev $rp1 down | ||
46 | } | ||
47 | |||
48 | router_setup_prepare() | ||
49 | { | ||
50 | h1=${NETIFS[p1]} | ||
51 | rp1=${NETIFS[p2]} | ||
52 | |||
53 | rp2=${NETIFS[p3]} | ||
54 | h2=${NETIFS[p4]} | ||
55 | |||
56 | h1mac=$(mac_get $h1) | ||
57 | rp1mac=$(mac_get $rp1) | ||
58 | |||
59 | vrf_prepare | ||
60 | |||
61 | router_h1_create | ||
62 | router_h2_create | ||
63 | |||
64 | router_create | ||
65 | } | ||
66 | |||
67 | router_offload_validate() | ||
68 | { | ||
69 | local route_count=$1 | ||
70 | local offloaded_count | ||
71 | |||
72 | offloaded_count=$(ip route | grep -o 'offload' | wc -l) | ||
73 | [[ $offloaded_count -ge $route_count ]] | ||
74 | } | ||
75 | |||
76 | router_routes_create() | ||
77 | { | ||
78 | local route_count=$1 | ||
79 | local count=0 | ||
80 | |||
81 | ROUTE_FILE="$(mktemp)" | ||
82 | |||
83 | for i in {0..255} | ||
84 | do | ||
85 | for j in {0..255} | ||
86 | do | ||
87 | for k in {0..255} | ||
88 | do | ||
89 | if [[ $count -eq $route_count ]]; then | ||
90 | break 3 | ||
91 | fi | ||
92 | |||
93 | echo route add 193.${i}.${j}.${k}/32 via \ | ||
94 | 192.0.2.1 dev $rp2 >> $ROUTE_FILE | ||
95 | ((count++)) | ||
96 | done | ||
97 | done | ||
98 | done | ||
99 | |||
100 | ip -b $ROUTE_FILE &> /dev/null | ||
101 | } | ||
102 | |||
103 | router_routes_destroy() | ||
104 | { | ||
105 | if [[ -v ROUTE_FILE ]]; then | ||
106 | rm -f $ROUTE_FILE | ||
107 | fi | ||
108 | } | ||
109 | |||
110 | router_test() | ||
111 | { | ||
112 | local route_count=$1 | ||
113 | local should_fail=$2 | ||
114 | local count=0 | ||
115 | |||
116 | RET=0 | ||
117 | |||
118 | router_routes_create $route_count | ||
119 | |||
120 | router_offload_validate $route_count | ||
121 | check_err_fail $should_fail $? "Offload of $route_count routes" | ||
122 | if [[ $RET -ne 0 ]] || [[ $should_fail -eq 1 ]]; then | ||
123 | return | ||
124 | fi | ||
125 | |||
126 | tc filter add dev $h2 ingress protocol ip pref 1 flower \ | ||
127 | skip_sw dst_ip 193.0.0.0/8 action drop | ||
128 | |||
129 | for i in {0..255} | ||
130 | do | ||
131 | for j in {0..255} | ||
132 | do | ||
133 | for k in {0..255} | ||
134 | do | ||
135 | if [[ $count -eq $route_count ]]; then | ||
136 | break 3 | ||
137 | fi | ||
138 | |||
139 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $rp1mac \ | ||
140 | -A 192.0.1.1 -B 193.${i}.${j}.${k} \ | ||
141 | -t ip -q | ||
142 | ((count++)) | ||
143 | done | ||
144 | done | ||
145 | done | ||
146 | |||
147 | tc_check_packets "dev $h2 ingress" 1 $route_count | ||
148 | check_err $? "Offload mismatch" | ||
149 | |||
150 | tc filter del dev $h2 ingress protocol ip pref 1 flower \ | ||
151 | skip_sw dst_ip 193.0.0.0/8 action drop | ||
152 | |||
153 | router_routes_destroy | ||
154 | } | ||
155 | |||
156 | router_cleanup() | ||
157 | { | ||
158 | pre_cleanup | ||
159 | |||
160 | router_routes_destroy | ||
161 | router_destroy | ||
162 | |||
163 | router_h2_destroy | ||
164 | router_h1_destroy | ||
165 | |||
166 | vrf_cleanup | ||
167 | } | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh new file mode 100755 index 000000000000..3b75180f455d --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh | |||
@@ -0,0 +1,366 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # This test is for checking the A-TCAM and C-TCAM operation in Spectrum-2. | ||
5 | # It tries to exercise as many code paths in the eRP state machine as | ||
6 | # possible. | ||
7 | |||
8 | lib_dir=$(dirname $0)/../../../../net/forwarding | ||
9 | |||
10 | ALL_TESTS="single_mask_test identical_filters_test two_masks_test \ | ||
11 | multiple_masks_test ctcam_edge_cases_test" | ||
12 | NUM_NETIFS=2 | ||
13 | source $lib_dir/tc_common.sh | ||
14 | source $lib_dir/lib.sh | ||
15 | |||
16 | tcflags="skip_hw" | ||
17 | |||
18 | h1_create() | ||
19 | { | ||
20 | simple_if_init $h1 192.0.2.1/24 198.51.100.1/24 | ||
21 | } | ||
22 | |||
23 | h1_destroy() | ||
24 | { | ||
25 | simple_if_fini $h1 192.0.2.1/24 198.51.100.1/24 | ||
26 | } | ||
27 | |||
28 | h2_create() | ||
29 | { | ||
30 | simple_if_init $h2 192.0.2.2/24 198.51.100.2/24 | ||
31 | tc qdisc add dev $h2 clsact | ||
32 | } | ||
33 | |||
34 | h2_destroy() | ||
35 | { | ||
36 | tc qdisc del dev $h2 clsact | ||
37 | simple_if_fini $h2 192.0.2.2/24 198.51.100.2/24 | ||
38 | } | ||
39 | |||
40 | single_mask_test() | ||
41 | { | ||
42 | # When only a single mask is required, the device uses the master | ||
43 | # mask and not the eRP table. Verify that under this mode the right | ||
44 | # filter is matched | ||
45 | |||
46 | RET=0 | ||
47 | |||
48 | tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ | ||
49 | $tcflags dst_ip 192.0.2.2 action drop | ||
50 | |||
51 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
52 | -t ip -q | ||
53 | |||
54 | tc_check_packets "dev $h2 ingress" 101 1 | ||
55 | check_err $? "Single filter - did not match" | ||
56 | |||
57 | tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ | ||
58 | $tcflags dst_ip 198.51.100.2 action drop | ||
59 | |||
60 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
61 | -t ip -q | ||
62 | |||
63 | tc_check_packets "dev $h2 ingress" 101 2 | ||
64 | check_err $? "Two filters - did not match highest priority" | ||
65 | |||
66 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ | ||
67 | -t ip -q | ||
68 | |||
69 | tc_check_packets "dev $h2 ingress" 102 1 | ||
70 | check_err $? "Two filters - did not match lowest priority" | ||
71 | |||
72 | tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower | ||
73 | |||
74 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 198.51.100.1 -B 198.51.100.2 \ | ||
75 | -t ip -q | ||
76 | |||
77 | tc_check_packets "dev $h2 ingress" 102 2 | ||
78 | check_err $? "Single filter - did not match after delete" | ||
79 | |||
80 | tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower | ||
81 | |||
82 | log_test "single mask test ($tcflags)" | ||
83 | } | ||
84 | |||
85 | identical_filters_test() | ||
86 | { | ||
87 | # When two filters that only differ in their priority are used, | ||
88 | # one needs to be inserted into the C-TCAM. This test verifies | ||
89 | # that filters are correctly spilled to C-TCAM and that the right | ||
90 | # filter is matched | ||
91 | |||
92 | RET=0 | ||
93 | |||
94 | tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ | ||
95 | $tcflags dst_ip 192.0.2.2 action drop | ||
96 | tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ | ||
97 | $tcflags dst_ip 192.0.2.2 action drop | ||
98 | |||
99 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
100 | -t ip -q | ||
101 | |||
102 | tc_check_packets "dev $h2 ingress" 101 1 | ||
103 | check_err $? "Did not match A-TCAM filter" | ||
104 | |||
105 | tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower | ||
106 | |||
107 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
108 | -t ip -q | ||
109 | |||
110 | tc_check_packets "dev $h2 ingress" 102 1 | ||
111 | check_err $? "Did not match C-TCAM filter after A-TCAM delete" | ||
112 | |||
113 | tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ | ||
114 | $tcflags dst_ip 192.0.2.2 action drop | ||
115 | |||
116 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
117 | -t ip -q | ||
118 | |||
119 | tc_check_packets "dev $h2 ingress" 102 2 | ||
120 | check_err $? "Did not match C-TCAM filter after A-TCAM add" | ||
121 | |||
122 | tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower | ||
123 | |||
124 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
125 | -t ip -q | ||
126 | |||
127 | tc_check_packets "dev $h2 ingress" 103 1 | ||
128 | check_err $? "Did not match A-TCAM filter after C-TCAM delete" | ||
129 | |||
130 | tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower | ||
131 | |||
132 | log_test "identical filters test ($tcflags)" | ||
133 | } | ||
134 | |||
135 | two_masks_test() | ||
136 | { | ||
137 | # When more than one mask is required, the eRP table is used. This | ||
138 | # test verifies that the eRP table is correctly allocated and used | ||
139 | |||
140 | RET=0 | ||
141 | |||
142 | tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ | ||
143 | $tcflags dst_ip 192.0.2.2 action drop | ||
144 | tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ | ||
145 | $tcflags dst_ip 192.0.0.0/16 action drop | ||
146 | |||
147 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
148 | -t ip -q | ||
149 | |||
150 | tc_check_packets "dev $h2 ingress" 101 1 | ||
151 | check_err $? "Two filters - did not match highest priority" | ||
152 | |||
153 | tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower | ||
154 | |||
155 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
156 | -t ip -q | ||
157 | |||
158 | tc_check_packets "dev $h2 ingress" 103 1 | ||
159 | check_err $? "Single filter - did not match" | ||
160 | |||
161 | tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ | ||
162 | $tcflags dst_ip 192.0.2.0/24 action drop | ||
163 | |||
164 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
165 | -t ip -q | ||
166 | |||
167 | tc_check_packets "dev $h2 ingress" 102 1 | ||
168 | check_err $? "Two filters - did not match highest priority after add" | ||
169 | |||
170 | tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower | ||
171 | tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower | ||
172 | |||
173 | log_test "two masks test ($tcflags)" | ||
174 | } | ||
175 | |||
176 | multiple_masks_test() | ||
177 | { | ||
178 | # The number of masks in a region is limited. Once the maximum | ||
179 | # number of masks has been reached filters that require new | ||
180 | # masks are spilled to the C-TCAM. This test verifies that | ||
181 | # spillage is performed correctly and that the right filter is | ||
182 | # matched | ||
183 | |||
184 | local index | ||
185 | |||
186 | RET=0 | ||
187 | |||
188 | NUM_MASKS=32 | ||
189 | BASE_INDEX=100 | ||
190 | |||
191 | for i in $(eval echo {1..$NUM_MASKS}); do | ||
192 | index=$((BASE_INDEX - i)) | ||
193 | |||
194 | tc filter add dev $h2 ingress protocol ip pref $index \ | ||
195 | handle $index \ | ||
196 | flower $tcflags dst_ip 192.0.2.2/${i} src_ip 192.0.2.1 \ | ||
197 | action drop | ||
198 | |||
199 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \ | ||
200 | -B 192.0.2.2 -t ip -q | ||
201 | |||
202 | tc_check_packets "dev $h2 ingress" $index 1 | ||
203 | check_err $? "$i filters - did not match highest priority (add)" | ||
204 | done | ||
205 | |||
206 | for i in $(eval echo {$NUM_MASKS..1}); do | ||
207 | index=$((BASE_INDEX - i)) | ||
208 | |||
209 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 \ | ||
210 | -B 192.0.2.2 -t ip -q | ||
211 | |||
212 | tc_check_packets "dev $h2 ingress" $index 2 | ||
213 | check_err $? "$i filters - did not match highest priority (del)" | ||
214 | |||
215 | tc filter del dev $h2 ingress protocol ip pref $index \ | ||
216 | handle $index flower | ||
217 | done | ||
218 | |||
219 | log_test "multiple masks test ($tcflags)" | ||
220 | } | ||
221 | |||
222 | ctcam_two_atcam_masks_test() | ||
223 | { | ||
224 | RET=0 | ||
225 | |||
226 | # First case: C-TCAM is disabled when there are two A-TCAM masks. | ||
227 | # We push a filter into the C-TCAM by using two identical filters | ||
228 | # as in identical_filters_test() | ||
229 | |||
230 | # Filter goes into A-TCAM | ||
231 | tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ | ||
232 | $tcflags dst_ip 192.0.2.2 action drop | ||
233 | # Filter goes into C-TCAM | ||
234 | tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ | ||
235 | $tcflags dst_ip 192.0.2.2 action drop | ||
236 | # Filter goes into A-TCAM | ||
237 | tc filter add dev $h2 ingress protocol ip pref 3 handle 103 flower \ | ||
238 | $tcflags dst_ip 192.0.2.0/24 action drop | ||
239 | |||
240 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
241 | -t ip -q | ||
242 | |||
243 | tc_check_packets "dev $h2 ingress" 101 1 | ||
244 | check_err $? "Did not match A-TCAM filter" | ||
245 | |||
246 | # Delete both A-TCAM and C-TCAM filters and make sure the remaining | ||
247 | # A-TCAM filter still works | ||
248 | tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower | ||
249 | tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower | ||
250 | |||
251 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
252 | -t ip -q | ||
253 | |||
254 | tc_check_packets "dev $h2 ingress" 103 1 | ||
255 | check_err $? "Did not match A-TCAM filter" | ||
256 | |||
257 | tc filter del dev $h2 ingress protocol ip pref 3 handle 103 flower | ||
258 | |||
259 | log_test "ctcam with two atcam masks test ($tcflags)" | ||
260 | } | ||
261 | |||
262 | ctcam_one_atcam_mask_test() | ||
263 | { | ||
264 | RET=0 | ||
265 | |||
266 | # Second case: C-TCAM is disabled when there is one A-TCAM mask. | ||
267 | # The test is similar to identical_filters_test() | ||
268 | |||
269 | # Filter goes into A-TCAM | ||
270 | tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ | ||
271 | $tcflags dst_ip 192.0.2.2 action drop | ||
272 | # Filter goes into C-TCAM | ||
273 | tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ | ||
274 | $tcflags dst_ip 192.0.2.2 action drop | ||
275 | |||
276 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
277 | -t ip -q | ||
278 | |||
279 | tc_check_packets "dev $h2 ingress" 101 1 | ||
280 | check_err $? "Did not match C-TCAM filter" | ||
281 | |||
282 | tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower | ||
283 | |||
284 | $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ | ||
285 | -t ip -q | ||
286 | |||
287 | tc_check_packets "dev $h2 ingress" 102 1 | ||
288 | check_err $? "Did not match A-TCAM filter" | ||
289 | |||
290 | tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower | ||
291 | |||
292 | log_test "ctcam with one atcam mask test ($tcflags)" | ||
293 | } | ||
294 | |||
295 | ctcam_no_atcam_masks_test() | ||
296 | { | ||
297 | RET=0 | ||
298 | |||
299 | # Third case: C-TCAM is disabled when there are no A-TCAM masks | ||
300 | # This test exercises the code path that transitions the eRP table | ||
301 | # to its initial state after deleting the last C-TCAM mask | ||
302 | |||
303 | # Filter goes into A-TCAM | ||
304 | tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ | ||
305 | $tcflags dst_ip 192.0.2.2 action drop | ||
306 | # Filter goes into C-TCAM | ||
307 | tc filter add dev $h2 ingress protocol ip pref 2 handle 102 flower \ | ||
308 | $tcflags dst_ip 192.0.2.2 action drop | ||
309 | |||
310 | tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower | ||
311 | tc filter del dev $h2 ingress protocol ip pref 2 handle 102 flower | ||
312 | |||
313 | log_test "ctcam with no atcam masks test ($tcflags)" | ||
314 | } | ||
315 | |||
316 | ctcam_edge_cases_test() | ||
317 | { | ||
318 | # When the C-TCAM is disabled after deleting the last C-TCAM | ||
319 | # mask, we want to make sure the eRP state machine is put in | ||
320 | # the correct state | ||
321 | |||
322 | ctcam_two_atcam_masks_test | ||
323 | ctcam_one_atcam_mask_test | ||
324 | ctcam_no_atcam_masks_test | ||
325 | } | ||
326 | |||
327 | setup_prepare() | ||
328 | { | ||
329 | h1=${NETIFS[p1]} | ||
330 | h2=${NETIFS[p2]} | ||
331 | h1mac=$(mac_get $h1) | ||
332 | h2mac=$(mac_get $h2) | ||
333 | |||
334 | vrf_prepare | ||
335 | |||
336 | h1_create | ||
337 | h2_create | ||
338 | } | ||
339 | |||
340 | cleanup() | ||
341 | { | ||
342 | pre_cleanup | ||
343 | |||
344 | h2_destroy | ||
345 | h1_destroy | ||
346 | |||
347 | vrf_cleanup | ||
348 | } | ||
349 | |||
350 | trap cleanup EXIT | ||
351 | |||
352 | setup_prepare | ||
353 | setup_wait | ||
354 | |||
355 | tests_run | ||
356 | |||
357 | if ! tc_offload_check; then | ||
358 | check_err 1 "Could not test offloaded functionality" | ||
359 | log_test "mlxsw-specific tests for tc flower" | ||
360 | exit | ||
361 | else | ||
362 | tcflags="skip_sw" | ||
363 | tests_run | ||
364 | fi | ||
365 | |||
366 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh new file mode 100644 index 000000000000..73035e25085d --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_lib_spectrum.sh | |||
@@ -0,0 +1,119 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | source "../../../../net/forwarding/devlink_lib.sh" | ||
5 | |||
6 | if [ "$DEVLINK_VIDDID" != "15b3:cb84" ]; then | ||
7 | echo "SKIP: test is tailored for Mellanox Spectrum" | ||
8 | exit 1 | ||
9 | fi | ||
10 | |||
11 | # Needed for returning to default | ||
12 | declare -A KVD_DEFAULTS | ||
13 | |||
14 | KVD_CHILDREN="linear hash_single hash_double" | ||
15 | KVDL_CHILDREN="singles chunks large_chunks" | ||
16 | |||
17 | devlink_sp_resource_minimize() | ||
18 | { | ||
19 | local size | ||
20 | local i | ||
21 | |||
22 | for i in $KVD_CHILDREN; do | ||
23 | size=$(devlink_resource_get kvd "$i" | jq '.["size_min"]') | ||
24 | devlink_resource_size_set "$size" kvd "$i" | ||
25 | done | ||
26 | |||
27 | for i in $KVDL_CHILDREN; do | ||
28 | size=$(devlink_resource_get kvd linear "$i" | \ | ||
29 | jq '.["size_min"]') | ||
30 | devlink_resource_size_set "$size" kvd linear "$i" | ||
31 | done | ||
32 | } | ||
33 | |||
34 | devlink_sp_size_kvd_to_default() | ||
35 | { | ||
36 | local need_reload=0 | ||
37 | local i | ||
38 | |||
39 | for i in $KVD_CHILDREN; do | ||
40 | local size=$(echo "${KVD_DEFAULTS[kvd_$i]}" | jq '.["size"]') | ||
41 | current_size=$(devlink_resource_size_get kvd "$i") | ||
42 | |||
43 | if [ "$size" -ne "$current_size" ]; then | ||
44 | devlink_resource_size_set "$size" kvd "$i" | ||
45 | need_reload=1 | ||
46 | fi | ||
47 | done | ||
48 | |||
49 | for i in $KVDL_CHILDREN; do | ||
50 | local size=$(echo "${KVD_DEFAULTS[kvd_linear_$i]}" | \ | ||
51 | jq '.["size"]') | ||
52 | current_size=$(devlink_resource_size_get kvd linear "$i") | ||
53 | |||
54 | if [ "$size" -ne "$current_size" ]; then | ||
55 | devlink_resource_size_set "$size" kvd linear "$i" | ||
56 | need_reload=1 | ||
57 | fi | ||
58 | done | ||
59 | |||
60 | if [ "$need_reload" -ne "0" ]; then | ||
61 | devlink_reload | ||
62 | fi | ||
63 | } | ||
64 | |||
65 | devlink_sp_read_kvd_defaults() | ||
66 | { | ||
67 | local key | ||
68 | local i | ||
69 | |||
70 | KVD_DEFAULTS[kvd]=$(devlink_resource_get "kvd") | ||
71 | for i in $KVD_CHILDREN; do | ||
72 | key=kvd_$i | ||
73 | KVD_DEFAULTS[$key]=$(devlink_resource_get kvd "$i") | ||
74 | done | ||
75 | |||
76 | for i in $KVDL_CHILDREN; do | ||
77 | key=kvd_linear_$i | ||
78 | KVD_DEFAULTS[$key]=$(devlink_resource_get kvd linear "$i") | ||
79 | done | ||
80 | } | ||
81 | |||
82 | KVD_PROFILES="default scale ipv4_max" | ||
83 | |||
84 | devlink_sp_resource_kvd_profile_set() | ||
85 | { | ||
86 | local profile=$1 | ||
87 | |||
88 | case "$profile" in | ||
89 | scale) | ||
90 | devlink_resource_size_set 64000 kvd linear | ||
91 | devlink_resource_size_set 15616 kvd linear singles | ||
92 | devlink_resource_size_set 32000 kvd linear chunks | ||
93 | devlink_resource_size_set 16384 kvd linear large_chunks | ||
94 | devlink_resource_size_set 128000 kvd hash_single | ||
95 | devlink_resource_size_set 48000 kvd hash_double | ||
96 | devlink_reload | ||
97 | ;; | ||
98 | ipv4_max) | ||
99 | devlink_resource_size_set 64000 kvd linear | ||
100 | devlink_resource_size_set 15616 kvd linear singles | ||
101 | devlink_resource_size_set 32000 kvd linear chunks | ||
102 | devlink_resource_size_set 16384 kvd linear large_chunks | ||
103 | devlink_resource_size_set 144000 kvd hash_single | ||
104 | devlink_resource_size_set 32768 kvd hash_double | ||
105 | devlink_reload | ||
106 | ;; | ||
107 | default) | ||
108 | devlink_resource_size_set 98304 kvd linear | ||
109 | devlink_resource_size_set 16384 kvd linear singles | ||
110 | devlink_resource_size_set 49152 kvd linear chunks | ||
111 | devlink_resource_size_set 32768 kvd linear large_chunks | ||
112 | devlink_resource_size_set 87040 kvd hash_single | ||
113 | devlink_resource_size_set 60416 kvd hash_double | ||
114 | devlink_reload | ||
115 | ;; | ||
116 | *) | ||
117 | check_err 1 "Unknown profile $profile" | ||
118 | esac | ||
119 | } | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh new file mode 100755 index 000000000000..b1fe960e398a --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/devlink_resources.sh | |||
@@ -0,0 +1,117 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | NUM_NETIFS=1 | ||
5 | source devlink_lib_spectrum.sh | ||
6 | |||
7 | setup_prepare() | ||
8 | { | ||
9 | devlink_sp_read_kvd_defaults | ||
10 | } | ||
11 | |||
12 | cleanup() | ||
13 | { | ||
14 | pre_cleanup | ||
15 | devlink_sp_size_kvd_to_default | ||
16 | } | ||
17 | |||
18 | trap cleanup EXIT | ||
19 | |||
20 | setup_prepare | ||
21 | |||
22 | profiles_test() | ||
23 | { | ||
24 | local i | ||
25 | |||
26 | log_info "Running profile tests" | ||
27 | |||
28 | for i in $KVD_PROFILES; do | ||
29 | RET=0 | ||
30 | devlink_sp_resource_kvd_profile_set $i | ||
31 | log_test "'$i' profile" | ||
32 | done | ||
33 | |||
34 | # Default is explicitly tested at end to ensure it's actually applied | ||
35 | RET=0 | ||
36 | devlink_sp_resource_kvd_profile_set "default" | ||
37 | log_test "'default' profile" | ||
38 | } | ||
39 | |||
40 | resources_min_test() | ||
41 | { | ||
42 | local size | ||
43 | local i | ||
44 | local j | ||
45 | |||
46 | log_info "Running KVD-minimum tests" | ||
47 | |||
48 | for i in $KVD_CHILDREN; do | ||
49 | RET=0 | ||
50 | size=$(devlink_resource_get kvd "$i" | jq '.["size_min"]') | ||
51 | devlink_resource_size_set "$size" kvd "$i" | ||
52 | |||
53 | # In case of linear, need to minimize sub-resources as well | ||
54 | if [[ "$i" == "linear" ]]; then | ||
55 | for j in $KVDL_CHILDREN; do | ||
56 | devlink_resource_size_set 0 kvd linear "$j" | ||
57 | done | ||
58 | fi | ||
59 | |||
60 | devlink_reload | ||
61 | devlink_sp_size_kvd_to_default | ||
62 | log_test "'$i' minimize [$size]" | ||
63 | done | ||
64 | } | ||
65 | |||
66 | resources_max_test() | ||
67 | { | ||
68 | local min_size | ||
69 | local size | ||
70 | local i | ||
71 | local j | ||
72 | |||
73 | log_info "Running KVD-maximum tests" | ||
74 | for i in $KVD_CHILDREN; do | ||
75 | RET=0 | ||
76 | devlink_sp_resource_minimize | ||
77 | |||
78 | # Calculate the maximum possible size for the given partition | ||
79 | size=$(devlink_resource_size_get kvd) | ||
80 | for j in $KVD_CHILDREN; do | ||
81 | if [ "$i" != "$j" ]; then | ||
82 | min_size=$(devlink_resource_get kvd "$j" | \ | ||
83 | jq '.["size_min"]') | ||
84 | size=$((size - min_size)) | ||
85 | fi | ||
86 | done | ||
87 | |||
88 | # Test almost maximum size | ||
89 | devlink_resource_size_set "$((size - 128))" kvd "$i" | ||
90 | devlink_reload | ||
91 | log_test "'$i' almost maximize [$((size - 128))]" | ||
92 | |||
93 | # Test above maximum size | ||
94 | devlink resource set "$DEVLINK_DEV" \ | ||
95 | path "kvd/$i" size $((size + 128)) &> /dev/null | ||
96 | check_fail $? "Set kvd/$i to size $((size + 128)) should fail" | ||
97 | log_test "'$i' Overflow rejection [$((size + 128))]" | ||
98 | |||
99 | # Test maximum size | ||
100 | if [ "$i" == "hash_single" ] || [ "$i" == "hash_double" ]; then | ||
101 | echo "SKIP: Observed problem with exact max $i" | ||
102 | continue | ||
103 | fi | ||
104 | |||
105 | devlink_resource_size_set "$size" kvd "$i" | ||
106 | devlink_reload | ||
107 | log_test "'$i' maximize [$size]" | ||
108 | |||
109 | devlink_sp_size_kvd_to_default | ||
110 | done | ||
111 | } | ||
112 | |||
113 | profiles_test | ||
114 | resources_min_test | ||
115 | resources_max_test | ||
116 | |||
117 | exit "$RET" | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh new file mode 100644 index 000000000000..8d2186c7c62b --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/mirror_gre_scale.sh | |||
@@ -0,0 +1,13 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | source ../mirror_gre_scale.sh | ||
3 | |||
4 | mirror_gre_get_target() | ||
5 | { | ||
6 | local should_fail=$1; shift | ||
7 | |||
8 | if ((! should_fail)); then | ||
9 | echo 3 | ||
10 | else | ||
11 | echo 4 | ||
12 | fi | ||
13 | } | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh new file mode 100755 index 000000000000..a0a80e1a69e8 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh | |||
@@ -0,0 +1,55 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | NUM_NETIFS=6 | ||
5 | source ../../../../net/forwarding/lib.sh | ||
6 | source ../../../../net/forwarding/tc_common.sh | ||
7 | source devlink_lib_spectrum.sh | ||
8 | |||
9 | current_test="" | ||
10 | |||
11 | cleanup() | ||
12 | { | ||
13 | pre_cleanup | ||
14 | if [ ! -z $current_test ]; then | ||
15 | ${current_test}_cleanup | ||
16 | fi | ||
17 | devlink_sp_size_kvd_to_default | ||
18 | } | ||
19 | |||
20 | devlink_sp_read_kvd_defaults | ||
21 | trap cleanup EXIT | ||
22 | |||
23 | ALL_TESTS="router tc_flower mirror_gre" | ||
24 | for current_test in ${TESTS:-$ALL_TESTS}; do | ||
25 | source ${current_test}_scale.sh | ||
26 | |||
27 | num_netifs_var=${current_test^^}_NUM_NETIFS | ||
28 | num_netifs=${!num_netifs_var:-$NUM_NETIFS} | ||
29 | |||
30 | for profile in $KVD_PROFILES; do | ||
31 | RET=0 | ||
32 | devlink_sp_resource_kvd_profile_set $profile | ||
33 | if [[ $RET -gt 0 ]]; then | ||
34 | log_test "'$current_test' [$profile] setting" | ||
35 | continue | ||
36 | fi | ||
37 | |||
38 | for should_fail in 0 1; do | ||
39 | RET=0 | ||
40 | target=$(${current_test}_get_target "$should_fail") | ||
41 | ${current_test}_setup_prepare | ||
42 | setup_wait $num_netifs | ||
43 | ${current_test}_test "$target" "$should_fail" | ||
44 | ${current_test}_cleanup | ||
45 | if [[ "$should_fail" -eq 0 ]]; then | ||
46 | log_test "'$current_test' [$profile] $target" | ||
47 | else | ||
48 | log_test "'$current_test' [$profile] overflow $target" | ||
49 | fi | ||
50 | done | ||
51 | done | ||
52 | done | ||
53 | current_test="" | ||
54 | |||
55 | exit "$RET" | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh new file mode 100644 index 000000000000..21c4697d5bab --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/router_scale.sh | |||
@@ -0,0 +1,18 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | source ../router_scale.sh | ||
3 | |||
4 | router_get_target() | ||
5 | { | ||
6 | local should_fail=$1 | ||
7 | local target | ||
8 | |||
9 | target=$(devlink_resource_size_get kvd hash_single) | ||
10 | |||
11 | if [[ $should_fail -eq 0 ]]; then | ||
12 | target=$((target * 85 / 100)) | ||
13 | else | ||
14 | target=$((target + 1)) | ||
15 | fi | ||
16 | |||
17 | echo $target | ||
18 | } | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh new file mode 100644 index 000000000000..f9bfd8937765 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/tc_flower_scale.sh | |||
@@ -0,0 +1,19 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | source ../tc_flower_scale.sh | ||
3 | |||
4 | tc_flower_get_target() | ||
5 | { | ||
6 | local should_fail=$1; shift | ||
7 | |||
8 | # 6144 (6x1024) is the theoretical maximum. | ||
9 | # One bank of 512 rules is taken by the 18-byte MC router rule. | ||
10 | # One rule is the ACL catch-all. | ||
11 | # 6144 - 512 - 1 = 5631 | ||
12 | local target=5631 | ||
13 | |||
14 | if ((! should_fail)); then | ||
15 | echo $target | ||
16 | else | ||
17 | echo $((target + 1)) | ||
18 | fi | ||
19 | } | ||
diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh new file mode 100644 index 000000000000..a6d733d2a4b4 --- /dev/null +++ b/tools/testing/selftests/drivers/net/mlxsw/tc_flower_scale.sh | |||
@@ -0,0 +1,134 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for resource limit of offloaded flower rules. The test adds a given | ||
5 | # number of flower matches for different IPv6 addresses, then generates traffic, | ||
6 | # and ensures each was hit exactly once. This file contains functions to set up | ||
7 | # a testing topology and run the test, and is meant to be sourced from a test | ||
8 | # script that calls the testing routine with a given number of rules. | ||
9 | |||
10 | TC_FLOWER_NUM_NETIFS=2 | ||
11 | |||
12 | tc_flower_h1_create() | ||
13 | { | ||
14 | simple_if_init $h1 | ||
15 | tc qdisc add dev $h1 clsact | ||
16 | } | ||
17 | |||
18 | tc_flower_h1_destroy() | ||
19 | { | ||
20 | tc qdisc del dev $h1 clsact | ||
21 | simple_if_fini $h1 | ||
22 | } | ||
23 | |||
24 | tc_flower_h2_create() | ||
25 | { | ||
26 | simple_if_init $h2 | ||
27 | tc qdisc add dev $h2 clsact | ||
28 | } | ||
29 | |||
30 | tc_flower_h2_destroy() | ||
31 | { | ||
32 | tc qdisc del dev $h2 clsact | ||
33 | simple_if_fini $h2 | ||
34 | } | ||
35 | |||
36 | tc_flower_setup_prepare() | ||
37 | { | ||
38 | h1=${NETIFS[p1]} | ||
39 | h2=${NETIFS[p2]} | ||
40 | |||
41 | vrf_prepare | ||
42 | |||
43 | tc_flower_h1_create | ||
44 | tc_flower_h2_create | ||
45 | } | ||
46 | |||
47 | tc_flower_cleanup() | ||
48 | { | ||
49 | pre_cleanup | ||
50 | |||
51 | tc_flower_h2_destroy | ||
52 | tc_flower_h1_destroy | ||
53 | |||
54 | vrf_cleanup | ||
55 | |||
56 | if [[ -v TC_FLOWER_BATCH_FILE ]]; then | ||
57 | rm -f $TC_FLOWER_BATCH_FILE | ||
58 | fi | ||
59 | } | ||
60 | |||
61 | tc_flower_addr() | ||
62 | { | ||
63 | local num=$1; shift | ||
64 | |||
65 | printf "2001:db8:1::%x" $num | ||
66 | } | ||
67 | |||
68 | tc_flower_rules_create() | ||
69 | { | ||
70 | local count=$1; shift | ||
71 | local should_fail=$1; shift | ||
72 | |||
73 | TC_FLOWER_BATCH_FILE="$(mktemp)" | ||
74 | |||
75 | for ((i = 0; i < count; ++i)); do | ||
76 | cat >> $TC_FLOWER_BATCH_FILE <<-EOF | ||
77 | filter add dev $h2 ingress \ | ||
78 | prot ipv6 \ | ||
79 | pref 1000 \ | ||
80 | flower $tcflags dst_ip $(tc_flower_addr $i) \ | ||
81 | action drop | ||
82 | EOF | ||
83 | done | ||
84 | |||
85 | tc -b $TC_FLOWER_BATCH_FILE | ||
86 | check_err_fail $should_fail $? "Rule insertion" | ||
87 | } | ||
88 | |||
89 | __tc_flower_test() | ||
90 | { | ||
91 | local count=$1; shift | ||
92 | local should_fail=$1; shift | ||
93 | local last=$((count - 1)) | ||
94 | |||
95 | tc_flower_rules_create $count $should_fail | ||
96 | |||
97 | for ((i = 0; i < count; ++i)); do | ||
98 | $MZ $h1 -q -c 1 -t ip -p 20 -b bc -6 \ | ||
99 | -A 2001:db8:2::1 \ | ||
100 | -B $(tc_flower_addr $i) | ||
101 | done | ||
102 | |||
103 | MISMATCHES=$( | ||
104 | tc -j -s filter show dev $h2 ingress | | ||
105 | jq -r '[ .[] | select(.kind == "flower") | .options | | ||
106 | values as $rule | .actions[].stats.packets | | ||
107 | select(. != 1) | "\(.) on \($rule.keys.dst_ip)" ] | | ||
108 | join(", ")' | ||
109 | ) | ||
110 | |||
111 | test -z "$MISMATCHES" | ||
112 | check_err $? "Expected to capture 1 packet for each IP, but got $MISMATCHES" | ||
113 | } | ||
114 | |||
115 | tc_flower_test() | ||
116 | { | ||
117 | local count=$1; shift | ||
118 | local should_fail=$1; shift | ||
119 | |||
120 | # We use lower 16 bits of IPv6 address for match. Also there are only 16 | ||
121 | # bits of rule priority space. | ||
122 | if ((count > 65536)); then | ||
123 | check_err 1 "Invalid count of $count. At most 65536 rules supported" | ||
124 | return | ||
125 | fi | ||
126 | |||
127 | if ! tc_offload_check $TC_FLOWER_NUM_NETIFS; then | ||
128 | check_err 1 "Could not test offloaded functionality" | ||
129 | return | ||
130 | fi | ||
131 | |||
132 | tcflags="skip_sw" | ||
133 | __tc_flower_test $count $should_fail | ||
134 | } | ||
diff --git a/tools/testing/selftests/gpio/gpio-mockup-chardev.c b/tools/testing/selftests/gpio/gpio-mockup-chardev.c index 667e916fa7cc..f8d468f54e98 100644 --- a/tools/testing/selftests/gpio/gpio-mockup-chardev.c +++ b/tools/testing/selftests/gpio/gpio-mockup-chardev.c | |||
@@ -225,10 +225,10 @@ int gpio_pin_test(struct gpiochip_info *cinfo, int line, int flag, int value) | |||
225 | if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW) | 225 | if (flag & GPIOHANDLE_REQUEST_ACTIVE_LOW) |
226 | debugfs_value = !debugfs_value; | 226 | debugfs_value = !debugfs_value; |
227 | 227 | ||
228 | if (!(debugfs_dir == OUT && value == debugfs_value)) | 228 | if (!(debugfs_dir == OUT && value == debugfs_value)) { |
229 | errno = -EINVAL; | 229 | errno = -EINVAL; |
230 | ret = -errno; | 230 | ret = -errno; |
231 | 231 | } | |
232 | } | 232 | } |
233 | gpiotools_release_linehandle(fd); | 233 | gpiotools_release_linehandle(fd); |
234 | 234 | ||
diff --git a/tools/testing/selftests/net/.gitignore b/tools/testing/selftests/net/.gitignore index 1a0ac3a29ec5..78b24cf76f40 100644 --- a/tools/testing/selftests/net/.gitignore +++ b/tools/testing/selftests/net/.gitignore | |||
@@ -13,3 +13,4 @@ udpgso | |||
13 | udpgso_bench_rx | 13 | udpgso_bench_rx |
14 | udpgso_bench_tx | 14 | udpgso_bench_tx |
15 | tcp_inq | 15 | tcp_inq |
16 | tls | ||
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 663e11e85727..9cca68e440a0 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile | |||
@@ -13,7 +13,7 @@ TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy | |||
13 | TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd | 13 | TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd |
14 | TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx | 14 | TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx |
15 | TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa | 15 | TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa |
16 | TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict | 16 | TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls |
17 | 17 | ||
18 | include ../lib.mk | 18 | include ../lib.mk |
19 | 19 | ||
diff --git a/tools/testing/selftests/net/forwarding/README b/tools/testing/selftests/net/forwarding/README index 4a0964c42860..b8a2af8fcfb7 100644 --- a/tools/testing/selftests/net/forwarding/README +++ b/tools/testing/selftests/net/forwarding/README | |||
@@ -46,6 +46,8 @@ Guidelines for Writing Tests | |||
46 | 46 | ||
47 | o Where possible, reuse an existing topology for different tests instead | 47 | o Where possible, reuse an existing topology for different tests instead |
48 | of recreating the same topology. | 48 | of recreating the same topology. |
49 | o Tests that use anything but the most trivial topologies should include | ||
50 | an ASCII art showing the topology. | ||
49 | o Where possible, IPv6 and IPv4 addresses shall conform to RFC 3849 and | 51 | o Where possible, IPv6 and IPv4 addresses shall conform to RFC 3849 and |
50 | RFC 5737, respectively. | 52 | RFC 5737, respectively. |
51 | o Where possible, tests shall be written so that they can be reused by | 53 | o Where possible, tests shall be written so that they can be reused by |
diff --git a/tools/testing/selftests/net/forwarding/bridge_port_isolation.sh b/tools/testing/selftests/net/forwarding/bridge_port_isolation.sh new file mode 100755 index 000000000000..a43b4645c4de --- /dev/null +++ b/tools/testing/selftests/net/forwarding/bridge_port_isolation.sh | |||
@@ -0,0 +1,151 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | ALL_TESTS="ping_ipv4 ping_ipv6 flooding" | ||
5 | NUM_NETIFS=6 | ||
6 | CHECK_TC="yes" | ||
7 | source lib.sh | ||
8 | |||
9 | h1_create() | ||
10 | { | ||
11 | simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64 | ||
12 | } | ||
13 | |||
14 | h1_destroy() | ||
15 | { | ||
16 | simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64 | ||
17 | } | ||
18 | |||
19 | h2_create() | ||
20 | { | ||
21 | simple_if_init $h2 192.0.2.2/24 2001:db8:1::2/64 | ||
22 | } | ||
23 | |||
24 | h2_destroy() | ||
25 | { | ||
26 | simple_if_fini $h2 192.0.2.2/24 2001:db8:1::2/64 | ||
27 | } | ||
28 | |||
29 | h3_create() | ||
30 | { | ||
31 | simple_if_init $h3 192.0.2.3/24 2001:db8:1::3/64 | ||
32 | } | ||
33 | |||
34 | h3_destroy() | ||
35 | { | ||
36 | simple_if_fini $h3 192.0.2.3/24 2001:db8:1::3/64 | ||
37 | } | ||
38 | |||
39 | switch_create() | ||
40 | { | ||
41 | ip link add dev br0 type bridge | ||
42 | |||
43 | ip link set dev $swp1 master br0 | ||
44 | ip link set dev $swp2 master br0 | ||
45 | ip link set dev $swp3 master br0 | ||
46 | |||
47 | ip link set dev $swp1 type bridge_slave isolated on | ||
48 | check_err $? "Can't set isolation on port $swp1" | ||
49 | ip link set dev $swp2 type bridge_slave isolated on | ||
50 | check_err $? "Can't set isolation on port $swp2" | ||
51 | ip link set dev $swp3 type bridge_slave isolated off | ||
52 | check_err $? "Can't disable isolation on port $swp3" | ||
53 | |||
54 | ip link set dev br0 up | ||
55 | ip link set dev $swp1 up | ||
56 | ip link set dev $swp2 up | ||
57 | ip link set dev $swp3 up | ||
58 | } | ||
59 | |||
60 | switch_destroy() | ||
61 | { | ||
62 | ip link set dev $swp3 down | ||
63 | ip link set dev $swp2 down | ||
64 | ip link set dev $swp1 down | ||
65 | |||
66 | ip link del dev br0 | ||
67 | } | ||
68 | |||
69 | setup_prepare() | ||
70 | { | ||
71 | h1=${NETIFS[p1]} | ||
72 | swp1=${NETIFS[p2]} | ||
73 | |||
74 | swp2=${NETIFS[p3]} | ||
75 | h2=${NETIFS[p4]} | ||
76 | |||
77 | swp3=${NETIFS[p5]} | ||
78 | h3=${NETIFS[p6]} | ||
79 | |||
80 | vrf_prepare | ||
81 | |||
82 | h1_create | ||
83 | h2_create | ||
84 | h3_create | ||
85 | |||
86 | switch_create | ||
87 | } | ||
88 | |||
89 | cleanup() | ||
90 | { | ||
91 | pre_cleanup | ||
92 | |||
93 | switch_destroy | ||
94 | |||
95 | h3_destroy | ||
96 | h2_destroy | ||
97 | h1_destroy | ||
98 | |||
99 | vrf_cleanup | ||
100 | } | ||
101 | |||
102 | ping_ipv4() | ||
103 | { | ||
104 | RET=0 | ||
105 | ping_do $h1 192.0.2.2 | ||
106 | check_fail $? "Ping worked when it should not have" | ||
107 | |||
108 | RET=0 | ||
109 | ping_do $h3 192.0.2.2 | ||
110 | check_err $? "Ping didn't work when it should have" | ||
111 | |||
112 | log_test "Isolated port ping" | ||
113 | } | ||
114 | |||
115 | ping_ipv6() | ||
116 | { | ||
117 | RET=0 | ||
118 | ping6_do $h1 2001:db8:1::2 | ||
119 | check_fail $? "Ping6 worked when it should not have" | ||
120 | |||
121 | RET=0 | ||
122 | ping6_do $h3 2001:db8:1::2 | ||
123 | check_err $? "Ping6 didn't work when it should have" | ||
124 | |||
125 | log_test "Isolated port ping6" | ||
126 | } | ||
127 | |||
128 | flooding() | ||
129 | { | ||
130 | local mac=de:ad:be:ef:13:37 | ||
131 | local ip=192.0.2.100 | ||
132 | |||
133 | RET=0 | ||
134 | flood_test_do false $mac $ip $h1 $h2 | ||
135 | check_err $? "Packet was flooded when it should not have been" | ||
136 | |||
137 | RET=0 | ||
138 | flood_test_do true $mac $ip $h3 $h2 | ||
139 | check_err $? "Packet was not flooded when it should have been" | ||
140 | |||
141 | log_test "Isolated port flooding" | ||
142 | } | ||
143 | |||
144 | trap cleanup EXIT | ||
145 | |||
146 | setup_prepare | ||
147 | setup_wait | ||
148 | |||
149 | tests_run | ||
150 | |||
151 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/devlink_lib.sh b/tools/testing/selftests/net/forwarding/devlink_lib.sh new file mode 100644 index 000000000000..5ab1e5f43022 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/devlink_lib.sh | |||
@@ -0,0 +1,108 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | ############################################################################## | ||
5 | # Source library | ||
6 | |||
7 | relative_path="${BASH_SOURCE%/*}" | ||
8 | if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then | ||
9 | relative_path="." | ||
10 | fi | ||
11 | |||
12 | source "$relative_path/lib.sh" | ||
13 | |||
14 | ############################################################################## | ||
15 | # Defines | ||
16 | |||
17 | DEVLINK_DEV=$(devlink port show | grep "${NETIFS[p1]}" | \ | ||
18 | grep -v "${NETIFS[p1]}[0-9]" | cut -d" " -f1 | \ | ||
19 | rev | cut -d"/" -f2- | rev) | ||
20 | if [ -z "$DEVLINK_DEV" ]; then | ||
21 | echo "SKIP: ${NETIFS[p1]} has no devlink device registered for it" | ||
22 | exit 1 | ||
23 | fi | ||
24 | if [[ "$(echo $DEVLINK_DEV | grep -c pci)" -eq 0 ]]; then | ||
25 | echo "SKIP: devlink device's bus is not PCI" | ||
26 | exit 1 | ||
27 | fi | ||
28 | |||
29 | DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \ | ||
30 | -n | cut -d" " -f3) | ||
31 | |||
32 | ############################################################################## | ||
33 | # Sanity checks | ||
34 | |||
35 | devlink -j resource show "$DEVLINK_DEV" &> /dev/null | ||
36 | if [ $? -ne 0 ]; then | ||
37 | echo "SKIP: iproute2 too old, missing devlink resource support" | ||
38 | exit 1 | ||
39 | fi | ||
40 | |||
41 | ############################################################################## | ||
42 | # Devlink helpers | ||
43 | |||
44 | devlink_resource_names_to_path() | ||
45 | { | ||
46 | local resource | ||
47 | local path="" | ||
48 | |||
49 | for resource in "${@}"; do | ||
50 | if [ "$path" == "" ]; then | ||
51 | path="$resource" | ||
52 | else | ||
53 | path="${path}/$resource" | ||
54 | fi | ||
55 | done | ||
56 | |||
57 | echo "$path" | ||
58 | } | ||
59 | |||
60 | devlink_resource_get() | ||
61 | { | ||
62 | local name=$1 | ||
63 | local resource_name=.[][\"$DEVLINK_DEV\"] | ||
64 | |||
65 | resource_name="$resource_name | .[] | select (.name == \"$name\")" | ||
66 | |||
67 | shift | ||
68 | for resource in "${@}"; do | ||
69 | resource_name="${resource_name} | .[\"resources\"][] | \ | ||
70 | select (.name == \"$resource\")" | ||
71 | done | ||
72 | |||
73 | devlink -j resource show "$DEVLINK_DEV" | jq "$resource_name" | ||
74 | } | ||
75 | |||
76 | devlink_resource_size_get() | ||
77 | { | ||
78 | local size=$(devlink_resource_get "$@" | jq '.["size_new"]') | ||
79 | |||
80 | if [ "$size" == "null" ]; then | ||
81 | devlink_resource_get "$@" | jq '.["size"]' | ||
82 | else | ||
83 | echo "$size" | ||
84 | fi | ||
85 | } | ||
86 | |||
87 | devlink_resource_size_set() | ||
88 | { | ||
89 | local new_size=$1 | ||
90 | local path | ||
91 | |||
92 | shift | ||
93 | path=$(devlink_resource_names_to_path "$@") | ||
94 | devlink resource set "$DEVLINK_DEV" path "$path" size "$new_size" | ||
95 | check_err $? "Failed setting path $path to size $size" | ||
96 | } | ||
97 | |||
98 | devlink_reload() | ||
99 | { | ||
100 | local still_pending | ||
101 | |||
102 | devlink dev reload "$DEVLINK_DEV" &> /dev/null | ||
103 | check_err $? "Failed reload" | ||
104 | |||
105 | still_pending=$(devlink resource show "$DEVLINK_DEV" | \ | ||
106 | grep -c "size_new") | ||
107 | check_err $still_pending "Failed reload - There are still unset sizes" | ||
108 | } | ||
diff --git a/tools/testing/selftests/net/forwarding/gre_multipath.sh b/tools/testing/selftests/net/forwarding/gre_multipath.sh new file mode 100755 index 000000000000..cca2baa03fb8 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/gre_multipath.sh | |||
@@ -0,0 +1,253 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test traffic distribution when a wECMP route forwards traffic to two GRE | ||
5 | # tunnels. | ||
6 | # | ||
7 | # +-------------------------+ | ||
8 | # | H1 | | ||
9 | # | $h1 + | | ||
10 | # | 192.0.2.1/28 | | | ||
11 | # +-------------------|-----+ | ||
12 | # | | ||
13 | # +-------------------|------------------------+ | ||
14 | # | SW1 | | | ||
15 | # | $ol1 + | | ||
16 | # | 192.0.2.2/28 | | ||
17 | # | | | ||
18 | # | + g1a (gre) + g1b (gre) | | ||
19 | # | loc=192.0.2.65 loc=192.0.2.81 | | ||
20 | # | rem=192.0.2.66 --. rem=192.0.2.82 --. | | ||
21 | # | tos=inherit | tos=inherit | | | ||
22 | # | .------------------' | | | ||
23 | # | | .------------------' | | ||
24 | # | v v | | ||
25 | # | + $ul1.111 (vlan) + $ul1.222 (vlan) | | ||
26 | # | | 192.0.2.129/28 | 192.0.2.145/28 | | ||
27 | # | \ / | | ||
28 | # | \________________/ | | ||
29 | # | | | | ||
30 | # | + $ul1 | | ||
31 | # +------------|-------------------------------+ | ||
32 | # | | ||
33 | # +------------|-------------------------------+ | ||
34 | # | SW2 + $ul2 | | ||
35 | # | _______|________ | | ||
36 | # | / \ | | ||
37 | # | / \ | | ||
38 | # | + $ul2.111 (vlan) + $ul2.222 (vlan) | | ||
39 | # | ^ 192.0.2.130/28 ^ 192.0.2.146/28 | | ||
40 | # | | | | | ||
41 | # | | '------------------. | | ||
42 | # | '------------------. | | | ||
43 | # | + g2a (gre) | + g2b (gre) | | | ||
44 | # | loc=192.0.2.66 | loc=192.0.2.82 | | | ||
45 | # | rem=192.0.2.65 --' rem=192.0.2.81 --' | | ||
46 | # | tos=inherit tos=inherit | | ||
47 | # | | | ||
48 | # | $ol2 + | | ||
49 | # | 192.0.2.17/28 | | | ||
50 | # +-------------------|------------------------+ | ||
51 | # | | ||
52 | # +-------------------|-----+ | ||
53 | # | H2 | | | ||
54 | # | $h2 + | | ||
55 | # | 192.0.2.18/28 | | ||
56 | # +-------------------------+ | ||
57 | |||
58 | ALL_TESTS=" | ||
59 | ping_ipv4 | ||
60 | multipath_ipv4 | ||
61 | " | ||
62 | |||
63 | NUM_NETIFS=6 | ||
64 | source lib.sh | ||
65 | |||
66 | h1_create() | ||
67 | { | ||
68 | simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64 | ||
69 | ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2 | ||
70 | } | ||
71 | |||
72 | h1_destroy() | ||
73 | { | ||
74 | ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2 | ||
75 | simple_if_fini $h1 192.0.2.1/28 | ||
76 | } | ||
77 | |||
78 | sw1_create() | ||
79 | { | ||
80 | simple_if_init $ol1 192.0.2.2/28 | ||
81 | __simple_if_init $ul1 v$ol1 | ||
82 | vlan_create $ul1 111 v$ol1 192.0.2.129/28 | ||
83 | vlan_create $ul1 222 v$ol1 192.0.2.145/28 | ||
84 | |||
85 | tunnel_create g1a gre 192.0.2.65 192.0.2.66 tos inherit dev v$ol1 | ||
86 | __simple_if_init g1a v$ol1 192.0.2.65/32 | ||
87 | ip route add vrf v$ol1 192.0.2.66/32 via 192.0.2.130 | ||
88 | |||
89 | tunnel_create g1b gre 192.0.2.81 192.0.2.82 tos inherit dev v$ol1 | ||
90 | __simple_if_init g1b v$ol1 192.0.2.81/32 | ||
91 | ip route add vrf v$ol1 192.0.2.82/32 via 192.0.2.146 | ||
92 | |||
93 | ip route add vrf v$ol1 192.0.2.16/28 \ | ||
94 | nexthop dev g1a \ | ||
95 | nexthop dev g1b | ||
96 | |||
97 | tc qdisc add dev $ul1 clsact | ||
98 | tc filter add dev $ul1 egress pref 111 prot ipv4 \ | ||
99 | flower dst_ip 192.0.2.66 action pass | ||
100 | tc filter add dev $ul1 egress pref 222 prot ipv4 \ | ||
101 | flower dst_ip 192.0.2.82 action pass | ||
102 | } | ||
103 | |||
104 | sw1_destroy() | ||
105 | { | ||
106 | tc qdisc del dev $ul1 clsact | ||
107 | |||
108 | ip route del vrf v$ol1 192.0.2.16/28 | ||
109 | |||
110 | ip route del vrf v$ol1 192.0.2.82/32 via 192.0.2.146 | ||
111 | __simple_if_fini g1b 192.0.2.81/32 | ||
112 | tunnel_destroy g1b | ||
113 | |||
114 | ip route del vrf v$ol1 192.0.2.66/32 via 192.0.2.130 | ||
115 | __simple_if_fini g1a 192.0.2.65/32 | ||
116 | tunnel_destroy g1a | ||
117 | |||
118 | vlan_destroy $ul1 222 | ||
119 | vlan_destroy $ul1 111 | ||
120 | __simple_if_fini $ul1 | ||
121 | simple_if_fini $ol1 192.0.2.2/28 | ||
122 | } | ||
123 | |||
124 | sw2_create() | ||
125 | { | ||
126 | simple_if_init $ol2 192.0.2.17/28 | ||
127 | __simple_if_init $ul2 v$ol2 | ||
128 | vlan_create $ul2 111 v$ol2 192.0.2.130/28 | ||
129 | vlan_create $ul2 222 v$ol2 192.0.2.146/28 | ||
130 | |||
131 | tunnel_create g2a gre 192.0.2.66 192.0.2.65 tos inherit dev v$ol2 | ||
132 | __simple_if_init g2a v$ol2 192.0.2.66/32 | ||
133 | ip route add vrf v$ol2 192.0.2.65/32 via 192.0.2.129 | ||
134 | |||
135 | tunnel_create g2b gre 192.0.2.82 192.0.2.81 tos inherit dev v$ol2 | ||
136 | __simple_if_init g2b v$ol2 192.0.2.82/32 | ||
137 | ip route add vrf v$ol2 192.0.2.81/32 via 192.0.2.145 | ||
138 | |||
139 | ip route add vrf v$ol2 192.0.2.0/28 \ | ||
140 | nexthop dev g2a \ | ||
141 | nexthop dev g2b | ||
142 | } | ||
143 | |||
144 | sw2_destroy() | ||
145 | { | ||
146 | ip route del vrf v$ol2 192.0.2.0/28 | ||
147 | |||
148 | ip route del vrf v$ol2 192.0.2.81/32 via 192.0.2.145 | ||
149 | __simple_if_fini g2b 192.0.2.82/32 | ||
150 | tunnel_destroy g2b | ||
151 | |||
152 | ip route del vrf v$ol2 192.0.2.65/32 via 192.0.2.129 | ||
153 | __simple_if_fini g2a 192.0.2.66/32 | ||
154 | tunnel_destroy g2a | ||
155 | |||
156 | vlan_destroy $ul2 222 | ||
157 | vlan_destroy $ul2 111 | ||
158 | __simple_if_fini $ul2 | ||
159 | simple_if_fini $ol2 192.0.2.17/28 | ||
160 | } | ||
161 | |||
162 | h2_create() | ||
163 | { | ||
164 | simple_if_init $h2 192.0.2.18/28 | ||
165 | ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17 | ||
166 | } | ||
167 | |||
168 | h2_destroy() | ||
169 | { | ||
170 | ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17 | ||
171 | simple_if_fini $h2 192.0.2.18/28 | ||
172 | } | ||
173 | |||
174 | setup_prepare() | ||
175 | { | ||
176 | h1=${NETIFS[p1]} | ||
177 | ol1=${NETIFS[p2]} | ||
178 | |||
179 | ul1=${NETIFS[p3]} | ||
180 | ul2=${NETIFS[p4]} | ||
181 | |||
182 | ol2=${NETIFS[p5]} | ||
183 | h2=${NETIFS[p6]} | ||
184 | |||
185 | vrf_prepare | ||
186 | h1_create | ||
187 | sw1_create | ||
188 | sw2_create | ||
189 | h2_create | ||
190 | } | ||
191 | |||
192 | cleanup() | ||
193 | { | ||
194 | pre_cleanup | ||
195 | |||
196 | h2_destroy | ||
197 | sw2_destroy | ||
198 | sw1_destroy | ||
199 | h1_destroy | ||
200 | vrf_cleanup | ||
201 | } | ||
202 | |||
203 | multipath4_test() | ||
204 | { | ||
205 | local what=$1; shift | ||
206 | local weight1=$1; shift | ||
207 | local weight2=$1; shift | ||
208 | |||
209 | sysctl_set net.ipv4.fib_multipath_hash_policy 1 | ||
210 | ip route replace vrf v$ol1 192.0.2.16/28 \ | ||
211 | nexthop dev g1a weight $weight1 \ | ||
212 | nexthop dev g1b weight $weight2 | ||
213 | |||
214 | local t0_111=$(tc_rule_stats_get $ul1 111 egress) | ||
215 | local t0_222=$(tc_rule_stats_get $ul1 222 egress) | ||
216 | |||
217 | ip vrf exec v$h1 \ | ||
218 | $MZ $h1 -q -p 64 -A 192.0.2.1 -B 192.0.2.18 \ | ||
219 | -d 1msec -t udp "sp=1024,dp=0-32768" | ||
220 | |||
221 | local t1_111=$(tc_rule_stats_get $ul1 111 egress) | ||
222 | local t1_222=$(tc_rule_stats_get $ul1 222 egress) | ||
223 | |||
224 | local d111=$((t1_111 - t0_111)) | ||
225 | local d222=$((t1_222 - t0_222)) | ||
226 | multipath_eval "$what" $weight1 $weight2 $d111 $d222 | ||
227 | |||
228 | ip route replace vrf v$ol1 192.0.2.16/28 \ | ||
229 | nexthop dev g1a \ | ||
230 | nexthop dev g1b | ||
231 | sysctl_restore net.ipv4.fib_multipath_hash_policy | ||
232 | } | ||
233 | |||
234 | ping_ipv4() | ||
235 | { | ||
236 | ping_test $h1 192.0.2.18 | ||
237 | } | ||
238 | |||
239 | multipath_ipv4() | ||
240 | { | ||
241 | log_info "Running IPv4 multipath tests" | ||
242 | multipath4_test "ECMP" 1 1 | ||
243 | multipath4_test "Weighted MP 2:1" 2 1 | ||
244 | multipath4_test "Weighted MP 11:45" 11 45 | ||
245 | } | ||
246 | |||
247 | trap cleanup EXIT | ||
248 | |||
249 | setup_prepare | ||
250 | setup_wait | ||
251 | tests_run | ||
252 | |||
253 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index 7b18a53aa556..ca53b539aa2d 100644 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh | |||
@@ -8,14 +8,21 @@ | |||
8 | PING=${PING:=ping} | 8 | PING=${PING:=ping} |
9 | PING6=${PING6:=ping6} | 9 | PING6=${PING6:=ping6} |
10 | MZ=${MZ:=mausezahn} | 10 | MZ=${MZ:=mausezahn} |
11 | ARPING=${ARPING:=arping} | ||
12 | TEAMD=${TEAMD:=teamd} | ||
11 | WAIT_TIME=${WAIT_TIME:=5} | 13 | WAIT_TIME=${WAIT_TIME:=5} |
12 | PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} | 14 | PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} |
13 | PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no} | 15 | PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no} |
14 | NETIF_TYPE=${NETIF_TYPE:=veth} | 16 | NETIF_TYPE=${NETIF_TYPE:=veth} |
15 | NETIF_CREATE=${NETIF_CREATE:=yes} | 17 | NETIF_CREATE=${NETIF_CREATE:=yes} |
16 | 18 | ||
17 | if [[ -f forwarding.config ]]; then | 19 | relative_path="${BASH_SOURCE%/*}" |
18 | source forwarding.config | 20 | if [[ "$relative_path" == "${BASH_SOURCE}" ]]; then |
21 | relative_path="." | ||
22 | fi | ||
23 | |||
24 | if [[ -f $relative_path/forwarding.config ]]; then | ||
25 | source "$relative_path/forwarding.config" | ||
19 | fi | 26 | fi |
20 | 27 | ||
21 | ############################################################################## | 28 | ############################################################################## |
@@ -28,7 +35,10 @@ check_tc_version() | |||
28 | echo "SKIP: iproute2 too old; tc is missing JSON support" | 35 | echo "SKIP: iproute2 too old; tc is missing JSON support" |
29 | exit 1 | 36 | exit 1 |
30 | fi | 37 | fi |
38 | } | ||
31 | 39 | ||
40 | check_tc_shblock_support() | ||
41 | { | ||
32 | tc filter help 2>&1 | grep block &> /dev/null | 42 | tc filter help 2>&1 | grep block &> /dev/null |
33 | if [[ $? -ne 0 ]]; then | 43 | if [[ $? -ne 0 ]]; then |
34 | echo "SKIP: iproute2 too old; tc is missing shared block support" | 44 | echo "SKIP: iproute2 too old; tc is missing shared block support" |
@@ -36,6 +46,15 @@ check_tc_version() | |||
36 | fi | 46 | fi |
37 | } | 47 | } |
38 | 48 | ||
49 | check_tc_chain_support() | ||
50 | { | ||
51 | tc help 2>&1|grep chain &> /dev/null | ||
52 | if [[ $? -ne 0 ]]; then | ||
53 | echo "SKIP: iproute2 too old; tc is missing chain support" | ||
54 | exit 1 | ||
55 | fi | ||
56 | } | ||
57 | |||
39 | if [[ "$(id -u)" -ne 0 ]]; then | 58 | if [[ "$(id -u)" -ne 0 ]]; then |
40 | echo "SKIP: need root privileges" | 59 | echo "SKIP: need root privileges" |
41 | exit 0 | 60 | exit 0 |
@@ -45,15 +64,18 @@ if [[ "$CHECK_TC" = "yes" ]]; then | |||
45 | check_tc_version | 64 | check_tc_version |
46 | fi | 65 | fi |
47 | 66 | ||
48 | if [[ ! -x "$(command -v jq)" ]]; then | 67 | require_command() |
49 | echo "SKIP: jq not installed" | 68 | { |
50 | exit 1 | 69 | local cmd=$1; shift |
51 | fi | ||
52 | 70 | ||
53 | if [[ ! -x "$(command -v $MZ)" ]]; then | 71 | if [[ ! -x "$(command -v "$cmd")" ]]; then |
54 | echo "SKIP: $MZ not installed" | 72 | echo "SKIP: $cmd not installed" |
55 | exit 1 | 73 | exit 1 |
56 | fi | 74 | fi |
75 | } | ||
76 | |||
77 | require_command jq | ||
78 | require_command $MZ | ||
57 | 79 | ||
58 | if [[ ! -v NUM_NETIFS ]]; then | 80 | if [[ ! -v NUM_NETIFS ]]; then |
59 | echo "SKIP: importer does not define \"NUM_NETIFS\"" | 81 | echo "SKIP: importer does not define \"NUM_NETIFS\"" |
@@ -151,6 +173,19 @@ check_fail() | |||
151 | fi | 173 | fi |
152 | } | 174 | } |
153 | 175 | ||
176 | check_err_fail() | ||
177 | { | ||
178 | local should_fail=$1; shift | ||
179 | local err=$1; shift | ||
180 | local what=$1; shift | ||
181 | |||
182 | if ((should_fail)); then | ||
183 | check_fail $err "$what succeeded, but should have failed" | ||
184 | else | ||
185 | check_err $err "$what failed" | ||
186 | fi | ||
187 | } | ||
188 | |||
154 | log_test() | 189 | log_test() |
155 | { | 190 | { |
156 | local test_name=$1 | 191 | local test_name=$1 |
@@ -185,24 +220,54 @@ log_info() | |||
185 | echo "INFO: $msg" | 220 | echo "INFO: $msg" |
186 | } | 221 | } |
187 | 222 | ||
223 | setup_wait_dev() | ||
224 | { | ||
225 | local dev=$1; shift | ||
226 | |||
227 | while true; do | ||
228 | ip link show dev $dev up \ | ||
229 | | grep 'state UP' &> /dev/null | ||
230 | if [[ $? -ne 0 ]]; then | ||
231 | sleep 1 | ||
232 | else | ||
233 | break | ||
234 | fi | ||
235 | done | ||
236 | } | ||
237 | |||
188 | setup_wait() | 238 | setup_wait() |
189 | { | 239 | { |
190 | for i in $(eval echo {1..$NUM_NETIFS}); do | 240 | local num_netifs=${1:-$NUM_NETIFS} |
191 | while true; do | 241 | |
192 | ip link show dev ${NETIFS[p$i]} up \ | 242 | for ((i = 1; i <= num_netifs; ++i)); do |
193 | | grep 'state UP' &> /dev/null | 243 | setup_wait_dev ${NETIFS[p$i]} |
194 | if [[ $? -ne 0 ]]; then | ||
195 | sleep 1 | ||
196 | else | ||
197 | break | ||
198 | fi | ||
199 | done | ||
200 | done | 244 | done |
201 | 245 | ||
202 | # Make sure links are ready. | 246 | # Make sure links are ready. |
203 | sleep $WAIT_TIME | 247 | sleep $WAIT_TIME |
204 | } | 248 | } |
205 | 249 | ||
250 | lldpad_app_wait_set() | ||
251 | { | ||
252 | local dev=$1; shift | ||
253 | |||
254 | while lldptool -t -i $dev -V APP -c app | grep -q pending; do | ||
255 | echo "$dev: waiting for lldpad to push pending APP updates" | ||
256 | sleep 5 | ||
257 | done | ||
258 | } | ||
259 | |||
260 | lldpad_app_wait_del() | ||
261 | { | ||
262 | # Give lldpad a chance to push down the changes. If the device is downed | ||
263 | # too soon, the updates will be left pending. However, they will have | ||
264 | # been struck off the lldpad's DB already, so we won't be able to tell | ||
265 | # they are pending. Then on next test iteration this would cause | ||
266 | # weirdness as newly-added APP rules conflict with the old ones, | ||
267 | # sometimes getting stuck in an "unknown" state. | ||
268 | sleep 5 | ||
269 | } | ||
270 | |||
206 | pre_cleanup() | 271 | pre_cleanup() |
207 | { | 272 | { |
208 | if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then | 273 | if [ "${PAUSE_ON_CLEANUP}" = "yes" ]; then |
@@ -287,6 +352,29 @@ __addr_add_del() | |||
287 | done | 352 | done |
288 | } | 353 | } |
289 | 354 | ||
355 | __simple_if_init() | ||
356 | { | ||
357 | local if_name=$1; shift | ||
358 | local vrf_name=$1; shift | ||
359 | local addrs=("${@}") | ||
360 | |||
361 | ip link set dev $if_name master $vrf_name | ||
362 | ip link set dev $if_name up | ||
363 | |||
364 | __addr_add_del $if_name add "${addrs[@]}" | ||
365 | } | ||
366 | |||
367 | __simple_if_fini() | ||
368 | { | ||
369 | local if_name=$1; shift | ||
370 | local addrs=("${@}") | ||
371 | |||
372 | __addr_add_del $if_name del "${addrs[@]}" | ||
373 | |||
374 | ip link set dev $if_name down | ||
375 | ip link set dev $if_name nomaster | ||
376 | } | ||
377 | |||
290 | simple_if_init() | 378 | simple_if_init() |
291 | { | 379 | { |
292 | local if_name=$1 | 380 | local if_name=$1 |
@@ -298,11 +386,8 @@ simple_if_init() | |||
298 | array=("${@}") | 386 | array=("${@}") |
299 | 387 | ||
300 | vrf_create $vrf_name | 388 | vrf_create $vrf_name |
301 | ip link set dev $if_name master $vrf_name | ||
302 | ip link set dev $vrf_name up | 389 | ip link set dev $vrf_name up |
303 | ip link set dev $if_name up | 390 | __simple_if_init $if_name $vrf_name "${array[@]}" |
304 | |||
305 | __addr_add_del $if_name add "${array[@]}" | ||
306 | } | 391 | } |
307 | 392 | ||
308 | simple_if_fini() | 393 | simple_if_fini() |
@@ -315,9 +400,7 @@ simple_if_fini() | |||
315 | vrf_name=v$if_name | 400 | vrf_name=v$if_name |
316 | array=("${@}") | 401 | array=("${@}") |
317 | 402 | ||
318 | __addr_add_del $if_name del "${array[@]}" | 403 | __simple_if_fini $if_name "${array[@]}" |
319 | |||
320 | ip link set dev $if_name down | ||
321 | vrf_destroy $vrf_name | 404 | vrf_destroy $vrf_name |
322 | } | 405 | } |
323 | 406 | ||
@@ -365,6 +448,28 @@ vlan_destroy() | |||
365 | ip link del dev $name | 448 | ip link del dev $name |
366 | } | 449 | } |
367 | 450 | ||
451 | team_create() | ||
452 | { | ||
453 | local if_name=$1; shift | ||
454 | local mode=$1; shift | ||
455 | |||
456 | require_command $TEAMD | ||
457 | $TEAMD -t $if_name -d -c '{"runner": {"name": "'$mode'"}}' | ||
458 | for slave in "$@"; do | ||
459 | ip link set dev $slave down | ||
460 | ip link set dev $slave master $if_name | ||
461 | ip link set dev $slave up | ||
462 | done | ||
463 | ip link set dev $if_name up | ||
464 | } | ||
465 | |||
466 | team_destroy() | ||
467 | { | ||
468 | local if_name=$1; shift | ||
469 | |||
470 | $TEAMD -t $if_name -k | ||
471 | } | ||
472 | |||
368 | master_name_get() | 473 | master_name_get() |
369 | { | 474 | { |
370 | local if_name=$1 | 475 | local if_name=$1 |
@@ -383,9 +488,10 @@ tc_rule_stats_get() | |||
383 | { | 488 | { |
384 | local dev=$1; shift | 489 | local dev=$1; shift |
385 | local pref=$1; shift | 490 | local pref=$1; shift |
491 | local dir=$1; shift | ||
386 | 492 | ||
387 | tc -j -s filter show dev $dev ingress pref $pref | | 493 | tc -j -s filter show dev $dev ${dir:-ingress} pref $pref \ |
388 | jq '.[1].options.actions[].stats.packets' | 494 | | jq '.[1].options.actions[].stats.packets' |
389 | } | 495 | } |
390 | 496 | ||
391 | mac_get() | 497 | mac_get() |
@@ -437,7 +543,9 @@ forwarding_restore() | |||
437 | 543 | ||
438 | tc_offload_check() | 544 | tc_offload_check() |
439 | { | 545 | { |
440 | for i in $(eval echo {1..$NUM_NETIFS}); do | 546 | local num_netifs=${1:-$NUM_NETIFS} |
547 | |||
548 | for ((i = 1; i <= num_netifs; ++i)); do | ||
441 | ethtool -k ${NETIFS[p$i]} \ | 549 | ethtool -k ${NETIFS[p$i]} \ |
442 | | grep "hw-tc-offload: on" &> /dev/null | 550 | | grep "hw-tc-offload: on" &> /dev/null |
443 | if [[ $? -ne 0 ]]; then | 551 | if [[ $? -ne 0 ]]; then |
@@ -453,9 +561,15 @@ trap_install() | |||
453 | local dev=$1; shift | 561 | local dev=$1; shift |
454 | local direction=$1; shift | 562 | local direction=$1; shift |
455 | 563 | ||
456 | # For slow-path testing, we need to install a trap to get to | 564 | # Some devices may not support or need in-hardware trapping of traffic |
457 | # slow path the packets that would otherwise be switched in HW. | 565 | # (e.g. the veth pairs that this library creates for non-existent |
458 | tc filter add dev $dev $direction pref 1 flower skip_sw action trap | 566 | # loopbacks). Use continue instead, so that there is a filter in there |
567 | # (some tests check counters), and so that other filters are still | ||
568 | # processed. | ||
569 | tc filter add dev $dev $direction pref 1 \ | ||
570 | flower skip_sw action trap 2>/dev/null \ | ||
571 | || tc filter add dev $dev $direction pref 1 \ | ||
572 | flower action continue | ||
459 | } | 573 | } |
460 | 574 | ||
461 | trap_uninstall() | 575 | trap_uninstall() |
@@ -463,11 +577,13 @@ trap_uninstall() | |||
463 | local dev=$1; shift | 577 | local dev=$1; shift |
464 | local direction=$1; shift | 578 | local direction=$1; shift |
465 | 579 | ||
466 | tc filter del dev $dev $direction pref 1 flower skip_sw | 580 | tc filter del dev $dev $direction pref 1 flower |
467 | } | 581 | } |
468 | 582 | ||
469 | slow_path_trap_install() | 583 | slow_path_trap_install() |
470 | { | 584 | { |
585 | # For slow-path testing, we need to install a trap to get to | ||
586 | # slow path the packets that would otherwise be switched in HW. | ||
471 | if [ "${tcflags/skip_hw}" != "$tcflags" ]; then | 587 | if [ "${tcflags/skip_hw}" != "$tcflags" ]; then |
472 | trap_install "$@" | 588 | trap_install "$@" |
473 | fi | 589 | fi |
@@ -537,6 +653,48 @@ vlan_capture_uninstall() | |||
537 | __vlan_capture_add_del del 100 "$@" | 653 | __vlan_capture_add_del del 100 "$@" |
538 | } | 654 | } |
539 | 655 | ||
656 | __dscp_capture_add_del() | ||
657 | { | ||
658 | local add_del=$1; shift | ||
659 | local dev=$1; shift | ||
660 | local base=$1; shift | ||
661 | local dscp; | ||
662 | |||
663 | for prio in {0..7}; do | ||
664 | dscp=$((base + prio)) | ||
665 | __icmp_capture_add_del $add_del $((dscp + 100)) "" $dev \ | ||
666 | "skip_hw ip_tos $((dscp << 2))" | ||
667 | done | ||
668 | } | ||
669 | |||
670 | dscp_capture_install() | ||
671 | { | ||
672 | local dev=$1; shift | ||
673 | local base=$1; shift | ||
674 | |||
675 | __dscp_capture_add_del add $dev $base | ||
676 | } | ||
677 | |||
678 | dscp_capture_uninstall() | ||
679 | { | ||
680 | local dev=$1; shift | ||
681 | local base=$1; shift | ||
682 | |||
683 | __dscp_capture_add_del del $dev $base | ||
684 | } | ||
685 | |||
686 | dscp_fetch_stats() | ||
687 | { | ||
688 | local dev=$1; shift | ||
689 | local base=$1; shift | ||
690 | |||
691 | for prio in {0..7}; do | ||
692 | local dscp=$((base + prio)) | ||
693 | local t=$(tc_rule_stats_get $dev $((dscp + 100))) | ||
694 | echo "[$dscp]=$t " | ||
695 | done | ||
696 | } | ||
697 | |||
540 | matchall_sink_create() | 698 | matchall_sink_create() |
541 | { | 699 | { |
542 | local dev=$1; shift | 700 | local dev=$1; shift |
@@ -557,33 +715,86 @@ tests_run() | |||
557 | done | 715 | done |
558 | } | 716 | } |
559 | 717 | ||
718 | multipath_eval() | ||
719 | { | ||
720 | local desc="$1" | ||
721 | local weight_rp12=$2 | ||
722 | local weight_rp13=$3 | ||
723 | local packets_rp12=$4 | ||
724 | local packets_rp13=$5 | ||
725 | local weights_ratio packets_ratio diff | ||
726 | |||
727 | RET=0 | ||
728 | |||
729 | if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then | ||
730 | weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \ | ||
731 | | bc -l) | ||
732 | else | ||
733 | weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" \ | ||
734 | | bc -l) | ||
735 | fi | ||
736 | |||
737 | if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then | ||
738 | check_err 1 "Packet difference is 0" | ||
739 | log_test "Multipath" | ||
740 | log_info "Expected ratio $weights_ratio" | ||
741 | return | ||
742 | fi | ||
743 | |||
744 | if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then | ||
745 | packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \ | ||
746 | | bc -l) | ||
747 | else | ||
748 | packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" \ | ||
749 | | bc -l) | ||
750 | fi | ||
751 | |||
752 | diff=$(echo $weights_ratio - $packets_ratio | bc -l) | ||
753 | diff=${diff#-} | ||
754 | |||
755 | test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0 | ||
756 | check_err $? "Too large discrepancy between expected and measured ratios" | ||
757 | log_test "$desc" | ||
758 | log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio" | ||
759 | } | ||
760 | |||
560 | ############################################################################## | 761 | ############################################################################## |
561 | # Tests | 762 | # Tests |
562 | 763 | ||
563 | ping_test() | 764 | ping_do() |
564 | { | 765 | { |
565 | local if_name=$1 | 766 | local if_name=$1 |
566 | local dip=$2 | 767 | local dip=$2 |
567 | local vrf_name | 768 | local vrf_name |
568 | 769 | ||
569 | RET=0 | ||
570 | |||
571 | vrf_name=$(master_name_get $if_name) | 770 | vrf_name=$(master_name_get $if_name) |
572 | ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null | 771 | ip vrf exec $vrf_name $PING $dip -c 10 -i 0.1 -w 2 &> /dev/null |
772 | } | ||
773 | |||
774 | ping_test() | ||
775 | { | ||
776 | RET=0 | ||
777 | |||
778 | ping_do $1 $2 | ||
573 | check_err $? | 779 | check_err $? |
574 | log_test "ping" | 780 | log_test "ping" |
575 | } | 781 | } |
576 | 782 | ||
577 | ping6_test() | 783 | ping6_do() |
578 | { | 784 | { |
579 | local if_name=$1 | 785 | local if_name=$1 |
580 | local dip=$2 | 786 | local dip=$2 |
581 | local vrf_name | 787 | local vrf_name |
582 | 788 | ||
583 | RET=0 | ||
584 | |||
585 | vrf_name=$(master_name_get $if_name) | 789 | vrf_name=$(master_name_get $if_name) |
586 | ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null | 790 | ip vrf exec $vrf_name $PING6 $dip -c 10 -i 0.1 -w 2 &> /dev/null |
791 | } | ||
792 | |||
793 | ping6_test() | ||
794 | { | ||
795 | RET=0 | ||
796 | |||
797 | ping6_do $1 $2 | ||
587 | check_err $? | 798 | check_err $? |
588 | log_test "ping6" | 799 | log_test "ping6" |
589 | } | 800 | } |
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh new file mode 100755 index 000000000000..c5095da7f6bf --- /dev/null +++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d.sh | |||
@@ -0,0 +1,132 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for "tc action mirred egress mirror" when the underlay route points at a | ||
5 | # bridge device without vlan filtering (802.1d). | ||
6 | # | ||
7 | # This test uses standard topology for testing mirror-to-gretap. See | ||
8 | # mirror_gre_topo_lib.sh for more details. The full topology is as follows: | ||
9 | # | ||
10 | # +---------------------+ +---------------------+ | ||
11 | # | H1 | | H2 | | ||
12 | # | + $h1 | | $h2 + | | ||
13 | # | | 192.0.2.1/28 | | 192.0.2.2/28 | | | ||
14 | # +-----|---------------+ +---------------|-----+ | ||
15 | # | | | ||
16 | # +-----|-------------------------------------------------------------|-----+ | ||
17 | # | SW o---> mirror | | | ||
18 | # | +---|-------------------------------------------------------------|---+ | | ||
19 | # | | + $swp1 + br1 (802.1q bridge) $swp2 + | | | ||
20 | # | +---------------------------------------------------------------------+ | | ||
21 | # | | | ||
22 | # | +---------------------------------------------------------------------+ | | ||
23 | # | | + br2 (802.1d bridge) | | | ||
24 | # | | 192.0.2.129/28 | | | ||
25 | # | | + $swp3 2001:db8:2::1/64 | | | ||
26 | # | +---|-----------------------------------------------------------------+ | | ||
27 | # | | ^ ^ | | ||
28 | # | | + gt6 (ip6gretap) | + gt4 (gretap) | | | ||
29 | # | | : loc=2001:db8:2::1 | : loc=192.0.2.129 | | | ||
30 | # | | : rem=2001:db8:2::2 -+ : rem=192.0.2.130 -+ | | ||
31 | # | | : ttl=100 : ttl=100 | | ||
32 | # | | : tos=inherit : tos=inherit | | ||
33 | # +-----|---------------------:----------------------:----------------------+ | ||
34 | # | : : | ||
35 | # +-----|---------------------:----------------------:----------------------+ | ||
36 | # | H3 + $h3 + h3-gt6(ip6gretap) + h3-gt4 (gretap) | | ||
37 | # | 192.0.2.130/28 loc=2001:db8:2::2 loc=192.0.2.130 | | ||
38 | # | 2001:db8:2::2/64 rem=2001:db8:2::1 rem=192.0.2.129 | | ||
39 | # | ttl=100 ttl=100 | | ||
40 | # | tos=inherit tos=inherit | | ||
41 | # +-------------------------------------------------------------------------+ | ||
42 | |||
43 | ALL_TESTS=" | ||
44 | test_gretap | ||
45 | test_ip6gretap | ||
46 | " | ||
47 | |||
48 | NUM_NETIFS=6 | ||
49 | source lib.sh | ||
50 | source mirror_lib.sh | ||
51 | source mirror_gre_lib.sh | ||
52 | source mirror_gre_topo_lib.sh | ||
53 | |||
54 | setup_prepare() | ||
55 | { | ||
56 | h1=${NETIFS[p1]} | ||
57 | swp1=${NETIFS[p2]} | ||
58 | |||
59 | swp2=${NETIFS[p3]} | ||
60 | h2=${NETIFS[p4]} | ||
61 | |||
62 | swp3=${NETIFS[p5]} | ||
63 | h3=${NETIFS[p6]} | ||
64 | |||
65 | vrf_prepare | ||
66 | mirror_gre_topo_create | ||
67 | |||
68 | ip link add name br2 type bridge vlan_filtering 0 | ||
69 | ip link set dev br2 up | ||
70 | |||
71 | ip link set dev $swp3 master br2 | ||
72 | ip route add 192.0.2.130/32 dev br2 | ||
73 | ip -6 route add 2001:db8:2::2/128 dev br2 | ||
74 | |||
75 | ip address add dev br2 192.0.2.129/28 | ||
76 | ip address add dev br2 2001:db8:2::1/64 | ||
77 | |||
78 | ip address add dev $h3 192.0.2.130/28 | ||
79 | ip address add dev $h3 2001:db8:2::2/64 | ||
80 | } | ||
81 | |||
82 | cleanup() | ||
83 | { | ||
84 | pre_cleanup | ||
85 | |||
86 | ip address del dev $h3 2001:db8:2::2/64 | ||
87 | ip address del dev $h3 192.0.2.130/28 | ||
88 | ip link del dev br2 | ||
89 | |||
90 | mirror_gre_topo_destroy | ||
91 | vrf_cleanup | ||
92 | } | ||
93 | |||
94 | test_gretap() | ||
95 | { | ||
96 | full_test_span_gre_dir gt4 ingress 8 0 "mirror to gretap" | ||
97 | full_test_span_gre_dir gt4 egress 0 8 "mirror to gretap" | ||
98 | } | ||
99 | |||
100 | test_ip6gretap() | ||
101 | { | ||
102 | full_test_span_gre_dir gt6 ingress 8 0 "mirror to ip6gretap" | ||
103 | full_test_span_gre_dir gt6 egress 0 8 "mirror to ip6gretap" | ||
104 | } | ||
105 | |||
106 | test_all() | ||
107 | { | ||
108 | slow_path_trap_install $swp1 ingress | ||
109 | slow_path_trap_install $swp1 egress | ||
110 | |||
111 | tests_run | ||
112 | |||
113 | slow_path_trap_uninstall $swp1 egress | ||
114 | slow_path_trap_uninstall $swp1 ingress | ||
115 | } | ||
116 | |||
117 | trap cleanup EXIT | ||
118 | |||
119 | setup_prepare | ||
120 | setup_wait | ||
121 | |||
122 | tcflags="skip_hw" | ||
123 | test_all | ||
124 | |||
125 | if ! tc_offload_check; then | ||
126 | echo "WARN: Could not test offloaded functionality" | ||
127 | else | ||
128 | tcflags="skip_sw" | ||
129 | test_all | ||
130 | fi | ||
131 | |||
132 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh index 3bb4c2ba7b14..197e769c2ed1 100755 --- a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh | |||
@@ -74,12 +74,14 @@ test_vlan_match() | |||
74 | 74 | ||
75 | test_gretap() | 75 | test_gretap() |
76 | { | 76 | { |
77 | test_vlan_match gt4 'vlan_id 555 vlan_ethtype ip' "mirror to gretap" | 77 | test_vlan_match gt4 'skip_hw vlan_id 555 vlan_ethtype ip' \ |
78 | "mirror to gretap" | ||
78 | } | 79 | } |
79 | 80 | ||
80 | test_ip6gretap() | 81 | test_ip6gretap() |
81 | { | 82 | { |
82 | test_vlan_match gt6 'vlan_id 555 vlan_ethtype ipv6' "mirror to ip6gretap" | 83 | test_vlan_match gt6 'skip_hw vlan_id 555 vlan_ethtype ip' \ |
84 | "mirror to ip6gretap" | ||
83 | } | 85 | } |
84 | 86 | ||
85 | test_gretap_stp() | 87 | test_gretap_stp() |
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh new file mode 100755 index 000000000000..a3402cd8d5b6 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q.sh | |||
@@ -0,0 +1,126 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for "tc action mirred egress mirror" when the underlay route points at a | ||
5 | # bridge device with vlan filtering (802.1q). | ||
6 | # | ||
7 | # This test uses standard topology for testing mirror-to-gretap. See | ||
8 | # mirror_gre_topo_lib.sh for more details. The full topology is as follows: | ||
9 | # | ||
10 | # +---------------------+ +---------------------+ | ||
11 | # | H1 | | H2 | | ||
12 | # | + $h1 | | $h2 + | | ||
13 | # | | 192.0.2.1/28 | | 192.0.2.2/28 | | | ||
14 | # +-----|---------------+ +---------------|-----+ | ||
15 | # | | | ||
16 | # +-----|---------------------------------------------------------------|-----+ | ||
17 | # | SW o---> mirror | | | ||
18 | # | +---|---------------------------------------------------------------|---+ | | ||
19 | # | | + $swp1 + br1 (802.1q bridge) $swp2 + | | | ||
20 | # | | 192.0.2.129/28 | | | ||
21 | # | | + $swp3 2001:db8:2::1/64 | | | ||
22 | # | | | vid555 vid555[pvid,untagged] | | | ||
23 | # | +---|-------------------------------------------------------------------+ | | ||
24 | # | | ^ ^ | | ||
25 | # | | + gt6 (ip6gretap) | + gt4 (gretap) | | | ||
26 | # | | : loc=2001:db8:2::1 | : loc=192.0.2.129 | | | ||
27 | # | | : rem=2001:db8:2::2 -+ : rem=192.0.2.130 -+ | | ||
28 | # | | : ttl=100 : ttl=100 | | ||
29 | # | | : tos=inherit : tos=inherit | | ||
30 | # +-----|---------------------:------------------------:----------------------+ | ||
31 | # | : : | ||
32 | # +-----|---------------------:------------------------:----------------------+ | ||
33 | # | H3 + $h3 + h3-gt6(ip6gretap) + h3-gt4 (gretap) | | ||
34 | # | | loc=2001:db8:2::2 loc=192.0.2.130 | | ||
35 | # | + $h3.555 rem=2001:db8:2::1 rem=192.0.2.129 | | ||
36 | # | 192.0.2.130/28 ttl=100 ttl=100 | | ||
37 | # | 2001:db8:2::2/64 tos=inherit tos=inherit | | ||
38 | # +---------------------------------------------------------------------------+ | ||
39 | |||
40 | ALL_TESTS=" | ||
41 | test_gretap | ||
42 | test_ip6gretap | ||
43 | " | ||
44 | |||
45 | NUM_NETIFS=6 | ||
46 | source lib.sh | ||
47 | source mirror_lib.sh | ||
48 | source mirror_gre_lib.sh | ||
49 | source mirror_gre_topo_lib.sh | ||
50 | |||
51 | setup_prepare() | ||
52 | { | ||
53 | h1=${NETIFS[p1]} | ||
54 | swp1=${NETIFS[p2]} | ||
55 | |||
56 | swp2=${NETIFS[p3]} | ||
57 | h2=${NETIFS[p4]} | ||
58 | |||
59 | swp3=${NETIFS[p5]} | ||
60 | h3=${NETIFS[p6]} | ||
61 | |||
62 | vrf_prepare | ||
63 | mirror_gre_topo_create | ||
64 | |||
65 | ip link set dev $swp3 master br1 | ||
66 | bridge vlan add dev br1 vid 555 pvid untagged self | ||
67 | ip address add dev br1 192.0.2.129/28 | ||
68 | ip address add dev br1 2001:db8:2::1/64 | ||
69 | |||
70 | ip -4 route add 192.0.2.130/32 dev br1 | ||
71 | ip -6 route add 2001:db8:2::2/128 dev br1 | ||
72 | |||
73 | vlan_create $h3 555 v$h3 192.0.2.130/28 2001:db8:2::2/64 | ||
74 | bridge vlan add dev $swp3 vid 555 | ||
75 | } | ||
76 | |||
77 | cleanup() | ||
78 | { | ||
79 | pre_cleanup | ||
80 | |||
81 | ip link set dev $swp3 nomaster | ||
82 | vlan_destroy $h3 555 | ||
83 | |||
84 | mirror_gre_topo_destroy | ||
85 | vrf_cleanup | ||
86 | } | ||
87 | |||
88 | test_gretap() | ||
89 | { | ||
90 | full_test_span_gre_dir gt4 ingress 8 0 "mirror to gretap" | ||
91 | full_test_span_gre_dir gt4 egress 0 8 "mirror to gretap" | ||
92 | } | ||
93 | |||
94 | test_ip6gretap() | ||
95 | { | ||
96 | full_test_span_gre_dir gt6 ingress 8 0 "mirror to ip6gretap" | ||
97 | full_test_span_gre_dir gt6 egress 0 8 "mirror to ip6gretap" | ||
98 | } | ||
99 | |||
100 | tests() | ||
101 | { | ||
102 | slow_path_trap_install $swp1 ingress | ||
103 | slow_path_trap_install $swp1 egress | ||
104 | |||
105 | tests_run | ||
106 | |||
107 | slow_path_trap_uninstall $swp1 egress | ||
108 | slow_path_trap_uninstall $swp1 ingress | ||
109 | } | ||
110 | |||
111 | trap cleanup EXIT | ||
112 | |||
113 | setup_prepare | ||
114 | setup_wait | ||
115 | |||
116 | tcflags="skip_hw" | ||
117 | tests | ||
118 | |||
119 | if ! tc_offload_check; then | ||
120 | echo "WARN: Could not test offloaded functionality" | ||
121 | else | ||
122 | tcflags="skip_sw" | ||
123 | tests | ||
124 | fi | ||
125 | |||
126 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh new file mode 100755 index 000000000000..61844caf671e --- /dev/null +++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1q_lag.sh | |||
@@ -0,0 +1,283 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for "tc action mirred egress mirror" when the underlay route points at a | ||
5 | # bridge device with vlan filtering (802.1q), and the egress device is a team | ||
6 | # device. | ||
7 | # | ||
8 | # +----------------------+ +----------------------+ | ||
9 | # | H1 | | H2 | | ||
10 | # | + $h1.333 | | $h1.555 + | | ||
11 | # | | 192.0.2.1/28 | | 192.0.2.18/28 | | | ||
12 | # +-----|----------------+ +----------------|-----+ | ||
13 | # | $h1 | | ||
14 | # +--------------------------------+------------------------------+ | ||
15 | # | | ||
16 | # +--------------------------------------|------------------------------------+ | ||
17 | # | SW o---> mirror | | ||
18 | # | | | | ||
19 | # | +--------------------------------+------------------------------+ | | ||
20 | # | | $swp1 | | | ||
21 | # | + $swp1.333 $swp1.555 + | | ||
22 | # | 192.0.2.2/28 192.0.2.17/28 | | ||
23 | # | | | ||
24 | # | +-----------------------------------------------------------------------+ | | ||
25 | # | | BR1 (802.1q) | | | ||
26 | # | | + lag (team) 192.0.2.129/28 | | | ||
27 | # | | / \ 2001:db8:2::1/64 | | | ||
28 | # | +---/---\---------------------------------------------------------------+ | | ||
29 | # | / \ ^ | | ||
30 | # | | \ + gt4 (gretap) | | | ||
31 | # | | \ loc=192.0.2.129 | | | ||
32 | # | | \ rem=192.0.2.130 -+ | | ||
33 | # | | \ ttl=100 | | ||
34 | # | | \ tos=inherit | | ||
35 | # | | \ | | ||
36 | # | | \_________________________________ | | ||
37 | # | | \ | | ||
38 | # | + $swp3 + $swp4 | | ||
39 | # +---|------------------------------------------------|----------------------+ | ||
40 | # | | | ||
41 | # +---|----------------------+ +---|----------------------+ | ||
42 | # | + $h3 H3 | | + $h4 H4 | | ||
43 | # | 192.0.2.130/28 | | 192.0.2.130/28 | | ||
44 | # | 2001:db8:2::2/64 | | 2001:db8:2::2/64 | | ||
45 | # +--------------------------+ +--------------------------+ | ||
46 | |||
47 | ALL_TESTS=" | ||
48 | test_mirror_gretap_first | ||
49 | test_mirror_gretap_second | ||
50 | " | ||
51 | |||
52 | NUM_NETIFS=6 | ||
53 | source lib.sh | ||
54 | source mirror_lib.sh | ||
55 | source mirror_gre_lib.sh | ||
56 | |||
57 | require_command $ARPING | ||
58 | |||
59 | vlan_host_create() | ||
60 | { | ||
61 | local if_name=$1; shift | ||
62 | local vid=$1; shift | ||
63 | local vrf_name=$1; shift | ||
64 | local ips=("${@}") | ||
65 | |||
66 | vrf_create $vrf_name | ||
67 | ip link set dev $vrf_name up | ||
68 | vlan_create $if_name $vid $vrf_name "${ips[@]}" | ||
69 | } | ||
70 | |||
71 | vlan_host_destroy() | ||
72 | { | ||
73 | local if_name=$1; shift | ||
74 | local vid=$1; shift | ||
75 | local vrf_name=$1; shift | ||
76 | |||
77 | vlan_destroy $if_name $vid | ||
78 | ip link set dev $vrf_name down | ||
79 | vrf_destroy $vrf_name | ||
80 | } | ||
81 | |||
82 | h1_create() | ||
83 | { | ||
84 | vlan_host_create $h1 333 vrf-h1 192.0.2.1/28 | ||
85 | ip -4 route add 192.0.2.16/28 vrf vrf-h1 nexthop via 192.0.2.2 | ||
86 | } | ||
87 | |||
88 | h1_destroy() | ||
89 | { | ||
90 | ip -4 route del 192.0.2.16/28 vrf vrf-h1 | ||
91 | vlan_host_destroy $h1 333 vrf-h1 | ||
92 | } | ||
93 | |||
94 | h2_create() | ||
95 | { | ||
96 | vlan_host_create $h1 555 vrf-h2 192.0.2.18/28 | ||
97 | ip -4 route add 192.0.2.0/28 vrf vrf-h2 nexthop via 192.0.2.17 | ||
98 | } | ||
99 | |||
100 | h2_destroy() | ||
101 | { | ||
102 | ip -4 route del 192.0.2.0/28 vrf vrf-h2 | ||
103 | vlan_host_destroy $h1 555 vrf-h2 | ||
104 | } | ||
105 | |||
106 | h3_create() | ||
107 | { | ||
108 | simple_if_init $h3 192.0.2.130/28 | ||
109 | tc qdisc add dev $h3 clsact | ||
110 | } | ||
111 | |||
112 | h3_destroy() | ||
113 | { | ||
114 | tc qdisc del dev $h3 clsact | ||
115 | simple_if_fini $h3 192.0.2.130/28 | ||
116 | } | ||
117 | |||
118 | h4_create() | ||
119 | { | ||
120 | simple_if_init $h4 192.0.2.130/28 | ||
121 | tc qdisc add dev $h4 clsact | ||
122 | } | ||
123 | |||
124 | h4_destroy() | ||
125 | { | ||
126 | tc qdisc del dev $h4 clsact | ||
127 | simple_if_fini $h4 192.0.2.130/28 | ||
128 | } | ||
129 | |||
130 | switch_create() | ||
131 | { | ||
132 | ip link set dev $swp1 up | ||
133 | tc qdisc add dev $swp1 clsact | ||
134 | vlan_create $swp1 333 "" 192.0.2.2/28 | ||
135 | vlan_create $swp1 555 "" 192.0.2.17/28 | ||
136 | |||
137 | tunnel_create gt4 gretap 192.0.2.129 192.0.2.130 \ | ||
138 | ttl 100 tos inherit | ||
139 | |||
140 | ip link set dev $swp3 up | ||
141 | ip link set dev $swp4 up | ||
142 | |||
143 | ip link add name br1 type bridge vlan_filtering 1 | ||
144 | ip link set dev br1 up | ||
145 | __addr_add_del br1 add 192.0.2.129/32 | ||
146 | ip -4 route add 192.0.2.130/32 dev br1 | ||
147 | |||
148 | team_create lag loadbalance $swp3 $swp4 | ||
149 | ip link set dev lag master br1 | ||
150 | } | ||
151 | |||
152 | switch_destroy() | ||
153 | { | ||
154 | ip link set dev lag nomaster | ||
155 | team_destroy lag | ||
156 | |||
157 | ip -4 route del 192.0.2.130/32 dev br1 | ||
158 | __addr_add_del br1 del 192.0.2.129/32 | ||
159 | ip link set dev br1 down | ||
160 | ip link del dev br1 | ||
161 | |||
162 | ip link set dev $swp4 down | ||
163 | ip link set dev $swp3 down | ||
164 | |||
165 | tunnel_destroy gt4 | ||
166 | |||
167 | vlan_destroy $swp1 555 | ||
168 | vlan_destroy $swp1 333 | ||
169 | tc qdisc del dev $swp1 clsact | ||
170 | ip link set dev $swp1 down | ||
171 | } | ||
172 | |||
173 | setup_prepare() | ||
174 | { | ||
175 | h1=${NETIFS[p1]} | ||
176 | swp1=${NETIFS[p2]} | ||
177 | |||
178 | swp3=${NETIFS[p3]} | ||
179 | h3=${NETIFS[p4]} | ||
180 | |||
181 | swp4=${NETIFS[p5]} | ||
182 | h4=${NETIFS[p6]} | ||
183 | |||
184 | vrf_prepare | ||
185 | |||
186 | ip link set dev $h1 up | ||
187 | h1_create | ||
188 | h2_create | ||
189 | h3_create | ||
190 | h4_create | ||
191 | switch_create | ||
192 | |||
193 | trap_install $h3 ingress | ||
194 | trap_install $h4 ingress | ||
195 | } | ||
196 | |||
197 | cleanup() | ||
198 | { | ||
199 | pre_cleanup | ||
200 | |||
201 | trap_uninstall $h4 ingress | ||
202 | trap_uninstall $h3 ingress | ||
203 | |||
204 | switch_destroy | ||
205 | h4_destroy | ||
206 | h3_destroy | ||
207 | h2_destroy | ||
208 | h1_destroy | ||
209 | ip link set dev $h1 down | ||
210 | |||
211 | vrf_cleanup | ||
212 | } | ||
213 | |||
214 | test_lag_slave() | ||
215 | { | ||
216 | local host_dev=$1; shift | ||
217 | local up_dev=$1; shift | ||
218 | local down_dev=$1; shift | ||
219 | local what=$1; shift | ||
220 | |||
221 | RET=0 | ||
222 | |||
223 | mirror_install $swp1 ingress gt4 \ | ||
224 | "proto 802.1q flower vlan_id 333 $tcflags" | ||
225 | |||
226 | # Test connectivity through $up_dev when $down_dev is set down. | ||
227 | ip link set dev $down_dev down | ||
228 | setup_wait_dev $up_dev | ||
229 | setup_wait_dev $host_dev | ||
230 | $ARPING -I br1 192.0.2.130 -qfc 1 | ||
231 | sleep 2 | ||
232 | mirror_test vrf-h1 192.0.2.1 192.0.2.18 $host_dev 1 10 | ||
233 | |||
234 | # Test lack of connectivity when both slaves are down. | ||
235 | ip link set dev $up_dev down | ||
236 | sleep 2 | ||
237 | mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h3 1 0 | ||
238 | mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h4 1 0 | ||
239 | |||
240 | ip link set dev $up_dev up | ||
241 | ip link set dev $down_dev up | ||
242 | mirror_uninstall $swp1 ingress | ||
243 | |||
244 | log_test "$what ($tcflags)" | ||
245 | } | ||
246 | |||
247 | test_mirror_gretap_first() | ||
248 | { | ||
249 | test_lag_slave $h3 $swp3 $swp4 "mirror to gretap: LAG first slave" | ||
250 | } | ||
251 | |||
252 | test_mirror_gretap_second() | ||
253 | { | ||
254 | test_lag_slave $h4 $swp4 $swp3 "mirror to gretap: LAG second slave" | ||
255 | } | ||
256 | |||
257 | test_all() | ||
258 | { | ||
259 | slow_path_trap_install $swp1 ingress | ||
260 | slow_path_trap_install $swp1 egress | ||
261 | |||
262 | tests_run | ||
263 | |||
264 | slow_path_trap_uninstall $swp1 egress | ||
265 | slow_path_trap_uninstall $swp1 ingress | ||
266 | } | ||
267 | |||
268 | trap cleanup EXIT | ||
269 | |||
270 | setup_prepare | ||
271 | setup_wait | ||
272 | |||
273 | tcflags="skip_hw" | ||
274 | test_all | ||
275 | |||
276 | if ! tc_offload_check; then | ||
277 | echo "WARN: Could not test offloaded functionality" | ||
278 | else | ||
279 | tcflags="skip_sw" | ||
280 | test_all | ||
281 | fi | ||
282 | |||
283 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh b/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh index aa29d46186a8..135902aa8b11 100755 --- a/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_changes.sh | |||
@@ -122,15 +122,8 @@ test_span_gre_egress_up() | |||
122 | # After setting the device up, wait for neighbor to get resolved so that | 122 | # After setting the device up, wait for neighbor to get resolved so that |
123 | # we can expect mirroring to work. | 123 | # we can expect mirroring to work. |
124 | ip link set dev $swp3 up | 124 | ip link set dev $swp3 up |
125 | while true; do | 125 | setup_wait_dev $swp3 |
126 | ip neigh sh dev $swp3 $remote_ip nud reachable | | 126 | ping -c 1 -I $swp3 $remote_ip &>/dev/null |
127 | grep -q ^ | ||
128 | if [[ $? -ne 0 ]]; then | ||
129 | sleep 1 | ||
130 | else | ||
131 | break | ||
132 | fi | ||
133 | done | ||
134 | 127 | ||
135 | quick_test_span_gre_dir $tundev ingress | 128 | quick_test_span_gre_dir $tundev ingress |
136 | mirror_uninstall $swp1 ingress | 129 | mirror_uninstall $swp1 ingress |
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh b/tools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh new file mode 100755 index 000000000000..9edf4cb104a8 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/mirror_gre_lag_lacp.sh | |||
@@ -0,0 +1,285 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | # Test for "tc action mirred egress mirror" when the underlay route points at a | ||
5 | # team device. | ||
6 | # | ||
7 | # +----------------------+ +----------------------+ | ||
8 | # | H1 | | H2 | | ||
9 | # | + $h1.333 | | $h1.555 + | | ||
10 | # | | 192.0.2.1/28 | | 192.0.2.18/28 | | | ||
11 | # +----|-----------------+ +----------------|-----+ | ||
12 | # | $h1 | | ||
13 | # +---------------------------------+------------------------------+ | ||
14 | # | | ||
15 | # +--------------------------------------|------------------------------------+ | ||
16 | # | SW o---> mirror | | ||
17 | # | | | | ||
18 | # | +----------------------------------+------------------------------+ | | ||
19 | # | | $swp1 | | | ||
20 | # | + $swp1.333 $swp1.555 + | | ||
21 | # | 192.0.2.2/28 192.0.2.17/28 | | ||
22 | # | | | ||
23 | # | | | ||
24 | # | + gt4 (gretap) ,-> + lag1 (team) | | ||
25 | # | loc=192.0.2.129 | | 192.0.2.129/28 | | ||
26 | # | rem=192.0.2.130 --' | | | ||
27 | # | ttl=100 | | | ||
28 | # | tos=inherit | | | ||
29 | # | _____________________|______________________ | | ||
30 | # | / \ | | ||
31 | # | / \ | | ||
32 | # | + $swp3 + $swp4 | | ||
33 | # +---|------------------------------------------------|----------------------+ | ||
34 | # | | | ||
35 | # +---|------------------------------------------------|----------------------+ | ||
36 | # | + $h3 + $h4 H3 | | ||
37 | # | \ / | | ||
38 | # | \____________________________________________/ | | ||
39 | # | | | | ||
40 | # | + lag2 (team) | | ||
41 | # | 192.0.2.130/28 | | ||
42 | # | | | ||
43 | # +---------------------------------------------------------------------------+ | ||
44 | |||
45 | ALL_TESTS=" | ||
46 | test_mirror_gretap_first | ||
47 | test_mirror_gretap_second | ||
48 | " | ||
49 | |||
50 | NUM_NETIFS=6 | ||
51 | source lib.sh | ||
52 | source mirror_lib.sh | ||
53 | source mirror_gre_lib.sh | ||
54 | |||
55 | require_command $ARPING | ||
56 | |||
57 | vlan_host_create() | ||
58 | { | ||
59 | local if_name=$1; shift | ||
60 | local vid=$1; shift | ||
61 | local vrf_name=$1; shift | ||
62 | local ips=("${@}") | ||
63 | |||
64 | vrf_create $vrf_name | ||
65 | ip link set dev $vrf_name up | ||
66 | vlan_create $if_name $vid $vrf_name "${ips[@]}" | ||
67 | } | ||
68 | |||
69 | vlan_host_destroy() | ||
70 | { | ||
71 | local if_name=$1; shift | ||
72 | local vid=$1; shift | ||
73 | local vrf_name=$1; shift | ||
74 | |||
75 | vlan_destroy $if_name $vid | ||
76 | ip link set dev $vrf_name down | ||
77 | vrf_destroy $vrf_name | ||
78 | } | ||
79 | |||
80 | h1_create() | ||
81 | { | ||
82 | vlan_host_create $h1 333 vrf-h1 192.0.2.1/28 | ||
83 | ip -4 route add 192.0.2.16/28 vrf vrf-h1 nexthop via 192.0.2.2 | ||
84 | } | ||
85 | |||
86 | h1_destroy() | ||
87 | { | ||
88 | ip -4 route del 192.0.2.16/28 vrf vrf-h1 | ||
89 | vlan_host_destroy $h1 333 vrf-h1 | ||
90 | } | ||
91 | |||
92 | h2_create() | ||
93 | { | ||
94 | vlan_host_create $h1 555 vrf-h2 192.0.2.18/28 | ||
95 | ip -4 route add 192.0.2.0/28 vrf vrf-h2 nexthop via 192.0.2.17 | ||
96 | } | ||
97 | |||
98 | h2_destroy() | ||
99 | { | ||
100 | ip -4 route del 192.0.2.0/28 vrf vrf-h2 | ||
101 | vlan_host_destroy $h1 555 vrf-h2 | ||
102 | } | ||
103 | |||
104 | h3_create_team() | ||
105 | { | ||
106 | team_create lag2 lacp $h3 $h4 | ||
107 | __simple_if_init lag2 vrf-h3 192.0.2.130/32 | ||
108 | ip -4 route add vrf vrf-h3 192.0.2.129/32 dev lag2 | ||
109 | } | ||
110 | |||
111 | h3_destroy_team() | ||
112 | { | ||
113 | ip -4 route del vrf vrf-h3 192.0.2.129/32 dev lag2 | ||
114 | __simple_if_fini lag2 192.0.2.130/32 | ||
115 | team_destroy lag2 | ||
116 | |||
117 | ip link set dev $h3 down | ||
118 | ip link set dev $h4 down | ||
119 | } | ||
120 | |||
121 | h3_create() | ||
122 | { | ||
123 | vrf_create vrf-h3 | ||
124 | ip link set dev vrf-h3 up | ||
125 | tc qdisc add dev $h3 clsact | ||
126 | tc qdisc add dev $h4 clsact | ||
127 | h3_create_team | ||
128 | } | ||
129 | |||
130 | h3_destroy() | ||
131 | { | ||
132 | h3_destroy_team | ||
133 | tc qdisc del dev $h4 clsact | ||
134 | tc qdisc del dev $h3 clsact | ||
135 | ip link set dev vrf-h3 down | ||
136 | vrf_destroy vrf-h3 | ||
137 | } | ||
138 | |||
139 | switch_create() | ||
140 | { | ||
141 | ip link set dev $swp1 up | ||
142 | tc qdisc add dev $swp1 clsact | ||
143 | vlan_create $swp1 333 "" 192.0.2.2/28 | ||
144 | vlan_create $swp1 555 "" 192.0.2.17/28 | ||
145 | |||
146 | tunnel_create gt4 gretap 192.0.2.129 192.0.2.130 \ | ||
147 | ttl 100 tos inherit | ||
148 | |||
149 | ip link set dev $swp3 up | ||
150 | ip link set dev $swp4 up | ||
151 | team_create lag1 lacp $swp3 $swp4 | ||
152 | __addr_add_del lag1 add 192.0.2.129/32 | ||
153 | ip -4 route add 192.0.2.130/32 dev lag1 | ||
154 | } | ||
155 | |||
156 | switch_destroy() | ||
157 | { | ||
158 | ip -4 route del 192.0.2.130/32 dev lag1 | ||
159 | __addr_add_del lag1 del 192.0.2.129/32 | ||
160 | team_destroy lag1 | ||
161 | |||
162 | ip link set dev $swp4 down | ||
163 | ip link set dev $swp3 down | ||
164 | |||
165 | tunnel_destroy gt4 | ||
166 | |||
167 | vlan_destroy $swp1 555 | ||
168 | vlan_destroy $swp1 333 | ||
169 | tc qdisc del dev $swp1 clsact | ||
170 | ip link set dev $swp1 down | ||
171 | } | ||
172 | |||
173 | setup_prepare() | ||
174 | { | ||
175 | h1=${NETIFS[p1]} | ||
176 | swp1=${NETIFS[p2]} | ||
177 | |||
178 | swp3=${NETIFS[p3]} | ||
179 | h3=${NETIFS[p4]} | ||
180 | |||
181 | swp4=${NETIFS[p5]} | ||
182 | h4=${NETIFS[p6]} | ||
183 | |||
184 | vrf_prepare | ||
185 | |||
186 | ip link set dev $h1 up | ||
187 | h1_create | ||
188 | h2_create | ||
189 | h3_create | ||
190 | switch_create | ||
191 | |||
192 | trap_install $h3 ingress | ||
193 | trap_install $h4 ingress | ||
194 | } | ||
195 | |||
196 | cleanup() | ||
197 | { | ||
198 | pre_cleanup | ||
199 | |||
200 | trap_uninstall $h4 ingress | ||
201 | trap_uninstall $h3 ingress | ||
202 | |||
203 | switch_destroy | ||
204 | h3_destroy | ||
205 | h2_destroy | ||
206 | h1_destroy | ||
207 | ip link set dev $h1 down | ||
208 | |||
209 | vrf_cleanup | ||
210 | } | ||
211 | |||
212 | test_lag_slave() | ||
213 | { | ||
214 | local up_dev=$1; shift | ||
215 | local down_dev=$1; shift | ||
216 | local what=$1; shift | ||
217 | |||
218 | RET=0 | ||
219 | |||
220 | mirror_install $swp1 ingress gt4 \ | ||
221 | "proto 802.1q flower vlan_id 333 $tcflags" | ||
222 | |||
223 | # Move $down_dev away from the team. That will prompt change in | ||
224 | # txability of the connected device, without changing its upness. The | ||
225 | # driver should notice the txability change and move the traffic to the | ||
226 | # other slave. | ||
227 | ip link set dev $down_dev nomaster | ||
228 | sleep 2 | ||
229 | mirror_test vrf-h1 192.0.2.1 192.0.2.18 $up_dev 1 10 | ||
230 | |||
231 | # Test lack of connectivity when neither slave is txable. | ||
232 | ip link set dev $up_dev nomaster | ||
233 | sleep 2 | ||
234 | mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h3 1 0 | ||
235 | mirror_test vrf-h1 192.0.2.1 192.0.2.18 $h4 1 0 | ||
236 | mirror_uninstall $swp1 ingress | ||
237 | |||
238 | # Recreate H3's team device, because mlxsw, which this test is | ||
239 | # predominantly mean to test, requires a bottom-up construction and | ||
240 | # doesn't allow enslavement to a device that already has an upper. | ||
241 | h3_destroy_team | ||
242 | h3_create_team | ||
243 | # Wait for ${h,swp}{3,4}. | ||
244 | setup_wait | ||
245 | |||
246 | log_test "$what ($tcflags)" | ||
247 | } | ||
248 | |||
249 | test_mirror_gretap_first() | ||
250 | { | ||
251 | test_lag_slave $h3 $h4 "mirror to gretap: LAG first slave" | ||
252 | } | ||
253 | |||
254 | test_mirror_gretap_second() | ||
255 | { | ||
256 | test_lag_slave $h4 $h3 "mirror to gretap: LAG second slave" | ||
257 | } | ||
258 | |||
259 | test_all() | ||
260 | { | ||
261 | slow_path_trap_install $swp1 ingress | ||
262 | slow_path_trap_install $swp1 egress | ||
263 | |||
264 | tests_run | ||
265 | |||
266 | slow_path_trap_uninstall $swp1 egress | ||
267 | slow_path_trap_uninstall $swp1 ingress | ||
268 | } | ||
269 | |||
270 | trap cleanup EXIT | ||
271 | |||
272 | setup_prepare | ||
273 | setup_wait | ||
274 | |||
275 | tcflags="skip_hw" | ||
276 | test_all | ||
277 | |||
278 | if ! tc_offload_check; then | ||
279 | echo "WARN: Could not test offloaded functionality" | ||
280 | else | ||
281 | tcflags="skip_sw" | ||
282 | test_all | ||
283 | fi | ||
284 | |||
285 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh b/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh index 619b469365be..fac486178ef7 100644 --- a/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | 2 | ||
3 | source mirror_lib.sh | 3 | source "$relative_path/mirror_lib.sh" |
4 | 4 | ||
5 | quick_test_span_gre_dir_ips() | 5 | quick_test_span_gre_dir_ips() |
6 | { | 6 | { |
@@ -62,7 +62,7 @@ full_test_span_gre_dir_vlan_ips() | |||
62 | "$backward_type" "$ip1" "$ip2" | 62 | "$backward_type" "$ip1" "$ip2" |
63 | 63 | ||
64 | tc filter add dev $h3 ingress pref 77 prot 802.1q \ | 64 | tc filter add dev $h3 ingress pref 77 prot 802.1q \ |
65 | flower $vlan_match ip_proto 0x2f \ | 65 | flower $vlan_match \ |
66 | action pass | 66 | action pass |
67 | mirror_test v$h1 $ip1 $ip2 $h3 77 10 | 67 | mirror_test v$h1 $ip1 $ip2 $h3 77 10 |
68 | tc filter del dev $h3 ingress pref 77 | 68 | tc filter del dev $h3 ingress pref 77 |
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh b/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh index 8fa681eb90e7..6f9ef1820e93 100755 --- a/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_nh.sh | |||
@@ -35,6 +35,8 @@ setup_prepare() | |||
35 | vrf_prepare | 35 | vrf_prepare |
36 | mirror_gre_topo_create | 36 | mirror_gre_topo_create |
37 | 37 | ||
38 | sysctl_set net.ipv4.conf.v$h3.rp_filter 0 | ||
39 | |||
38 | ip address add dev $swp3 192.0.2.161/28 | 40 | ip address add dev $swp3 192.0.2.161/28 |
39 | ip address add dev $h3 192.0.2.162/28 | 41 | ip address add dev $h3 192.0.2.162/28 |
40 | ip address add dev gt4 192.0.2.129/32 | 42 | ip address add dev gt4 192.0.2.129/32 |
@@ -61,6 +63,8 @@ cleanup() | |||
61 | ip address del dev $h3 192.0.2.162/28 | 63 | ip address del dev $h3 192.0.2.162/28 |
62 | ip address del dev $swp3 192.0.2.161/28 | 64 | ip address del dev $swp3 192.0.2.161/28 |
63 | 65 | ||
66 | sysctl_restore net.ipv4.conf.v$h3.rp_filter 0 | ||
67 | |||
64 | mirror_gre_topo_destroy | 68 | mirror_gre_topo_destroy |
65 | vrf_cleanup | 69 | vrf_cleanup |
66 | 70 | ||
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh b/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh index 253419564708..39c03e2867f4 100644 --- a/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh | |||
@@ -33,7 +33,7 @@ | |||
33 | # | | | 33 | # | | |
34 | # +-------------------------------------------------------------------------+ | 34 | # +-------------------------------------------------------------------------+ |
35 | 35 | ||
36 | source mirror_topo_lib.sh | 36 | source "$relative_path/mirror_topo_lib.sh" |
37 | 37 | ||
38 | mirror_gre_topo_h3_create() | 38 | mirror_gre_topo_h3_create() |
39 | { | 39 | { |
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh b/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh index 5dbc7a08f4bd..204b25f13934 100755 --- a/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_vlan_bridge_1q.sh | |||
@@ -28,6 +28,8 @@ source mirror_lib.sh | |||
28 | source mirror_gre_lib.sh | 28 | source mirror_gre_lib.sh |
29 | source mirror_gre_topo_lib.sh | 29 | source mirror_gre_topo_lib.sh |
30 | 30 | ||
31 | require_command $ARPING | ||
32 | |||
31 | setup_prepare() | 33 | setup_prepare() |
32 | { | 34 | { |
33 | h1=${NETIFS[p1]} | 35 | h1=${NETIFS[p1]} |
@@ -39,6 +41,12 @@ setup_prepare() | |||
39 | swp3=${NETIFS[p5]} | 41 | swp3=${NETIFS[p5]} |
40 | h3=${NETIFS[p6]} | 42 | h3=${NETIFS[p6]} |
41 | 43 | ||
44 | # gt4's remote address is at $h3.555, not $h3. Thus the packets arriving | ||
45 | # directly to $h3 for test_gretap_untagged_egress() are rejected by | ||
46 | # rp_filter and the test spuriously fails. | ||
47 | sysctl_set net.ipv4.conf.all.rp_filter 0 | ||
48 | sysctl_set net.ipv4.conf.$h3.rp_filter 0 | ||
49 | |||
42 | vrf_prepare | 50 | vrf_prepare |
43 | mirror_gre_topo_create | 51 | mirror_gre_topo_create |
44 | 52 | ||
@@ -65,6 +73,9 @@ cleanup() | |||
65 | 73 | ||
66 | mirror_gre_topo_destroy | 74 | mirror_gre_topo_destroy |
67 | vrf_cleanup | 75 | vrf_cleanup |
76 | |||
77 | sysctl_restore net.ipv4.conf.$h3.rp_filter | ||
78 | sysctl_restore net.ipv4.conf.all.rp_filter | ||
68 | } | 79 | } |
69 | 80 | ||
70 | test_vlan_match() | 81 | test_vlan_match() |
@@ -79,12 +90,14 @@ test_vlan_match() | |||
79 | 90 | ||
80 | test_gretap() | 91 | test_gretap() |
81 | { | 92 | { |
82 | test_vlan_match gt4 'vlan_id 555 vlan_ethtype ip' "mirror to gretap" | 93 | test_vlan_match gt4 'skip_hw vlan_id 555 vlan_ethtype ip' \ |
94 | "mirror to gretap" | ||
83 | } | 95 | } |
84 | 96 | ||
85 | test_ip6gretap() | 97 | test_ip6gretap() |
86 | { | 98 | { |
87 | test_vlan_match gt6 'vlan_id 555 vlan_ethtype ipv6' "mirror to ip6gretap" | 99 | test_vlan_match gt6 'skip_hw vlan_id 555 vlan_ethtype ip' \ |
100 | "mirror to ip6gretap" | ||
88 | } | 101 | } |
89 | 102 | ||
90 | test_span_gre_forbidden_cpu() | 103 | test_span_gre_forbidden_cpu() |
@@ -138,7 +151,7 @@ test_span_gre_forbidden_egress() | |||
138 | 151 | ||
139 | bridge vlan add dev $swp3 vid 555 | 152 | bridge vlan add dev $swp3 vid 555 |
140 | # Re-prime FDB | 153 | # Re-prime FDB |
141 | arping -I br1.555 192.0.2.130 -fqc 1 | 154 | $ARPING -I br1.555 192.0.2.130 -fqc 1 |
142 | sleep 1 | 155 | sleep 1 |
143 | quick_test_span_gre_dir $tundev ingress | 156 | quick_test_span_gre_dir $tundev ingress |
144 | 157 | ||
@@ -212,7 +225,7 @@ test_span_gre_fdb_roaming() | |||
212 | 225 | ||
213 | bridge fdb del dev $swp2 $h3mac vlan 555 master | 226 | bridge fdb del dev $swp2 $h3mac vlan 555 master |
214 | # Re-prime FDB | 227 | # Re-prime FDB |
215 | arping -I br1.555 192.0.2.130 -fqc 1 | 228 | $ARPING -I br1.555 192.0.2.130 -fqc 1 |
216 | sleep 1 | 229 | sleep 1 |
217 | quick_test_span_gre_dir $tundev ingress | 230 | quick_test_span_gre_dir $tundev ingress |
218 | 231 | ||
diff --git a/tools/testing/selftests/net/forwarding/mirror_lib.sh b/tools/testing/selftests/net/forwarding/mirror_lib.sh index d36dc26c6c51..07991e1025c7 100644 --- a/tools/testing/selftests/net/forwarding/mirror_lib.sh +++ b/tools/testing/selftests/net/forwarding/mirror_lib.sh | |||
@@ -105,7 +105,7 @@ do_test_span_vlan_dir_ips() | |||
105 | # Install the capture as skip_hw to avoid double-counting of packets. | 105 | # Install the capture as skip_hw to avoid double-counting of packets. |
106 | # The traffic is meant for local box anyway, so will be trapped to | 106 | # The traffic is meant for local box anyway, so will be trapped to |
107 | # kernel. | 107 | # kernel. |
108 | vlan_capture_install $dev "skip_hw vlan_id $vid" | 108 | vlan_capture_install $dev "skip_hw vlan_id $vid vlan_ethtype ip" |
109 | mirror_test v$h1 $ip1 $ip2 $dev 100 $expect | 109 | mirror_test v$h1 $ip1 $ip2 $dev 100 $expect |
110 | mirror_test v$h2 $ip2 $ip1 $dev 100 $expect | 110 | mirror_test v$h2 $ip2 $ip1 $dev 100 $expect |
111 | vlan_capture_uninstall $dev | 111 | vlan_capture_uninstall $dev |
diff --git a/tools/testing/selftests/net/forwarding/router_bridge.sh b/tools/testing/selftests/net/forwarding/router_bridge.sh new file mode 100755 index 000000000000..ebc596a272f7 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/router_bridge.sh | |||
@@ -0,0 +1,113 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | ALL_TESTS=" | ||
5 | ping_ipv4 | ||
6 | ping_ipv6 | ||
7 | " | ||
8 | NUM_NETIFS=4 | ||
9 | source lib.sh | ||
10 | |||
11 | h1_create() | ||
12 | { | ||
13 | simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64 | ||
14 | ip -4 route add 192.0.2.128/28 vrf v$h1 nexthop via 192.0.2.2 | ||
15 | ip -6 route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2 | ||
16 | } | ||
17 | |||
18 | h1_destroy() | ||
19 | { | ||
20 | ip -6 route del 2001:db8:2::/64 vrf v$h1 | ||
21 | ip -4 route del 192.0.2.128/28 vrf v$h1 | ||
22 | simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/64 | ||
23 | } | ||
24 | |||
25 | h2_create() | ||
26 | { | ||
27 | simple_if_init $h2 192.0.2.130/28 2001:db8:2::2/64 | ||
28 | ip -4 route add 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.129 | ||
29 | ip -6 route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1 | ||
30 | } | ||
31 | |||
32 | h2_destroy() | ||
33 | { | ||
34 | ip -6 route del 2001:db8:1::/64 vrf v$h2 | ||
35 | ip -4 route del 192.0.2.0/28 vrf v$h2 | ||
36 | simple_if_fini $h2 192.0.2.130/28 2001:db8:2::2/64 | ||
37 | } | ||
38 | |||
39 | router_create() | ||
40 | { | ||
41 | ip link add name br1 type bridge vlan_filtering 1 | ||
42 | ip link set dev br1 up | ||
43 | |||
44 | ip link set dev $swp1 master br1 | ||
45 | ip link set dev $swp1 up | ||
46 | __addr_add_del br1 add 192.0.2.2/28 2001:db8:1::2/64 | ||
47 | |||
48 | ip link set dev $swp2 up | ||
49 | __addr_add_del $swp2 add 192.0.2.129/28 2001:db8:2::1/64 | ||
50 | } | ||
51 | |||
52 | router_destroy() | ||
53 | { | ||
54 | __addr_add_del $swp2 del 192.0.2.129/28 2001:db8:2::1/64 | ||
55 | ip link set dev $swp2 down | ||
56 | |||
57 | __addr_add_del br1 del 192.0.2.2/28 2001:db8:1::2/64 | ||
58 | ip link set dev $swp1 down | ||
59 | ip link set dev $swp1 nomaster | ||
60 | |||
61 | ip link del dev br1 | ||
62 | } | ||
63 | |||
64 | setup_prepare() | ||
65 | { | ||
66 | h1=${NETIFS[p1]} | ||
67 | swp1=${NETIFS[p2]} | ||
68 | |||
69 | swp2=${NETIFS[p3]} | ||
70 | h2=${NETIFS[p4]} | ||
71 | |||
72 | vrf_prepare | ||
73 | |||
74 | h1_create | ||
75 | h2_create | ||
76 | |||
77 | router_create | ||
78 | |||
79 | forwarding_enable | ||
80 | } | ||
81 | |||
82 | cleanup() | ||
83 | { | ||
84 | pre_cleanup | ||
85 | |||
86 | forwarding_restore | ||
87 | |||
88 | router_destroy | ||
89 | |||
90 | h2_destroy | ||
91 | h1_destroy | ||
92 | |||
93 | vrf_cleanup | ||
94 | } | ||
95 | |||
96 | ping_ipv4() | ||
97 | { | ||
98 | ping_test $h1 192.0.2.130 | ||
99 | } | ||
100 | |||
101 | ping_ipv6() | ||
102 | { | ||
103 | ping6_test $h1 2001:db8:2::2 | ||
104 | } | ||
105 | |||
106 | trap cleanup EXIT | ||
107 | |||
108 | setup_prepare | ||
109 | setup_wait | ||
110 | |||
111 | tests_run | ||
112 | |||
113 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/router_bridge_vlan.sh b/tools/testing/selftests/net/forwarding/router_bridge_vlan.sh new file mode 100755 index 000000000000..fef88eb4b873 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/router_bridge_vlan.sh | |||
@@ -0,0 +1,132 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | ALL_TESTS=" | ||
5 | ping_ipv4 | ||
6 | ping_ipv6 | ||
7 | vlan | ||
8 | " | ||
9 | NUM_NETIFS=4 | ||
10 | source lib.sh | ||
11 | |||
12 | h1_create() | ||
13 | { | ||
14 | simple_if_init $h1 | ||
15 | vlan_create $h1 555 v$h1 192.0.2.1/28 2001:db8:1::1/64 | ||
16 | ip -4 route add 192.0.2.128/28 vrf v$h1 nexthop via 192.0.2.2 | ||
17 | ip -6 route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::2 | ||
18 | } | ||
19 | |||
20 | h1_destroy() | ||
21 | { | ||
22 | ip -6 route del 2001:db8:2::/64 vrf v$h1 | ||
23 | ip -4 route del 192.0.2.128/28 vrf v$h1 | ||
24 | vlan_destroy $h1 555 | ||
25 | simple_if_fini $h1 | ||
26 | } | ||
27 | |||
28 | h2_create() | ||
29 | { | ||
30 | simple_if_init $h2 192.0.2.130/28 2001:db8:2::2/64 | ||
31 | ip -4 route add 192.0.2.0/28 vrf v$h2 nexthop via 192.0.2.129 | ||
32 | ip -6 route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1 | ||
33 | } | ||
34 | |||
35 | h2_destroy() | ||
36 | { | ||
37 | ip -6 route del 2001:db8:1::/64 vrf v$h2 | ||
38 | ip -4 route del 192.0.2.0/28 vrf v$h2 | ||
39 | simple_if_fini $h2 192.0.2.130/28 | ||
40 | } | ||
41 | |||
42 | router_create() | ||
43 | { | ||
44 | ip link add name br1 type bridge vlan_filtering 1 | ||
45 | ip link set dev br1 up | ||
46 | |||
47 | ip link set dev $swp1 master br1 | ||
48 | ip link set dev $swp1 up | ||
49 | |||
50 | bridge vlan add dev br1 vid 555 self pvid untagged | ||
51 | bridge vlan add dev $swp1 vid 555 | ||
52 | |||
53 | __addr_add_del br1 add 192.0.2.2/28 2001:db8:1::2/64 | ||
54 | |||
55 | ip link set dev $swp2 up | ||
56 | __addr_add_del $swp2 add 192.0.2.129/28 2001:db8:2::1/64 | ||
57 | } | ||
58 | |||
59 | router_destroy() | ||
60 | { | ||
61 | __addr_add_del $swp2 del 192.0.2.129/28 2001:db8:2::1/64 | ||
62 | ip link set dev $swp2 down | ||
63 | |||
64 | __addr_add_del br1 del 192.0.2.2/28 2001:db8:1::2/64 | ||
65 | ip link set dev $swp1 down | ||
66 | ip link set dev $swp1 nomaster | ||
67 | |||
68 | ip link del dev br1 | ||
69 | } | ||
70 | |||
71 | setup_prepare() | ||
72 | { | ||
73 | h1=${NETIFS[p1]} | ||
74 | swp1=${NETIFS[p2]} | ||
75 | |||
76 | swp2=${NETIFS[p3]} | ||
77 | h2=${NETIFS[p4]} | ||
78 | |||
79 | vrf_prepare | ||
80 | |||
81 | h1_create | ||
82 | h2_create | ||
83 | |||
84 | router_create | ||
85 | |||
86 | forwarding_enable | ||
87 | } | ||
88 | |||
89 | cleanup() | ||
90 | { | ||
91 | pre_cleanup | ||
92 | |||
93 | forwarding_restore | ||
94 | |||
95 | router_destroy | ||
96 | |||
97 | h2_destroy | ||
98 | h1_destroy | ||
99 | |||
100 | vrf_cleanup | ||
101 | } | ||
102 | |||
103 | vlan() | ||
104 | { | ||
105 | RET=0 | ||
106 | |||
107 | bridge vlan add dev br1 vid 333 self | ||
108 | check_err $? "Can't add a non-PVID VLAN" | ||
109 | bridge vlan del dev br1 vid 333 self | ||
110 | check_err $? "Can't remove a non-PVID VLAN" | ||
111 | |||
112 | log_test "vlan" | ||
113 | } | ||
114 | |||
115 | ping_ipv4() | ||
116 | { | ||
117 | ping_test $h1 192.0.2.130 | ||
118 | } | ||
119 | |||
120 | ping_ipv6() | ||
121 | { | ||
122 | ping6_test $h1 2001:db8:2::2 | ||
123 | } | ||
124 | |||
125 | trap cleanup EXIT | ||
126 | |||
127 | setup_prepare | ||
128 | setup_wait | ||
129 | |||
130 | tests_run | ||
131 | |||
132 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/router_broadcast.sh b/tools/testing/selftests/net/forwarding/router_broadcast.sh new file mode 100755 index 000000000000..7bd2ebb6e9de --- /dev/null +++ b/tools/testing/selftests/net/forwarding/router_broadcast.sh | |||
@@ -0,0 +1,233 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | |||
4 | ALL_TESTS="ping_ipv4" | ||
5 | NUM_NETIFS=6 | ||
6 | source lib.sh | ||
7 | |||
8 | h1_create() | ||
9 | { | ||
10 | vrf_create "vrf-h1" | ||
11 | ip link set dev $h1 master vrf-h1 | ||
12 | |||
13 | ip link set dev vrf-h1 up | ||
14 | ip link set dev $h1 up | ||
15 | |||
16 | ip address add 192.0.2.2/24 dev $h1 | ||
17 | |||
18 | ip route add 198.51.100.0/24 vrf vrf-h1 nexthop via 192.0.2.1 | ||
19 | ip route add 198.51.200.0/24 vrf vrf-h1 nexthop via 192.0.2.1 | ||
20 | } | ||
21 | |||
22 | h1_destroy() | ||
23 | { | ||
24 | ip route del 198.51.200.0/24 vrf vrf-h1 | ||
25 | ip route del 198.51.100.0/24 vrf vrf-h1 | ||
26 | |||
27 | ip address del 192.0.2.2/24 dev $h1 | ||
28 | |||
29 | ip link set dev $h1 down | ||
30 | vrf_destroy "vrf-h1" | ||
31 | } | ||
32 | |||
33 | h2_create() | ||
34 | { | ||
35 | vrf_create "vrf-h2" | ||
36 | ip link set dev $h2 master vrf-h2 | ||
37 | |||
38 | ip link set dev vrf-h2 up | ||
39 | ip link set dev $h2 up | ||
40 | |||
41 | ip address add 198.51.100.2/24 dev $h2 | ||
42 | |||
43 | ip route add 192.0.2.0/24 vrf vrf-h2 nexthop via 198.51.100.1 | ||
44 | ip route add 198.51.200.0/24 vrf vrf-h2 nexthop via 198.51.100.1 | ||
45 | } | ||
46 | |||
47 | h2_destroy() | ||
48 | { | ||
49 | ip route del 198.51.200.0/24 vrf vrf-h2 | ||
50 | ip route del 192.0.2.0/24 vrf vrf-h2 | ||
51 | |||
52 | ip address del 198.51.100.2/24 dev $h2 | ||
53 | |||
54 | ip link set dev $h2 down | ||
55 | vrf_destroy "vrf-h2" | ||
56 | } | ||
57 | |||
58 | h3_create() | ||
59 | { | ||
60 | vrf_create "vrf-h3" | ||
61 | ip link set dev $h3 master vrf-h3 | ||
62 | |||
63 | ip link set dev vrf-h3 up | ||
64 | ip link set dev $h3 up | ||
65 | |||
66 | ip address add 198.51.200.2/24 dev $h3 | ||
67 | |||
68 | ip route add 192.0.2.0/24 vrf vrf-h3 nexthop via 198.51.200.1 | ||
69 | ip route add 198.51.100.0/24 vrf vrf-h3 nexthop via 198.51.200.1 | ||
70 | } | ||
71 | |||
72 | h3_destroy() | ||
73 | { | ||
74 | ip route del 198.51.100.0/24 vrf vrf-h3 | ||
75 | ip route del 192.0.2.0/24 vrf vrf-h3 | ||
76 | |||
77 | ip address del 198.51.200.2/24 dev $h3 | ||
78 | |||
79 | ip link set dev $h3 down | ||
80 | vrf_destroy "vrf-h3" | ||
81 | } | ||
82 | |||
83 | router_create() | ||
84 | { | ||
85 | ip link set dev $rp1 up | ||
86 | ip link set dev $rp2 up | ||
87 | ip link set dev $rp3 up | ||
88 | |||
89 | ip address add 192.0.2.1/24 dev $rp1 | ||
90 | |||
91 | ip address add 198.51.100.1/24 dev $rp2 | ||
92 | ip address add 198.51.200.1/24 dev $rp3 | ||
93 | } | ||
94 | |||
95 | router_destroy() | ||
96 | { | ||
97 | ip address del 198.51.200.1/24 dev $rp3 | ||
98 | ip address del 198.51.100.1/24 dev $rp2 | ||
99 | |||
100 | ip address del 192.0.2.1/24 dev $rp1 | ||
101 | |||
102 | ip link set dev $rp3 down | ||
103 | ip link set dev $rp2 down | ||
104 | ip link set dev $rp1 down | ||
105 | } | ||
106 | |||
107 | setup_prepare() | ||
108 | { | ||
109 | h1=${NETIFS[p1]} | ||
110 | rp1=${NETIFS[p2]} | ||
111 | |||
112 | rp2=${NETIFS[p3]} | ||
113 | h2=${NETIFS[p4]} | ||
114 | |||
115 | rp3=${NETIFS[p5]} | ||
116 | h3=${NETIFS[p6]} | ||
117 | |||
118 | vrf_prepare | ||
119 | |||
120 | h1_create | ||
121 | h2_create | ||
122 | h3_create | ||
123 | |||
124 | router_create | ||
125 | |||
126 | forwarding_enable | ||
127 | } | ||
128 | |||
129 | cleanup() | ||
130 | { | ||
131 | pre_cleanup | ||
132 | |||
133 | forwarding_restore | ||
134 | |||
135 | router_destroy | ||
136 | |||
137 | h3_destroy | ||
138 | h2_destroy | ||
139 | h1_destroy | ||
140 | |||
141 | vrf_cleanup | ||
142 | } | ||
143 | |||
144 | bc_forwarding_disable() | ||
145 | { | ||
146 | sysctl_set net.ipv4.conf.all.bc_forwarding 0 | ||
147 | sysctl_set net.ipv4.conf.$rp1.bc_forwarding 0 | ||
148 | } | ||
149 | |||
150 | bc_forwarding_enable() | ||
151 | { | ||
152 | sysctl_set net.ipv4.conf.all.bc_forwarding 1 | ||
153 | sysctl_set net.ipv4.conf.$rp1.bc_forwarding 1 | ||
154 | } | ||
155 | |||
156 | bc_forwarding_restore() | ||
157 | { | ||
158 | sysctl_restore net.ipv4.conf.$rp1.bc_forwarding | ||
159 | sysctl_restore net.ipv4.conf.all.bc_forwarding | ||
160 | } | ||
161 | |||
162 | ping_test_from() | ||
163 | { | ||
164 | local oif=$1 | ||
165 | local dip=$2 | ||
166 | local from=$3 | ||
167 | local fail=${4:-0} | ||
168 | |||
169 | RET=0 | ||
170 | |||
171 | log_info "ping $dip, expected reply from $from" | ||
172 | ip vrf exec $(master_name_get $oif) \ | ||
173 | $PING -I $oif $dip -c 10 -i 0.1 -w 2 -b 2>&1 | grep $from &> /dev/null | ||
174 | check_err_fail $fail $? | ||
175 | } | ||
176 | |||
177 | ping_ipv4() | ||
178 | { | ||
179 | sysctl_set net.ipv4.icmp_echo_ignore_broadcasts 0 | ||
180 | |||
181 | bc_forwarding_disable | ||
182 | log_info "bc_forwarding disabled on r1 =>" | ||
183 | ping_test_from $h1 198.51.100.255 192.0.2.1 | ||
184 | log_test "h1 -> net2: reply from r1 (not forwarding)" | ||
185 | ping_test_from $h1 198.51.200.255 192.0.2.1 | ||
186 | log_test "h1 -> net3: reply from r1 (not forwarding)" | ||
187 | ping_test_from $h1 192.0.2.255 192.0.2.1 | ||
188 | log_test "h1 -> net1: reply from r1 (not dropping)" | ||
189 | ping_test_from $h1 255.255.255.255 192.0.2.1 | ||
190 | log_test "h1 -> 255.255.255.255: reply from r1 (not forwarding)" | ||
191 | |||
192 | ping_test_from $h2 192.0.2.255 198.51.100.1 | ||
193 | log_test "h2 -> net1: reply from r1 (not forwarding)" | ||
194 | ping_test_from $h2 198.51.200.255 198.51.100.1 | ||
195 | log_test "h2 -> net3: reply from r1 (not forwarding)" | ||
196 | ping_test_from $h2 198.51.100.255 198.51.100.1 | ||
197 | log_test "h2 -> net2: reply from r1 (not dropping)" | ||
198 | ping_test_from $h2 255.255.255.255 198.51.100.1 | ||
199 | log_test "h2 -> 255.255.255.255: reply from r1 (not forwarding)" | ||
200 | bc_forwarding_restore | ||
201 | |||
202 | bc_forwarding_enable | ||
203 | log_info "bc_forwarding enabled on r1 =>" | ||
204 | ping_test_from $h1 198.51.100.255 198.51.100.2 | ||
205 | log_test "h1 -> net2: reply from h2 (forwarding)" | ||
206 | ping_test_from $h1 198.51.200.255 198.51.200.2 | ||
207 | log_test "h1 -> net3: reply from h3 (forwarding)" | ||
208 | ping_test_from $h1 192.0.2.255 192.0.2.1 1 | ||
209 | log_test "h1 -> net1: no reply (dropping)" | ||
210 | ping_test_from $h1 255.255.255.255 192.0.2.1 | ||
211 | log_test "h1 -> 255.255.255.255: reply from r1 (not forwarding)" | ||
212 | |||
213 | ping_test_from $h2 192.0.2.255 192.0.2.2 | ||
214 | log_test "h2 -> net1: reply from h1 (forwarding)" | ||
215 | ping_test_from $h2 198.51.200.255 198.51.200.2 | ||
216 | log_test "h2 -> net3: reply from h3 (forwarding)" | ||
217 | ping_test_from $h2 198.51.100.255 198.51.100.1 1 | ||
218 | log_test "h2 -> net2: no reply (dropping)" | ||
219 | ping_test_from $h2 255.255.255.255 198.51.100.1 | ||
220 | log_test "h2 -> 255.255.255.255: reply from r1 (not forwarding)" | ||
221 | bc_forwarding_restore | ||
222 | |||
223 | sysctl_restore net.ipv4.icmp_echo_ignore_broadcasts | ||
224 | } | ||
225 | |||
226 | trap cleanup EXIT | ||
227 | |||
228 | setup_prepare | ||
229 | setup_wait | ||
230 | |||
231 | tests_run | ||
232 | |||
233 | exit $EXIT_STATUS | ||
diff --git a/tools/testing/selftests/net/forwarding/router_multipath.sh b/tools/testing/selftests/net/forwarding/router_multipath.sh index 8b6d0fb6d604..79a209927962 100755 --- a/tools/testing/selftests/net/forwarding/router_multipath.sh +++ b/tools/testing/selftests/net/forwarding/router_multipath.sh | |||
@@ -159,45 +159,6 @@ router2_destroy() | |||
159 | vrf_destroy "vrf-r2" | 159 | vrf_destroy "vrf-r2" |
160 | } | 160 | } |
161 | 161 | ||
162 | multipath_eval() | ||
163 | { | ||
164 | local desc="$1" | ||
165 | local weight_rp12=$2 | ||
166 | local weight_rp13=$3 | ||
167 | local packets_rp12=$4 | ||
168 | local packets_rp13=$5 | ||
169 | local weights_ratio packets_ratio diff | ||
170 | |||
171 | RET=0 | ||
172 | |||
173 | if [[ "$packets_rp12" -eq "0" || "$packets_rp13" -eq "0" ]]; then | ||
174 | check_err 1 "Packet difference is 0" | ||
175 | log_test "Multipath" | ||
176 | log_info "Expected ratio $weights_ratio" | ||
177 | return | ||
178 | fi | ||
179 | |||
180 | if [[ "$weight_rp12" -gt "$weight_rp13" ]]; then | ||
181 | weights_ratio=$(echo "scale=2; $weight_rp12 / $weight_rp13" \ | ||
182 | | bc -l) | ||
183 | packets_ratio=$(echo "scale=2; $packets_rp12 / $packets_rp13" \ | ||
184 | | bc -l) | ||
185 | else | ||
186 | weights_ratio=$(echo "scale=2; $weight_rp13 / $weight_rp12" | \ | ||
187 | bc -l) | ||
188 | packets_ratio=$(echo "scale=2; $packets_rp13 / $packets_rp12" | \ | ||
189 | bc -l) | ||
190 | fi | ||
191 | |||
192 | diff=$(echo $weights_ratio - $packets_ratio | bc -l) | ||
193 | diff=${diff#-} | ||
194 | |||
195 | test "$(echo "$diff / $weights_ratio > 0.15" | bc -l)" -eq 0 | ||
196 | check_err $? "Too large discrepancy between expected and measured ratios" | ||
197 | log_test "$desc" | ||
198 | log_info "Expected ratio $weights_ratio Measured ratio $packets_ratio" | ||
199 | } | ||
200 | |||
201 | multipath4_test() | 162 | multipath4_test() |
202 | { | 163 | { |
203 | local desc="$1" | 164 | local desc="$1" |
diff --git a/tools/testing/selftests/net/forwarding/tc_chains.sh b/tools/testing/selftests/net/forwarding/tc_chains.sh index d2c783e94df3..2934fb5ed2a2 100755 --- a/tools/testing/selftests/net/forwarding/tc_chains.sh +++ b/tools/testing/selftests/net/forwarding/tc_chains.sh | |||
@@ -1,7 +1,8 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | 3 | ||
4 | ALL_TESTS="unreachable_chain_test gact_goto_chain_test" | 4 | ALL_TESTS="unreachable_chain_test gact_goto_chain_test create_destroy_chain \ |
5 | template_filter_fits" | ||
5 | NUM_NETIFS=2 | 6 | NUM_NETIFS=2 |
6 | source tc_common.sh | 7 | source tc_common.sh |
7 | source lib.sh | 8 | source lib.sh |
@@ -80,6 +81,87 @@ gact_goto_chain_test() | |||
80 | log_test "gact goto chain ($tcflags)" | 81 | log_test "gact goto chain ($tcflags)" |
81 | } | 82 | } |
82 | 83 | ||
84 | create_destroy_chain() | ||
85 | { | ||
86 | RET=0 | ||
87 | |||
88 | tc chain add dev $h2 ingress | ||
89 | check_err $? "Failed to create default chain" | ||
90 | |||
91 | output="$(tc -j chain get dev $h2 ingress)" | ||
92 | check_err $? "Failed to get default chain" | ||
93 | |||
94 | echo $output | jq -e ".[] | select(.chain == 0)" &> /dev/null | ||
95 | check_err $? "Unexpected output for default chain" | ||
96 | |||
97 | tc chain add dev $h2 ingress chain 1 | ||
98 | check_err $? "Failed to create chain 1" | ||
99 | |||
100 | output="$(tc -j chain get dev $h2 ingress chain 1)" | ||
101 | check_err $? "Failed to get chain 1" | ||
102 | |||
103 | echo $output | jq -e ".[] | select(.chain == 1)" &> /dev/null | ||
104 | check_err $? "Unexpected output for chain 1" | ||
105 | |||
106 | output="$(tc -j chain show dev $h2 ingress)" | ||
107 | check_err $? "Failed to dump chains" | ||
108 | |||
109 | echo $output | jq -e ".[] | select(.chain == 0)" &> /dev/null | ||
110 | check_err $? "Can't find default chain in dump" | ||
111 | |||
112 | echo $output | jq -e ".[] | select(.chain == 1)" &> /dev/null | ||
113 | check_err $? "Can't find chain 1 in dump" | ||
114 | |||
115 | tc chain del dev $h2 ingress | ||
116 | check_err $? "Failed to destroy default chain" | ||
117 | |||
118 | tc chain del dev $h2 ingress chain 1 | ||
119 | check_err $? "Failed to destroy chain 1" | ||
120 | |||
121 | log_test "create destroy chain" | ||
122 | } | ||
123 | |||
124 | template_filter_fits() | ||
125 | { | ||
126 | RET=0 | ||
127 | |||
128 | tc chain add dev $h2 ingress protocol ip \ | ||
129 | flower dst_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null | ||
130 | tc chain add dev $h2 ingress chain 1 protocol ip \ | ||
131 | flower src_mac 00:00:00:00:00:00/FF:FF:FF:FF:FF:FF &> /dev/null | ||
132 | |||
133 | tc filter add dev $h2 ingress protocol ip pref 1 handle 1101 \ | ||
134 | flower dst_mac $h2mac action drop | ||
135 | check_err $? "Failed to insert filter which fits template" | ||
136 | |||
137 | tc filter add dev $h2 ingress protocol ip pref 1 handle 1102 \ | ||
138 | flower src_mac $h2mac action drop &> /dev/null | ||
139 | check_fail $? "Incorrectly succeded to insert filter which does not template" | ||
140 | |||
141 | tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \ | ||
142 | flower src_mac $h2mac action drop | ||
143 | check_err $? "Failed to insert filter which fits template" | ||
144 | |||
145 | tc filter add dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \ | ||
146 | flower dst_mac $h2mac action drop &> /dev/null | ||
147 | check_fail $? "Incorrectly succeded to insert filter which does not template" | ||
148 | |||
149 | tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1102 \ | ||
150 | flower &> /dev/null | ||
151 | tc filter del dev $h2 ingress chain 1 protocol ip pref 1 handle 1101 \ | ||
152 | flower &> /dev/null | ||
153 | |||
154 | tc filter del dev $h2 ingress protocol ip pref 1 handle 1102 \ | ||
155 | flower &> /dev/null | ||
156 | tc filter del dev $h2 ingress protocol ip pref 1 handle 1101 \ | ||
157 | flower &> /dev/null | ||
158 | |||
159 | tc chain del dev $h2 ingress chain 1 | ||
160 | tc chain del dev $h2 ingress | ||
161 | |||
162 | log_test "template filter fits" | ||
163 | } | ||
164 | |||
83 | setup_prepare() | 165 | setup_prepare() |
84 | { | 166 | { |
85 | h1=${NETIFS[p1]} | 167 | h1=${NETIFS[p1]} |
@@ -103,6 +185,8 @@ cleanup() | |||
103 | vrf_cleanup | 185 | vrf_cleanup |
104 | } | 186 | } |
105 | 187 | ||
188 | check_tc_chain_support | ||
189 | |||
106 | trap cleanup EXIT | 190 | trap cleanup EXIT |
107 | 191 | ||
108 | setup_prepare | 192 | setup_prepare |
diff --git a/tools/testing/selftests/net/forwarding/tc_shblocks.sh b/tools/testing/selftests/net/forwarding/tc_shblocks.sh index b5b917203815..9826a446e2c0 100755 --- a/tools/testing/selftests/net/forwarding/tc_shblocks.sh +++ b/tools/testing/selftests/net/forwarding/tc_shblocks.sh | |||
@@ -105,6 +105,8 @@ cleanup() | |||
105 | ip link set $swp2 address $swp2origmac | 105 | ip link set $swp2 address $swp2origmac |
106 | } | 106 | } |
107 | 107 | ||
108 | check_tc_shblock_support | ||
109 | |||
108 | trap cleanup EXIT | 110 | trap cleanup EXIT |
109 | 111 | ||
110 | setup_prepare | 112 | setup_prepare |
diff --git a/tools/testing/selftests/net/ip6_gre_headroom.sh b/tools/testing/selftests/net/ip6_gre_headroom.sh new file mode 100755 index 000000000000..5b41e8bb6e2d --- /dev/null +++ b/tools/testing/selftests/net/ip6_gre_headroom.sh | |||
@@ -0,0 +1,65 @@ | |||
1 | #!/bin/bash | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | # | ||
4 | # Test that enough headroom is reserved for the first packet passing through an | ||
5 | # IPv6 GRE-like netdevice. | ||
6 | |||
7 | setup_prepare() | ||
8 | { | ||
9 | ip link add h1 type veth peer name swp1 | ||
10 | ip link add h3 type veth peer name swp3 | ||
11 | |||
12 | ip link set dev h1 up | ||
13 | ip address add 192.0.2.1/28 dev h1 | ||
14 | |||
15 | ip link add dev vh3 type vrf table 20 | ||
16 | ip link set dev h3 master vh3 | ||
17 | ip link set dev vh3 up | ||
18 | ip link set dev h3 up | ||
19 | |||
20 | ip link set dev swp3 up | ||
21 | ip address add dev swp3 2001:db8:2::1/64 | ||
22 | ip address add dev swp3 2001:db8:2::3/64 | ||
23 | |||
24 | ip link set dev swp1 up | ||
25 | tc qdisc add dev swp1 clsact | ||
26 | |||
27 | ip link add name er6 type ip6erspan \ | ||
28 | local 2001:db8:2::1 remote 2001:db8:2::2 oseq okey 123 | ||
29 | ip link set dev er6 up | ||
30 | |||
31 | ip link add name gt6 type ip6gretap \ | ||
32 | local 2001:db8:2::3 remote 2001:db8:2::4 | ||
33 | ip link set dev gt6 up | ||
34 | |||
35 | sleep 1 | ||
36 | } | ||
37 | |||
38 | cleanup() | ||
39 | { | ||
40 | ip link del dev gt6 | ||
41 | ip link del dev er6 | ||
42 | ip link del dev swp1 | ||
43 | ip link del dev swp3 | ||
44 | ip link del dev vh3 | ||
45 | } | ||
46 | |||
47 | test_headroom() | ||
48 | { | ||
49 | local type=$1; shift | ||
50 | local tundev=$1; shift | ||
51 | |||
52 | tc filter add dev swp1 ingress pref 1000 matchall skip_hw \ | ||
53 | action mirred egress mirror dev $tundev | ||
54 | ping -I h1 192.0.2.2 -c 1 -w 2 &> /dev/null | ||
55 | tc filter del dev swp1 ingress pref 1000 | ||
56 | |||
57 | # If it doesn't panic, it passes. | ||
58 | printf "TEST: %-60s [PASS]\n" "$type headroom" | ||
59 | } | ||
60 | |||
61 | trap cleanup EXIT | ||
62 | |||
63 | setup_prepare | ||
64 | test_headroom ip6gretap gt6 | ||
65 | test_headroom ip6erspan er6 | ||
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 0d7a44fa30af..08c341b49760 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh | |||
@@ -525,18 +525,21 @@ kci_test_macsec() | |||
525 | #------------------------------------------------------------------- | 525 | #------------------------------------------------------------------- |
526 | kci_test_ipsec() | 526 | kci_test_ipsec() |
527 | { | 527 | { |
528 | srcip="14.0.0.52" | 528 | ret=0 |
529 | dstip="14.0.0.70" | ||
530 | algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128" | 529 | algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128" |
530 | srcip=192.168.123.1 | ||
531 | dstip=192.168.123.2 | ||
532 | spi=7 | ||
533 | |||
534 | ip addr add $srcip dev $devdummy | ||
531 | 535 | ||
532 | # flush to be sure there's nothing configured | 536 | # flush to be sure there's nothing configured |
533 | ip x s flush ; ip x p flush | 537 | ip x s flush ; ip x p flush |
534 | check_err $? | 538 | check_err $? |
535 | 539 | ||
536 | # start the monitor in the background | 540 | # start the monitor in the background |
537 | tmpfile=`mktemp ipsectestXXX` | 541 | tmpfile=`mktemp /var/run/ipsectestXXX` |
538 | ip x m > $tmpfile & | 542 | mpid=`(ip x m > $tmpfile & echo $!) 2>/dev/null` |
539 | mpid=$! | ||
540 | sleep 0.2 | 543 | sleep 0.2 |
541 | 544 | ||
542 | ipsecid="proto esp src $srcip dst $dstip spi 0x07" | 545 | ipsecid="proto esp src $srcip dst $dstip spi 0x07" |
@@ -599,6 +602,7 @@ kci_test_ipsec() | |||
599 | check_err $? | 602 | check_err $? |
600 | ip x p flush | 603 | ip x p flush |
601 | check_err $? | 604 | check_err $? |
605 | ip addr del $srcip/32 dev $devdummy | ||
602 | 606 | ||
603 | if [ $ret -ne 0 ]; then | 607 | if [ $ret -ne 0 ]; then |
604 | echo "FAIL: ipsec" | 608 | echo "FAIL: ipsec" |
@@ -607,6 +611,119 @@ kci_test_ipsec() | |||
607 | echo "PASS: ipsec" | 611 | echo "PASS: ipsec" |
608 | } | 612 | } |
609 | 613 | ||
614 | #------------------------------------------------------------------- | ||
615 | # Example commands | ||
616 | # ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 \ | ||
617 | # spi 0x07 mode transport reqid 0x07 replay-window 32 \ | ||
618 | # aead 'rfc4106(gcm(aes))' 1234567890123456dcba 128 \ | ||
619 | # sel src 14.0.0.52/24 dst 14.0.0.70/24 | ||
620 | # offload dev sim1 dir out | ||
621 | # ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 \ | ||
622 | # tmpl proto esp src 14.0.0.52 dst 14.0.0.70 \ | ||
623 | # spi 0x07 mode transport reqid 0x07 | ||
624 | # | ||
625 | #------------------------------------------------------------------- | ||
626 | kci_test_ipsec_offload() | ||
627 | { | ||
628 | ret=0 | ||
629 | algo="aead rfc4106(gcm(aes)) 0x3132333435363738393031323334353664636261 128" | ||
630 | srcip=192.168.123.3 | ||
631 | dstip=192.168.123.4 | ||
632 | dev=simx1 | ||
633 | sysfsd=/sys/kernel/debug/netdevsim/$dev | ||
634 | sysfsf=$sysfsd/ipsec | ||
635 | |||
636 | # setup netdevsim since dummydev doesn't have offload support | ||
637 | modprobe netdevsim | ||
638 | check_err $? | ||
639 | if [ $ret -ne 0 ]; then | ||
640 | echo "FAIL: ipsec_offload can't load netdevsim" | ||
641 | return 1 | ||
642 | fi | ||
643 | |||
644 | ip link add $dev type netdevsim | ||
645 | ip addr add $srcip dev $dev | ||
646 | ip link set $dev up | ||
647 | if [ ! -d $sysfsd ] ; then | ||
648 | echo "FAIL: ipsec_offload can't create device $dev" | ||
649 | return 1 | ||
650 | fi | ||
651 | if [ ! -f $sysfsf ] ; then | ||
652 | echo "FAIL: ipsec_offload netdevsim doesn't support IPsec offload" | ||
653 | return 1 | ||
654 | fi | ||
655 | |||
656 | # flush to be sure there's nothing configured | ||
657 | ip x s flush ; ip x p flush | ||
658 | |||
659 | # create offloaded SAs, both in and out | ||
660 | ip x p add dir out src $srcip/24 dst $dstip/24 \ | ||
661 | tmpl proto esp src $srcip dst $dstip spi 9 \ | ||
662 | mode transport reqid 42 | ||
663 | check_err $? | ||
664 | ip x p add dir out src $dstip/24 dst $srcip/24 \ | ||
665 | tmpl proto esp src $dstip dst $srcip spi 9 \ | ||
666 | mode transport reqid 42 | ||
667 | check_err $? | ||
668 | |||
669 | ip x s add proto esp src $srcip dst $dstip spi 9 \ | ||
670 | mode transport reqid 42 $algo sel src $srcip/24 dst $dstip/24 \ | ||
671 | offload dev $dev dir out | ||
672 | check_err $? | ||
673 | ip x s add proto esp src $dstip dst $srcip spi 9 \ | ||
674 | mode transport reqid 42 $algo sel src $dstip/24 dst $srcip/24 \ | ||
675 | offload dev $dev dir in | ||
676 | check_err $? | ||
677 | if [ $ret -ne 0 ]; then | ||
678 | echo "FAIL: ipsec_offload can't create SA" | ||
679 | return 1 | ||
680 | fi | ||
681 | |||
682 | # does offload show up in ip output | ||
683 | lines=`ip x s list | grep -c "crypto offload parameters: dev $dev dir"` | ||
684 | if [ $lines -ne 2 ] ; then | ||
685 | echo "FAIL: ipsec_offload SA offload missing from list output" | ||
686 | check_err 1 | ||
687 | fi | ||
688 | |||
689 | # use ping to exercise the Tx path | ||
690 | ping -I $dev -c 3 -W 1 -i 0 $dstip >/dev/null | ||
691 | |||
692 | # does driver have correct offload info | ||
693 | diff $sysfsf - << EOF | ||
694 | SA count=2 tx=3 | ||
695 | sa[0] tx ipaddr=0x00000000 00000000 00000000 00000000 | ||
696 | sa[0] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 | ||
697 | sa[0] key=0x34333231 38373635 32313039 36353433 | ||
698 | sa[1] rx ipaddr=0x00000000 00000000 00000000 037ba8c0 | ||
699 | sa[1] spi=0x00000009 proto=0x32 salt=0x61626364 crypt=1 | ||
700 | sa[1] key=0x34333231 38373635 32313039 36353433 | ||
701 | EOF | ||
702 | if [ $? -ne 0 ] ; then | ||
703 | echo "FAIL: ipsec_offload incorrect driver data" | ||
704 | check_err 1 | ||
705 | fi | ||
706 | |||
707 | # does offload get removed from driver | ||
708 | ip x s flush | ||
709 | ip x p flush | ||
710 | lines=`grep -c "SA count=0" $sysfsf` | ||
711 | if [ $lines -ne 1 ] ; then | ||
712 | echo "FAIL: ipsec_offload SA not removed from driver" | ||
713 | check_err 1 | ||
714 | fi | ||
715 | |||
716 | # clean up any leftovers | ||
717 | ip link del $dev | ||
718 | rmmod netdevsim | ||
719 | |||
720 | if [ $ret -ne 0 ]; then | ||
721 | echo "FAIL: ipsec_offload" | ||
722 | return 1 | ||
723 | fi | ||
724 | echo "PASS: ipsec_offload" | ||
725 | } | ||
726 | |||
610 | kci_test_gretap() | 727 | kci_test_gretap() |
611 | { | 728 | { |
612 | testns="testns" | 729 | testns="testns" |
@@ -861,6 +978,7 @@ kci_test_rtnl() | |||
861 | kci_test_encap | 978 | kci_test_encap |
862 | kci_test_macsec | 979 | kci_test_macsec |
863 | kci_test_ipsec | 980 | kci_test_ipsec |
981 | kci_test_ipsec_offload | ||
864 | 982 | ||
865 | kci_del_dummy | 983 | kci_del_dummy |
866 | } | 984 | } |
diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c new file mode 100644 index 000000000000..b3ebf2646e52 --- /dev/null +++ b/tools/testing/selftests/net/tls.c | |||
@@ -0,0 +1,692 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | |||
3 | #define _GNU_SOURCE | ||
4 | |||
5 | #include <arpa/inet.h> | ||
6 | #include <errno.h> | ||
7 | #include <error.h> | ||
8 | #include <fcntl.h> | ||
9 | #include <poll.h> | ||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <unistd.h> | ||
13 | |||
14 | #include <linux/tls.h> | ||
15 | #include <linux/tcp.h> | ||
16 | #include <linux/socket.h> | ||
17 | |||
18 | #include <sys/types.h> | ||
19 | #include <sys/sendfile.h> | ||
20 | #include <sys/socket.h> | ||
21 | #include <sys/stat.h> | ||
22 | |||
23 | #include "../kselftest_harness.h" | ||
24 | |||
25 | #define TLS_PAYLOAD_MAX_LEN 16384 | ||
26 | #define SOL_TLS 282 | ||
27 | |||
28 | FIXTURE(tls) | ||
29 | { | ||
30 | int fd, cfd; | ||
31 | bool notls; | ||
32 | }; | ||
33 | |||
34 | FIXTURE_SETUP(tls) | ||
35 | { | ||
36 | struct tls12_crypto_info_aes_gcm_128 tls12; | ||
37 | struct sockaddr_in addr; | ||
38 | socklen_t len; | ||
39 | int sfd, ret; | ||
40 | |||
41 | self->notls = false; | ||
42 | len = sizeof(addr); | ||
43 | |||
44 | memset(&tls12, 0, sizeof(tls12)); | ||
45 | tls12.info.version = TLS_1_2_VERSION; | ||
46 | tls12.info.cipher_type = TLS_CIPHER_AES_GCM_128; | ||
47 | |||
48 | addr.sin_family = AF_INET; | ||
49 | addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||
50 | addr.sin_port = 0; | ||
51 | |||
52 | self->fd = socket(AF_INET, SOCK_STREAM, 0); | ||
53 | sfd = socket(AF_INET, SOCK_STREAM, 0); | ||
54 | |||
55 | ret = bind(sfd, &addr, sizeof(addr)); | ||
56 | ASSERT_EQ(ret, 0); | ||
57 | ret = listen(sfd, 10); | ||
58 | ASSERT_EQ(ret, 0); | ||
59 | |||
60 | ret = getsockname(sfd, &addr, &len); | ||
61 | ASSERT_EQ(ret, 0); | ||
62 | |||
63 | ret = connect(self->fd, &addr, sizeof(addr)); | ||
64 | ASSERT_EQ(ret, 0); | ||
65 | |||
66 | ret = setsockopt(self->fd, IPPROTO_TCP, TCP_ULP, "tls", sizeof("tls")); | ||
67 | if (ret != 0) { | ||
68 | self->notls = true; | ||
69 | printf("Failure setting TCP_ULP, testing without tls\n"); | ||
70 | } | ||
71 | |||
72 | if (!self->notls) { | ||
73 | ret = setsockopt(self->fd, SOL_TLS, TLS_TX, &tls12, | ||
74 | sizeof(tls12)); | ||
75 | ASSERT_EQ(ret, 0); | ||
76 | } | ||
77 | |||
78 | self->cfd = accept(sfd, &addr, &len); | ||
79 | ASSERT_GE(self->cfd, 0); | ||
80 | |||
81 | if (!self->notls) { | ||
82 | ret = setsockopt(self->cfd, IPPROTO_TCP, TCP_ULP, "tls", | ||
83 | sizeof("tls")); | ||
84 | ASSERT_EQ(ret, 0); | ||
85 | |||
86 | ret = setsockopt(self->cfd, SOL_TLS, TLS_RX, &tls12, | ||
87 | sizeof(tls12)); | ||
88 | ASSERT_EQ(ret, 0); | ||
89 | } | ||
90 | |||
91 | close(sfd); | ||
92 | } | ||
93 | |||
94 | FIXTURE_TEARDOWN(tls) | ||
95 | { | ||
96 | close(self->fd); | ||
97 | close(self->cfd); | ||
98 | } | ||
99 | |||
100 | TEST_F(tls, sendfile) | ||
101 | { | ||
102 | int filefd = open("/proc/self/exe", O_RDONLY); | ||
103 | struct stat st; | ||
104 | |||
105 | EXPECT_GE(filefd, 0); | ||
106 | fstat(filefd, &st); | ||
107 | EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0); | ||
108 | } | ||
109 | |||
110 | TEST_F(tls, send_then_sendfile) | ||
111 | { | ||
112 | int filefd = open("/proc/self/exe", O_RDONLY); | ||
113 | char const *test_str = "test_send"; | ||
114 | int to_send = strlen(test_str) + 1; | ||
115 | char recv_buf[10]; | ||
116 | struct stat st; | ||
117 | char *buf; | ||
118 | |||
119 | EXPECT_GE(filefd, 0); | ||
120 | fstat(filefd, &st); | ||
121 | buf = (char *)malloc(st.st_size); | ||
122 | |||
123 | EXPECT_EQ(send(self->fd, test_str, to_send, 0), to_send); | ||
124 | EXPECT_EQ(recv(self->cfd, recv_buf, to_send, 0), to_send); | ||
125 | EXPECT_EQ(memcmp(test_str, recv_buf, to_send), 0); | ||
126 | |||
127 | EXPECT_GE(sendfile(self->fd, filefd, 0, st.st_size), 0); | ||
128 | EXPECT_EQ(recv(self->cfd, buf, st.st_size, 0), st.st_size); | ||
129 | } | ||
130 | |||
131 | TEST_F(tls, recv_max) | ||
132 | { | ||
133 | unsigned int send_len = TLS_PAYLOAD_MAX_LEN; | ||
134 | char recv_mem[TLS_PAYLOAD_MAX_LEN]; | ||
135 | char buf[TLS_PAYLOAD_MAX_LEN]; | ||
136 | |||
137 | EXPECT_GE(send(self->fd, buf, send_len, 0), 0); | ||
138 | EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1); | ||
139 | EXPECT_EQ(memcmp(buf, recv_mem, send_len), 0); | ||
140 | } | ||
141 | |||
142 | TEST_F(tls, recv_small) | ||
143 | { | ||
144 | char const *test_str = "test_read"; | ||
145 | int send_len = 10; | ||
146 | char buf[10]; | ||
147 | |||
148 | send_len = strlen(test_str) + 1; | ||
149 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
150 | EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1); | ||
151 | EXPECT_EQ(memcmp(buf, test_str, send_len), 0); | ||
152 | } | ||
153 | |||
154 | TEST_F(tls, msg_more) | ||
155 | { | ||
156 | char const *test_str = "test_read"; | ||
157 | int send_len = 10; | ||
158 | char buf[10 * 2]; | ||
159 | |||
160 | EXPECT_EQ(send(self->fd, test_str, send_len, MSG_MORE), send_len); | ||
161 | EXPECT_EQ(recv(self->cfd, buf, send_len, MSG_DONTWAIT), -1); | ||
162 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
163 | EXPECT_EQ(recv(self->cfd, buf, send_len * 2, MSG_DONTWAIT), | ||
164 | send_len * 2); | ||
165 | EXPECT_EQ(memcmp(buf, test_str, send_len), 0); | ||
166 | } | ||
167 | |||
168 | TEST_F(tls, sendmsg_single) | ||
169 | { | ||
170 | struct msghdr msg; | ||
171 | |||
172 | char const *test_str = "test_sendmsg"; | ||
173 | size_t send_len = 13; | ||
174 | struct iovec vec; | ||
175 | char buf[13]; | ||
176 | |||
177 | vec.iov_base = (char *)test_str; | ||
178 | vec.iov_len = send_len; | ||
179 | memset(&msg, 0, sizeof(struct msghdr)); | ||
180 | msg.msg_iov = &vec; | ||
181 | msg.msg_iovlen = 1; | ||
182 | EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len); | ||
183 | EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len); | ||
184 | EXPECT_EQ(memcmp(buf, test_str, send_len), 0); | ||
185 | } | ||
186 | |||
187 | TEST_F(tls, sendmsg_large) | ||
188 | { | ||
189 | void *mem = malloc(16384); | ||
190 | size_t send_len = 16384; | ||
191 | size_t sends = 128; | ||
192 | struct msghdr msg; | ||
193 | size_t recvs = 0; | ||
194 | size_t sent = 0; | ||
195 | |||
196 | memset(&msg, 0, sizeof(struct msghdr)); | ||
197 | while (sent++ < sends) { | ||
198 | struct iovec vec = { (void *)mem, send_len }; | ||
199 | |||
200 | msg.msg_iov = &vec; | ||
201 | msg.msg_iovlen = 1; | ||
202 | EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len); | ||
203 | } | ||
204 | |||
205 | while (recvs++ < sends) | ||
206 | EXPECT_NE(recv(self->fd, mem, send_len, 0), -1); | ||
207 | |||
208 | free(mem); | ||
209 | } | ||
210 | |||
211 | TEST_F(tls, sendmsg_multiple) | ||
212 | { | ||
213 | char const *test_str = "test_sendmsg_multiple"; | ||
214 | struct iovec vec[5]; | ||
215 | char *test_strs[5]; | ||
216 | struct msghdr msg; | ||
217 | int total_len = 0; | ||
218 | int len_cmp = 0; | ||
219 | int iov_len = 5; | ||
220 | char *buf; | ||
221 | int i; | ||
222 | |||
223 | memset(&msg, 0, sizeof(struct msghdr)); | ||
224 | for (i = 0; i < iov_len; i++) { | ||
225 | test_strs[i] = (char *)malloc(strlen(test_str) + 1); | ||
226 | snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str); | ||
227 | vec[i].iov_base = (void *)test_strs[i]; | ||
228 | vec[i].iov_len = strlen(test_strs[i]) + 1; | ||
229 | total_len += vec[i].iov_len; | ||
230 | } | ||
231 | msg.msg_iov = vec; | ||
232 | msg.msg_iovlen = iov_len; | ||
233 | |||
234 | EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len); | ||
235 | buf = malloc(total_len); | ||
236 | EXPECT_NE(recv(self->fd, buf, total_len, 0), -1); | ||
237 | for (i = 0; i < iov_len; i++) { | ||
238 | EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp, | ||
239 | strlen(test_strs[i])), | ||
240 | 0); | ||
241 | len_cmp += strlen(buf + len_cmp) + 1; | ||
242 | } | ||
243 | for (i = 0; i < iov_len; i++) | ||
244 | free(test_strs[i]); | ||
245 | free(buf); | ||
246 | } | ||
247 | |||
248 | TEST_F(tls, sendmsg_multiple_stress) | ||
249 | { | ||
250 | char const *test_str = "abcdefghijklmno"; | ||
251 | struct iovec vec[1024]; | ||
252 | char *test_strs[1024]; | ||
253 | int iov_len = 1024; | ||
254 | int total_len = 0; | ||
255 | char buf[1 << 14]; | ||
256 | struct msghdr msg; | ||
257 | int len_cmp = 0; | ||
258 | int i; | ||
259 | |||
260 | memset(&msg, 0, sizeof(struct msghdr)); | ||
261 | for (i = 0; i < iov_len; i++) { | ||
262 | test_strs[i] = (char *)malloc(strlen(test_str) + 1); | ||
263 | snprintf(test_strs[i], strlen(test_str) + 1, "%s", test_str); | ||
264 | vec[i].iov_base = (void *)test_strs[i]; | ||
265 | vec[i].iov_len = strlen(test_strs[i]) + 1; | ||
266 | total_len += vec[i].iov_len; | ||
267 | } | ||
268 | msg.msg_iov = vec; | ||
269 | msg.msg_iovlen = iov_len; | ||
270 | |||
271 | EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len); | ||
272 | EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1); | ||
273 | |||
274 | for (i = 0; i < iov_len; i++) | ||
275 | len_cmp += strlen(buf + len_cmp) + 1; | ||
276 | |||
277 | for (i = 0; i < iov_len; i++) | ||
278 | free(test_strs[i]); | ||
279 | } | ||
280 | |||
281 | TEST_F(tls, splice_from_pipe) | ||
282 | { | ||
283 | int send_len = TLS_PAYLOAD_MAX_LEN; | ||
284 | char mem_send[TLS_PAYLOAD_MAX_LEN]; | ||
285 | char mem_recv[TLS_PAYLOAD_MAX_LEN]; | ||
286 | int p[2]; | ||
287 | |||
288 | ASSERT_GE(pipe(p), 0); | ||
289 | EXPECT_GE(write(p[1], mem_send, send_len), 0); | ||
290 | EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), 0); | ||
291 | EXPECT_GE(recv(self->cfd, mem_recv, send_len, 0), 0); | ||
292 | EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0); | ||
293 | } | ||
294 | |||
295 | TEST_F(tls, splice_from_pipe2) | ||
296 | { | ||
297 | int send_len = 16000; | ||
298 | char mem_send[16000]; | ||
299 | char mem_recv[16000]; | ||
300 | int p2[2]; | ||
301 | int p[2]; | ||
302 | |||
303 | ASSERT_GE(pipe(p), 0); | ||
304 | ASSERT_GE(pipe(p2), 0); | ||
305 | EXPECT_GE(write(p[1], mem_send, 8000), 0); | ||
306 | EXPECT_GE(splice(p[0], NULL, self->fd, NULL, 8000, 0), 0); | ||
307 | EXPECT_GE(write(p2[1], mem_send + 8000, 8000), 0); | ||
308 | EXPECT_GE(splice(p2[0], NULL, self->fd, NULL, 8000, 0), 0); | ||
309 | EXPECT_GE(recv(self->cfd, mem_recv, send_len, 0), 0); | ||
310 | EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0); | ||
311 | } | ||
312 | |||
313 | TEST_F(tls, send_and_splice) | ||
314 | { | ||
315 | int send_len = TLS_PAYLOAD_MAX_LEN; | ||
316 | char mem_send[TLS_PAYLOAD_MAX_LEN]; | ||
317 | char mem_recv[TLS_PAYLOAD_MAX_LEN]; | ||
318 | char const *test_str = "test_read"; | ||
319 | int send_len2 = 10; | ||
320 | char buf[10]; | ||
321 | int p[2]; | ||
322 | |||
323 | ASSERT_GE(pipe(p), 0); | ||
324 | EXPECT_EQ(send(self->fd, test_str, send_len2, 0), send_len2); | ||
325 | EXPECT_NE(recv(self->cfd, buf, send_len2, 0), -1); | ||
326 | EXPECT_EQ(memcmp(test_str, buf, send_len2), 0); | ||
327 | |||
328 | EXPECT_GE(write(p[1], mem_send, send_len), send_len); | ||
329 | EXPECT_GE(splice(p[0], NULL, self->fd, NULL, send_len, 0), send_len); | ||
330 | |||
331 | EXPECT_GE(recv(self->cfd, mem_recv, send_len, 0), 0); | ||
332 | EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0); | ||
333 | } | ||
334 | |||
335 | TEST_F(tls, splice_to_pipe) | ||
336 | { | ||
337 | int send_len = TLS_PAYLOAD_MAX_LEN; | ||
338 | char mem_send[TLS_PAYLOAD_MAX_LEN]; | ||
339 | char mem_recv[TLS_PAYLOAD_MAX_LEN]; | ||
340 | int p[2]; | ||
341 | |||
342 | ASSERT_GE(pipe(p), 0); | ||
343 | EXPECT_GE(send(self->fd, mem_send, send_len, 0), 0); | ||
344 | EXPECT_GE(splice(self->cfd, NULL, p[1], NULL, send_len, 0), 0); | ||
345 | EXPECT_GE(read(p[0], mem_recv, send_len), 0); | ||
346 | EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0); | ||
347 | } | ||
348 | |||
349 | TEST_F(tls, recvmsg_single) | ||
350 | { | ||
351 | char const *test_str = "test_recvmsg_single"; | ||
352 | int send_len = strlen(test_str) + 1; | ||
353 | char buf[20]; | ||
354 | struct msghdr hdr; | ||
355 | struct iovec vec; | ||
356 | |||
357 | memset(&hdr, 0, sizeof(hdr)); | ||
358 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
359 | vec.iov_base = (char *)buf; | ||
360 | vec.iov_len = send_len; | ||
361 | hdr.msg_iovlen = 1; | ||
362 | hdr.msg_iov = &vec; | ||
363 | EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1); | ||
364 | EXPECT_EQ(memcmp(test_str, buf, send_len), 0); | ||
365 | } | ||
366 | |||
367 | TEST_F(tls, recvmsg_single_max) | ||
368 | { | ||
369 | int send_len = TLS_PAYLOAD_MAX_LEN; | ||
370 | char send_mem[TLS_PAYLOAD_MAX_LEN]; | ||
371 | char recv_mem[TLS_PAYLOAD_MAX_LEN]; | ||
372 | struct iovec vec; | ||
373 | struct msghdr hdr; | ||
374 | |||
375 | EXPECT_EQ(send(self->fd, send_mem, send_len, 0), send_len); | ||
376 | vec.iov_base = (char *)recv_mem; | ||
377 | vec.iov_len = TLS_PAYLOAD_MAX_LEN; | ||
378 | |||
379 | hdr.msg_iovlen = 1; | ||
380 | hdr.msg_iov = &vec; | ||
381 | EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1); | ||
382 | EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0); | ||
383 | } | ||
384 | |||
385 | TEST_F(tls, recvmsg_multiple) | ||
386 | { | ||
387 | unsigned int msg_iovlen = 1024; | ||
388 | unsigned int len_compared = 0; | ||
389 | struct iovec vec[1024]; | ||
390 | char *iov_base[1024]; | ||
391 | unsigned int iov_len = 16; | ||
392 | int send_len = 1 << 14; | ||
393 | char buf[1 << 14]; | ||
394 | struct msghdr hdr; | ||
395 | int i; | ||
396 | |||
397 | EXPECT_EQ(send(self->fd, buf, send_len, 0), send_len); | ||
398 | for (i = 0; i < msg_iovlen; i++) { | ||
399 | iov_base[i] = (char *)malloc(iov_len); | ||
400 | vec[i].iov_base = iov_base[i]; | ||
401 | vec[i].iov_len = iov_len; | ||
402 | } | ||
403 | |||
404 | hdr.msg_iovlen = msg_iovlen; | ||
405 | hdr.msg_iov = vec; | ||
406 | EXPECT_NE(recvmsg(self->cfd, &hdr, 0), -1); | ||
407 | for (i = 0; i < msg_iovlen; i++) | ||
408 | len_compared += iov_len; | ||
409 | |||
410 | for (i = 0; i < msg_iovlen; i++) | ||
411 | free(iov_base[i]); | ||
412 | } | ||
413 | |||
414 | TEST_F(tls, single_send_multiple_recv) | ||
415 | { | ||
416 | unsigned int total_len = TLS_PAYLOAD_MAX_LEN * 2; | ||
417 | unsigned int send_len = TLS_PAYLOAD_MAX_LEN; | ||
418 | char send_mem[TLS_PAYLOAD_MAX_LEN * 2]; | ||
419 | char recv_mem[TLS_PAYLOAD_MAX_LEN * 2]; | ||
420 | |||
421 | EXPECT_GE(send(self->fd, send_mem, total_len, 0), 0); | ||
422 | memset(recv_mem, 0, total_len); | ||
423 | |||
424 | EXPECT_NE(recv(self->cfd, recv_mem, send_len, 0), -1); | ||
425 | EXPECT_NE(recv(self->cfd, recv_mem + send_len, send_len, 0), -1); | ||
426 | EXPECT_EQ(memcmp(send_mem, recv_mem, total_len), 0); | ||
427 | } | ||
428 | |||
429 | TEST_F(tls, multiple_send_single_recv) | ||
430 | { | ||
431 | unsigned int total_len = 2 * 10; | ||
432 | unsigned int send_len = 10; | ||
433 | char recv_mem[2 * 10]; | ||
434 | char send_mem[10]; | ||
435 | |||
436 | EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0); | ||
437 | EXPECT_GE(send(self->fd, send_mem, send_len, 0), 0); | ||
438 | memset(recv_mem, 0, total_len); | ||
439 | EXPECT_EQ(recv(self->cfd, recv_mem, total_len, 0), total_len); | ||
440 | |||
441 | EXPECT_EQ(memcmp(send_mem, recv_mem, send_len), 0); | ||
442 | EXPECT_EQ(memcmp(send_mem, recv_mem + send_len, send_len), 0); | ||
443 | } | ||
444 | |||
445 | TEST_F(tls, recv_partial) | ||
446 | { | ||
447 | char const *test_str = "test_read_partial"; | ||
448 | char const *test_str_first = "test_read"; | ||
449 | char const *test_str_second = "_partial"; | ||
450 | int send_len = strlen(test_str) + 1; | ||
451 | char recv_mem[18]; | ||
452 | |||
453 | memset(recv_mem, 0, sizeof(recv_mem)); | ||
454 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
455 | EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_first), 0), -1); | ||
456 | EXPECT_EQ(memcmp(test_str_first, recv_mem, strlen(test_str_first)), 0); | ||
457 | memset(recv_mem, 0, sizeof(recv_mem)); | ||
458 | EXPECT_NE(recv(self->cfd, recv_mem, strlen(test_str_second), 0), -1); | ||
459 | EXPECT_EQ(memcmp(test_str_second, recv_mem, strlen(test_str_second)), | ||
460 | 0); | ||
461 | } | ||
462 | |||
463 | TEST_F(tls, recv_nonblock) | ||
464 | { | ||
465 | char buf[4096]; | ||
466 | bool err; | ||
467 | |||
468 | EXPECT_EQ(recv(self->cfd, buf, sizeof(buf), MSG_DONTWAIT), -1); | ||
469 | err = (errno == EAGAIN || errno == EWOULDBLOCK); | ||
470 | EXPECT_EQ(err, true); | ||
471 | } | ||
472 | |||
473 | TEST_F(tls, recv_peek) | ||
474 | { | ||
475 | char const *test_str = "test_read_peek"; | ||
476 | int send_len = strlen(test_str) + 1; | ||
477 | char buf[15]; | ||
478 | |||
479 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
480 | EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1); | ||
481 | EXPECT_EQ(memcmp(test_str, buf, send_len), 0); | ||
482 | memset(buf, 0, sizeof(buf)); | ||
483 | EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1); | ||
484 | EXPECT_EQ(memcmp(test_str, buf, send_len), 0); | ||
485 | } | ||
486 | |||
487 | TEST_F(tls, recv_peek_multiple) | ||
488 | { | ||
489 | char const *test_str = "test_read_peek"; | ||
490 | int send_len = strlen(test_str) + 1; | ||
491 | unsigned int num_peeks = 100; | ||
492 | char buf[15]; | ||
493 | int i; | ||
494 | |||
495 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
496 | for (i = 0; i < num_peeks; i++) { | ||
497 | EXPECT_NE(recv(self->cfd, buf, send_len, MSG_PEEK), -1); | ||
498 | EXPECT_EQ(memcmp(test_str, buf, send_len), 0); | ||
499 | memset(buf, 0, sizeof(buf)); | ||
500 | } | ||
501 | EXPECT_NE(recv(self->cfd, buf, send_len, 0), -1); | ||
502 | EXPECT_EQ(memcmp(test_str, buf, send_len), 0); | ||
503 | } | ||
504 | |||
505 | TEST_F(tls, pollin) | ||
506 | { | ||
507 | char const *test_str = "test_poll"; | ||
508 | struct pollfd fd = { 0, 0, 0 }; | ||
509 | char buf[10]; | ||
510 | int send_len = 10; | ||
511 | |||
512 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
513 | fd.fd = self->cfd; | ||
514 | fd.events = POLLIN; | ||
515 | |||
516 | EXPECT_EQ(poll(&fd, 1, 20), 1); | ||
517 | EXPECT_EQ(fd.revents & POLLIN, 1); | ||
518 | EXPECT_EQ(recv(self->cfd, buf, send_len, 0), send_len); | ||
519 | /* Test timing out */ | ||
520 | EXPECT_EQ(poll(&fd, 1, 20), 0); | ||
521 | } | ||
522 | |||
523 | TEST_F(tls, poll_wait) | ||
524 | { | ||
525 | char const *test_str = "test_poll_wait"; | ||
526 | int send_len = strlen(test_str) + 1; | ||
527 | struct pollfd fd = { 0, 0, 0 }; | ||
528 | char recv_mem[15]; | ||
529 | |||
530 | fd.fd = self->cfd; | ||
531 | fd.events = POLLIN; | ||
532 | EXPECT_EQ(send(self->fd, test_str, send_len, 0), send_len); | ||
533 | /* Set timeout to inf. secs */ | ||
534 | EXPECT_EQ(poll(&fd, 1, -1), 1); | ||
535 | EXPECT_EQ(fd.revents & POLLIN, 1); | ||
536 | EXPECT_EQ(recv(self->cfd, recv_mem, send_len, 0), send_len); | ||
537 | } | ||
538 | |||
539 | TEST_F(tls, blocking) | ||
540 | { | ||
541 | size_t data = 100000; | ||
542 | int res = fork(); | ||
543 | |||
544 | EXPECT_NE(res, -1); | ||
545 | |||
546 | if (res) { | ||
547 | /* parent */ | ||
548 | size_t left = data; | ||
549 | char buf[16384]; | ||
550 | int status; | ||
551 | int pid2; | ||
552 | |||
553 | while (left) { | ||
554 | int res = send(self->fd, buf, | ||
555 | left > 16384 ? 16384 : left, 0); | ||
556 | |||
557 | EXPECT_GE(res, 0); | ||
558 | left -= res; | ||
559 | } | ||
560 | |||
561 | pid2 = wait(&status); | ||
562 | EXPECT_EQ(status, 0); | ||
563 | EXPECT_EQ(res, pid2); | ||
564 | } else { | ||
565 | /* child */ | ||
566 | size_t left = data; | ||
567 | char buf[16384]; | ||
568 | |||
569 | while (left) { | ||
570 | int res = recv(self->cfd, buf, | ||
571 | left > 16384 ? 16384 : left, 0); | ||
572 | |||
573 | EXPECT_GE(res, 0); | ||
574 | left -= res; | ||
575 | } | ||
576 | } | ||
577 | } | ||
578 | |||
579 | TEST_F(tls, nonblocking) | ||
580 | { | ||
581 | size_t data = 100000; | ||
582 | int sendbuf = 100; | ||
583 | int flags; | ||
584 | int res; | ||
585 | |||
586 | flags = fcntl(self->fd, F_GETFL, 0); | ||
587 | fcntl(self->fd, F_SETFL, flags | O_NONBLOCK); | ||
588 | fcntl(self->cfd, F_SETFL, flags | O_NONBLOCK); | ||
589 | |||
590 | /* Ensure nonblocking behavior by imposing a small send | ||
591 | * buffer. | ||
592 | */ | ||
593 | EXPECT_EQ(setsockopt(self->fd, SOL_SOCKET, SO_SNDBUF, | ||
594 | &sendbuf, sizeof(sendbuf)), 0); | ||
595 | |||
596 | res = fork(); | ||
597 | EXPECT_NE(res, -1); | ||
598 | |||
599 | if (res) { | ||
600 | /* parent */ | ||
601 | bool eagain = false; | ||
602 | size_t left = data; | ||
603 | char buf[16384]; | ||
604 | int status; | ||
605 | int pid2; | ||
606 | |||
607 | while (left) { | ||
608 | int res = send(self->fd, buf, | ||
609 | left > 16384 ? 16384 : left, 0); | ||
610 | |||
611 | if (res == -1 && errno == EAGAIN) { | ||
612 | eagain = true; | ||
613 | usleep(10000); | ||
614 | continue; | ||
615 | } | ||
616 | EXPECT_GE(res, 0); | ||
617 | left -= res; | ||
618 | } | ||
619 | |||
620 | EXPECT_TRUE(eagain); | ||
621 | pid2 = wait(&status); | ||
622 | |||
623 | EXPECT_EQ(status, 0); | ||
624 | EXPECT_EQ(res, pid2); | ||
625 | } else { | ||
626 | /* child */ | ||
627 | bool eagain = false; | ||
628 | size_t left = data; | ||
629 | char buf[16384]; | ||
630 | |||
631 | while (left) { | ||
632 | int res = recv(self->cfd, buf, | ||
633 | left > 16384 ? 16384 : left, 0); | ||
634 | |||
635 | if (res == -1 && errno == EAGAIN) { | ||
636 | eagain = true; | ||
637 | usleep(10000); | ||
638 | continue; | ||
639 | } | ||
640 | EXPECT_GE(res, 0); | ||
641 | left -= res; | ||
642 | } | ||
643 | EXPECT_TRUE(eagain); | ||
644 | } | ||
645 | } | ||
646 | |||
647 | TEST_F(tls, control_msg) | ||
648 | { | ||
649 | if (self->notls) | ||
650 | return; | ||
651 | |||
652 | char cbuf[CMSG_SPACE(sizeof(char))]; | ||
653 | char const *test_str = "test_read"; | ||
654 | int cmsg_len = sizeof(char); | ||
655 | char record_type = 100; | ||
656 | struct cmsghdr *cmsg; | ||
657 | struct msghdr msg; | ||
658 | int send_len = 10; | ||
659 | struct iovec vec; | ||
660 | char buf[10]; | ||
661 | |||
662 | vec.iov_base = (char *)test_str; | ||
663 | vec.iov_len = 10; | ||
664 | memset(&msg, 0, sizeof(struct msghdr)); | ||
665 | msg.msg_iov = &vec; | ||
666 | msg.msg_iovlen = 1; | ||
667 | msg.msg_control = cbuf; | ||
668 | msg.msg_controllen = sizeof(cbuf); | ||
669 | cmsg = CMSG_FIRSTHDR(&msg); | ||
670 | cmsg->cmsg_level = SOL_TLS; | ||
671 | /* test sending non-record types. */ | ||
672 | cmsg->cmsg_type = TLS_SET_RECORD_TYPE; | ||
673 | cmsg->cmsg_len = CMSG_LEN(cmsg_len); | ||
674 | *CMSG_DATA(cmsg) = record_type; | ||
675 | msg.msg_controllen = cmsg->cmsg_len; | ||
676 | |||
677 | EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len); | ||
678 | /* Should fail because we didn't provide a control message */ | ||
679 | EXPECT_EQ(recv(self->cfd, buf, send_len, 0), -1); | ||
680 | |||
681 | vec.iov_base = buf; | ||
682 | EXPECT_EQ(recvmsg(self->cfd, &msg, 0), send_len); | ||
683 | cmsg = CMSG_FIRSTHDR(&msg); | ||
684 | EXPECT_NE(cmsg, NULL); | ||
685 | EXPECT_EQ(cmsg->cmsg_level, SOL_TLS); | ||
686 | EXPECT_EQ(cmsg->cmsg_type, TLS_GET_RECORD_TYPE); | ||
687 | record_type = *((unsigned char *)CMSG_DATA(cmsg)); | ||
688 | EXPECT_EQ(record_type, 100); | ||
689 | EXPECT_EQ(memcmp(buf, test_str, send_len), 0); | ||
690 | } | ||
691 | |||
692 | TEST_HARNESS_MAIN | ||
diff --git a/tools/testing/selftests/rcutorture/bin/configinit.sh b/tools/testing/selftests/rcutorture/bin/configinit.sh index c15f270e121d..65541c21a544 100755 --- a/tools/testing/selftests/rcutorture/bin/configinit.sh +++ b/tools/testing/selftests/rcutorture/bin/configinit.sh | |||
@@ -1,6 +1,6 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # | 2 | # |
3 | # Usage: configinit.sh config-spec-file [ build output dir ] | 3 | # Usage: configinit.sh config-spec-file build-output-dir results-dir |
4 | # | 4 | # |
5 | # Create a .config file from the spec file. Run from the kernel source tree. | 5 | # Create a .config file from the spec file. Run from the kernel source tree. |
6 | # Exits with 0 if all went well, with 1 if all went well but the config | 6 | # Exits with 0 if all went well, with 1 if all went well but the config |
@@ -40,20 +40,18 @@ mkdir $T | |||
40 | 40 | ||
41 | c=$1 | 41 | c=$1 |
42 | buildloc=$2 | 42 | buildloc=$2 |
43 | resdir=$3 | ||
43 | builddir= | 44 | builddir= |
44 | if test -n $buildloc | 45 | if echo $buildloc | grep -q '^O=' |
45 | then | 46 | then |
46 | if echo $buildloc | grep -q '^O=' | 47 | builddir=`echo $buildloc | sed -e 's/^O=//'` |
48 | if test ! -d $builddir | ||
47 | then | 49 | then |
48 | builddir=`echo $buildloc | sed -e 's/^O=//'` | 50 | mkdir $builddir |
49 | if test ! -d $builddir | ||
50 | then | ||
51 | mkdir $builddir | ||
52 | fi | ||
53 | else | ||
54 | echo Bad build directory: \"$buildloc\" | ||
55 | exit 2 | ||
56 | fi | 51 | fi |
52 | else | ||
53 | echo Bad build directory: \"$buildloc\" | ||
54 | exit 2 | ||
57 | fi | 55 | fi |
58 | 56 | ||
59 | sed -e 's/^\(CONFIG[0-9A-Z_]*\)=.*$/grep -v "^# \1" |/' < $c > $T/u.sh | 57 | sed -e 's/^\(CONFIG[0-9A-Z_]*\)=.*$/grep -v "^# \1" |/' < $c > $T/u.sh |
@@ -61,12 +59,12 @@ sed -e 's/^\(CONFIG[0-9A-Z_]*=\).*$/grep -v \1 |/' < $c >> $T/u.sh | |||
61 | grep '^grep' < $T/u.sh > $T/upd.sh | 59 | grep '^grep' < $T/u.sh > $T/upd.sh |
62 | echo "cat - $c" >> $T/upd.sh | 60 | echo "cat - $c" >> $T/upd.sh |
63 | make mrproper | 61 | make mrproper |
64 | make $buildloc distclean > $builddir/Make.distclean 2>&1 | 62 | make $buildloc distclean > $resdir/Make.distclean 2>&1 |
65 | make $buildloc $TORTURE_DEFCONFIG > $builddir/Make.defconfig.out 2>&1 | 63 | make $buildloc $TORTURE_DEFCONFIG > $resdir/Make.defconfig.out 2>&1 |
66 | mv $builddir/.config $builddir/.config.sav | 64 | mv $builddir/.config $builddir/.config.sav |
67 | sh $T/upd.sh < $builddir/.config.sav > $builddir/.config | 65 | sh $T/upd.sh < $builddir/.config.sav > $builddir/.config |
68 | cp $builddir/.config $builddir/.config.new | 66 | cp $builddir/.config $builddir/.config.new |
69 | yes '' | make $buildloc oldconfig > $builddir/Make.oldconfig.out 2> $builddir/Make.oldconfig.err | 67 | yes '' | make $buildloc oldconfig > $resdir/Make.oldconfig.out 2> $resdir/Make.oldconfig.err |
70 | 68 | ||
71 | # verify new config matches specification. | 69 | # verify new config matches specification. |
72 | configcheck.sh $builddir/.config $c | 70 | configcheck.sh $builddir/.config $c |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-build.sh b/tools/testing/selftests/rcutorture/bin/kvm-build.sh index 34d126734cde..9115fcdb5617 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-build.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-build.sh | |||
@@ -2,7 +2,7 @@ | |||
2 | # | 2 | # |
3 | # Build a kvm-ready Linux kernel from the tree in the current directory. | 3 | # Build a kvm-ready Linux kernel from the tree in the current directory. |
4 | # | 4 | # |
5 | # Usage: kvm-build.sh config-template build-dir | 5 | # Usage: kvm-build.sh config-template build-dir resdir |
6 | # | 6 | # |
7 | # This program is free software; you can redistribute it and/or modify | 7 | # This program is free software; you can redistribute it and/or modify |
8 | # it under the terms of the GNU General Public License as published by | 8 | # it under the terms of the GNU General Public License as published by |
@@ -29,6 +29,7 @@ then | |||
29 | exit 1 | 29 | exit 1 |
30 | fi | 30 | fi |
31 | builddir=${2} | 31 | builddir=${2} |
32 | resdir=${3} | ||
32 | 33 | ||
33 | T=${TMPDIR-/tmp}/test-linux.sh.$$ | 34 | T=${TMPDIR-/tmp}/test-linux.sh.$$ |
34 | trap 'rm -rf $T' 0 | 35 | trap 'rm -rf $T' 0 |
@@ -41,19 +42,19 @@ CONFIG_VIRTIO_PCI=y | |||
41 | CONFIG_VIRTIO_CONSOLE=y | 42 | CONFIG_VIRTIO_CONSOLE=y |
42 | ___EOF___ | 43 | ___EOF___ |
43 | 44 | ||
44 | configinit.sh $T/config O=$builddir | 45 | configinit.sh $T/config O=$builddir $resdir |
45 | retval=$? | 46 | retval=$? |
46 | if test $retval -gt 1 | 47 | if test $retval -gt 1 |
47 | then | 48 | then |
48 | exit 2 | 49 | exit 2 |
49 | fi | 50 | fi |
50 | ncpus=`cpus2use.sh` | 51 | ncpus=`cpus2use.sh` |
51 | make O=$builddir -j$ncpus $TORTURE_KMAKE_ARG > $builddir/Make.out 2>&1 | 52 | make O=$builddir -j$ncpus $TORTURE_KMAKE_ARG > $resdir/Make.out 2>&1 |
52 | retval=$? | 53 | retval=$? |
53 | if test $retval -ne 0 || grep "rcu[^/]*": < $builddir/Make.out | egrep -q "Stop|Error|error:|warning:" || egrep -q "Stop|Error|error:" < $builddir/Make.out | 54 | if test $retval -ne 0 || grep "rcu[^/]*": < $resdir/Make.out | egrep -q "Stop|Error|error:|warning:" || egrep -q "Stop|Error|error:" < $resdir/Make.out |
54 | then | 55 | then |
55 | echo Kernel build error | 56 | echo Kernel build error |
56 | egrep "Stop|Error|error:|warning:" < $builddir/Make.out | 57 | egrep "Stop|Error|error:|warning:" < $resdir/Make.out |
57 | echo Run aborted. | 58 | echo Run aborted. |
58 | exit 3 | 59 | exit 3 |
59 | fi | 60 | fi |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh index 477ecb1293ab..0fa8a61ccb7b 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh | |||
@@ -70,4 +70,5 @@ else | |||
70 | else | 70 | else |
71 | print_warning $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i | 71 | print_warning $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i |
72 | fi | 72 | fi |
73 | echo $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i > $i/console.log.rcu.diags | ||
73 | fi | 74 | fi |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh index c27e97824163..c9bab57a77eb 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck.sh | |||
@@ -39,6 +39,7 @@ do | |||
39 | head -1 $resdir/log | 39 | head -1 $resdir/log |
40 | fi | 40 | fi |
41 | TORTURE_SUITE="`cat $i/../TORTURE_SUITE`" | 41 | TORTURE_SUITE="`cat $i/../TORTURE_SUITE`" |
42 | rm -f $i/console.log.*.diags | ||
42 | kvm-recheck-${TORTURE_SUITE}.sh $i | 43 | kvm-recheck-${TORTURE_SUITE}.sh $i |
43 | if test -f "$i/console.log" | 44 | if test -f "$i/console.log" |
44 | then | 45 | then |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh index c5b0f94341d9..f7247ee00514 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh | |||
@@ -98,14 +98,15 @@ then | |||
98 | ln -s $base_resdir/.config $resdir # for kvm-recheck.sh | 98 | ln -s $base_resdir/.config $resdir # for kvm-recheck.sh |
99 | # Arch-independent indicator | 99 | # Arch-independent indicator |
100 | touch $resdir/builtkernel | 100 | touch $resdir/builtkernel |
101 | elif kvm-build.sh $T/Kc2 $builddir | 101 | elif kvm-build.sh $T/Kc2 $builddir $resdir |
102 | then | 102 | then |
103 | # Had to build a kernel for this test. | 103 | # Had to build a kernel for this test. |
104 | QEMU="`identify_qemu $builddir/vmlinux`" | 104 | QEMU="`identify_qemu $builddir/vmlinux`" |
105 | BOOT_IMAGE="`identify_boot_image $QEMU`" | 105 | BOOT_IMAGE="`identify_boot_image $QEMU`" |
106 | cp $builddir/Make*.out $resdir | ||
107 | cp $builddir/vmlinux $resdir | 106 | cp $builddir/vmlinux $resdir |
108 | cp $builddir/.config $resdir | 107 | cp $builddir/.config $resdir |
108 | cp $builddir/Module.symvers $resdir > /dev/null || : | ||
109 | cp $builddir/System.map $resdir > /dev/null || : | ||
109 | if test -n "$BOOT_IMAGE" | 110 | if test -n "$BOOT_IMAGE" |
110 | then | 111 | then |
111 | cp $builddir/$BOOT_IMAGE $resdir | 112 | cp $builddir/$BOOT_IMAGE $resdir |
diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index 56610dbbdf73..5a7a62d76a50 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh | |||
@@ -347,7 +347,7 @@ function dump(first, pastlast, batchnum) | |||
347 | print "needqemurun=" | 347 | print "needqemurun=" |
348 | jn=1 | 348 | jn=1 |
349 | for (j = first; j < pastlast; j++) { | 349 | for (j = first; j < pastlast; j++) { |
350 | builddir=KVM "/b" jn | 350 | builddir=KVM "/b1" |
351 | cpusr[jn] = cpus[j]; | 351 | cpusr[jn] = cpus[j]; |
352 | if (cfrep[cf[j]] == "") { | 352 | if (cfrep[cf[j]] == "") { |
353 | cfr[jn] = cf[j]; | 353 | cfr[jn] = cf[j]; |
diff --git a/tools/testing/selftests/rcutorture/bin/parse-console.sh b/tools/testing/selftests/rcutorture/bin/parse-console.sh index 17293436f551..84933f6aed77 100755 --- a/tools/testing/selftests/rcutorture/bin/parse-console.sh +++ b/tools/testing/selftests/rcutorture/bin/parse-console.sh | |||
@@ -163,6 +163,13 @@ then | |||
163 | print_warning Summary: $summary | 163 | print_warning Summary: $summary |
164 | cat $T.diags >> $file.diags | 164 | cat $T.diags >> $file.diags |
165 | fi | 165 | fi |
166 | for i in $file.*.diags | ||
167 | do | ||
168 | if test -f "$i" | ||
169 | then | ||
170 | cat $i >> $file.diags | ||
171 | fi | ||
172 | done | ||
166 | if ! test -s $file.diags | 173 | if ! test -s $file.diags |
167 | then | 174 | then |
168 | rm -f $file.diags | 175 | rm -f $file.diags |
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot index 5d2cc0bd50a0..5c3213cc3ad7 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot | |||
@@ -1,5 +1,5 @@ | |||
1 | rcutorture.onoff_interval=1 rcutorture.onoff_holdoff=30 | 1 | rcutorture.onoff_interval=200 rcutorture.onoff_holdoff=30 |
2 | rcutree.gp_preinit_delay=3 | 2 | rcutree.gp_preinit_delay=12 |
3 | rcutree.gp_init_delay=3 | 3 | rcutree.gp_init_delay=3 |
4 | rcutree.gp_cleanup_delay=3 | 4 | rcutree.gp_cleanup_delay=3 |
5 | rcutree.kthread_prio=2 | 5 | rcutree.kthread_prio=2 |
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot b/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot deleted file mode 100644 index 883149b5f2d1..000000000000 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | rcutree.rcu_fanout_exact=1 | ||
diff --git a/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh index 24ec91041957..7bab8246392b 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh +++ b/tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh | |||
@@ -39,7 +39,7 @@ rcutorture_param_onoff () { | |||
39 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" | 39 | if ! bootparam_hotplug_cpu "$1" && configfrag_hotplug_cpu "$2" |
40 | then | 40 | then |
41 | echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 | 41 | echo CPU-hotplug kernel, adding rcutorture onoff. 1>&2 |
42 | echo rcutorture.onoff_interval=3 rcutorture.onoff_holdoff=30 | 42 | echo rcutorture.onoff_interval=1000 rcutorture.onoff_holdoff=30 |
43 | fi | 43 | fi |
44 | } | 44 | } |
45 | 45 | ||
diff --git a/tools/testing/selftests/rseq/param_test.c b/tools/testing/selftests/rseq/param_test.c index 615252331813..642d4e12abea 100644 --- a/tools/testing/selftests/rseq/param_test.c +++ b/tools/testing/selftests/rseq/param_test.c | |||
@@ -90,6 +90,30 @@ unsigned int yield_mod_cnt, nr_abort; | |||
90 | #error "Unsupported architecture" | 90 | #error "Unsupported architecture" |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #elif defined(__s390__) | ||
94 | |||
95 | #define RSEQ_INJECT_INPUT \ | ||
96 | , [loop_cnt_1]"m"(loop_cnt[1]) \ | ||
97 | , [loop_cnt_2]"m"(loop_cnt[2]) \ | ||
98 | , [loop_cnt_3]"m"(loop_cnt[3]) \ | ||
99 | , [loop_cnt_4]"m"(loop_cnt[4]) \ | ||
100 | , [loop_cnt_5]"m"(loop_cnt[5]) \ | ||
101 | , [loop_cnt_6]"m"(loop_cnt[6]) | ||
102 | |||
103 | #define INJECT_ASM_REG "r12" | ||
104 | |||
105 | #define RSEQ_INJECT_CLOBBER \ | ||
106 | , INJECT_ASM_REG | ||
107 | |||
108 | #define RSEQ_INJECT_ASM(n) \ | ||
109 | "l %%" INJECT_ASM_REG ", %[loop_cnt_" #n "]\n\t" \ | ||
110 | "ltr %%" INJECT_ASM_REG ", %%" INJECT_ASM_REG "\n\t" \ | ||
111 | "je 333f\n\t" \ | ||
112 | "222:\n\t" \ | ||
113 | "ahi %%" INJECT_ASM_REG ", -1\n\t" \ | ||
114 | "jnz 222b\n\t" \ | ||
115 | "333:\n\t" | ||
116 | |||
93 | #elif defined(__ARMEL__) | 117 | #elif defined(__ARMEL__) |
94 | 118 | ||
95 | #define RSEQ_INJECT_INPUT \ | 119 | #define RSEQ_INJECT_INPUT \ |
@@ -114,6 +138,26 @@ unsigned int yield_mod_cnt, nr_abort; | |||
114 | "bne 222b\n\t" \ | 138 | "bne 222b\n\t" \ |
115 | "333:\n\t" | 139 | "333:\n\t" |
116 | 140 | ||
141 | #elif defined(__AARCH64EL__) | ||
142 | |||
143 | #define RSEQ_INJECT_INPUT \ | ||
144 | , [loop_cnt_1] "Qo" (loop_cnt[1]) \ | ||
145 | , [loop_cnt_2] "Qo" (loop_cnt[2]) \ | ||
146 | , [loop_cnt_3] "Qo" (loop_cnt[3]) \ | ||
147 | , [loop_cnt_4] "Qo" (loop_cnt[4]) \ | ||
148 | , [loop_cnt_5] "Qo" (loop_cnt[5]) \ | ||
149 | , [loop_cnt_6] "Qo" (loop_cnt[6]) | ||
150 | |||
151 | #define INJECT_ASM_REG RSEQ_ASM_TMP_REG32 | ||
152 | |||
153 | #define RSEQ_INJECT_ASM(n) \ | ||
154 | " ldr " INJECT_ASM_REG ", %[loop_cnt_" #n "]\n" \ | ||
155 | " cbz " INJECT_ASM_REG ", 333f\n" \ | ||
156 | "222:\n" \ | ||
157 | " sub " INJECT_ASM_REG ", " INJECT_ASM_REG ", #1\n" \ | ||
158 | " cbnz " INJECT_ASM_REG ", 222b\n" \ | ||
159 | "333:\n" | ||
160 | |||
117 | #elif __PPC__ | 161 | #elif __PPC__ |
118 | 162 | ||
119 | #define RSEQ_INJECT_INPUT \ | 163 | #define RSEQ_INJECT_INPUT \ |
diff --git a/tools/testing/selftests/rseq/rseq-arm64.h b/tools/testing/selftests/rseq/rseq-arm64.h new file mode 100644 index 000000000000..954f34671ca6 --- /dev/null +++ b/tools/testing/selftests/rseq/rseq-arm64.h | |||
@@ -0,0 +1,594 @@ | |||
1 | /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ | ||
2 | /* | ||
3 | * rseq-arm64.h | ||
4 | * | ||
5 | * (C) Copyright 2016-2018 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | ||
6 | * (C) Copyright 2018 - Will Deacon <will.deacon@arm.com> | ||
7 | */ | ||
8 | |||
9 | #define RSEQ_SIG 0xd428bc00 /* BRK #0x45E0 */ | ||
10 | |||
11 | #define rseq_smp_mb() __asm__ __volatile__ ("dmb ish" ::: "memory") | ||
12 | #define rseq_smp_rmb() __asm__ __volatile__ ("dmb ishld" ::: "memory") | ||
13 | #define rseq_smp_wmb() __asm__ __volatile__ ("dmb ishst" ::: "memory") | ||
14 | |||
15 | #define rseq_smp_load_acquire(p) \ | ||
16 | __extension__ ({ \ | ||
17 | __typeof(*p) ____p1; \ | ||
18 | switch (sizeof(*p)) { \ | ||
19 | case 1: \ | ||
20 | asm volatile ("ldarb %w0, %1" \ | ||
21 | : "=r" (*(__u8 *)p) \ | ||
22 | : "Q" (*p) : "memory"); \ | ||
23 | break; \ | ||
24 | case 2: \ | ||
25 | asm volatile ("ldarh %w0, %1" \ | ||
26 | : "=r" (*(__u16 *)p) \ | ||
27 | : "Q" (*p) : "memory"); \ | ||
28 | break; \ | ||
29 | case 4: \ | ||
30 | asm volatile ("ldar %w0, %1" \ | ||
31 | : "=r" (*(__u32 *)p) \ | ||
32 | : "Q" (*p) : "memory"); \ | ||
33 | break; \ | ||
34 | case 8: \ | ||
35 | asm volatile ("ldar %0, %1" \ | ||
36 | : "=r" (*(__u64 *)p) \ | ||
37 | : "Q" (*p) : "memory"); \ | ||
38 | break; \ | ||
39 | } \ | ||
40 | ____p1; \ | ||
41 | }) | ||
42 | |||
43 | #define rseq_smp_acquire__after_ctrl_dep() rseq_smp_rmb() | ||
44 | |||
45 | #define rseq_smp_store_release(p, v) \ | ||
46 | do { \ | ||
47 | switch (sizeof(*p)) { \ | ||
48 | case 1: \ | ||
49 | asm volatile ("stlrb %w1, %0" \ | ||
50 | : "=Q" (*p) \ | ||
51 | : "r" ((__u8)v) \ | ||
52 | : "memory"); \ | ||
53 | break; \ | ||
54 | case 2: \ | ||
55 | asm volatile ("stlrh %w1, %0" \ | ||
56 | : "=Q" (*p) \ | ||
57 | : "r" ((__u16)v) \ | ||
58 | : "memory"); \ | ||
59 | break; \ | ||
60 | case 4: \ | ||
61 | asm volatile ("stlr %w1, %0" \ | ||
62 | : "=Q" (*p) \ | ||
63 | : "r" ((__u32)v) \ | ||
64 | : "memory"); \ | ||
65 | break; \ | ||
66 | case 8: \ | ||
67 | asm volatile ("stlr %1, %0" \ | ||
68 | : "=Q" (*p) \ | ||
69 | : "r" ((__u64)v) \ | ||
70 | : "memory"); \ | ||
71 | break; \ | ||
72 | } \ | ||
73 | } while (0) | ||
74 | |||
75 | #ifdef RSEQ_SKIP_FASTPATH | ||
76 | #include "rseq-skip.h" | ||
77 | #else /* !RSEQ_SKIP_FASTPATH */ | ||
78 | |||
79 | #define RSEQ_ASM_TMP_REG32 "w15" | ||
80 | #define RSEQ_ASM_TMP_REG "x15" | ||
81 | #define RSEQ_ASM_TMP_REG_2 "x14" | ||
82 | |||
83 | #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, start_ip, \ | ||
84 | post_commit_offset, abort_ip) \ | ||
85 | " .pushsection __rseq_table, \"aw\"\n" \ | ||
86 | " .balign 32\n" \ | ||
87 | __rseq_str(label) ":\n" \ | ||
88 | " .long " __rseq_str(version) ", " __rseq_str(flags) "\n" \ | ||
89 | " .quad " __rseq_str(start_ip) ", " \ | ||
90 | __rseq_str(post_commit_offset) ", " \ | ||
91 | __rseq_str(abort_ip) "\n" \ | ||
92 | " .popsection\n" | ||
93 | |||
94 | #define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \ | ||
95 | __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \ | ||
96 | (post_commit_ip - start_ip), abort_ip) | ||
97 | |||
98 | #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \ | ||
99 | RSEQ_INJECT_ASM(1) \ | ||
100 | " adrp " RSEQ_ASM_TMP_REG ", " __rseq_str(cs_label) "\n" \ | ||
101 | " add " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \ | ||
102 | ", :lo12:" __rseq_str(cs_label) "\n" \ | ||
103 | " str " RSEQ_ASM_TMP_REG ", %[" __rseq_str(rseq_cs) "]\n" \ | ||
104 | __rseq_str(label) ":\n" | ||
105 | |||
106 | #define RSEQ_ASM_DEFINE_ABORT(label, abort_label) \ | ||
107 | " b 222f\n" \ | ||
108 | " .inst " __rseq_str(RSEQ_SIG) "\n" \ | ||
109 | __rseq_str(label) ":\n" \ | ||
110 | " b %l[" __rseq_str(abort_label) "]\n" \ | ||
111 | "222:\n" | ||
112 | |||
113 | #define RSEQ_ASM_OP_STORE(value, var) \ | ||
114 | " str %[" __rseq_str(value) "], %[" __rseq_str(var) "]\n" | ||
115 | |||
116 | #define RSEQ_ASM_OP_STORE_RELEASE(value, var) \ | ||
117 | " stlr %[" __rseq_str(value) "], %[" __rseq_str(var) "]\n" | ||
118 | |||
119 | #define RSEQ_ASM_OP_FINAL_STORE(value, var, post_commit_label) \ | ||
120 | RSEQ_ASM_OP_STORE(value, var) \ | ||
121 | __rseq_str(post_commit_label) ":\n" | ||
122 | |||
123 | #define RSEQ_ASM_OP_FINAL_STORE_RELEASE(value, var, post_commit_label) \ | ||
124 | RSEQ_ASM_OP_STORE_RELEASE(value, var) \ | ||
125 | __rseq_str(post_commit_label) ":\n" | ||
126 | |||
127 | #define RSEQ_ASM_OP_CMPEQ(var, expect, label) \ | ||
128 | " ldr " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" \ | ||
129 | " sub " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \ | ||
130 | ", %[" __rseq_str(expect) "]\n" \ | ||
131 | " cbnz " RSEQ_ASM_TMP_REG ", " __rseq_str(label) "\n" | ||
132 | |||
133 | #define RSEQ_ASM_OP_CMPEQ32(var, expect, label) \ | ||
134 | " ldr " RSEQ_ASM_TMP_REG32 ", %[" __rseq_str(var) "]\n" \ | ||
135 | " sub " RSEQ_ASM_TMP_REG32 ", " RSEQ_ASM_TMP_REG32 \ | ||
136 | ", %w[" __rseq_str(expect) "]\n" \ | ||
137 | " cbnz " RSEQ_ASM_TMP_REG32 ", " __rseq_str(label) "\n" | ||
138 | |||
139 | #define RSEQ_ASM_OP_CMPNE(var, expect, label) \ | ||
140 | " ldr " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" \ | ||
141 | " sub " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \ | ||
142 | ", %[" __rseq_str(expect) "]\n" \ | ||
143 | " cbz " RSEQ_ASM_TMP_REG ", " __rseq_str(label) "\n" | ||
144 | |||
145 | #define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \ | ||
146 | RSEQ_INJECT_ASM(2) \ | ||
147 | RSEQ_ASM_OP_CMPEQ32(current_cpu_id, cpu_id, label) | ||
148 | |||
149 | #define RSEQ_ASM_OP_R_LOAD(var) \ | ||
150 | " ldr " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" | ||
151 | |||
152 | #define RSEQ_ASM_OP_R_STORE(var) \ | ||
153 | " str " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" | ||
154 | |||
155 | #define RSEQ_ASM_OP_R_LOAD_OFF(offset) \ | ||
156 | " ldr " RSEQ_ASM_TMP_REG ", [" RSEQ_ASM_TMP_REG \ | ||
157 | ", %[" __rseq_str(offset) "]]\n" | ||
158 | |||
159 | #define RSEQ_ASM_OP_R_ADD(count) \ | ||
160 | " add " RSEQ_ASM_TMP_REG ", " RSEQ_ASM_TMP_REG \ | ||
161 | ", %[" __rseq_str(count) "]\n" | ||
162 | |||
163 | #define RSEQ_ASM_OP_R_FINAL_STORE(var, post_commit_label) \ | ||
164 | " str " RSEQ_ASM_TMP_REG ", %[" __rseq_str(var) "]\n" \ | ||
165 | __rseq_str(post_commit_label) ":\n" | ||
166 | |||
167 | #define RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len) \ | ||
168 | " cbz %[" __rseq_str(len) "], 333f\n" \ | ||
169 | " mov " RSEQ_ASM_TMP_REG_2 ", %[" __rseq_str(len) "]\n" \ | ||
170 | "222: sub " RSEQ_ASM_TMP_REG_2 ", " RSEQ_ASM_TMP_REG_2 ", #1\n" \ | ||
171 | " ldrb " RSEQ_ASM_TMP_REG32 ", [%[" __rseq_str(src) "]" \ | ||
172 | ", " RSEQ_ASM_TMP_REG_2 "]\n" \ | ||
173 | " strb " RSEQ_ASM_TMP_REG32 ", [%[" __rseq_str(dst) "]" \ | ||
174 | ", " RSEQ_ASM_TMP_REG_2 "]\n" \ | ||
175 | " cbnz " RSEQ_ASM_TMP_REG_2 ", 222b\n" \ | ||
176 | "333:\n" | ||
177 | |||
178 | static inline __attribute__((always_inline)) | ||
179 | int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu) | ||
180 | { | ||
181 | RSEQ_INJECT_C(9) | ||
182 | |||
183 | __asm__ __volatile__ goto ( | ||
184 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
185 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
186 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
187 | RSEQ_INJECT_ASM(3) | ||
188 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail]) | ||
189 | RSEQ_INJECT_ASM(4) | ||
190 | #ifdef RSEQ_COMPARE_TWICE | ||
191 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
192 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2]) | ||
193 | #endif | ||
194 | RSEQ_ASM_OP_FINAL_STORE(newv, v, 3) | ||
195 | RSEQ_INJECT_ASM(5) | ||
196 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
197 | : /* gcc asm goto does not allow outputs */ | ||
198 | : [cpu_id] "r" (cpu), | ||
199 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
200 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
201 | [v] "Qo" (*v), | ||
202 | [expect] "r" (expect), | ||
203 | [newv] "r" (newv) | ||
204 | RSEQ_INJECT_INPUT | ||
205 | : "memory", RSEQ_ASM_TMP_REG | ||
206 | : abort, cmpfail | ||
207 | #ifdef RSEQ_COMPARE_TWICE | ||
208 | , error1, error2 | ||
209 | #endif | ||
210 | ); | ||
211 | |||
212 | return 0; | ||
213 | abort: | ||
214 | RSEQ_INJECT_FAILED | ||
215 | return -1; | ||
216 | cmpfail: | ||
217 | return 1; | ||
218 | #ifdef RSEQ_COMPARE_TWICE | ||
219 | error1: | ||
220 | rseq_bug("cpu_id comparison failed"); | ||
221 | error2: | ||
222 | rseq_bug("expected value comparison failed"); | ||
223 | #endif | ||
224 | } | ||
225 | |||
226 | static inline __attribute__((always_inline)) | ||
227 | int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot, | ||
228 | off_t voffp, intptr_t *load, int cpu) | ||
229 | { | ||
230 | RSEQ_INJECT_C(9) | ||
231 | |||
232 | __asm__ __volatile__ goto ( | ||
233 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
234 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
235 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
236 | RSEQ_INJECT_ASM(3) | ||
237 | RSEQ_ASM_OP_CMPNE(v, expectnot, %l[cmpfail]) | ||
238 | RSEQ_INJECT_ASM(4) | ||
239 | #ifdef RSEQ_COMPARE_TWICE | ||
240 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
241 | RSEQ_ASM_OP_CMPNE(v, expectnot, %l[error2]) | ||
242 | #endif | ||
243 | RSEQ_ASM_OP_R_LOAD(v) | ||
244 | RSEQ_ASM_OP_R_STORE(load) | ||
245 | RSEQ_ASM_OP_R_LOAD_OFF(voffp) | ||
246 | RSEQ_ASM_OP_R_FINAL_STORE(v, 3) | ||
247 | RSEQ_INJECT_ASM(5) | ||
248 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
249 | : /* gcc asm goto does not allow outputs */ | ||
250 | : [cpu_id] "r" (cpu), | ||
251 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
252 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
253 | [v] "Qo" (*v), | ||
254 | [expectnot] "r" (expectnot), | ||
255 | [load] "Qo" (*load), | ||
256 | [voffp] "r" (voffp) | ||
257 | RSEQ_INJECT_INPUT | ||
258 | : "memory", RSEQ_ASM_TMP_REG | ||
259 | : abort, cmpfail | ||
260 | #ifdef RSEQ_COMPARE_TWICE | ||
261 | , error1, error2 | ||
262 | #endif | ||
263 | ); | ||
264 | return 0; | ||
265 | abort: | ||
266 | RSEQ_INJECT_FAILED | ||
267 | return -1; | ||
268 | cmpfail: | ||
269 | return 1; | ||
270 | #ifdef RSEQ_COMPARE_TWICE | ||
271 | error1: | ||
272 | rseq_bug("cpu_id comparison failed"); | ||
273 | error2: | ||
274 | rseq_bug("expected value comparison failed"); | ||
275 | #endif | ||
276 | } | ||
277 | |||
278 | static inline __attribute__((always_inline)) | ||
279 | int rseq_addv(intptr_t *v, intptr_t count, int cpu) | ||
280 | { | ||
281 | RSEQ_INJECT_C(9) | ||
282 | |||
283 | __asm__ __volatile__ goto ( | ||
284 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
285 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
286 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
287 | RSEQ_INJECT_ASM(3) | ||
288 | #ifdef RSEQ_COMPARE_TWICE | ||
289 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
290 | #endif | ||
291 | RSEQ_ASM_OP_R_LOAD(v) | ||
292 | RSEQ_ASM_OP_R_ADD(count) | ||
293 | RSEQ_ASM_OP_R_FINAL_STORE(v, 3) | ||
294 | RSEQ_INJECT_ASM(4) | ||
295 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
296 | : /* gcc asm goto does not allow outputs */ | ||
297 | : [cpu_id] "r" (cpu), | ||
298 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
299 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
300 | [v] "Qo" (*v), | ||
301 | [count] "r" (count) | ||
302 | RSEQ_INJECT_INPUT | ||
303 | : "memory", RSEQ_ASM_TMP_REG | ||
304 | : abort | ||
305 | #ifdef RSEQ_COMPARE_TWICE | ||
306 | , error1 | ||
307 | #endif | ||
308 | ); | ||
309 | return 0; | ||
310 | abort: | ||
311 | RSEQ_INJECT_FAILED | ||
312 | return -1; | ||
313 | #ifdef RSEQ_COMPARE_TWICE | ||
314 | error1: | ||
315 | rseq_bug("cpu_id comparison failed"); | ||
316 | #endif | ||
317 | } | ||
318 | |||
319 | static inline __attribute__((always_inline)) | ||
320 | int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect, | ||
321 | intptr_t *v2, intptr_t newv2, | ||
322 | intptr_t newv, int cpu) | ||
323 | { | ||
324 | RSEQ_INJECT_C(9) | ||
325 | |||
326 | __asm__ __volatile__ goto ( | ||
327 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
328 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
329 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
330 | RSEQ_INJECT_ASM(3) | ||
331 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail]) | ||
332 | RSEQ_INJECT_ASM(4) | ||
333 | #ifdef RSEQ_COMPARE_TWICE | ||
334 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
335 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2]) | ||
336 | #endif | ||
337 | RSEQ_ASM_OP_STORE(newv2, v2) | ||
338 | RSEQ_INJECT_ASM(5) | ||
339 | RSEQ_ASM_OP_FINAL_STORE(newv, v, 3) | ||
340 | RSEQ_INJECT_ASM(6) | ||
341 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
342 | : /* gcc asm goto does not allow outputs */ | ||
343 | : [cpu_id] "r" (cpu), | ||
344 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
345 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
346 | [expect] "r" (expect), | ||
347 | [v] "Qo" (*v), | ||
348 | [newv] "r" (newv), | ||
349 | [v2] "Qo" (*v2), | ||
350 | [newv2] "r" (newv2) | ||
351 | RSEQ_INJECT_INPUT | ||
352 | : "memory", RSEQ_ASM_TMP_REG | ||
353 | : abort, cmpfail | ||
354 | #ifdef RSEQ_COMPARE_TWICE | ||
355 | , error1, error2 | ||
356 | #endif | ||
357 | ); | ||
358 | |||
359 | return 0; | ||
360 | abort: | ||
361 | RSEQ_INJECT_FAILED | ||
362 | return -1; | ||
363 | cmpfail: | ||
364 | return 1; | ||
365 | #ifdef RSEQ_COMPARE_TWICE | ||
366 | error1: | ||
367 | rseq_bug("cpu_id comparison failed"); | ||
368 | error2: | ||
369 | rseq_bug("expected value comparison failed"); | ||
370 | #endif | ||
371 | } | ||
372 | |||
373 | static inline __attribute__((always_inline)) | ||
374 | int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect, | ||
375 | intptr_t *v2, intptr_t newv2, | ||
376 | intptr_t newv, int cpu) | ||
377 | { | ||
378 | RSEQ_INJECT_C(9) | ||
379 | |||
380 | __asm__ __volatile__ goto ( | ||
381 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
382 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
383 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
384 | RSEQ_INJECT_ASM(3) | ||
385 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail]) | ||
386 | RSEQ_INJECT_ASM(4) | ||
387 | #ifdef RSEQ_COMPARE_TWICE | ||
388 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
389 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2]) | ||
390 | #endif | ||
391 | RSEQ_ASM_OP_STORE(newv2, v2) | ||
392 | RSEQ_INJECT_ASM(5) | ||
393 | RSEQ_ASM_OP_FINAL_STORE_RELEASE(newv, v, 3) | ||
394 | RSEQ_INJECT_ASM(6) | ||
395 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
396 | : /* gcc asm goto does not allow outputs */ | ||
397 | : [cpu_id] "r" (cpu), | ||
398 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
399 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
400 | [expect] "r" (expect), | ||
401 | [v] "Qo" (*v), | ||
402 | [newv] "r" (newv), | ||
403 | [v2] "Qo" (*v2), | ||
404 | [newv2] "r" (newv2) | ||
405 | RSEQ_INJECT_INPUT | ||
406 | : "memory", RSEQ_ASM_TMP_REG | ||
407 | : abort, cmpfail | ||
408 | #ifdef RSEQ_COMPARE_TWICE | ||
409 | , error1, error2 | ||
410 | #endif | ||
411 | ); | ||
412 | |||
413 | return 0; | ||
414 | abort: | ||
415 | RSEQ_INJECT_FAILED | ||
416 | return -1; | ||
417 | cmpfail: | ||
418 | return 1; | ||
419 | #ifdef RSEQ_COMPARE_TWICE | ||
420 | error1: | ||
421 | rseq_bug("cpu_id comparison failed"); | ||
422 | error2: | ||
423 | rseq_bug("expected value comparison failed"); | ||
424 | #endif | ||
425 | } | ||
426 | |||
427 | static inline __attribute__((always_inline)) | ||
428 | int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect, | ||
429 | intptr_t *v2, intptr_t expect2, | ||
430 | intptr_t newv, int cpu) | ||
431 | { | ||
432 | RSEQ_INJECT_C(9) | ||
433 | |||
434 | __asm__ __volatile__ goto ( | ||
435 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
436 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
437 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
438 | RSEQ_INJECT_ASM(3) | ||
439 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail]) | ||
440 | RSEQ_INJECT_ASM(4) | ||
441 | RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[cmpfail]) | ||
442 | RSEQ_INJECT_ASM(5) | ||
443 | #ifdef RSEQ_COMPARE_TWICE | ||
444 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
445 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2]) | ||
446 | RSEQ_ASM_OP_CMPEQ(v2, expect2, %l[error3]) | ||
447 | #endif | ||
448 | RSEQ_ASM_OP_FINAL_STORE(newv, v, 3) | ||
449 | RSEQ_INJECT_ASM(6) | ||
450 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
451 | : /* gcc asm goto does not allow outputs */ | ||
452 | : [cpu_id] "r" (cpu), | ||
453 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
454 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
455 | [v] "Qo" (*v), | ||
456 | [expect] "r" (expect), | ||
457 | [v2] "Qo" (*v2), | ||
458 | [expect2] "r" (expect2), | ||
459 | [newv] "r" (newv) | ||
460 | RSEQ_INJECT_INPUT | ||
461 | : "memory", RSEQ_ASM_TMP_REG | ||
462 | : abort, cmpfail | ||
463 | #ifdef RSEQ_COMPARE_TWICE | ||
464 | , error1, error2, error3 | ||
465 | #endif | ||
466 | ); | ||
467 | |||
468 | return 0; | ||
469 | abort: | ||
470 | RSEQ_INJECT_FAILED | ||
471 | return -1; | ||
472 | cmpfail: | ||
473 | return 1; | ||
474 | #ifdef RSEQ_COMPARE_TWICE | ||
475 | error1: | ||
476 | rseq_bug("cpu_id comparison failed"); | ||
477 | error2: | ||
478 | rseq_bug("expected value comparison failed"); | ||
479 | error3: | ||
480 | rseq_bug("2nd expected value comparison failed"); | ||
481 | #endif | ||
482 | } | ||
483 | |||
484 | static inline __attribute__((always_inline)) | ||
485 | int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect, | ||
486 | void *dst, void *src, size_t len, | ||
487 | intptr_t newv, int cpu) | ||
488 | { | ||
489 | RSEQ_INJECT_C(9) | ||
490 | |||
491 | __asm__ __volatile__ goto ( | ||
492 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
493 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
494 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
495 | RSEQ_INJECT_ASM(3) | ||
496 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail]) | ||
497 | RSEQ_INJECT_ASM(4) | ||
498 | #ifdef RSEQ_COMPARE_TWICE | ||
499 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
500 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2]) | ||
501 | #endif | ||
502 | RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len) | ||
503 | RSEQ_INJECT_ASM(5) | ||
504 | RSEQ_ASM_OP_FINAL_STORE(newv, v, 3) | ||
505 | RSEQ_INJECT_ASM(6) | ||
506 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
507 | : /* gcc asm goto does not allow outputs */ | ||
508 | : [cpu_id] "r" (cpu), | ||
509 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
510 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
511 | [expect] "r" (expect), | ||
512 | [v] "Qo" (*v), | ||
513 | [newv] "r" (newv), | ||
514 | [dst] "r" (dst), | ||
515 | [src] "r" (src), | ||
516 | [len] "r" (len) | ||
517 | RSEQ_INJECT_INPUT | ||
518 | : "memory", RSEQ_ASM_TMP_REG, RSEQ_ASM_TMP_REG_2 | ||
519 | : abort, cmpfail | ||
520 | #ifdef RSEQ_COMPARE_TWICE | ||
521 | , error1, error2 | ||
522 | #endif | ||
523 | ); | ||
524 | |||
525 | return 0; | ||
526 | abort: | ||
527 | RSEQ_INJECT_FAILED | ||
528 | return -1; | ||
529 | cmpfail: | ||
530 | return 1; | ||
531 | #ifdef RSEQ_COMPARE_TWICE | ||
532 | error1: | ||
533 | rseq_bug("cpu_id comparison failed"); | ||
534 | error2: | ||
535 | rseq_bug("expected value comparison failed"); | ||
536 | #endif | ||
537 | } | ||
538 | |||
539 | static inline __attribute__((always_inline)) | ||
540 | int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect, | ||
541 | void *dst, void *src, size_t len, | ||
542 | intptr_t newv, int cpu) | ||
543 | { | ||
544 | RSEQ_INJECT_C(9) | ||
545 | |||
546 | __asm__ __volatile__ goto ( | ||
547 | RSEQ_ASM_DEFINE_TABLE(1, 2f, 3f, 4f) | ||
548 | RSEQ_ASM_STORE_RSEQ_CS(2, 1b, rseq_cs) | ||
549 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
550 | RSEQ_INJECT_ASM(3) | ||
551 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail]) | ||
552 | RSEQ_INJECT_ASM(4) | ||
553 | #ifdef RSEQ_COMPARE_TWICE | ||
554 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
555 | RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2]) | ||
556 | #endif | ||
557 | RSEQ_ASM_OP_R_BAD_MEMCPY(dst, src, len) | ||
558 | RSEQ_INJECT_ASM(5) | ||
559 | RSEQ_ASM_OP_FINAL_STORE_RELEASE(newv, v, 3) | ||
560 | RSEQ_INJECT_ASM(6) | ||
561 | RSEQ_ASM_DEFINE_ABORT(4, abort) | ||
562 | : /* gcc asm goto does not allow outputs */ | ||
563 | : [cpu_id] "r" (cpu), | ||
564 | [current_cpu_id] "Qo" (__rseq_abi.cpu_id), | ||
565 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
566 | [expect] "r" (expect), | ||
567 | [v] "Qo" (*v), | ||
568 | [newv] "r" (newv), | ||
569 | [dst] "r" (dst), | ||
570 | [src] "r" (src), | ||
571 | [len] "r" (len) | ||
572 | RSEQ_INJECT_INPUT | ||
573 | : "memory", RSEQ_ASM_TMP_REG, RSEQ_ASM_TMP_REG_2 | ||
574 | : abort, cmpfail | ||
575 | #ifdef RSEQ_COMPARE_TWICE | ||
576 | , error1, error2 | ||
577 | #endif | ||
578 | ); | ||
579 | |||
580 | return 0; | ||
581 | abort: | ||
582 | RSEQ_INJECT_FAILED | ||
583 | return -1; | ||
584 | cmpfail: | ||
585 | return 1; | ||
586 | #ifdef RSEQ_COMPARE_TWICE | ||
587 | error1: | ||
588 | rseq_bug("cpu_id comparison failed"); | ||
589 | error2: | ||
590 | rseq_bug("expected value comparison failed"); | ||
591 | #endif | ||
592 | } | ||
593 | |||
594 | #endif /* !RSEQ_SKIP_FASTPATH */ | ||
diff --git a/tools/testing/selftests/rseq/rseq-s390.h b/tools/testing/selftests/rseq/rseq-s390.h new file mode 100644 index 000000000000..1069e85258ce --- /dev/null +++ b/tools/testing/selftests/rseq/rseq-s390.h | |||
@@ -0,0 +1,513 @@ | |||
1 | /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ | ||
2 | |||
3 | #define RSEQ_SIG 0x53053053 | ||
4 | |||
5 | #define rseq_smp_mb() __asm__ __volatile__ ("bcr 15,0" ::: "memory") | ||
6 | #define rseq_smp_rmb() rseq_smp_mb() | ||
7 | #define rseq_smp_wmb() rseq_smp_mb() | ||
8 | |||
9 | #define rseq_smp_load_acquire(p) \ | ||
10 | __extension__ ({ \ | ||
11 | __typeof(*p) ____p1 = RSEQ_READ_ONCE(*p); \ | ||
12 | rseq_barrier(); \ | ||
13 | ____p1; \ | ||
14 | }) | ||
15 | |||
16 | #define rseq_smp_acquire__after_ctrl_dep() rseq_smp_rmb() | ||
17 | |||
18 | #define rseq_smp_store_release(p, v) \ | ||
19 | do { \ | ||
20 | rseq_barrier(); \ | ||
21 | RSEQ_WRITE_ONCE(*p, v); \ | ||
22 | } while (0) | ||
23 | |||
24 | #ifdef RSEQ_SKIP_FASTPATH | ||
25 | #include "rseq-skip.h" | ||
26 | #else /* !RSEQ_SKIP_FASTPATH */ | ||
27 | |||
28 | #ifdef __s390x__ | ||
29 | |||
30 | #define LONG_L "lg" | ||
31 | #define LONG_S "stg" | ||
32 | #define LONG_LT_R "ltgr" | ||
33 | #define LONG_CMP "cg" | ||
34 | #define LONG_CMP_R "cgr" | ||
35 | #define LONG_ADDI "aghi" | ||
36 | #define LONG_ADD_R "agr" | ||
37 | |||
38 | #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \ | ||
39 | start_ip, post_commit_offset, abort_ip) \ | ||
40 | ".pushsection __rseq_table, \"aw\"\n\t" \ | ||
41 | ".balign 32\n\t" \ | ||
42 | __rseq_str(label) ":\n\t" \ | ||
43 | ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ | ||
44 | ".quad " __rseq_str(start_ip) ", " __rseq_str(post_commit_offset) ", " __rseq_str(abort_ip) "\n\t" \ | ||
45 | ".popsection\n\t" | ||
46 | |||
47 | #elif __s390__ | ||
48 | |||
49 | #define __RSEQ_ASM_DEFINE_TABLE(label, version, flags, \ | ||
50 | start_ip, post_commit_offset, abort_ip) \ | ||
51 | ".pushsection __rseq_table, \"aw\"\n\t" \ | ||
52 | ".balign 32\n\t" \ | ||
53 | __rseq_str(label) ":\n\t" \ | ||
54 | ".long " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ | ||
55 | ".long 0x0, " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) "\n\t" \ | ||
56 | ".popsection\n\t" | ||
57 | |||
58 | #define LONG_L "l" | ||
59 | #define LONG_S "st" | ||
60 | #define LONG_LT_R "ltr" | ||
61 | #define LONG_CMP "c" | ||
62 | #define LONG_CMP_R "cr" | ||
63 | #define LONG_ADDI "ahi" | ||
64 | #define LONG_ADD_R "ar" | ||
65 | |||
66 | #endif | ||
67 | |||
68 | #define RSEQ_ASM_DEFINE_TABLE(label, start_ip, post_commit_ip, abort_ip) \ | ||
69 | __RSEQ_ASM_DEFINE_TABLE(label, 0x0, 0x0, start_ip, \ | ||
70 | (post_commit_ip - start_ip), abort_ip) | ||
71 | |||
72 | #define RSEQ_ASM_STORE_RSEQ_CS(label, cs_label, rseq_cs) \ | ||
73 | RSEQ_INJECT_ASM(1) \ | ||
74 | "larl %%r0, " __rseq_str(cs_label) "\n\t" \ | ||
75 | LONG_S " %%r0, %[" __rseq_str(rseq_cs) "]\n\t" \ | ||
76 | __rseq_str(label) ":\n\t" | ||
77 | |||
78 | #define RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, label) \ | ||
79 | RSEQ_INJECT_ASM(2) \ | ||
80 | "c %[" __rseq_str(cpu_id) "], %[" __rseq_str(current_cpu_id) "]\n\t" \ | ||
81 | "jnz " __rseq_str(label) "\n\t" | ||
82 | |||
83 | #define RSEQ_ASM_DEFINE_ABORT(label, teardown, abort_label) \ | ||
84 | ".pushsection __rseq_failure, \"ax\"\n\t" \ | ||
85 | ".long " __rseq_str(RSEQ_SIG) "\n\t" \ | ||
86 | __rseq_str(label) ":\n\t" \ | ||
87 | teardown \ | ||
88 | "j %l[" __rseq_str(abort_label) "]\n\t" \ | ||
89 | ".popsection\n\t" | ||
90 | |||
91 | #define RSEQ_ASM_DEFINE_CMPFAIL(label, teardown, cmpfail_label) \ | ||
92 | ".pushsection __rseq_failure, \"ax\"\n\t" \ | ||
93 | __rseq_str(label) ":\n\t" \ | ||
94 | teardown \ | ||
95 | "j %l[" __rseq_str(cmpfail_label) "]\n\t" \ | ||
96 | ".popsection\n\t" | ||
97 | |||
98 | static inline __attribute__((always_inline)) | ||
99 | int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu) | ||
100 | { | ||
101 | RSEQ_INJECT_C(9) | ||
102 | |||
103 | __asm__ __volatile__ goto ( | ||
104 | RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ | ||
105 | /* Start rseq by storing table entry pointer into rseq_cs. */ | ||
106 | RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs) | ||
107 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
108 | RSEQ_INJECT_ASM(3) | ||
109 | LONG_CMP " %[expect], %[v]\n\t" | ||
110 | "jnz %l[cmpfail]\n\t" | ||
111 | RSEQ_INJECT_ASM(4) | ||
112 | #ifdef RSEQ_COMPARE_TWICE | ||
113 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
114 | LONG_CMP " %[expect], %[v]\n\t" | ||
115 | "jnz %l[error2]\n\t" | ||
116 | #endif | ||
117 | /* final store */ | ||
118 | LONG_S " %[newv], %[v]\n\t" | ||
119 | "2:\n\t" | ||
120 | RSEQ_INJECT_ASM(5) | ||
121 | RSEQ_ASM_DEFINE_ABORT(4, "", abort) | ||
122 | : /* gcc asm goto does not allow outputs */ | ||
123 | : [cpu_id] "r" (cpu), | ||
124 | [current_cpu_id] "m" (__rseq_abi.cpu_id), | ||
125 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
126 | [v] "m" (*v), | ||
127 | [expect] "r" (expect), | ||
128 | [newv] "r" (newv) | ||
129 | RSEQ_INJECT_INPUT | ||
130 | : "memory", "cc", "r0" | ||
131 | RSEQ_INJECT_CLOBBER | ||
132 | : abort, cmpfail | ||
133 | #ifdef RSEQ_COMPARE_TWICE | ||
134 | , error1, error2 | ||
135 | #endif | ||
136 | ); | ||
137 | return 0; | ||
138 | abort: | ||
139 | RSEQ_INJECT_FAILED | ||
140 | return -1; | ||
141 | cmpfail: | ||
142 | return 1; | ||
143 | #ifdef RSEQ_COMPARE_TWICE | ||
144 | error1: | ||
145 | rseq_bug("cpu_id comparison failed"); | ||
146 | error2: | ||
147 | rseq_bug("expected value comparison failed"); | ||
148 | #endif | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * Compare @v against @expectnot. When it does _not_ match, load @v | ||
153 | * into @load, and store the content of *@v + voffp into @v. | ||
154 | */ | ||
155 | static inline __attribute__((always_inline)) | ||
156 | int rseq_cmpnev_storeoffp_load(intptr_t *v, intptr_t expectnot, | ||
157 | off_t voffp, intptr_t *load, int cpu) | ||
158 | { | ||
159 | RSEQ_INJECT_C(9) | ||
160 | |||
161 | __asm__ __volatile__ goto ( | ||
162 | RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ | ||
163 | /* Start rseq by storing table entry pointer into rseq_cs. */ | ||
164 | RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs) | ||
165 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
166 | RSEQ_INJECT_ASM(3) | ||
167 | LONG_L " %%r1, %[v]\n\t" | ||
168 | LONG_CMP_R " %%r1, %[expectnot]\n\t" | ||
169 | "je %l[cmpfail]\n\t" | ||
170 | RSEQ_INJECT_ASM(4) | ||
171 | #ifdef RSEQ_COMPARE_TWICE | ||
172 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
173 | LONG_L " %%r1, %[v]\n\t" | ||
174 | LONG_CMP_R " %%r1, %[expectnot]\n\t" | ||
175 | "je %l[error2]\n\t" | ||
176 | #endif | ||
177 | LONG_S " %%r1, %[load]\n\t" | ||
178 | LONG_ADD_R " %%r1, %[voffp]\n\t" | ||
179 | LONG_L " %%r1, 0(%%r1)\n\t" | ||
180 | /* final store */ | ||
181 | LONG_S " %%r1, %[v]\n\t" | ||
182 | "2:\n\t" | ||
183 | RSEQ_INJECT_ASM(5) | ||
184 | RSEQ_ASM_DEFINE_ABORT(4, "", abort) | ||
185 | : /* gcc asm goto does not allow outputs */ | ||
186 | : [cpu_id] "r" (cpu), | ||
187 | [current_cpu_id] "m" (__rseq_abi.cpu_id), | ||
188 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
189 | /* final store input */ | ||
190 | [v] "m" (*v), | ||
191 | [expectnot] "r" (expectnot), | ||
192 | [voffp] "r" (voffp), | ||
193 | [load] "m" (*load) | ||
194 | RSEQ_INJECT_INPUT | ||
195 | : "memory", "cc", "r0", "r1" | ||
196 | RSEQ_INJECT_CLOBBER | ||
197 | : abort, cmpfail | ||
198 | #ifdef RSEQ_COMPARE_TWICE | ||
199 | , error1, error2 | ||
200 | #endif | ||
201 | ); | ||
202 | return 0; | ||
203 | abort: | ||
204 | RSEQ_INJECT_FAILED | ||
205 | return -1; | ||
206 | cmpfail: | ||
207 | return 1; | ||
208 | #ifdef RSEQ_COMPARE_TWICE | ||
209 | error1: | ||
210 | rseq_bug("cpu_id comparison failed"); | ||
211 | error2: | ||
212 | rseq_bug("expected value comparison failed"); | ||
213 | #endif | ||
214 | } | ||
215 | |||
216 | static inline __attribute__((always_inline)) | ||
217 | int rseq_addv(intptr_t *v, intptr_t count, int cpu) | ||
218 | { | ||
219 | RSEQ_INJECT_C(9) | ||
220 | |||
221 | __asm__ __volatile__ goto ( | ||
222 | RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ | ||
223 | /* Start rseq by storing table entry pointer into rseq_cs. */ | ||
224 | RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs) | ||
225 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
226 | RSEQ_INJECT_ASM(3) | ||
227 | #ifdef RSEQ_COMPARE_TWICE | ||
228 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
229 | #endif | ||
230 | LONG_L " %%r0, %[v]\n\t" | ||
231 | LONG_ADD_R " %%r0, %[count]\n\t" | ||
232 | /* final store */ | ||
233 | LONG_S " %%r0, %[v]\n\t" | ||
234 | "2:\n\t" | ||
235 | RSEQ_INJECT_ASM(4) | ||
236 | RSEQ_ASM_DEFINE_ABORT(4, "", abort) | ||
237 | : /* gcc asm goto does not allow outputs */ | ||
238 | : [cpu_id] "r" (cpu), | ||
239 | [current_cpu_id] "m" (__rseq_abi.cpu_id), | ||
240 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
241 | /* final store input */ | ||
242 | [v] "m" (*v), | ||
243 | [count] "r" (count) | ||
244 | RSEQ_INJECT_INPUT | ||
245 | : "memory", "cc", "r0" | ||
246 | RSEQ_INJECT_CLOBBER | ||
247 | : abort | ||
248 | #ifdef RSEQ_COMPARE_TWICE | ||
249 | , error1 | ||
250 | #endif | ||
251 | ); | ||
252 | return 0; | ||
253 | abort: | ||
254 | RSEQ_INJECT_FAILED | ||
255 | return -1; | ||
256 | #ifdef RSEQ_COMPARE_TWICE | ||
257 | error1: | ||
258 | rseq_bug("cpu_id comparison failed"); | ||
259 | #endif | ||
260 | } | ||
261 | |||
262 | static inline __attribute__((always_inline)) | ||
263 | int rseq_cmpeqv_trystorev_storev(intptr_t *v, intptr_t expect, | ||
264 | intptr_t *v2, intptr_t newv2, | ||
265 | intptr_t newv, int cpu) | ||
266 | { | ||
267 | RSEQ_INJECT_C(9) | ||
268 | |||
269 | __asm__ __volatile__ goto ( | ||
270 | RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ | ||
271 | /* Start rseq by storing table entry pointer into rseq_cs. */ | ||
272 | RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs) | ||
273 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
274 | RSEQ_INJECT_ASM(3) | ||
275 | LONG_CMP " %[expect], %[v]\n\t" | ||
276 | "jnz %l[cmpfail]\n\t" | ||
277 | RSEQ_INJECT_ASM(4) | ||
278 | #ifdef RSEQ_COMPARE_TWICE | ||
279 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
280 | LONG_CMP " %[expect], %[v]\n\t" | ||
281 | "jnz %l[error2]\n\t" | ||
282 | #endif | ||
283 | /* try store */ | ||
284 | LONG_S " %[newv2], %[v2]\n\t" | ||
285 | RSEQ_INJECT_ASM(5) | ||
286 | /* final store */ | ||
287 | LONG_S " %[newv], %[v]\n\t" | ||
288 | "2:\n\t" | ||
289 | RSEQ_INJECT_ASM(6) | ||
290 | RSEQ_ASM_DEFINE_ABORT(4, "", abort) | ||
291 | : /* gcc asm goto does not allow outputs */ | ||
292 | : [cpu_id] "r" (cpu), | ||
293 | [current_cpu_id] "m" (__rseq_abi.cpu_id), | ||
294 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
295 | /* try store input */ | ||
296 | [v2] "m" (*v2), | ||
297 | [newv2] "r" (newv2), | ||
298 | /* final store input */ | ||
299 | [v] "m" (*v), | ||
300 | [expect] "r" (expect), | ||
301 | [newv] "r" (newv) | ||
302 | RSEQ_INJECT_INPUT | ||
303 | : "memory", "cc", "r0" | ||
304 | RSEQ_INJECT_CLOBBER | ||
305 | : abort, cmpfail | ||
306 | #ifdef RSEQ_COMPARE_TWICE | ||
307 | , error1, error2 | ||
308 | #endif | ||
309 | ); | ||
310 | return 0; | ||
311 | abort: | ||
312 | RSEQ_INJECT_FAILED | ||
313 | return -1; | ||
314 | cmpfail: | ||
315 | return 1; | ||
316 | #ifdef RSEQ_COMPARE_TWICE | ||
317 | error1: | ||
318 | rseq_bug("cpu_id comparison failed"); | ||
319 | error2: | ||
320 | rseq_bug("expected value comparison failed"); | ||
321 | #endif | ||
322 | } | ||
323 | |||
324 | /* s390 is TSO. */ | ||
325 | static inline __attribute__((always_inline)) | ||
326 | int rseq_cmpeqv_trystorev_storev_release(intptr_t *v, intptr_t expect, | ||
327 | intptr_t *v2, intptr_t newv2, | ||
328 | intptr_t newv, int cpu) | ||
329 | { | ||
330 | return rseq_cmpeqv_trystorev_storev(v, expect, v2, newv2, newv, cpu); | ||
331 | } | ||
332 | |||
333 | static inline __attribute__((always_inline)) | ||
334 | int rseq_cmpeqv_cmpeqv_storev(intptr_t *v, intptr_t expect, | ||
335 | intptr_t *v2, intptr_t expect2, | ||
336 | intptr_t newv, int cpu) | ||
337 | { | ||
338 | RSEQ_INJECT_C(9) | ||
339 | |||
340 | __asm__ __volatile__ goto ( | ||
341 | RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ | ||
342 | /* Start rseq by storing table entry pointer into rseq_cs. */ | ||
343 | RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs) | ||
344 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
345 | RSEQ_INJECT_ASM(3) | ||
346 | LONG_CMP " %[expect], %[v]\n\t" | ||
347 | "jnz %l[cmpfail]\n\t" | ||
348 | RSEQ_INJECT_ASM(4) | ||
349 | LONG_CMP " %[expect2], %[v2]\n\t" | ||
350 | "jnz %l[cmpfail]\n\t" | ||
351 | RSEQ_INJECT_ASM(5) | ||
352 | #ifdef RSEQ_COMPARE_TWICE | ||
353 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1]) | ||
354 | LONG_CMP " %[expect], %[v]\n\t" | ||
355 | "jnz %l[error2]\n\t" | ||
356 | LONG_CMP " %[expect2], %[v2]\n\t" | ||
357 | "jnz %l[error3]\n\t" | ||
358 | #endif | ||
359 | /* final store */ | ||
360 | LONG_S " %[newv], %[v]\n\t" | ||
361 | "2:\n\t" | ||
362 | RSEQ_INJECT_ASM(6) | ||
363 | RSEQ_ASM_DEFINE_ABORT(4, "", abort) | ||
364 | : /* gcc asm goto does not allow outputs */ | ||
365 | : [cpu_id] "r" (cpu), | ||
366 | [current_cpu_id] "m" (__rseq_abi.cpu_id), | ||
367 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
368 | /* cmp2 input */ | ||
369 | [v2] "m" (*v2), | ||
370 | [expect2] "r" (expect2), | ||
371 | /* final store input */ | ||
372 | [v] "m" (*v), | ||
373 | [expect] "r" (expect), | ||
374 | [newv] "r" (newv) | ||
375 | RSEQ_INJECT_INPUT | ||
376 | : "memory", "cc", "r0" | ||
377 | RSEQ_INJECT_CLOBBER | ||
378 | : abort, cmpfail | ||
379 | #ifdef RSEQ_COMPARE_TWICE | ||
380 | , error1, error2, error3 | ||
381 | #endif | ||
382 | ); | ||
383 | return 0; | ||
384 | abort: | ||
385 | RSEQ_INJECT_FAILED | ||
386 | return -1; | ||
387 | cmpfail: | ||
388 | return 1; | ||
389 | #ifdef RSEQ_COMPARE_TWICE | ||
390 | error1: | ||
391 | rseq_bug("cpu_id comparison failed"); | ||
392 | error2: | ||
393 | rseq_bug("1st expected value comparison failed"); | ||
394 | error3: | ||
395 | rseq_bug("2nd expected value comparison failed"); | ||
396 | #endif | ||
397 | } | ||
398 | |||
399 | static inline __attribute__((always_inline)) | ||
400 | int rseq_cmpeqv_trymemcpy_storev(intptr_t *v, intptr_t expect, | ||
401 | void *dst, void *src, size_t len, | ||
402 | intptr_t newv, int cpu) | ||
403 | { | ||
404 | uint64_t rseq_scratch[3]; | ||
405 | |||
406 | RSEQ_INJECT_C(9) | ||
407 | |||
408 | __asm__ __volatile__ goto ( | ||
409 | RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */ | ||
410 | LONG_S " %[src], %[rseq_scratch0]\n\t" | ||
411 | LONG_S " %[dst], %[rseq_scratch1]\n\t" | ||
412 | LONG_S " %[len], %[rseq_scratch2]\n\t" | ||
413 | /* Start rseq by storing table entry pointer into rseq_cs. */ | ||
414 | RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs) | ||
415 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f) | ||
416 | RSEQ_INJECT_ASM(3) | ||
417 | LONG_CMP " %[expect], %[v]\n\t" | ||
418 | "jnz 5f\n\t" | ||
419 | RSEQ_INJECT_ASM(4) | ||
420 | #ifdef RSEQ_COMPARE_TWICE | ||
421 | RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 6f) | ||
422 | LONG_CMP " %[expect], %[v]\n\t" | ||
423 | "jnz 7f\n\t" | ||
424 | #endif | ||
425 | /* try memcpy */ | ||
426 | LONG_LT_R " %[len], %[len]\n\t" | ||
427 | "jz 333f\n\t" | ||
428 | "222:\n\t" | ||
429 | "ic %%r0,0(%[src])\n\t" | ||
430 | "stc %%r0,0(%[dst])\n\t" | ||
431 | LONG_ADDI " %[src], 1\n\t" | ||
432 | LONG_ADDI " %[dst], 1\n\t" | ||
433 | LONG_ADDI " %[len], -1\n\t" | ||
434 | "jnz 222b\n\t" | ||
435 | "333:\n\t" | ||
436 | RSEQ_INJECT_ASM(5) | ||
437 | /* final store */ | ||
438 | LONG_S " %[newv], %[v]\n\t" | ||
439 | "2:\n\t" | ||
440 | RSEQ_INJECT_ASM(6) | ||
441 | /* teardown */ | ||
442 | LONG_L " %[len], %[rseq_scratch2]\n\t" | ||
443 | LONG_L " %[dst], %[rseq_scratch1]\n\t" | ||
444 | LONG_L " %[src], %[rseq_scratch0]\n\t" | ||
445 | RSEQ_ASM_DEFINE_ABORT(4, | ||
446 | LONG_L " %[len], %[rseq_scratch2]\n\t" | ||
447 | LONG_L " %[dst], %[rseq_scratch1]\n\t" | ||
448 | LONG_L " %[src], %[rseq_scratch0]\n\t", | ||
449 | abort) | ||
450 | RSEQ_ASM_DEFINE_CMPFAIL(5, | ||
451 | LONG_L " %[len], %[rseq_scratch2]\n\t" | ||
452 | LONG_L " %[dst], %[rseq_scratch1]\n\t" | ||
453 | LONG_L " %[src], %[rseq_scratch0]\n\t", | ||
454 | cmpfail) | ||
455 | #ifdef RSEQ_COMPARE_TWICE | ||
456 | RSEQ_ASM_DEFINE_CMPFAIL(6, | ||
457 | LONG_L " %[len], %[rseq_scratch2]\n\t" | ||
458 | LONG_L " %[dst], %[rseq_scratch1]\n\t" | ||
459 | LONG_L " %[src], %[rseq_scratch0]\n\t", | ||
460 | error1) | ||
461 | RSEQ_ASM_DEFINE_CMPFAIL(7, | ||
462 | LONG_L " %[len], %[rseq_scratch2]\n\t" | ||
463 | LONG_L " %[dst], %[rseq_scratch1]\n\t" | ||
464 | LONG_L " %[src], %[rseq_scratch0]\n\t", | ||
465 | error2) | ||
466 | #endif | ||
467 | : /* gcc asm goto does not allow outputs */ | ||
468 | : [cpu_id] "r" (cpu), | ||
469 | [current_cpu_id] "m" (__rseq_abi.cpu_id), | ||
470 | [rseq_cs] "m" (__rseq_abi.rseq_cs), | ||
471 | /* final store input */ | ||
472 | [v] "m" (*v), | ||
473 | [expect] "r" (expect), | ||
474 | [newv] "r" (newv), | ||
475 | /* try memcpy input */ | ||
476 | [dst] "r" (dst), | ||
477 | [src] "r" (src), | ||
478 | [len] "r" (len), | ||
479 | [rseq_scratch0] "m" (rseq_scratch[0]), | ||
480 | [rseq_scratch1] "m" (rseq_scratch[1]), | ||
481 | [rseq_scratch2] "m" (rseq_scratch[2]) | ||
482 | RSEQ_INJECT_INPUT | ||
483 | : "memory", "cc", "r0" | ||
484 | RSEQ_INJECT_CLOBBER | ||
485 | : abort, cmpfail | ||
486 | #ifdef RSEQ_COMPARE_TWICE | ||
487 | , error1, error2 | ||
488 | #endif | ||
489 | ); | ||
490 | return 0; | ||
491 | abort: | ||
492 | RSEQ_INJECT_FAILED | ||
493 | return -1; | ||
494 | cmpfail: | ||
495 | return 1; | ||
496 | #ifdef RSEQ_COMPARE_TWICE | ||
497 | error1: | ||
498 | rseq_bug("cpu_id comparison failed"); | ||
499 | error2: | ||
500 | rseq_bug("expected value comparison failed"); | ||
501 | #endif | ||
502 | } | ||
503 | |||
504 | /* s390 is TSO. */ | ||
505 | static inline __attribute__((always_inline)) | ||
506 | int rseq_cmpeqv_trymemcpy_storev_release(intptr_t *v, intptr_t expect, | ||
507 | void *dst, void *src, size_t len, | ||
508 | intptr_t newv, int cpu) | ||
509 | { | ||
510 | return rseq_cmpeqv_trymemcpy_storev(v, expect, dst, src, len, | ||
511 | newv, cpu); | ||
512 | } | ||
513 | #endif /* !RSEQ_SKIP_FASTPATH */ | ||
diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h index 86ce22417e0d..c72eb70f9b52 100644 --- a/tools/testing/selftests/rseq/rseq.h +++ b/tools/testing/selftests/rseq/rseq.h | |||
@@ -71,10 +71,14 @@ extern __thread volatile struct rseq __rseq_abi; | |||
71 | #include <rseq-x86.h> | 71 | #include <rseq-x86.h> |
72 | #elif defined(__ARMEL__) | 72 | #elif defined(__ARMEL__) |
73 | #include <rseq-arm.h> | 73 | #include <rseq-arm.h> |
74 | #elif defined (__AARCH64EL__) | ||
75 | #include <rseq-arm64.h> | ||
74 | #elif defined(__PPC__) | 76 | #elif defined(__PPC__) |
75 | #include <rseq-ppc.h> | 77 | #include <rseq-ppc.h> |
76 | #elif defined(__mips__) | 78 | #elif defined(__mips__) |
77 | #include <rseq-mips.h> | 79 | #include <rseq-mips.h> |
80 | #elif defined(__s390__) | ||
81 | #include <rseq-s390.h> | ||
78 | #else | 82 | #else |
79 | #error unsupported target | 83 | #error unsupported target |
80 | #endif | 84 | #endif |
diff --git a/tools/testing/selftests/tc-testing/README b/tools/testing/selftests/tc-testing/README index 3a0336782d2d..49a6f8c3fdae 100644 --- a/tools/testing/selftests/tc-testing/README +++ b/tools/testing/selftests/tc-testing/README | |||
@@ -17,6 +17,10 @@ REQUIREMENTS | |||
17 | * The kernel must have veth support available, as a veth pair is created | 17 | * The kernel must have veth support available, as a veth pair is created |
18 | prior to running the tests. | 18 | prior to running the tests. |
19 | 19 | ||
20 | * The kernel must have the appropriate infrastructure enabled to run all tdc | ||
21 | unit tests. See the config file in this directory for minimum required | ||
22 | features. As new tests will be added, config options list will be updated. | ||
23 | |||
20 | * All tc-related features being tested must be built in or available as | 24 | * All tc-related features being tested must be built in or available as |
21 | modules. To check what is required in current setup run: | 25 | modules. To check what is required in current setup run: |
22 | ./tdc.py -c | 26 | ./tdc.py -c |
@@ -109,8 +113,8 @@ COMMAND LINE ARGUMENTS | |||
109 | Run tdc.py -h to see the full list of available arguments. | 113 | Run tdc.py -h to see the full list of available arguments. |
110 | 114 | ||
111 | usage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]] | 115 | usage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]] |
112 | [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v] | 116 | [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v] [-N] |
113 | [-d DEVICE] [-n NS] [-V] | 117 | [-d DEVICE] [-P] [-n] [-V] |
114 | 118 | ||
115 | Linux TC unit tests | 119 | Linux TC unit tests |
116 | 120 | ||
@@ -118,8 +122,10 @@ optional arguments: | |||
118 | -h, --help show this help message and exit | 122 | -h, --help show this help message and exit |
119 | -p PATH, --path PATH The full path to the tc executable to use | 123 | -p PATH, --path PATH The full path to the tc executable to use |
120 | -v, --verbose Show the commands that are being run | 124 | -v, --verbose Show the commands that are being run |
125 | -N, --notap Suppress tap results for command under test | ||
121 | -d DEVICE, --device DEVICE | 126 | -d DEVICE, --device DEVICE |
122 | Execute the test case in flower category | 127 | Execute the test case in flower category |
128 | -P, --pause Pause execution just before post-suite stage | ||
123 | 129 | ||
124 | selection: | 130 | selection: |
125 | select which test cases: files plus directories; filtered by categories | 131 | select which test cases: files plus directories; filtered by categories |
@@ -146,10 +152,10 @@ action: | |||
146 | -i, --id Generate ID numbers for new test cases | 152 | -i, --id Generate ID numbers for new test cases |
147 | 153 | ||
148 | netns: | 154 | netns: |
149 | options for nsPlugin(run commands in net namespace) | 155 | options for nsPlugin (run commands in net namespace) |
150 | 156 | ||
151 | -n NS, --namespace NS | 157 | -n, --namespace |
152 | Run commands in namespace NS | 158 | Run commands in namespace as specified in tdc_config.py |
153 | 159 | ||
154 | valgrind: | 160 | valgrind: |
155 | options for valgrindPlugin (run command under test under Valgrind) | 161 | options for valgrindPlugin (run command under test under Valgrind) |
diff --git a/tools/testing/selftests/tc-testing/config b/tools/testing/selftests/tc-testing/config new file mode 100644 index 000000000000..203302065458 --- /dev/null +++ b/tools/testing/selftests/tc-testing/config | |||
@@ -0,0 +1,48 @@ | |||
1 | CONFIG_NET_SCHED=y | ||
2 | |||
3 | # | ||
4 | # Queueing/Scheduling | ||
5 | # | ||
6 | CONFIG_NET_SCH_PRIO=m | ||
7 | CONFIG_NET_SCH_INGRESS=m | ||
8 | |||
9 | # | ||
10 | # Classification | ||
11 | # | ||
12 | CONFIG_NET_CLS=y | ||
13 | CONFIG_NET_CLS_FW=m | ||
14 | CONFIG_NET_CLS_U32=m | ||
15 | CONFIG_CLS_U32_PERF=y | ||
16 | CONFIG_CLS_U32_MARK=y | ||
17 | CONFIG_NET_EMATCH=y | ||
18 | CONFIG_NET_EMATCH_STACK=32 | ||
19 | CONFIG_NET_EMATCH_CMP=m | ||
20 | CONFIG_NET_EMATCH_NBYTE=m | ||
21 | CONFIG_NET_EMATCH_U32=m | ||
22 | CONFIG_NET_EMATCH_META=m | ||
23 | CONFIG_NET_EMATCH_TEXT=m | ||
24 | CONFIG_NET_EMATCH_IPSET=m | ||
25 | CONFIG_NET_EMATCH_IPT=m | ||
26 | CONFIG_NET_CLS_ACT=y | ||
27 | CONFIG_NET_ACT_POLICE=m | ||
28 | CONFIG_NET_ACT_GACT=m | ||
29 | CONFIG_GACT_PROB=y | ||
30 | CONFIG_NET_ACT_MIRRED=m | ||
31 | CONFIG_NET_ACT_SAMPLE=m | ||
32 | CONFIG_NET_ACT_IPT=m | ||
33 | CONFIG_NET_ACT_NAT=m | ||
34 | CONFIG_NET_ACT_PEDIT=m | ||
35 | CONFIG_NET_ACT_SIMP=m | ||
36 | CONFIG_NET_ACT_SKBEDIT=m | ||
37 | CONFIG_NET_ACT_CSUM=m | ||
38 | CONFIG_NET_ACT_VLAN=m | ||
39 | CONFIG_NET_ACT_BPF=m | ||
40 | CONFIG_NET_ACT_CONNMARK=m | ||
41 | CONFIG_NET_ACT_SKBMOD=m | ||
42 | CONFIG_NET_ACT_IFE=m | ||
43 | CONFIG_NET_ACT_TUNNEL_KEY=m | ||
44 | CONFIG_NET_IFE_SKBMARK=m | ||
45 | CONFIG_NET_IFE_SKBPRIO=m | ||
46 | CONFIG_NET_IFE_SKBTCINDEX=m | ||
47 | CONFIG_NET_CLS_IND=y | ||
48 | CONFIG_NET_SCH_FIFO=y | ||
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json index 70952bd98ff9..13147a1f5731 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json | |||
@@ -17,7 +17,7 @@ | |||
17 | "cmdUnderTest": "$TC actions add action connmark", | 17 | "cmdUnderTest": "$TC actions add action connmark", |
18 | "expExitCode": "0", | 18 | "expExitCode": "0", |
19 | "verifyCmd": "$TC actions list action connmark", | 19 | "verifyCmd": "$TC actions list action connmark", |
20 | "matchPattern": "action order [0-9]+: connmark zone 0 pipe", | 20 | "matchPattern": "action order [0-9]+: connmark zone 0 pipe", |
21 | "matchCount": "1", | 21 | "matchCount": "1", |
22 | "teardown": [ | 22 | "teardown": [ |
23 | "$TC actions flush action connmark" | 23 | "$TC actions flush action connmark" |
@@ -41,7 +41,7 @@ | |||
41 | "cmdUnderTest": "$TC actions add action connmark pass index 1", | 41 | "cmdUnderTest": "$TC actions add action connmark pass index 1", |
42 | "expExitCode": "0", | 42 | "expExitCode": "0", |
43 | "verifyCmd": "$TC actions get action connmark index 1", | 43 | "verifyCmd": "$TC actions get action connmark index 1", |
44 | "matchPattern": "action order [0-9]+: connmark zone 0 pass.*index 1 ref", | 44 | "matchPattern": "action order [0-9]+: connmark zone 0 pass.*index 1 ref", |
45 | "matchCount": "1", | 45 | "matchCount": "1", |
46 | "teardown": [ | 46 | "teardown": [ |
47 | "$TC actions flush action connmark" | 47 | "$TC actions flush action connmark" |
@@ -65,7 +65,7 @@ | |||
65 | "cmdUnderTest": "$TC actions add action connmark drop index 100", | 65 | "cmdUnderTest": "$TC actions add action connmark drop index 100", |
66 | "expExitCode": "0", | 66 | "expExitCode": "0", |
67 | "verifyCmd": "$TC actions get action connmark index 100", | 67 | "verifyCmd": "$TC actions get action connmark index 100", |
68 | "matchPattern": "action order [0-9]+: connmark zone 0 drop.*index 100 ref", | 68 | "matchPattern": "action order [0-9]+: connmark zone 0 drop.*index 100 ref", |
69 | "matchCount": "1", | 69 | "matchCount": "1", |
70 | "teardown": [ | 70 | "teardown": [ |
71 | "$TC actions flush action connmark" | 71 | "$TC actions flush action connmark" |
@@ -89,7 +89,7 @@ | |||
89 | "cmdUnderTest": "$TC actions add action connmark pipe index 455", | 89 | "cmdUnderTest": "$TC actions add action connmark pipe index 455", |
90 | "expExitCode": "0", | 90 | "expExitCode": "0", |
91 | "verifyCmd": "$TC actions get action connmark index 455", | 91 | "verifyCmd": "$TC actions get action connmark index 455", |
92 | "matchPattern": "action order [0-9]+: connmark zone 0 pipe.*index 455 ref", | 92 | "matchPattern": "action order [0-9]+: connmark zone 0 pipe.*index 455 ref", |
93 | "matchCount": "1", | 93 | "matchCount": "1", |
94 | "teardown": [ | 94 | "teardown": [ |
95 | "$TC actions flush action connmark" | 95 | "$TC actions flush action connmark" |
@@ -113,7 +113,7 @@ | |||
113 | "cmdUnderTest": "$TC actions add action connmark reclassify index 7", | 113 | "cmdUnderTest": "$TC actions add action connmark reclassify index 7", |
114 | "expExitCode": "0", | 114 | "expExitCode": "0", |
115 | "verifyCmd": "$TC actions list action connmark", | 115 | "verifyCmd": "$TC actions list action connmark", |
116 | "matchPattern": "action order [0-9]+: connmark zone 0 reclassify.*index 7 ref", | 116 | "matchPattern": "action order [0-9]+: connmark zone 0 reclassify.*index 7 ref", |
117 | "matchCount": "1", | 117 | "matchCount": "1", |
118 | "teardown": [ | 118 | "teardown": [ |
119 | "$TC actions flush action connmark" | 119 | "$TC actions flush action connmark" |
@@ -137,7 +137,7 @@ | |||
137 | "cmdUnderTest": "$TC actions add action connmark continue index 17", | 137 | "cmdUnderTest": "$TC actions add action connmark continue index 17", |
138 | "expExitCode": "0", | 138 | "expExitCode": "0", |
139 | "verifyCmd": "$TC actions list action connmark", | 139 | "verifyCmd": "$TC actions list action connmark", |
140 | "matchPattern": "action order [0-9]+: connmark zone 0 continue.*index 17 ref", | 140 | "matchPattern": "action order [0-9]+: connmark zone 0 continue.*index 17 ref", |
141 | "matchCount": "1", | 141 | "matchCount": "1", |
142 | "teardown": [ | 142 | "teardown": [ |
143 | "$TC actions flush action connmark" | 143 | "$TC actions flush action connmark" |
@@ -161,7 +161,7 @@ | |||
161 | "cmdUnderTest": "$TC actions add action connmark jump 10 index 17", | 161 | "cmdUnderTest": "$TC actions add action connmark jump 10 index 17", |
162 | "expExitCode": "0", | 162 | "expExitCode": "0", |
163 | "verifyCmd": "$TC actions list action connmark", | 163 | "verifyCmd": "$TC actions list action connmark", |
164 | "matchPattern": "action order [0-9]+: connmark zone 0 jump 10.*index 17 ref", | 164 | "matchPattern": "action order [0-9]+: connmark zone 0 jump 10.*index 17 ref", |
165 | "matchCount": "1", | 165 | "matchCount": "1", |
166 | "teardown": [ | 166 | "teardown": [ |
167 | "$TC actions flush action connmark" | 167 | "$TC actions flush action connmark" |
@@ -185,7 +185,7 @@ | |||
185 | "cmdUnderTest": "$TC actions add action connmark zone 100 pipe index 1", | 185 | "cmdUnderTest": "$TC actions add action connmark zone 100 pipe index 1", |
186 | "expExitCode": "0", | 186 | "expExitCode": "0", |
187 | "verifyCmd": "$TC actions get action connmark index 1", | 187 | "verifyCmd": "$TC actions get action connmark index 1", |
188 | "matchPattern": "action order [0-9]+: connmark zone 100 pipe.*index 1 ref", | 188 | "matchPattern": "action order [0-9]+: connmark zone 100 pipe.*index 1 ref", |
189 | "matchCount": "1", | 189 | "matchCount": "1", |
190 | "teardown": [ | 190 | "teardown": [ |
191 | "$TC actions flush action connmark" | 191 | "$TC actions flush action connmark" |
@@ -209,7 +209,7 @@ | |||
209 | "cmdUnderTest": "$TC actions add action connmark zone 65536 reclassify index 21", | 209 | "cmdUnderTest": "$TC actions add action connmark zone 65536 reclassify index 21", |
210 | "expExitCode": "255", | 210 | "expExitCode": "255", |
211 | "verifyCmd": "$TC actions get action connmark index 1", | 211 | "verifyCmd": "$TC actions get action connmark index 1", |
212 | "matchPattern": "action order [0-9]+: connmark zone 65536 reclassify.*index 21 ref", | 212 | "matchPattern": "action order [0-9]+: connmark zone 65536 reclassify.*index 21 ref", |
213 | "matchCount": "0", | 213 | "matchCount": "0", |
214 | "teardown": [ | 214 | "teardown": [ |
215 | "$TC actions flush action connmark" | 215 | "$TC actions flush action connmark" |
@@ -233,7 +233,7 @@ | |||
233 | "cmdUnderTest": "$TC actions add action connmark zone 655 unsupp_arg pass index 2", | 233 | "cmdUnderTest": "$TC actions add action connmark zone 655 unsupp_arg pass index 2", |
234 | "expExitCode": "255", | 234 | "expExitCode": "255", |
235 | "verifyCmd": "$TC actions get action connmark index 2", | 235 | "verifyCmd": "$TC actions get action connmark index 2", |
236 | "matchPattern": "action order [0-9]+: connmark zone 655 unsupp_arg pass.*index 2 ref", | 236 | "matchPattern": "action order [0-9]+: connmark zone 655 unsupp_arg pass.*index 2 ref", |
237 | "matchCount": "0", | 237 | "matchCount": "0", |
238 | "teardown": [ | 238 | "teardown": [ |
239 | "$TC actions flush action connmark" | 239 | "$TC actions flush action connmark" |
@@ -258,7 +258,7 @@ | |||
258 | "cmdUnderTest": "$TC actions replace action connmark zone 555 reclassify index 555", | 258 | "cmdUnderTest": "$TC actions replace action connmark zone 555 reclassify index 555", |
259 | "expExitCode": "0", | 259 | "expExitCode": "0", |
260 | "verifyCmd": "$TC actions get action connmark index 555", | 260 | "verifyCmd": "$TC actions get action connmark index 555", |
261 | "matchPattern": "action order [0-9]+: connmark zone 555 reclassify.*index 555 ref", | 261 | "matchPattern": "action order [0-9]+: connmark zone 555 reclassify.*index 555 ref", |
262 | "matchCount": "1", | 262 | "matchCount": "1", |
263 | "teardown": [ | 263 | "teardown": [ |
264 | "$TC actions flush action connmark" | 264 | "$TC actions flush action connmark" |
@@ -282,7 +282,7 @@ | |||
282 | "cmdUnderTest": "$TC actions add action connmark zone 555 pipe index 5 cookie aabbccddeeff112233445566778800a1", | 282 | "cmdUnderTest": "$TC actions add action connmark zone 555 pipe index 5 cookie aabbccddeeff112233445566778800a1", |
283 | "expExitCode": "0", | 283 | "expExitCode": "0", |
284 | "verifyCmd": "$TC actions get action connmark index 5", | 284 | "verifyCmd": "$TC actions get action connmark index 5", |
285 | "matchPattern": "action order [0-9]+: connmark zone 555 pipe.*index 5 ref.*cookie aabbccddeeff112233445566778800a1", | 285 | "matchPattern": "action order [0-9]+: connmark zone 555 pipe.*index 5 ref.*cookie aabbccddeeff112233445566778800a1", |
286 | "matchCount": "1", | 286 | "matchCount": "1", |
287 | "teardown": [ | 287 | "teardown": [ |
288 | "$TC actions flush action connmark" | 288 | "$TC actions flush action connmark" |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json index 3a2f51fc7fd4..a022792d392a 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json | |||
@@ -336,6 +336,30 @@ | |||
336 | ] | 336 | ] |
337 | }, | 337 | }, |
338 | { | 338 | { |
339 | "id": "b10b", | ||
340 | "name": "Add all 7 csum actions", | ||
341 | "category": [ | ||
342 | "actions", | ||
343 | "csum" | ||
344 | ], | ||
345 | "setup": [ | ||
346 | [ | ||
347 | "$TC actions flush action csum", | ||
348 | 0, | ||
349 | 1, | ||
350 | 255 | ||
351 | ] | ||
352 | ], | ||
353 | "cmdUnderTest": "$TC actions add action csum icmp ip4h sctp igmp udplite udp tcp index 7", | ||
354 | "expExitCode": "0", | ||
355 | "verifyCmd": "$TC actions get action csum index 7", | ||
356 | "matchPattern": "action order [0-9]*: csum \\(iph, icmp, igmp, tcp, udp, udplite, sctp\\).*index 7 ref", | ||
357 | "matchCount": "1", | ||
358 | "teardown": [ | ||
359 | "$TC actions flush action csum" | ||
360 | ] | ||
361 | }, | ||
362 | { | ||
339 | "id": "ce92", | 363 | "id": "ce92", |
340 | "name": "Add csum udp action with cookie", | 364 | "name": "Add csum udp action with cookie", |
341 | "category": [ | 365 | "category": [ |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json index 6e4edfae1799..db49fd0f8445 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json | |||
@@ -44,7 +44,8 @@ | |||
44 | "matchPattern": "action order [0-9]*: mirred \\(Egress Redirect to device lo\\).*index 2 ref", | 44 | "matchPattern": "action order [0-9]*: mirred \\(Egress Redirect to device lo\\).*index 2 ref", |
45 | "matchCount": "1", | 45 | "matchCount": "1", |
46 | "teardown": [ | 46 | "teardown": [ |
47 | "$TC actions flush action mirred" | 47 | "$TC actions flush action mirred", |
48 | "$TC actions flush action gact" | ||
48 | ] | 49 | ] |
49 | }, | 50 | }, |
50 | { | 51 | { |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json b/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json new file mode 100644 index 000000000000..0080dc2fd41c --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json | |||
@@ -0,0 +1,593 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "7565", | ||
4 | "name": "Add nat action on ingress with default control action", | ||
5 | "category": [ | ||
6 | "actions", | ||
7 | "nat" | ||
8 | ], | ||
9 | "setup": [ | ||
10 | [ | ||
11 | "$TC actions flush action nat", | ||
12 | 0, | ||
13 | 1, | ||
14 | 255 | ||
15 | ] | ||
16 | ], | ||
17 | "cmdUnderTest": "$TC actions add action nat ingress 192.168.1.1 200.200.200.1", | ||
18 | "expExitCode": "0", | ||
19 | "verifyCmd": "$TC actions ls action nat", | ||
20 | "matchPattern": "action order [0-9]+: nat ingress 192.168.1.1/32 200.200.200.1 pass", | ||
21 | "matchCount": "1", | ||
22 | "teardown": [ | ||
23 | "$TC actions flush action nat" | ||
24 | ] | ||
25 | }, | ||
26 | { | ||
27 | "id": "fd79", | ||
28 | "name": "Add nat action on ingress with pipe control action", | ||
29 | "category": [ | ||
30 | "actions", | ||
31 | "nat" | ||
32 | ], | ||
33 | "setup": [ | ||
34 | [ | ||
35 | "$TC actions flush action nat", | ||
36 | 0, | ||
37 | 1, | ||
38 | 255 | ||
39 | ] | ||
40 | ], | ||
41 | "cmdUnderTest": "$TC actions add action nat ingress 1.1.1.1 2.2.2.1 pipe index 77", | ||
42 | "expExitCode": "0", | ||
43 | "verifyCmd": "$TC actions get action nat index 77", | ||
44 | "matchPattern": "action order [0-9]+: nat ingress 1.1.1.1/32 2.2.2.1 pipe.*index 77 ref", | ||
45 | "matchCount": "1", | ||
46 | "teardown": [ | ||
47 | "$TC actions flush action nat" | ||
48 | ] | ||
49 | }, | ||
50 | { | ||
51 | "id": "eab9", | ||
52 | "name": "Add nat action on ingress with continue control action", | ||
53 | "category": [ | ||
54 | "actions", | ||
55 | "nat" | ||
56 | ], | ||
57 | "setup": [ | ||
58 | [ | ||
59 | "$TC actions flush action nat", | ||
60 | 0, | ||
61 | 1, | ||
62 | 255 | ||
63 | ] | ||
64 | ], | ||
65 | "cmdUnderTest": "$TC actions add action nat ingress 192.168.10.10 192.168.20.20 continue index 1000", | ||
66 | "expExitCode": "0", | ||
67 | "verifyCmd": "$TC actions get action nat index 1000", | ||
68 | "matchPattern": "action order [0-9]+: nat ingress 192.168.10.10/32 192.168.20.20 continue.*index 1000 ref", | ||
69 | "matchCount": "1", | ||
70 | "teardown": [ | ||
71 | "$TC actions flush action nat" | ||
72 | ] | ||
73 | }, | ||
74 | { | ||
75 | "id": "c53a", | ||
76 | "name": "Add nat action on ingress with reclassify control action", | ||
77 | "category": [ | ||
78 | "actions", | ||
79 | "nat" | ||
80 | ], | ||
81 | "setup": [ | ||
82 | [ | ||
83 | "$TC actions flush action nat", | ||
84 | 0, | ||
85 | 1, | ||
86 | 255 | ||
87 | ] | ||
88 | ], | ||
89 | "cmdUnderTest": "$TC actions add action nat ingress 192.168.10.10 192.168.20.20 reclassify index 1000", | ||
90 | "expExitCode": "0", | ||
91 | "verifyCmd": "$TC actions get action nat index 1000", | ||
92 | "matchPattern": "action order [0-9]+: nat ingress 192.168.10.10/32 192.168.20.20 reclassify.*index 1000 ref", | ||
93 | "matchCount": "1", | ||
94 | "teardown": [ | ||
95 | "$TC actions flush action nat" | ||
96 | ] | ||
97 | }, | ||
98 | { | ||
99 | "id": "76c9", | ||
100 | "name": "Add nat action on ingress with jump control action", | ||
101 | "category": [ | ||
102 | "actions", | ||
103 | "nat" | ||
104 | ], | ||
105 | "setup": [ | ||
106 | [ | ||
107 | "$TC actions flush action nat", | ||
108 | 0, | ||
109 | 1, | ||
110 | 255 | ||
111 | ] | ||
112 | ], | ||
113 | "cmdUnderTest": "$TC actions add action nat ingress 12.18.10.10 12.18.20.20 jump 10 index 22", | ||
114 | "expExitCode": "0", | ||
115 | "verifyCmd": "$TC actions get action nat index 22", | ||
116 | "matchPattern": "action order [0-9]+: nat ingress 12.18.10.10/32 12.18.20.20 jump 10.*index 22 ref", | ||
117 | "matchCount": "1", | ||
118 | "teardown": [ | ||
119 | "$TC actions flush action nat" | ||
120 | ] | ||
121 | }, | ||
122 | { | ||
123 | "id": "24c6", | ||
124 | "name": "Add nat action on ingress with drop control action", | ||
125 | "category": [ | ||
126 | "actions", | ||
127 | "nat" | ||
128 | ], | ||
129 | "setup": [ | ||
130 | [ | ||
131 | "$TC actions flush action nat", | ||
132 | 0, | ||
133 | 1, | ||
134 | 255 | ||
135 | ] | ||
136 | ], | ||
137 | "cmdUnderTest": "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 drop index 722", | ||
138 | "expExitCode": "0", | ||
139 | "verifyCmd": "$TC actions get action nat index 722", | ||
140 | "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 drop.*index 722 ref", | ||
141 | "matchCount": "1", | ||
142 | "teardown": [ | ||
143 | "$TC actions flush action nat" | ||
144 | ] | ||
145 | }, | ||
146 | { | ||
147 | "id": "2120", | ||
148 | "name": "Add nat action on ingress with maximum index value", | ||
149 | "category": [ | ||
150 | "actions", | ||
151 | "nat" | ||
152 | ], | ||
153 | "setup": [ | ||
154 | [ | ||
155 | "$TC actions flush action nat", | ||
156 | 0, | ||
157 | 1, | ||
158 | 255 | ||
159 | ] | ||
160 | ], | ||
161 | "cmdUnderTest": "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 index 4294967295", | ||
162 | "expExitCode": "0", | ||
163 | "verifyCmd": "$TC actions get action nat index 4294967295", | ||
164 | "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 pass.*index 4294967295 ref", | ||
165 | "matchCount": "1", | ||
166 | "teardown": [ | ||
167 | "$TC actions flush action nat" | ||
168 | ] | ||
169 | }, | ||
170 | { | ||
171 | "id": "3e9d", | ||
172 | "name": "Add nat action on ingress with invalid index value", | ||
173 | "category": [ | ||
174 | "actions", | ||
175 | "nat" | ||
176 | ], | ||
177 | "setup": [ | ||
178 | [ | ||
179 | "$TC actions flush action nat", | ||
180 | 0, | ||
181 | 1, | ||
182 | 255 | ||
183 | ] | ||
184 | ], | ||
185 | "cmdUnderTest": "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 index 4294967295555", | ||
186 | "expExitCode": "255", | ||
187 | "verifyCmd": "$TC actions get action nat index 4294967295555", | ||
188 | "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 pass.*index 4294967295555 ref", | ||
189 | "matchCount": "0", | ||
190 | "teardown": [ | ||
191 | [ | ||
192 | "$TC actions flush action nat", | ||
193 | 0, | ||
194 | 1, | ||
195 | 255 | ||
196 | ] | ||
197 | ] | ||
198 | }, | ||
199 | { | ||
200 | "id": "f6c9", | ||
201 | "name": "Add nat action on ingress with invalid IP address", | ||
202 | "category": [ | ||
203 | "actions", | ||
204 | "nat" | ||
205 | ], | ||
206 | "setup": [ | ||
207 | [ | ||
208 | "$TC actions flush action nat", | ||
209 | 0, | ||
210 | 1, | ||
211 | 255 | ||
212 | ] | ||
213 | ], | ||
214 | "cmdUnderTest": "$TC actions add action nat ingress 1.1.1.1 1.1888.2.2 index 7", | ||
215 | "expExitCode": "255", | ||
216 | "verifyCmd": "$TC actions get action nat index 7", | ||
217 | "matchPattern": "action order [0-9]+: nat ingress 1.1.1.1/32 1.1888.2.2 pass.*index 7 ref", | ||
218 | "matchCount": "0", | ||
219 | "teardown": [ | ||
220 | [ | ||
221 | "$TC actions flush action nat", | ||
222 | 0, | ||
223 | 1, | ||
224 | 255 | ||
225 | ] | ||
226 | ] | ||
227 | }, | ||
228 | { | ||
229 | "id": "be25", | ||
230 | "name": "Add nat action on ingress with invalid argument", | ||
231 | "category": [ | ||
232 | "actions", | ||
233 | "nat" | ||
234 | ], | ||
235 | "setup": [ | ||
236 | [ | ||
237 | "$TC actions flush action nat", | ||
238 | 0, | ||
239 | 1, | ||
240 | 255 | ||
241 | ] | ||
242 | ], | ||
243 | "cmdUnderTest": "$TC actions add action nat ingress 1.1.1.1 1.18.2.2 another_arg index 12", | ||
244 | "expExitCode": "255", | ||
245 | "verifyCmd": "$TC actions get action nat index 12", | ||
246 | "matchPattern": "action order [0-9]+: nat ingress 1.1.1.1/32 1.18.2.2 pass.*another_arg.*index 12 ref", | ||
247 | "matchCount": "0", | ||
248 | "teardown": [ | ||
249 | [ | ||
250 | "$TC actions flush action nat", | ||
251 | 0, | ||
252 | 1, | ||
253 | 255 | ||
254 | ] | ||
255 | ] | ||
256 | }, | ||
257 | { | ||
258 | "id": "a7bd", | ||
259 | "name": "Add nat action on ingress with DEFAULT IP address", | ||
260 | "category": [ | ||
261 | "actions", | ||
262 | "nat" | ||
263 | ], | ||
264 | "setup": [ | ||
265 | [ | ||
266 | "$TC actions flush action nat", | ||
267 | 0, | ||
268 | 1, | ||
269 | 255 | ||
270 | ] | ||
271 | ], | ||
272 | "cmdUnderTest": "$TC actions add action nat ingress default 10.10.10.1 index 12", | ||
273 | "expExitCode": "0", | ||
274 | "verifyCmd": "$TC actions get action nat index 12", | ||
275 | "matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref", | ||
276 | "matchCount": "1", | ||
277 | "teardown": [ | ||
278 | "$TC actions flush action nat" | ||
279 | ] | ||
280 | }, | ||
281 | { | ||
282 | "id": "ee1e", | ||
283 | "name": "Add nat action on ingress with ANY IP address", | ||
284 | "category": [ | ||
285 | "actions", | ||
286 | "nat" | ||
287 | ], | ||
288 | "setup": [ | ||
289 | [ | ||
290 | "$TC actions flush action nat", | ||
291 | 0, | ||
292 | 1, | ||
293 | 255 | ||
294 | ] | ||
295 | ], | ||
296 | "cmdUnderTest": "$TC actions add action nat ingress any 10.10.10.1 index 12", | ||
297 | "expExitCode": "0", | ||
298 | "verifyCmd": "$TC actions get action nat index 12", | ||
299 | "matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref", | ||
300 | "matchCount": "1", | ||
301 | "teardown": [ | ||
302 | "$TC actions flush action nat" | ||
303 | ] | ||
304 | }, | ||
305 | { | ||
306 | "id": "1de8", | ||
307 | "name": "Add nat action on ingress with ALL IP address", | ||
308 | "category": [ | ||
309 | "actions", | ||
310 | "nat" | ||
311 | ], | ||
312 | "setup": [ | ||
313 | [ | ||
314 | "$TC actions flush action nat", | ||
315 | 0, | ||
316 | 1, | ||
317 | 255 | ||
318 | ] | ||
319 | ], | ||
320 | "cmdUnderTest": "$TC actions add action nat ingress all 10.10.10.1 index 12", | ||
321 | "expExitCode": "0", | ||
322 | "verifyCmd": "$TC actions get action nat index 12", | ||
323 | "matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref", | ||
324 | "matchCount": "1", | ||
325 | "teardown": [ | ||
326 | "$TC actions flush action nat" | ||
327 | ] | ||
328 | }, | ||
329 | { | ||
330 | "id": "8dba", | ||
331 | "name": "Add nat action on egress with default control action", | ||
332 | "category": [ | ||
333 | "actions", | ||
334 | "nat" | ||
335 | ], | ||
336 | "setup": [ | ||
337 | [ | ||
338 | "$TC actions flush action nat", | ||
339 | 0, | ||
340 | 1, | ||
341 | 255 | ||
342 | ] | ||
343 | ], | ||
344 | "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1", | ||
345 | "expExitCode": "0", | ||
346 | "verifyCmd": "$TC actions ls action nat", | ||
347 | "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 pass", | ||
348 | "matchCount": "1", | ||
349 | "teardown": [ | ||
350 | "$TC actions flush action nat" | ||
351 | ] | ||
352 | }, | ||
353 | { | ||
354 | "id": "19a7", | ||
355 | "name": "Add nat action on egress with pipe control action", | ||
356 | "category": [ | ||
357 | "actions", | ||
358 | "nat" | ||
359 | ], | ||
360 | "setup": [ | ||
361 | [ | ||
362 | "$TC actions flush action nat", | ||
363 | 0, | ||
364 | 1, | ||
365 | 255 | ||
366 | ] | ||
367 | ], | ||
368 | "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 pipe", | ||
369 | "expExitCode": "0", | ||
370 | "verifyCmd": "$TC actions ls action nat", | ||
371 | "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 pipe", | ||
372 | "matchCount": "1", | ||
373 | "teardown": [ | ||
374 | "$TC actions flush action nat" | ||
375 | ] | ||
376 | }, | ||
377 | { | ||
378 | "id": "f1d9", | ||
379 | "name": "Add nat action on egress with continue control action", | ||
380 | "category": [ | ||
381 | "actions", | ||
382 | "nat" | ||
383 | ], | ||
384 | "setup": [ | ||
385 | [ | ||
386 | "$TC actions flush action nat", | ||
387 | 0, | ||
388 | 1, | ||
389 | 255 | ||
390 | ] | ||
391 | ], | ||
392 | "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 continue", | ||
393 | "expExitCode": "0", | ||
394 | "verifyCmd": "$TC actions ls action nat", | ||
395 | "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 continue", | ||
396 | "matchCount": "1", | ||
397 | "teardown": [ | ||
398 | "$TC actions flush action nat" | ||
399 | ] | ||
400 | }, | ||
401 | { | ||
402 | "id": "6d4a", | ||
403 | "name": "Add nat action on egress with reclassify control action", | ||
404 | "category": [ | ||
405 | "actions", | ||
406 | "nat" | ||
407 | ], | ||
408 | "setup": [ | ||
409 | [ | ||
410 | "$TC actions flush action nat", | ||
411 | 0, | ||
412 | 1, | ||
413 | 255 | ||
414 | ] | ||
415 | ], | ||
416 | "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 reclassify", | ||
417 | "expExitCode": "0", | ||
418 | "verifyCmd": "$TC actions ls action nat", | ||
419 | "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 reclassify", | ||
420 | "matchCount": "1", | ||
421 | "teardown": [ | ||
422 | "$TC actions flush action nat" | ||
423 | ] | ||
424 | }, | ||
425 | { | ||
426 | "id": "b313", | ||
427 | "name": "Add nat action on egress with jump control action", | ||
428 | "category": [ | ||
429 | "actions", | ||
430 | "nat" | ||
431 | ], | ||
432 | "setup": [ | ||
433 | [ | ||
434 | "$TC actions flush action nat", | ||
435 | 0, | ||
436 | 1, | ||
437 | 255 | ||
438 | ] | ||
439 | ], | ||
440 | "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 jump 777", | ||
441 | "expExitCode": "0", | ||
442 | "verifyCmd": "$TC actions ls action nat", | ||
443 | "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 jump 777", | ||
444 | "matchCount": "1", | ||
445 | "teardown": [ | ||
446 | "$TC actions flush action nat" | ||
447 | ] | ||
448 | }, | ||
449 | { | ||
450 | "id": "d9fc", | ||
451 | "name": "Add nat action on egress with drop control action", | ||
452 | "category": [ | ||
453 | "actions", | ||
454 | "nat" | ||
455 | ], | ||
456 | "setup": [ | ||
457 | [ | ||
458 | "$TC actions flush action nat", | ||
459 | 0, | ||
460 | 1, | ||
461 | 255 | ||
462 | ] | ||
463 | ], | ||
464 | "cmdUnderTest": "$TC actions add action nat egress 10.10.10.1 20.20.20.1 drop", | ||
465 | "expExitCode": "0", | ||
466 | "verifyCmd": "$TC actions ls action nat", | ||
467 | "matchPattern": "action order [0-9]+: nat egress 10.10.10.1/32 20.20.20.1 drop", | ||
468 | "matchCount": "1", | ||
469 | "teardown": [ | ||
470 | "$TC actions flush action nat" | ||
471 | ] | ||
472 | }, | ||
473 | { | ||
474 | "id": "a895", | ||
475 | "name": "Add nat action on egress with DEFAULT IP address", | ||
476 | "category": [ | ||
477 | "actions", | ||
478 | "nat" | ||
479 | ], | ||
480 | "setup": [ | ||
481 | [ | ||
482 | "$TC actions flush action nat", | ||
483 | 0, | ||
484 | 1, | ||
485 | 255 | ||
486 | ] | ||
487 | ], | ||
488 | "cmdUnderTest": "$TC actions add action nat egress default 20.20.20.1 pipe index 10", | ||
489 | "expExitCode": "0", | ||
490 | "verifyCmd": "$TC actions get action nat index 10", | ||
491 | "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref", | ||
492 | "matchCount": "1", | ||
493 | "teardown": [ | ||
494 | "$TC actions flush action nat" | ||
495 | ] | ||
496 | }, | ||
497 | { | ||
498 | "id": "2572", | ||
499 | "name": "Add nat action on egress with ANY IP address", | ||
500 | "category": [ | ||
501 | "actions", | ||
502 | "nat" | ||
503 | ], | ||
504 | "setup": [ | ||
505 | [ | ||
506 | "$TC actions flush action nat", | ||
507 | 0, | ||
508 | 1, | ||
509 | 255 | ||
510 | ] | ||
511 | ], | ||
512 | "cmdUnderTest": "$TC actions add action nat egress any 20.20.20.1 pipe index 10", | ||
513 | "expExitCode": "0", | ||
514 | "verifyCmd": "$TC actions get action nat index 10", | ||
515 | "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref", | ||
516 | "matchCount": "1", | ||
517 | "teardown": [ | ||
518 | "$TC actions flush action nat" | ||
519 | ] | ||
520 | }, | ||
521 | { | ||
522 | "id": "37f3", | ||
523 | "name": "Add nat action on egress with ALL IP address", | ||
524 | "category": [ | ||
525 | "actions", | ||
526 | "nat" | ||
527 | ], | ||
528 | "setup": [ | ||
529 | [ | ||
530 | "$TC actions flush action nat", | ||
531 | 0, | ||
532 | 1, | ||
533 | 255 | ||
534 | ] | ||
535 | ], | ||
536 | "cmdUnderTest": "$TC actions add action nat egress all 20.20.20.1 pipe index 10", | ||
537 | "expExitCode": "0", | ||
538 | "verifyCmd": "$TC actions get action nat index 10", | ||
539 | "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref", | ||
540 | "matchCount": "1", | ||
541 | "teardown": [ | ||
542 | "$TC actions flush action nat" | ||
543 | ] | ||
544 | }, | ||
545 | { | ||
546 | "id": "6054", | ||
547 | "name": "Add nat action on egress with cookie", | ||
548 | "category": [ | ||
549 | "actions", | ||
550 | "nat" | ||
551 | ], | ||
552 | "setup": [ | ||
553 | [ | ||
554 | "$TC actions flush action nat", | ||
555 | 0, | ||
556 | 1, | ||
557 | 255 | ||
558 | ] | ||
559 | ], | ||
560 | "cmdUnderTest": "$TC actions add action nat egress all 20.20.20.1 pipe index 10 cookie aa1bc2d3eeff112233445566778800a1", | ||
561 | "expExitCode": "0", | ||
562 | "verifyCmd": "$TC actions get action nat index 10", | ||
563 | "matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref.*cookie aa1bc2d3eeff112233445566778800a1", | ||
564 | "matchCount": "1", | ||
565 | "teardown": [ | ||
566 | "$TC actions flush action nat" | ||
567 | ] | ||
568 | }, | ||
569 | { | ||
570 | "id": "79d6", | ||
571 | "name": "Add nat action on ingress with cookie", | ||
572 | "category": [ | ||
573 | "actions", | ||
574 | "nat" | ||
575 | ], | ||
576 | "setup": [ | ||
577 | [ | ||
578 | "$TC actions flush action nat", | ||
579 | 0, | ||
580 | 1, | ||
581 | 255 | ||
582 | ] | ||
583 | ], | ||
584 | "cmdUnderTest": "$TC actions add action nat ingress 192.168.1.1 10.10.10.1 reclassify index 1 cookie 112233445566778899aabbccddeeff11", | ||
585 | "expExitCode": "0", | ||
586 | "verifyCmd": "$TC actions get action nat index 1", | ||
587 | "matchPattern": "action order [0-9]+: nat ingress 192.168.1.1/32 10.10.10.1 reclassify.*index 1 ref.*cookie 112233445566778899aabbccddeeff11", | ||
588 | "matchCount": "1", | ||
589 | "teardown": [ | ||
590 | "$TC actions flush action nat" | ||
591 | ] | ||
592 | } | ||
593 | ] | ||
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json index 37ecc2716fee..5aaf593b914a 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json | |||
@@ -17,7 +17,7 @@ | |||
17 | "cmdUnderTest": "$TC actions add action skbedit mark 1", | 17 | "cmdUnderTest": "$TC actions add action skbedit mark 1", |
18 | "expExitCode": "0", | 18 | "expExitCode": "0", |
19 | "verifyCmd": "$TC actions list action skbedit", | 19 | "verifyCmd": "$TC actions list action skbedit", |
20 | "matchPattern": "action order [0-9]*: skbedit mark 1", | 20 | "matchPattern": "action order [0-9]*: skbedit mark 1", |
21 | "matchCount": "1", | 21 | "matchCount": "1", |
22 | "teardown": [ | 22 | "teardown": [ |
23 | "$TC actions flush action skbedit" | 23 | "$TC actions flush action skbedit" |
@@ -65,7 +65,7 @@ | |||
65 | "cmdUnderTest": "$TC actions add action skbedit prio 99", | 65 | "cmdUnderTest": "$TC actions add action skbedit prio 99", |
66 | "expExitCode": "0", | 66 | "expExitCode": "0", |
67 | "verifyCmd": "$TC actions list action skbedit", | 67 | "verifyCmd": "$TC actions list action skbedit", |
68 | "matchPattern": "action order [0-9]*: skbedit priority :99", | 68 | "matchPattern": "action order [0-9]*: skbedit priority :99", |
69 | "matchCount": "1", | 69 | "matchCount": "1", |
70 | "teardown": [ | 70 | "teardown": [ |
71 | "$TC actions flush action skbedit" | 71 | "$TC actions flush action skbedit" |
@@ -113,7 +113,7 @@ | |||
113 | "cmdUnderTest": "$TC actions add action skbedit queue_mapping 909", | 113 | "cmdUnderTest": "$TC actions add action skbedit queue_mapping 909", |
114 | "expExitCode": "0", | 114 | "expExitCode": "0", |
115 | "verifyCmd": "$TC actions list action skbedit", | 115 | "verifyCmd": "$TC actions list action skbedit", |
116 | "matchPattern": "action order [0-9]*: skbedit queue_mapping 909", | 116 | "matchPattern": "action order [0-9]*: skbedit queue_mapping 909", |
117 | "matchCount": "1", | 117 | "matchCount": "1", |
118 | "teardown": [ | 118 | "teardown": [ |
119 | "$TC actions flush action skbedit" | 119 | "$TC actions flush action skbedit" |
@@ -161,7 +161,7 @@ | |||
161 | "cmdUnderTest": "$TC actions add action skbedit ptype host", | 161 | "cmdUnderTest": "$TC actions add action skbedit ptype host", |
162 | "expExitCode": "0", | 162 | "expExitCode": "0", |
163 | "verifyCmd": "$TC actions list action skbedit", | 163 | "verifyCmd": "$TC actions list action skbedit", |
164 | "matchPattern": "action order [0-9]*: skbedit ptype host", | 164 | "matchPattern": "action order [0-9]*: skbedit ptype host", |
165 | "matchCount": "1", | 165 | "matchCount": "1", |
166 | "teardown": [ | 166 | "teardown": [ |
167 | "$TC actions flush action skbedit" | 167 | "$TC actions flush action skbedit" |
@@ -185,7 +185,7 @@ | |||
185 | "cmdUnderTest": "$TC actions add action skbedit ptype otherhost", | 185 | "cmdUnderTest": "$TC actions add action skbedit ptype otherhost", |
186 | "expExitCode": "0", | 186 | "expExitCode": "0", |
187 | "verifyCmd": "$TC actions list action skbedit", | 187 | "verifyCmd": "$TC actions list action skbedit", |
188 | "matchPattern": "action order [0-9]*: skbedit ptype otherhost", | 188 | "matchPattern": "action order [0-9]*: skbedit ptype otherhost", |
189 | "matchCount": "1", | 189 | "matchCount": "1", |
190 | "teardown": [ | 190 | "teardown": [ |
191 | "$TC actions flush action skbedit" | 191 | "$TC actions flush action skbedit" |
@@ -233,7 +233,7 @@ | |||
233 | "cmdUnderTest": "$TC actions add action skbedit ptype host pipe index 11", | 233 | "cmdUnderTest": "$TC actions add action skbedit ptype host pipe index 11", |
234 | "expExitCode": "0", | 234 | "expExitCode": "0", |
235 | "verifyCmd": "$TC actions get action skbedit index 11", | 235 | "verifyCmd": "$TC actions get action skbedit index 11", |
236 | "matchPattern": "action order [0-9]*: skbedit ptype host pipe.*index 11 ref", | 236 | "matchPattern": "action order [0-9]*: skbedit ptype host pipe.*index 11 ref", |
237 | "matchCount": "1", | 237 | "matchCount": "1", |
238 | "teardown": [ | 238 | "teardown": [ |
239 | "$TC actions flush action skbedit" | 239 | "$TC actions flush action skbedit" |
@@ -257,7 +257,7 @@ | |||
257 | "cmdUnderTest": "$TC actions add action skbedit mark 56789 reclassify index 90", | 257 | "cmdUnderTest": "$TC actions add action skbedit mark 56789 reclassify index 90", |
258 | "expExitCode": "0", | 258 | "expExitCode": "0", |
259 | "verifyCmd": "$TC actions get action skbedit index 90", | 259 | "verifyCmd": "$TC actions get action skbedit index 90", |
260 | "matchPattern": "action order [0-9]*: skbedit mark 56789 reclassify.*index 90 ref", | 260 | "matchPattern": "action order [0-9]*: skbedit mark 56789 reclassify.*index 90 ref", |
261 | "matchCount": "1", | 261 | "matchCount": "1", |
262 | "teardown": [ | 262 | "teardown": [ |
263 | "$TC actions flush action skbedit" | 263 | "$TC actions flush action skbedit" |
@@ -281,7 +281,7 @@ | |||
281 | "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 pass index 271", | 281 | "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 pass index 271", |
282 | "expExitCode": "0", | 282 | "expExitCode": "0", |
283 | "verifyCmd": "$TC actions get action skbedit index 271", | 283 | "verifyCmd": "$TC actions get action skbedit index 271", |
284 | "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 pass.*index 271 ref", | 284 | "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 pass.*index 271 ref", |
285 | "matchCount": "1", | 285 | "matchCount": "1", |
286 | "teardown": [ | 286 | "teardown": [ |
287 | "$TC actions flush action skbedit" | 287 | "$TC actions flush action skbedit" |
@@ -305,7 +305,7 @@ | |||
305 | "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 drop index 271", | 305 | "cmdUnderTest": "$TC actions add action skbedit queue_mapping 3 drop index 271", |
306 | "expExitCode": "0", | 306 | "expExitCode": "0", |
307 | "verifyCmd": "$TC actions get action skbedit index 271", | 307 | "verifyCmd": "$TC actions get action skbedit index 271", |
308 | "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 drop.*index 271 ref", | 308 | "matchPattern": "action order [0-9]*: skbedit queue_mapping 3 drop.*index 271 ref", |
309 | "matchCount": "1", | 309 | "matchCount": "1", |
310 | "teardown": [ | 310 | "teardown": [ |
311 | "$TC actions flush action skbedit" | 311 | "$TC actions flush action skbedit" |
@@ -329,7 +329,7 @@ | |||
329 | "cmdUnderTest": "$TC actions add action skbedit priority 8 jump 9 index 2", | 329 | "cmdUnderTest": "$TC actions add action skbedit priority 8 jump 9 index 2", |
330 | "expExitCode": "0", | 330 | "expExitCode": "0", |
331 | "verifyCmd": "$TC actions get action skbedit index 2", | 331 | "verifyCmd": "$TC actions get action skbedit index 2", |
332 | "matchPattern": "action order [0-9]*: skbedit priority :8 jump 9.*index 2 ref", | 332 | "matchPattern": "action order [0-9]*: skbedit priority :8 jump 9.*index 2 ref", |
333 | "matchCount": "1", | 333 | "matchCount": "1", |
334 | "teardown": [ | 334 | "teardown": [ |
335 | "$TC actions flush action skbedit" | 335 | "$TC actions flush action skbedit" |
@@ -353,7 +353,7 @@ | |||
353 | "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32", | 353 | "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32", |
354 | "expExitCode": "0", | 354 | "expExitCode": "0", |
355 | "verifyCmd": "$TC actions get action skbedit index 32", | 355 | "verifyCmd": "$TC actions get action skbedit index 32", |
356 | "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref", | 356 | "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref", |
357 | "matchCount": "1", | 357 | "matchCount": "1", |
358 | "teardown": [ | 358 | "teardown": [ |
359 | "$TC actions flush action skbedit" | 359 | "$TC actions flush action skbedit" |
@@ -377,7 +377,7 @@ | |||
377 | "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32 cookie deadbeef", | 377 | "cmdUnderTest": "$TC actions add action skbedit priority 16 continue index 32 cookie deadbeef", |
378 | "expExitCode": "0", | 378 | "expExitCode": "0", |
379 | "verifyCmd": "$TC actions get action skbedit index 32", | 379 | "verifyCmd": "$TC actions get action skbedit index 32", |
380 | "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref.*cookie deadbeef", | 380 | "matchPattern": "action order [0-9]*: skbedit priority :16 continue.*index 32 ref.*cookie deadbeef", |
381 | "matchCount": "1", | 381 | "matchCount": "1", |
382 | "teardown": [ | 382 | "teardown": [ |
383 | "$TC actions flush action skbedit" | 383 | "$TC actions flush action skbedit" |
@@ -405,7 +405,7 @@ | |||
405 | "cmdUnderTest": "$TC actions list action skbedit", | 405 | "cmdUnderTest": "$TC actions list action skbedit", |
406 | "expExitCode": "0", | 406 | "expExitCode": "0", |
407 | "verifyCmd": "$TC actions list action skbedit", | 407 | "verifyCmd": "$TC actions list action skbedit", |
408 | "matchPattern": "action order [0-9]*: skbedit", | 408 | "matchPattern": "action order [0-9]*: skbedit", |
409 | "matchCount": "4", | 409 | "matchCount": "4", |
410 | "teardown": [ | 410 | "teardown": [ |
411 | "$TC actions flush action skbedit" | 411 | "$TC actions flush action skbedit" |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json b/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json new file mode 100644 index 000000000000..10b2d894e436 --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json | |||
@@ -0,0 +1,917 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "2b11", | ||
4 | "name": "Add tunnel_key set action with mandatory parameters", | ||
5 | "category": [ | ||
6 | "actions", | ||
7 | "tunnel_key" | ||
8 | ], | ||
9 | "setup": [ | ||
10 | [ | ||
11 | "$TC actions flush action tunnel_key", | ||
12 | 0, | ||
13 | 1, | ||
14 | 255 | ||
15 | ] | ||
16 | ], | ||
17 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 id 1", | ||
18 | "expExitCode": "0", | ||
19 | "verifyCmd": "$TC actions list action tunnel_key", | ||
20 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1", | ||
21 | "matchCount": "1", | ||
22 | "teardown": [ | ||
23 | "$TC actions flush action tunnel_key" | ||
24 | ] | ||
25 | }, | ||
26 | { | ||
27 | "id": "dc6b", | ||
28 | "name": "Add tunnel_key set action with missing mandatory src_ip parameter", | ||
29 | "category": [ | ||
30 | "actions", | ||
31 | "tunnel_key" | ||
32 | ], | ||
33 | "setup": [ | ||
34 | [ | ||
35 | "$TC actions flush action tunnel_key", | ||
36 | 0, | ||
37 | 1, | ||
38 | 255 | ||
39 | ] | ||
40 | ], | ||
41 | "cmdUnderTest": "$TC actions add action tunnel_key set dst_ip 20.20.20.2 id 100", | ||
42 | "expExitCode": "255", | ||
43 | "verifyCmd": "$TC actions list action tunnel_key", | ||
44 | "matchPattern": "action order [0-9]+: tunnel_key set.*dst_ip 20.20.20.2.*key_id 100", | ||
45 | "matchCount": "0", | ||
46 | "teardown": [ | ||
47 | [ | ||
48 | "$TC actions flush action tunnel_key", | ||
49 | 0, | ||
50 | 1, | ||
51 | 255 | ||
52 | ] | ||
53 | ] | ||
54 | }, | ||
55 | { | ||
56 | "id": "7f25", | ||
57 | "name": "Add tunnel_key set action with missing mandatory dst_ip parameter", | ||
58 | "category": [ | ||
59 | "actions", | ||
60 | "tunnel_key" | ||
61 | ], | ||
62 | "setup": [ | ||
63 | [ | ||
64 | "$TC actions flush action tunnel_key", | ||
65 | 0, | ||
66 | 1, | ||
67 | 255 | ||
68 | ] | ||
69 | ], | ||
70 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 id 100", | ||
71 | "expExitCode": "255", | ||
72 | "verifyCmd": "$TC actions list action tunnel_key", | ||
73 | "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 10.10.10.1.*key_id 100", | ||
74 | "matchCount": "0", | ||
75 | "teardown": [ | ||
76 | [ | ||
77 | "$TC actions flush action tunnel_key", | ||
78 | 0, | ||
79 | 1, | ||
80 | 255 | ||
81 | ] | ||
82 | ] | ||
83 | }, | ||
84 | { | ||
85 | "id": "ba4e", | ||
86 | "name": "Add tunnel_key set action with missing mandatory id parameter", | ||
87 | "category": [ | ||
88 | "actions", | ||
89 | "tunnel_key" | ||
90 | ], | ||
91 | "setup": [ | ||
92 | [ | ||
93 | "$TC actions flush action tunnel_key", | ||
94 | 0, | ||
95 | 1, | ||
96 | 255 | ||
97 | ] | ||
98 | ], | ||
99 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2", | ||
100 | "expExitCode": "255", | ||
101 | "verifyCmd": "$TC actions list action tunnel_key", | ||
102 | "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2", | ||
103 | "matchCount": "0", | ||
104 | "teardown": [ | ||
105 | [ | ||
106 | "$TC actions flush action tunnel_key", | ||
107 | 0, | ||
108 | 1, | ||
109 | 255 | ||
110 | ] | ||
111 | ] | ||
112 | }, | ||
113 | { | ||
114 | "id": "a5e0", | ||
115 | "name": "Add tunnel_key set action with invalid src_ip parameter", | ||
116 | "category": [ | ||
117 | "actions", | ||
118 | "tunnel_key" | ||
119 | ], | ||
120 | "setup": [ | ||
121 | [ | ||
122 | "$TC actions flush action tunnel_key", | ||
123 | 0, | ||
124 | 1, | ||
125 | 255 | ||
126 | ] | ||
127 | ], | ||
128 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 300.168.100.1 dst_ip 192.168.200.1 id 7 index 1", | ||
129 | "expExitCode": "1", | ||
130 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
131 | "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 300.168.100.1.*dst_ip 192.168.200.1.*key_id 7.*index 1 ref", | ||
132 | "matchCount": "0", | ||
133 | "teardown": [ | ||
134 | [ | ||
135 | "$TC actions flush action tunnel_key", | ||
136 | 0, | ||
137 | 1, | ||
138 | 255 | ||
139 | ] | ||
140 | ] | ||
141 | }, | ||
142 | { | ||
143 | "id": "eaa8", | ||
144 | "name": "Add tunnel_key set action with invalid dst_ip parameter", | ||
145 | "category": [ | ||
146 | "actions", | ||
147 | "tunnel_key" | ||
148 | ], | ||
149 | "setup": [ | ||
150 | [ | ||
151 | "$TC actions flush action tunnel_key", | ||
152 | 0, | ||
153 | 1, | ||
154 | 255 | ||
155 | ] | ||
156 | ], | ||
157 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.100.1 dst_ip 192.168.800.1 id 10 index 11", | ||
158 | "expExitCode": "1", | ||
159 | "verifyCmd": "$TC actions get action tunnel_key index 11", | ||
160 | "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 192.168.100.1.*dst_ip 192.168.800.1.*key_id 10.*index 11 ref", | ||
161 | "matchCount": "0", | ||
162 | "teardown": [ | ||
163 | [ | ||
164 | "$TC actions flush action tunnel_key", | ||
165 | 0, | ||
166 | 1, | ||
167 | 255 | ||
168 | ] | ||
169 | ] | ||
170 | }, | ||
171 | { | ||
172 | "id": "3b09", | ||
173 | "name": "Add tunnel_key set action with invalid id parameter", | ||
174 | "category": [ | ||
175 | "actions", | ||
176 | "tunnel_key" | ||
177 | ], | ||
178 | "setup": [ | ||
179 | [ | ||
180 | "$TC actions flush action tunnel_key", | ||
181 | 0, | ||
182 | 1, | ||
183 | 255 | ||
184 | ] | ||
185 | ], | ||
186 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 112233445566778899 index 1", | ||
187 | "expExitCode": "255", | ||
188 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
189 | "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 112233445566778899.*index 1 ref", | ||
190 | "matchCount": "0", | ||
191 | "teardown": [ | ||
192 | [ | ||
193 | "$TC actions flush action tunnel_key", | ||
194 | 0, | ||
195 | 1, | ||
196 | 255 | ||
197 | ] | ||
198 | ] | ||
199 | }, | ||
200 | { | ||
201 | "id": "9625", | ||
202 | "name": "Add tunnel_key set action with invalid dst_port parameter", | ||
203 | "category": [ | ||
204 | "actions", | ||
205 | "tunnel_key" | ||
206 | ], | ||
207 | "setup": [ | ||
208 | [ | ||
209 | "$TC actions flush action tunnel_key", | ||
210 | 0, | ||
211 | 1, | ||
212 | 255 | ||
213 | ] | ||
214 | ], | ||
215 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 11 dst_port 998877 index 1", | ||
216 | "expExitCode": "255", | ||
217 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
218 | "matchPattern": "action order [0-9]+: tunnel_key set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 11.*dst_port 998877.*index 1 ref", | ||
219 | "matchCount": "0", | ||
220 | "teardown": [ | ||
221 | [ | ||
222 | "$TC actions flush action tunnel_key", | ||
223 | 0, | ||
224 | 1, | ||
225 | 255 | ||
226 | ] | ||
227 | ] | ||
228 | }, | ||
229 | { | ||
230 | "id": "05af", | ||
231 | "name": "Add tunnel_key set action with optional dst_port parameter", | ||
232 | "category": [ | ||
233 | "actions", | ||
234 | "tunnel_key" | ||
235 | ], | ||
236 | "setup": [ | ||
237 | [ | ||
238 | "$TC actions flush action tunnel_key", | ||
239 | 0, | ||
240 | 1, | ||
241 | 255 | ||
242 | ] | ||
243 | ], | ||
244 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.100.1 dst_ip 192.168.200.1 id 789 dst_port 4000 index 10", | ||
245 | "expExitCode": "0", | ||
246 | "verifyCmd": "$TC actions get action tunnel_key index 10", | ||
247 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 192.168.100.1.*dst_ip 192.168.200.1.*key_id 789.*dst_port 4000.*index 10 ref", | ||
248 | "matchCount": "1", | ||
249 | "teardown": [ | ||
250 | "$TC actions flush action tunnel_key" | ||
251 | ] | ||
252 | }, | ||
253 | { | ||
254 | "id": "da80", | ||
255 | "name": "Add tunnel_key set action with index at 32-bit maximum", | ||
256 | "category": [ | ||
257 | "actions", | ||
258 | "tunnel_key" | ||
259 | ], | ||
260 | "setup": [ | ||
261 | [ | ||
262 | "$TC actions flush action tunnel_key", | ||
263 | 0, | ||
264 | 1, | ||
265 | 255 | ||
266 | ] | ||
267 | ], | ||
268 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 11 index 4294967295", | ||
269 | "expExitCode": "0", | ||
270 | "verifyCmd": "$TC actions get action tunnel_key index 4294967295", | ||
271 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*id 11.*index 4294967295 ref", | ||
272 | "matchCount": "1", | ||
273 | "teardown": [ | ||
274 | "$TC actions flush action tunnel_key" | ||
275 | ] | ||
276 | }, | ||
277 | { | ||
278 | "id": "d407", | ||
279 | "name": "Add tunnel_key set action with index exceeding 32-bit maximum", | ||
280 | "category": [ | ||
281 | "actions", | ||
282 | "tunnel_key" | ||
283 | ], | ||
284 | "setup": [ | ||
285 | [ | ||
286 | "$TC actions flush action tunnel_key", | ||
287 | 0, | ||
288 | 1, | ||
289 | 255 | ||
290 | ] | ||
291 | ], | ||
292 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 11 index 4294967295678", | ||
293 | "expExitCode": "255", | ||
294 | "verifyCmd": "$TC actions get action tunnel_key index 4294967295678", | ||
295 | "matchPattern": "action order [0-9]+: tunnel_key set.*index 4294967295678 ref", | ||
296 | "matchCount": "0", | ||
297 | "teardown": [ | ||
298 | [ | ||
299 | "$TC actions flush action tunnel_key", | ||
300 | 0, | ||
301 | 1, | ||
302 | 255 | ||
303 | ] | ||
304 | ] | ||
305 | }, | ||
306 | { | ||
307 | "id": "5cba", | ||
308 | "name": "Add tunnel_key set action with id value at 32-bit maximum", | ||
309 | "category": [ | ||
310 | "actions", | ||
311 | "tunnel_key" | ||
312 | ], | ||
313 | "setup": [ | ||
314 | [ | ||
315 | "$TC actions flush action tunnel_key", | ||
316 | 0, | ||
317 | 1, | ||
318 | 255 | ||
319 | ] | ||
320 | ], | ||
321 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 4294967295 index 1", | ||
322 | "expExitCode": "0", | ||
323 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
324 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 4294967295.*index 1", | ||
325 | "matchCount": "1", | ||
326 | "teardown": [ | ||
327 | "$TC actions flush action tunnel_key" | ||
328 | ] | ||
329 | }, | ||
330 | { | ||
331 | "id": "e84a", | ||
332 | "name": "Add tunnel_key set action with id value exceeding 32-bit maximum", | ||
333 | "category": [ | ||
334 | "actions", | ||
335 | "tunnel_key" | ||
336 | ], | ||
337 | "setup": [ | ||
338 | [ | ||
339 | "$TC actions flush action tunnel_key", | ||
340 | 0, | ||
341 | 1, | ||
342 | 255 | ||
343 | ] | ||
344 | ], | ||
345 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42949672955 index 1", | ||
346 | "expExitCode": "255", | ||
347 | "verifyCmd": "$TC actions get action tunnel_key index 4294967295", | ||
348 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42949672955.*index 1", | ||
349 | "matchCount": "0", | ||
350 | "teardown": [ | ||
351 | [ | ||
352 | "$TC actions flush action tunnel_key", | ||
353 | 0, | ||
354 | 1, | ||
355 | 255 | ||
356 | ] | ||
357 | ] | ||
358 | }, | ||
359 | { | ||
360 | "id": "9c19", | ||
361 | "name": "Add tunnel_key set action with dst_port value at 16-bit maximum", | ||
362 | "category": [ | ||
363 | "actions", | ||
364 | "tunnel_key" | ||
365 | ], | ||
366 | "setup": [ | ||
367 | [ | ||
368 | "$TC actions flush action tunnel_key", | ||
369 | 0, | ||
370 | 1, | ||
371 | 255 | ||
372 | ] | ||
373 | ], | ||
374 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 429 dst_port 65535 index 1", | ||
375 | "expExitCode": "0", | ||
376 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
377 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 429.*dst_port 65535.*index 1", | ||
378 | "matchCount": "1", | ||
379 | "teardown": [ | ||
380 | "$TC actions flush action tunnel_key" | ||
381 | ] | ||
382 | }, | ||
383 | { | ||
384 | "id": "3bd9", | ||
385 | "name": "Add tunnel_key set action with dst_port value exceeding 16-bit maximum", | ||
386 | "category": [ | ||
387 | "actions", | ||
388 | "tunnel_key" | ||
389 | ], | ||
390 | "setup": [ | ||
391 | [ | ||
392 | "$TC actions flush action tunnel_key", | ||
393 | 0, | ||
394 | 1, | ||
395 | 255 | ||
396 | ] | ||
397 | ], | ||
398 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 429 dst_port 65535789 index 1", | ||
399 | "expExitCode": "255", | ||
400 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
401 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 429.*dst_port 65535789.*index 1", | ||
402 | "matchCount": "0", | ||
403 | "teardown": [ | ||
404 | [ | ||
405 | "$TC actions flush action tunnel_key", | ||
406 | 0, | ||
407 | 1, | ||
408 | 255 | ||
409 | ] | ||
410 | ] | ||
411 | }, | ||
412 | { | ||
413 | "id": "68e2", | ||
414 | "name": "Add tunnel_key unset action", | ||
415 | "category": [ | ||
416 | "actions", | ||
417 | "tunnel_key" | ||
418 | ], | ||
419 | "setup": [ | ||
420 | [ | ||
421 | "$TC actions flush action tunnel_key", | ||
422 | 0, | ||
423 | 1, | ||
424 | 255 | ||
425 | ] | ||
426 | ], | ||
427 | "cmdUnderTest": "$TC actions add action tunnel_key unset index 1", | ||
428 | "expExitCode": "0", | ||
429 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
430 | "matchPattern": "action order [0-9]+: tunnel_key.*unset.*index 1 ref", | ||
431 | "matchCount": "1", | ||
432 | "teardown": [ | ||
433 | "$TC actions flush action tunnel_key" | ||
434 | ] | ||
435 | }, | ||
436 | { | ||
437 | "id": "6192", | ||
438 | "name": "Add tunnel_key unset continue action", | ||
439 | "category": [ | ||
440 | "actions", | ||
441 | "tunnel_key" | ||
442 | ], | ||
443 | "setup": [ | ||
444 | [ | ||
445 | "$TC actions flush action tunnel_key", | ||
446 | 0, | ||
447 | 1, | ||
448 | 255 | ||
449 | ] | ||
450 | ], | ||
451 | "cmdUnderTest": "$TC actions add action tunnel_key unset continue index 1", | ||
452 | "expExitCode": "0", | ||
453 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
454 | "matchPattern": "action order [0-9]+: tunnel_key.*unset continue.*index 1 ref", | ||
455 | "matchCount": "1", | ||
456 | "teardown": [ | ||
457 | "$TC actions flush action tunnel_key" | ||
458 | ] | ||
459 | }, | ||
460 | { | ||
461 | "id": "061d", | ||
462 | "name": "Add tunnel_key set continue action with cookie", | ||
463 | "category": [ | ||
464 | "actions", | ||
465 | "tunnel_key" | ||
466 | ], | ||
467 | "setup": [ | ||
468 | [ | ||
469 | "$TC actions flush action tunnel_key", | ||
470 | 0, | ||
471 | 1, | ||
472 | 255 | ||
473 | ] | ||
474 | ], | ||
475 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.20.2 id 123 continue index 1 cookie aa11bb22cc33dd44ee55ff66aa11b1b2", | ||
476 | "expExitCode": "0", | ||
477 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
478 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 192.168.10.1.*dst_ip 192.168.20.2.*key_id 123.*csum continue.*index 1.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2", | ||
479 | "matchCount": "1", | ||
480 | "teardown": [ | ||
481 | "$TC actions flush action tunnel_key" | ||
482 | ] | ||
483 | }, | ||
484 | { | ||
485 | "id": "8acb", | ||
486 | "name": "Add tunnel_key set continue action with invalid cookie", | ||
487 | "category": [ | ||
488 | "actions", | ||
489 | "tunnel_key" | ||
490 | ], | ||
491 | "setup": [ | ||
492 | [ | ||
493 | "$TC actions flush action tunnel_key", | ||
494 | 0, | ||
495 | 1, | ||
496 | 255 | ||
497 | ] | ||
498 | ], | ||
499 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.20.2 id 123 continue index 1 cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888", | ||
500 | "expExitCode": "255", | ||
501 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
502 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 192.168.10.1.*dst_ip 192.168.20.2.*key_id 123.*csum continue.*index 1.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888", | ||
503 | "matchCount": "0", | ||
504 | "teardown": [ | ||
505 | [ | ||
506 | "$TC actions flush action tunnel_key", | ||
507 | 0, | ||
508 | 1, | ||
509 | 255 | ||
510 | ] | ||
511 | ] | ||
512 | }, | ||
513 | { | ||
514 | "id": "a07e", | ||
515 | "name": "Add tunnel_key action with no set/unset command specified", | ||
516 | "category": [ | ||
517 | "actions", | ||
518 | "tunnel_key" | ||
519 | ], | ||
520 | "setup": [ | ||
521 | [ | ||
522 | "$TC actions flush action tunnel_key", | ||
523 | 0, | ||
524 | 1, | ||
525 | 255 | ||
526 | ] | ||
527 | ], | ||
528 | "cmdUnderTest": "$TC actions add action tunnel_key src_ip 10.10.10.1 dst_ip 20.20.20.2 id 1", | ||
529 | "expExitCode": "255", | ||
530 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
531 | "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1", | ||
532 | "matchCount": "0", | ||
533 | "teardown": [ | ||
534 | [ | ||
535 | "$TC actions flush action tunnel_key", | ||
536 | 0, | ||
537 | 1, | ||
538 | 255 | ||
539 | ] | ||
540 | ] | ||
541 | }, | ||
542 | { | ||
543 | "id": "b227", | ||
544 | "name": "Add tunnel_key action with csum option", | ||
545 | "category": [ | ||
546 | "actions", | ||
547 | "tunnel_key" | ||
548 | ], | ||
549 | "setup": [ | ||
550 | [ | ||
551 | "$TC actions flush action tunnel_key", | ||
552 | 0, | ||
553 | 1, | ||
554 | 255 | ||
555 | ] | ||
556 | ], | ||
557 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 id 1 csum index 99", | ||
558 | "expExitCode": "0", | ||
559 | "verifyCmd": "$TC actions get action tunnel_key index 99", | ||
560 | "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1.*csum pipe.*index 99", | ||
561 | "matchCount": "1", | ||
562 | "teardown": [ | ||
563 | "$TC actions flush action tunnel_key" | ||
564 | ] | ||
565 | }, | ||
566 | { | ||
567 | "id": "58a7", | ||
568 | "name": "Add tunnel_key action with nocsum option", | ||
569 | "category": [ | ||
570 | "actions", | ||
571 | "tunnel_key" | ||
572 | ], | ||
573 | "setup": [ | ||
574 | [ | ||
575 | "$TC actions flush action tunnel_key", | ||
576 | 0, | ||
577 | 1, | ||
578 | 255 | ||
579 | ] | ||
580 | ], | ||
581 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 10.10.10.2 id 7823 nocsum index 234", | ||
582 | "expExitCode": "0", | ||
583 | "verifyCmd": "$TC actions get action tunnel_key index 234", | ||
584 | "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 10.10.10.2.*key_id 7823.*nocsum pipe.*index 234", | ||
585 | "matchCount": "1", | ||
586 | "teardown": [ | ||
587 | "$TC actions flush action tunnel_key" | ||
588 | ] | ||
589 | }, | ||
590 | { | ||
591 | "id": "2575", | ||
592 | "name": "Add tunnel_key action with not-supported parameter", | ||
593 | "category": [ | ||
594 | "actions", | ||
595 | "tunnel_key" | ||
596 | ], | ||
597 | "setup": [ | ||
598 | [ | ||
599 | "$TC actions flush action tunnel_key", | ||
600 | 0, | ||
601 | 1, | ||
602 | 255 | ||
603 | ] | ||
604 | ], | ||
605 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 10.10.10.2 id 7 foobar 999 index 4", | ||
606 | "expExitCode": "255", | ||
607 | "verifyCmd": "$TC actions get action tunnel_key index 4", | ||
608 | "matchPattern": "action order [0-9]+: tunnel_key.*src_ip 10.10.10.1.*dst_ip 10.10.10.2.*key_id 7.*foobar 999.*index 4", | ||
609 | "matchCount": "0", | ||
610 | "teardown": [ | ||
611 | [ | ||
612 | "$TC actions flush action tunnel_key", | ||
613 | 0, | ||
614 | 1, | ||
615 | 255 | ||
616 | ] | ||
617 | ] | ||
618 | }, | ||
619 | { | ||
620 | "id": "7a88", | ||
621 | "name": "Add tunnel_key action with cookie parameter", | ||
622 | "category": [ | ||
623 | "actions", | ||
624 | "tunnel_key" | ||
625 | ], | ||
626 | "setup": [ | ||
627 | [ | ||
628 | "$TC actions flush action tunnel_key", | ||
629 | 0, | ||
630 | 1, | ||
631 | 255 | ||
632 | ] | ||
633 | ], | ||
634 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 10.10.10.2 id 7 index 4 cookie aa11bb22cc33dd44ee55ff66aa11b1b2", | ||
635 | "expExitCode": "0", | ||
636 | "verifyCmd": "$TC actions get action tunnel_key index 4", | ||
637 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 10.10.10.2.*key_id 7.*dst_port 0.*csum pipe.*index 4 ref.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2", | ||
638 | "matchCount": "1", | ||
639 | "teardown": [ | ||
640 | "$TC actions flush action tunnel_key" | ||
641 | ] | ||
642 | }, | ||
643 | { | ||
644 | "id": "4f20", | ||
645 | "name": "Add tunnel_key action with a single geneve option parameter", | ||
646 | "category": [ | ||
647 | "actions", | ||
648 | "tunnel_key" | ||
649 | ], | ||
650 | "setup": [ | ||
651 | [ | ||
652 | "$TC actions flush action tunnel_key", | ||
653 | 0, | ||
654 | 1, | ||
655 | 255 | ||
656 | ] | ||
657 | ], | ||
658 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:00880022 index 1", | ||
659 | "expExitCode": "0", | ||
660 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
661 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:00880022.*index 1", | ||
662 | "matchCount": "1", | ||
663 | "teardown": [ | ||
664 | "$TC actions flush action tunnel_key" | ||
665 | ] | ||
666 | }, | ||
667 | { | ||
668 | "id": "e33d", | ||
669 | "name": "Add tunnel_key action with multiple geneve options parameter", | ||
670 | "category": [ | ||
671 | "actions", | ||
672 | "tunnel_key" | ||
673 | ], | ||
674 | "setup": [ | ||
675 | [ | ||
676 | "$TC actions flush action tunnel_key", | ||
677 | 0, | ||
678 | 1, | ||
679 | 255 | ||
680 | ] | ||
681 | ], | ||
682 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:00880022,0408:42:0040007611223344,0111:02:1020304011223344 index 1", | ||
683 | "expExitCode": "0", | ||
684 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
685 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:00880022,0408:42:0040007611223344,0111:02:1020304011223344.*index 1", | ||
686 | "matchCount": "1", | ||
687 | "teardown": [ | ||
688 | "$TC actions flush action tunnel_key" | ||
689 | ] | ||
690 | }, | ||
691 | { | ||
692 | "id": "0778", | ||
693 | "name": "Add tunnel_key action with invalid class geneve option parameter", | ||
694 | "category": [ | ||
695 | "actions", | ||
696 | "tunnel_key" | ||
697 | ], | ||
698 | "setup": [ | ||
699 | [ | ||
700 | "$TC actions flush action tunnel_key", | ||
701 | 0, | ||
702 | 1, | ||
703 | 255 | ||
704 | ] | ||
705 | ], | ||
706 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 824212:80:00880022 index 1", | ||
707 | "expExitCode": "255", | ||
708 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
709 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 824212:80:00880022.*index 1", | ||
710 | "matchCount": "0", | ||
711 | "teardown": [ | ||
712 | "$TC actions flush action tunnel_key" | ||
713 | ] | ||
714 | }, | ||
715 | { | ||
716 | "id": "4ae8", | ||
717 | "name": "Add tunnel_key action with invalid type geneve option parameter", | ||
718 | "category": [ | ||
719 | "actions", | ||
720 | "tunnel_key" | ||
721 | ], | ||
722 | "setup": [ | ||
723 | [ | ||
724 | "$TC actions flush action tunnel_key", | ||
725 | 0, | ||
726 | 1, | ||
727 | 255 | ||
728 | ] | ||
729 | ], | ||
730 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:4224:00880022 index 1", | ||
731 | "expExitCode": "255", | ||
732 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
733 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:4224:00880022.*index 1", | ||
734 | "matchCount": "0", | ||
735 | "teardown": [ | ||
736 | "$TC actions flush action tunnel_key" | ||
737 | ] | ||
738 | }, | ||
739 | { | ||
740 | "id": "4039", | ||
741 | "name": "Add tunnel_key action with short data length geneve option parameter", | ||
742 | "category": [ | ||
743 | "actions", | ||
744 | "tunnel_key" | ||
745 | ], | ||
746 | "setup": [ | ||
747 | [ | ||
748 | "$TC actions flush action tunnel_key", | ||
749 | 0, | ||
750 | 1, | ||
751 | 255 | ||
752 | ] | ||
753 | ], | ||
754 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:4288 index 1", | ||
755 | "expExitCode": "255", | ||
756 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
757 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:4288.*index 1", | ||
758 | "matchCount": "0", | ||
759 | "teardown": [ | ||
760 | "$TC actions flush action tunnel_key" | ||
761 | ] | ||
762 | }, | ||
763 | { | ||
764 | "id": "26a6", | ||
765 | "name": "Add tunnel_key action with non-multiple of 4 data length geneve option parameter", | ||
766 | "category": [ | ||
767 | "actions", | ||
768 | "tunnel_key" | ||
769 | ], | ||
770 | "setup": [ | ||
771 | [ | ||
772 | "$TC actions flush action tunnel_key", | ||
773 | 0, | ||
774 | 1, | ||
775 | 255 | ||
776 | ] | ||
777 | ], | ||
778 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:4288428822 index 1", | ||
779 | "expExitCode": "255", | ||
780 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
781 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:4288428822.*index 1", | ||
782 | "matchCount": "0", | ||
783 | "teardown": [ | ||
784 | "$TC actions flush action tunnel_key" | ||
785 | ] | ||
786 | }, | ||
787 | { | ||
788 | "id": "f44d", | ||
789 | "name": "Add tunnel_key action with incomplete geneve options parameter", | ||
790 | "category": [ | ||
791 | "actions", | ||
792 | "tunnel_key" | ||
793 | ], | ||
794 | "setup": [ | ||
795 | [ | ||
796 | "$TC actions flush action tunnel_key", | ||
797 | 0, | ||
798 | 1, | ||
799 | 255 | ||
800 | ] | ||
801 | ], | ||
802 | "cmdUnderTest": "$TC actions add action tunnel_key set src_ip 1.1.1.1 dst_ip 2.2.2.2 id 42 dst_port 6081 geneve_opts 0102:80:00880022,0408:42: index 1", | ||
803 | "expExitCode": "255", | ||
804 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
805 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 1.1.1.1.*dst_ip 2.2.2.2.*key_id 42.*dst_port 6081.*geneve_opt 0102:80:00880022,0408:42:.*index 1", | ||
806 | "matchCount": "0", | ||
807 | "teardown": [ | ||
808 | "$TC actions flush action tunnel_key" | ||
809 | ] | ||
810 | }, | ||
811 | { | ||
812 | "id": "7afc", | ||
813 | "name": "Replace tunnel_key set action with all parameters", | ||
814 | "category": [ | ||
815 | "actions", | ||
816 | "tunnel_key" | ||
817 | ], | ||
818 | "setup": [ | ||
819 | [ | ||
820 | "$TC actions flush action tunnel_key", | ||
821 | 0, | ||
822 | 1, | ||
823 | 255 | ||
824 | ], | ||
825 | "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 csum id 1 index 1" | ||
826 | ], | ||
827 | "cmdUnderTest": "$TC actions replace action tunnel_key set src_ip 11.11.11.1 dst_ip 21.21.21.2 dst_port 3129 nocsum id 11 index 1", | ||
828 | "expExitCode": "0", | ||
829 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
830 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 11.11.11.1.*dst_ip 21.21.21.2.*key_id 11.*dst_port 3129.*nocsum pipe.*index 1", | ||
831 | "matchCount": "1", | ||
832 | "teardown": [ | ||
833 | "$TC actions flush action tunnel_key" | ||
834 | ] | ||
835 | }, | ||
836 | { | ||
837 | "id": "364d", | ||
838 | "name": "Replace tunnel_key set action with all parameters and cookie", | ||
839 | "category": [ | ||
840 | "actions", | ||
841 | "tunnel_key" | ||
842 | ], | ||
843 | "setup": [ | ||
844 | [ | ||
845 | "$TC actions flush action tunnel_key", | ||
846 | 0, | ||
847 | 1, | ||
848 | 255 | ||
849 | ], | ||
850 | "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 index 1 cookie aabbccddeeff112233445566778800a" | ||
851 | ], | ||
852 | "cmdUnderTest": "$TC actions replace action tunnel_key set src_ip 11.11.11.1 dst_ip 21.21.21.2 dst_port 3129 id 11 csum reclassify index 1 cookie a1b1c1d1", | ||
853 | "expExitCode": "0", | ||
854 | "verifyCmd": "$TC actions get action tunnel_key index 1", | ||
855 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 11.11.11.1.*dst_ip 21.21.21.2.*key_id 11.*dst_port 3129.*csum reclassify.*index 1.*cookie a1b1c1d1", | ||
856 | "matchCount": "1", | ||
857 | "teardown": [ | ||
858 | "$TC actions flush action tunnel_key" | ||
859 | ] | ||
860 | }, | ||
861 | { | ||
862 | "id": "937c", | ||
863 | "name": "Fetch all existing tunnel_key actions", | ||
864 | "category": [ | ||
865 | "actions", | ||
866 | "tunnel_key" | ||
867 | ], | ||
868 | "setup": [ | ||
869 | [ | ||
870 | "$TC actions flush action tunnel_key", | ||
871 | 0, | ||
872 | 1, | ||
873 | 255 | ||
874 | ], | ||
875 | "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 pipe index 1", | ||
876 | "$TC actions add action tunnel_key set src_ip 11.10.10.1 dst_ip 21.20.20.2 dst_port 3129 csum id 2 jump 10 index 2", | ||
877 | "$TC actions add action tunnel_key set src_ip 12.10.10.1 dst_ip 22.20.20.2 dst_port 3130 csum id 3 pass index 3", | ||
878 | "$TC actions add action tunnel_key set src_ip 13.10.10.1 dst_ip 23.20.20.2 dst_port 3131 nocsum id 4 continue index 4" | ||
879 | ], | ||
880 | "cmdUnderTest": "$TC actions list action tunnel_key", | ||
881 | "expExitCode": "0", | ||
882 | "verifyCmd": "$TC actions list action tunnel_key", | ||
883 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1.*dst_port 3128.*nocsum pipe.*index 1.*set.*src_ip 11.10.10.1.*dst_ip 21.20.20.2.*key_id 2.*dst_port 3129.*csum jump 10.*index 2.*set.*src_ip 12.10.10.1.*dst_ip 22.20.20.2.*key_id 3.*dst_port 3130.*csum pass.*index 3.*set.*src_ip 13.10.10.1.*dst_ip 23.20.20.2.*key_id 4.*dst_port 3131.*nocsum continue.*index 4", | ||
884 | "matchCount": "1", | ||
885 | "teardown": [ | ||
886 | "$TC actions flush action tunnel_key" | ||
887 | ] | ||
888 | }, | ||
889 | { | ||
890 | "id": "6783", | ||
891 | "name": "Flush all existing tunnel_key actions", | ||
892 | "category": [ | ||
893 | "actions", | ||
894 | "tunnel_key" | ||
895 | ], | ||
896 | "setup": [ | ||
897 | [ | ||
898 | "$TC actions flush action tunnel_key", | ||
899 | 0, | ||
900 | 1, | ||
901 | 255 | ||
902 | ], | ||
903 | "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 pipe index 1", | ||
904 | "$TC actions add action tunnel_key set src_ip 11.10.10.1 dst_ip 21.20.20.2 dst_port 3129 csum id 2 reclassify index 2", | ||
905 | "$TC actions add action tunnel_key set src_ip 12.10.10.1 dst_ip 22.20.20.2 dst_port 3130 csum id 3 pass index 3", | ||
906 | "$TC actions add action tunnel_key set src_ip 13.10.10.1 dst_ip 23.20.20.2 dst_port 3131 nocsum id 4 continue index 4" | ||
907 | ], | ||
908 | "cmdUnderTest": "$TC actions flush action tunnel_key", | ||
909 | "expExitCode": "0", | ||
910 | "verifyCmd": "$TC actions list action tunnel_key", | ||
911 | "matchPattern": "action order [0-9]+:.*", | ||
912 | "matchCount": "0", | ||
913 | "teardown": [ | ||
914 | "$TC actions flush action tunnel_key" | ||
915 | ] | ||
916 | } | ||
917 | ] | ||
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json b/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json new file mode 100644 index 000000000000..3b97cfd7e0f8 --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json | |||
@@ -0,0 +1,1049 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "901f", | ||
4 | "name": "Add fw filter with prio at 32-bit maxixum", | ||
5 | "category": [ | ||
6 | "filter", | ||
7 | "fw" | ||
8 | ], | ||
9 | "setup": [ | ||
10 | "$TC qdisc add dev $DEV1 ingress" | ||
11 | ], | ||
12 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 65535 fw action ok", | ||
13 | "expExitCode": "0", | ||
14 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 65535 protocol all fw", | ||
15 | "matchPattern": "pref 65535 fw.*handle 0x1.*gact action pass", | ||
16 | "matchCount": "1", | ||
17 | "teardown": [ | ||
18 | "$TC qdisc del dev $DEV1 ingress" | ||
19 | ] | ||
20 | }, | ||
21 | { | ||
22 | "id": "51e2", | ||
23 | "name": "Add fw filter with prio exceeding 32-bit maxixum", | ||
24 | "category": [ | ||
25 | "filter", | ||
26 | "fw" | ||
27 | ], | ||
28 | "setup": [ | ||
29 | "$TC qdisc add dev $DEV1 ingress" | ||
30 | ], | ||
31 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 65536 fw action ok", | ||
32 | "expExitCode": "255", | ||
33 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 65536 protocol all fw", | ||
34 | "matchPattern": "pref 65536 fw.*handle 0x1.*gact action pass", | ||
35 | "matchCount": "0", | ||
36 | "teardown": [ | ||
37 | "$TC qdisc del dev $DEV1 ingress" | ||
38 | ] | ||
39 | }, | ||
40 | { | ||
41 | "id": "d987", | ||
42 | "name": "Add fw filter with action ok", | ||
43 | "category": [ | ||
44 | "filter", | ||
45 | "fw" | ||
46 | ], | ||
47 | "setup": [ | ||
48 | "$TC qdisc add dev $DEV1 ingress" | ||
49 | ], | ||
50 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action ok", | ||
51 | "expExitCode": "0", | ||
52 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
53 | "matchPattern": "handle 0x1.*gact action pass", | ||
54 | "matchCount": "1", | ||
55 | "teardown": [ | ||
56 | "$TC qdisc del dev $DEV1 ingress" | ||
57 | ] | ||
58 | }, | ||
59 | { | ||
60 | "id": "affe", | ||
61 | "name": "Add fw filter with action continue", | ||
62 | "category": [ | ||
63 | "filter", | ||
64 | "fw" | ||
65 | ], | ||
66 | "setup": [ | ||
67 | "$TC qdisc add dev $DEV1 ingress" | ||
68 | ], | ||
69 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action continue", | ||
70 | "expExitCode": "0", | ||
71 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
72 | "matchPattern": "handle 0x1.*gact action continue", | ||
73 | "matchCount": "1", | ||
74 | "teardown": [ | ||
75 | "$TC qdisc del dev $DEV1 ingress" | ||
76 | ] | ||
77 | }, | ||
78 | { | ||
79 | "id": "28bc", | ||
80 | "name": "Add fw filter with action pipe", | ||
81 | "category": [ | ||
82 | "filter", | ||
83 | "fw" | ||
84 | ], | ||
85 | "setup": [ | ||
86 | "$TC qdisc add dev $DEV1 ingress" | ||
87 | ], | ||
88 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action pipe", | ||
89 | "expExitCode": "0", | ||
90 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
91 | "matchPattern": "handle 0x1.*gact action pipe", | ||
92 | "matchCount": "1", | ||
93 | "teardown": [ | ||
94 | "$TC qdisc del dev $DEV1 ingress" | ||
95 | ] | ||
96 | }, | ||
97 | { | ||
98 | "id": "8da2", | ||
99 | "name": "Add fw filter with action drop", | ||
100 | "category": [ | ||
101 | "filter", | ||
102 | "fw" | ||
103 | ], | ||
104 | "setup": [ | ||
105 | "$TC qdisc add dev $DEV1 ingress" | ||
106 | ], | ||
107 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action drop", | ||
108 | "expExitCode": "0", | ||
109 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 protocol all prio 1 fw", | ||
110 | "matchPattern": "handle 0x1.*gact action drop", | ||
111 | "matchCount": "1", | ||
112 | "teardown": [ | ||
113 | "$TC qdisc del dev $DEV1 ingress" | ||
114 | ] | ||
115 | }, | ||
116 | { | ||
117 | "id": "9436", | ||
118 | "name": "Add fw filter with action reclassify", | ||
119 | "category": [ | ||
120 | "filter", | ||
121 | "fw" | ||
122 | ], | ||
123 | "setup": [ | ||
124 | "$TC qdisc add dev $DEV1 ingress" | ||
125 | ], | ||
126 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action reclassify", | ||
127 | "expExitCode": "0", | ||
128 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
129 | "matchPattern": "handle 0x1.*gact action reclassify", | ||
130 | "matchCount": "1", | ||
131 | "teardown": [ | ||
132 | "$TC qdisc del dev $DEV1 ingress" | ||
133 | ] | ||
134 | }, | ||
135 | { | ||
136 | "id": "95bb", | ||
137 | "name": "Add fw filter with action jump 10", | ||
138 | "category": [ | ||
139 | "filter", | ||
140 | "fw" | ||
141 | ], | ||
142 | "setup": [ | ||
143 | "$TC qdisc add dev $DEV1 ingress" | ||
144 | ], | ||
145 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action jump 10", | ||
146 | "expExitCode": "0", | ||
147 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
148 | "matchPattern": "handle 0x1.*gact action jump 10", | ||
149 | "matchCount": "1", | ||
150 | "teardown": [ | ||
151 | "$TC qdisc del dev $DEV1 ingress" | ||
152 | ] | ||
153 | }, | ||
154 | { | ||
155 | "id": "3d74", | ||
156 | "name": "Add fw filter with action goto chain 5", | ||
157 | "category": [ | ||
158 | "filter", | ||
159 | "fw" | ||
160 | ], | ||
161 | "setup": [ | ||
162 | "$TC qdisc add dev $DEV1 ingress" | ||
163 | ], | ||
164 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action goto chain 5", | ||
165 | "expExitCode": "0", | ||
166 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
167 | "matchPattern": "handle 0x1.*gact action goto chain 5", | ||
168 | "matchCount": "1", | ||
169 | "teardown": [ | ||
170 | "$TC qdisc del dev $DEV1 ingress" | ||
171 | ] | ||
172 | }, | ||
173 | { | ||
174 | "id": "eb8f", | ||
175 | "name": "Add fw filter with invalid action", | ||
176 | "category": [ | ||
177 | "filter", | ||
178 | "fw" | ||
179 | ], | ||
180 | "setup": [ | ||
181 | "$TC qdisc add dev $DEV1 ingress" | ||
182 | ], | ||
183 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action pump", | ||
184 | "expExitCode": "255", | ||
185 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
186 | "matchPattern": "handle 0x1.*gact action pump", | ||
187 | "matchCount": "0", | ||
188 | "teardown": [ | ||
189 | "$TC qdisc del dev $DEV1 ingress" | ||
190 | ] | ||
191 | }, | ||
192 | { | ||
193 | "id": "6a79", | ||
194 | "name": "Add fw filter with missing mandatory action", | ||
195 | "category": [ | ||
196 | "filter", | ||
197 | "fw" | ||
198 | ], | ||
199 | "setup": [ | ||
200 | "$TC qdisc add dev $DEV1 ingress" | ||
201 | ], | ||
202 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw", | ||
203 | "expExitCode": "2", | ||
204 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
205 | "matchPattern": "filter protocol all pref [0-9]+ fw.*handle 0x1", | ||
206 | "matchCount": "0", | ||
207 | "teardown": [ | ||
208 | "$TC qdisc del dev $DEV1 ingress" | ||
209 | ] | ||
210 | }, | ||
211 | { | ||
212 | "id": "8298", | ||
213 | "name": "Add fw filter with cookie", | ||
214 | "category": [ | ||
215 | "filter", | ||
216 | "fw" | ||
217 | ], | ||
218 | "setup": [ | ||
219 | "$TC qdisc add dev $DEV1 ingress" | ||
220 | ], | ||
221 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action pipe cookie aa11bb22cc33dd44ee55ff66aa11b1b2", | ||
222 | "expExitCode": "0", | ||
223 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 2 protocol all fw", | ||
224 | "matchPattern": "pref 2 fw.*handle 0x1.*gact action pipe.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2", | ||
225 | "matchCount": "1", | ||
226 | "teardown": [ | ||
227 | "$TC qdisc del dev $DEV1 ingress" | ||
228 | ] | ||
229 | }, | ||
230 | { | ||
231 | "id": "a88c", | ||
232 | "name": "Add fw filter with invalid cookie", | ||
233 | "category": [ | ||
234 | "filter", | ||
235 | "fw" | ||
236 | ], | ||
237 | "setup": [ | ||
238 | "$TC qdisc add dev $DEV1 ingress" | ||
239 | ], | ||
240 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action continue cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888", | ||
241 | "expExitCode": "255", | ||
242 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 2 protocol all fw", | ||
243 | "matchPattern": "pref 2 fw.*handle 0x1.*gact action continue.*cookie aa11bb22cc33dd44ee55ff66aa11b1b2777888", | ||
244 | "matchCount": "0", | ||
245 | "teardown": [ | ||
246 | "$TC qdisc del dev $DEV1 ingress" | ||
247 | ] | ||
248 | }, | ||
249 | { | ||
250 | "id": "10f6", | ||
251 | "name": "Add fw filter with handle in hex", | ||
252 | "category": [ | ||
253 | "filter", | ||
254 | "fw" | ||
255 | ], | ||
256 | "setup": [ | ||
257 | "$TC qdisc add dev $DEV1 ingress" | ||
258 | ], | ||
259 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0xa1b2ff prio 1 fw action ok", | ||
260 | "expExitCode": "0", | ||
261 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xa1b2ff prio 1 protocol all fw", | ||
262 | "matchPattern": "fw.*handle 0xa1b2ff.*gact action pass", | ||
263 | "matchCount": "1", | ||
264 | "teardown": [ | ||
265 | "$TC qdisc del dev $DEV1 ingress" | ||
266 | ] | ||
267 | }, | ||
268 | { | ||
269 | "id": "9d51", | ||
270 | "name": "Add fw filter with handle at 32-bit maximum", | ||
271 | "category": [ | ||
272 | "filter", | ||
273 | "fw" | ||
274 | ], | ||
275 | "setup": [ | ||
276 | "$TC qdisc add dev $DEV1 ingress" | ||
277 | ], | ||
278 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967295 prio 1 fw action ok", | ||
279 | "expExitCode": "0", | ||
280 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4294967295 prio 1 protocol all fw", | ||
281 | "matchPattern": "fw.*handle 0xffffffff.*gact action pass", | ||
282 | "matchCount": "1", | ||
283 | "teardown": [ | ||
284 | "$TC qdisc del dev $DEV1 ingress" | ||
285 | ] | ||
286 | }, | ||
287 | { | ||
288 | "id": "d939", | ||
289 | "name": "Add fw filter with handle exceeding 32-bit maximum", | ||
290 | "category": [ | ||
291 | "filter", | ||
292 | "fw" | ||
293 | ], | ||
294 | "setup": [ | ||
295 | "$TC qdisc add dev $DEV1 ingress" | ||
296 | ], | ||
297 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967296 prio 1 fw action ok", | ||
298 | "expExitCode": "1", | ||
299 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4294967296 prio 1 protocol all fw", | ||
300 | "matchPattern": "fw.*handle 0x.*gact action pass", | ||
301 | "matchCount": "0", | ||
302 | "teardown": [ | ||
303 | "$TC qdisc del dev $DEV1 ingress" | ||
304 | ] | ||
305 | }, | ||
306 | { | ||
307 | "id": "658c", | ||
308 | "name": "Add fw filter with mask in hex", | ||
309 | "category": [ | ||
310 | "filter", | ||
311 | "fw" | ||
312 | ], | ||
313 | "setup": [ | ||
314 | "$TC qdisc add dev $DEV1 ingress" | ||
315 | ], | ||
316 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10/0xa1b2f prio 1 fw action ok", | ||
317 | "expExitCode": "0", | ||
318 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw", | ||
319 | "matchPattern": "fw.*handle 0xa/0xa1b2f", | ||
320 | "matchCount": "1", | ||
321 | "teardown": [ | ||
322 | "$TC qdisc del dev $DEV1 ingress" | ||
323 | ] | ||
324 | }, | ||
325 | { | ||
326 | "id": "86be", | ||
327 | "name": "Add fw filter with mask at 32-bit maximum", | ||
328 | "category": [ | ||
329 | "filter", | ||
330 | "fw" | ||
331 | ], | ||
332 | "setup": [ | ||
333 | "$TC qdisc add dev $DEV1 ingress" | ||
334 | ], | ||
335 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10/4294967295 prio 1 fw action ok", | ||
336 | "expExitCode": "0", | ||
337 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw", | ||
338 | "matchPattern": "fw.*handle 0xa[^/]", | ||
339 | "matchCount": "1", | ||
340 | "teardown": [ | ||
341 | "$TC qdisc del dev $DEV1 ingress" | ||
342 | ] | ||
343 | }, | ||
344 | { | ||
345 | "id": "e635", | ||
346 | "name": "Add fw filter with mask exceeding 32-bit maximum", | ||
347 | "category": [ | ||
348 | "filter", | ||
349 | "fw" | ||
350 | ], | ||
351 | "setup": [ | ||
352 | "$TC qdisc add dev $DEV1 ingress" | ||
353 | ], | ||
354 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10/4294967296 prio 1 fw action ok", | ||
355 | "expExitCode": "1", | ||
356 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw", | ||
357 | "matchPattern": "fw.*handle 0xa", | ||
358 | "matchCount": "0", | ||
359 | "teardown": [ | ||
360 | "$TC qdisc del dev $DEV1 ingress" | ||
361 | ] | ||
362 | }, | ||
363 | { | ||
364 | "id": "6cab", | ||
365 | "name": "Add fw filter with handle/mask in hex", | ||
366 | "category": [ | ||
367 | "filter", | ||
368 | "fw" | ||
369 | ], | ||
370 | "setup": [ | ||
371 | "$TC qdisc add dev $DEV1 ingress" | ||
372 | ], | ||
373 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 0xa1b2cdff/0x1a2bffdc prio 1 fw action ok", | ||
374 | "expExitCode": "0", | ||
375 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xa1b2cdff prio 1 protocol all fw", | ||
376 | "matchPattern": "fw.*handle 0xa1b2cdff/0x1a2bffdc", | ||
377 | "matchCount": "1", | ||
378 | "teardown": [ | ||
379 | "$TC qdisc del dev $DEV1 ingress" | ||
380 | ] | ||
381 | }, | ||
382 | { | ||
383 | "id": "8700", | ||
384 | "name": "Add fw filter with handle/mask at 32-bit maximum", | ||
385 | "category": [ | ||
386 | "filter", | ||
387 | "fw" | ||
388 | ], | ||
389 | "setup": [ | ||
390 | "$TC qdisc add dev $DEV1 ingress" | ||
391 | ], | ||
392 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967295/4294967295 prio 1 fw action ok", | ||
393 | "expExitCode": "0", | ||
394 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 0xffffffff prio 1 protocol all fw", | ||
395 | "matchPattern": "fw.*handle 0xffffffff[^/]", | ||
396 | "matchCount": "1", | ||
397 | "teardown": [ | ||
398 | "$TC qdisc del dev $DEV1 ingress" | ||
399 | ] | ||
400 | }, | ||
401 | { | ||
402 | "id": "7d62", | ||
403 | "name": "Add fw filter with handle/mask exceeding 32-bit maximum", | ||
404 | "category": [ | ||
405 | "filter", | ||
406 | "fw" | ||
407 | ], | ||
408 | "setup": [ | ||
409 | "$TC qdisc add dev $DEV1 ingress" | ||
410 | ], | ||
411 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 4294967296/4294967296 prio 1 fw action ok", | ||
412 | "expExitCode": "1", | ||
413 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw", | ||
414 | "matchPattern": "fw.*handle", | ||
415 | "matchCount": "0", | ||
416 | "teardown": [ | ||
417 | "$TC qdisc del dev $DEV1 ingress" | ||
418 | ] | ||
419 | }, | ||
420 | { | ||
421 | "id": "7b69", | ||
422 | "name": "Add fw filter with missing mandatory handle", | ||
423 | "category": [ | ||
424 | "filter", | ||
425 | "fw" | ||
426 | ], | ||
427 | "setup": [ | ||
428 | "$TC qdisc add dev $DEV1 ingress" | ||
429 | ], | ||
430 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 1 fw action ok", | ||
431 | "expExitCode": "2", | ||
432 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
433 | "matchPattern": "filter protocol all.*fw.*handle.*gact action pass", | ||
434 | "matchCount": "0", | ||
435 | "teardown": [ | ||
436 | "$TC qdisc del dev $DEV1 ingress" | ||
437 | ] | ||
438 | }, | ||
439 | { | ||
440 | "id": "d68b", | ||
441 | "name": "Add fw filter with invalid parent", | ||
442 | "category": [ | ||
443 | "filter", | ||
444 | "fw" | ||
445 | ], | ||
446 | "setup": [ | ||
447 | "$TC qdisc add dev $DEV1 ingress" | ||
448 | ], | ||
449 | "cmdUnderTest": "$TC filter add dev $DEV1 parent aa11b1b2: handle 1 prio 1 fw action ok", | ||
450 | "expExitCode": "255", | ||
451 | "verifyCmd": "$TC filter dev $DEV1 parent aa11b1b2: handle 1 prio 1 protocol all fw", | ||
452 | "matchPattern": "filter protocol all pref 1 fw.*handle 0x1.*gact action pass", | ||
453 | "matchCount": "0", | ||
454 | "teardown": [ | ||
455 | "$TC qdisc del dev $DEV1 ingress" | ||
456 | ] | ||
457 | }, | ||
458 | { | ||
459 | "id": "66e0", | ||
460 | "name": "Add fw filter with missing mandatory parent id", | ||
461 | "category": [ | ||
462 | "filter", | ||
463 | "fw" | ||
464 | ], | ||
465 | "setup": [ | ||
466 | "$TC qdisc add dev $DEV1 ingress" | ||
467 | ], | ||
468 | "cmdUnderTest": "$TC filter add dev $DEV1 handle 1 prio 1 fw action ok", | ||
469 | "expExitCode": "2", | ||
470 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
471 | "matchPattern": "pref [0-9]+ fw.*handle 0x1.*gact action pass", | ||
472 | "matchCount": "0", | ||
473 | "teardown": [ | ||
474 | "$TC qdisc del dev $DEV1 ingress" | ||
475 | ] | ||
476 | }, | ||
477 | { | ||
478 | "id": "0ff3", | ||
479 | "name": "Add fw filter with classid", | ||
480 | "category": [ | ||
481 | "filter", | ||
482 | "fw" | ||
483 | ], | ||
484 | "setup": [ | ||
485 | "$TC qdisc add dev $DEV1 ingress" | ||
486 | ], | ||
487 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid 3 action ok", | ||
488 | "expExitCode": "0", | ||
489 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
490 | "matchPattern": "fw.*handle 0x1 classid :3.*gact action pass", | ||
491 | "matchCount": "1", | ||
492 | "teardown": [ | ||
493 | "$TC qdisc del dev $DEV1 ingress" | ||
494 | ] | ||
495 | }, | ||
496 | { | ||
497 | "id": "9849", | ||
498 | "name": "Add fw filter with classid at root", | ||
499 | "category": [ | ||
500 | "filter", | ||
501 | "fw" | ||
502 | ], | ||
503 | "setup": [ | ||
504 | "$TC qdisc add dev $DEV1 ingress" | ||
505 | ], | ||
506 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid ffff:ffff action ok", | ||
507 | "expExitCode": "0", | ||
508 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
509 | "matchPattern": "pref 1 fw.*handle 0x1 classid root.*gact action pass", | ||
510 | "matchCount": "1", | ||
511 | "teardown": [ | ||
512 | "$TC qdisc del dev $DEV1 ingress" | ||
513 | ] | ||
514 | }, | ||
515 | { | ||
516 | "id": "b7ff", | ||
517 | "name": "Add fw filter with classid - keeps last 8 (hex) digits", | ||
518 | "category": [ | ||
519 | "filter", | ||
520 | "fw" | ||
521 | ], | ||
522 | "setup": [ | ||
523 | "$TC qdisc add dev $DEV1 ingress" | ||
524 | ], | ||
525 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid 98765fedcb action ok", | ||
526 | "expExitCode": "0", | ||
527 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
528 | "matchPattern": "fw.*handle 0x1 classid 765f:edcb.*gact action pass", | ||
529 | "matchCount": "1", | ||
530 | "teardown": [ | ||
531 | "$TC qdisc del dev $DEV1 ingress" | ||
532 | ] | ||
533 | }, | ||
534 | { | ||
535 | "id": "2b18", | ||
536 | "name": "Add fw filter with invalid classid", | ||
537 | "category": [ | ||
538 | "filter", | ||
539 | "fw" | ||
540 | ], | ||
541 | "setup": [ | ||
542 | "$TC qdisc add dev $DEV1 ingress" | ||
543 | ], | ||
544 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw classid 6789defg action ok", | ||
545 | "expExitCode": "1", | ||
546 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", | ||
547 | "matchPattern": "fw.*handle 0x1 classid 6789:defg.*gact action pass", | ||
548 | "matchCount": "0", | ||
549 | "teardown": [ | ||
550 | "$TC qdisc del dev $DEV1 ingress" | ||
551 | ] | ||
552 | }, | ||
553 | { | ||
554 | "id": "fade", | ||
555 | "name": "Add fw filter with flowid", | ||
556 | "category": [ | ||
557 | "filter", | ||
558 | "fw" | ||
559 | ], | ||
560 | "setup": [ | ||
561 | "$TC qdisc add dev $DEV1 ingress" | ||
562 | ], | ||
563 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 10 prio 1 fw flowid 1:10 action ok", | ||
564 | "expExitCode": "0", | ||
565 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 1 protocol all fw", | ||
566 | "matchPattern": "filter parent ffff: protocol all pref 1 fw.*handle 0xa classid 1:10.*gact action pass", | ||
567 | "matchCount": "1", | ||
568 | "teardown": [ | ||
569 | "$TC qdisc del dev $DEV1 ingress" | ||
570 | ] | ||
571 | }, | ||
572 | { | ||
573 | "id": "33af", | ||
574 | "name": "Add fw filter with flowid then classid (same arg, takes second)", | ||
575 | "category": [ | ||
576 | "filter", | ||
577 | "fw" | ||
578 | ], | ||
579 | "setup": [ | ||
580 | "$TC qdisc add dev $DEV1 ingress" | ||
581 | ], | ||
582 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 11 prio 1 fw flowid 10 classid 4 action ok", | ||
583 | "expExitCode": "0", | ||
584 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 11 prio 1 protocol all fw", | ||
585 | "matchPattern": "filter parent ffff: protocol all pref 1 fw.*handle 0xb classid :4.*gact action pass", | ||
586 | "matchCount": "1", | ||
587 | "teardown": [ | ||
588 | "$TC qdisc del dev $DEV1 ingress" | ||
589 | ] | ||
590 | }, | ||
591 | { | ||
592 | "id": "8a8c", | ||
593 | "name": "Add fw filter with classid then flowid (same arg, takes second)", | ||
594 | "category": [ | ||
595 | "filter", | ||
596 | "fw" | ||
597 | ], | ||
598 | "setup": [ | ||
599 | "$TC qdisc add dev $DEV1 ingress" | ||
600 | ], | ||
601 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 11 prio 1 fw classid 4 flowid 10 action ok", | ||
602 | "expExitCode": "0", | ||
603 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 11 prio 1 protocol all fw", | ||
604 | "matchPattern": "filter parent ffff: protocol all pref 1 fw.*handle 0xb classid :10.*gact action pass", | ||
605 | "matchCount": "1", | ||
606 | "teardown": [ | ||
607 | "$TC qdisc del dev $DEV1 ingress" | ||
608 | ] | ||
609 | }, | ||
610 | { | ||
611 | "id": "b50d", | ||
612 | "name": "Add fw filter with handle val/mask and flowid 10:1000", | ||
613 | "category": [ | ||
614 | "filter", | ||
615 | "fw" | ||
616 | ], | ||
617 | "setup": [ | ||
618 | "$TC qdisc add dev $DEV1 ingress" | ||
619 | ], | ||
620 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 3 handle 10/0xff fw flowid 10:1000 action ok", | ||
621 | "expExitCode": "0", | ||
622 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 10 prio 3 protocol all fw", | ||
623 | "matchPattern": "filter parent ffff: protocol all pref 3 fw.*handle 0xa/0xff classid 10:1000.*gact action pass", | ||
624 | "matchCount": "1", | ||
625 | "teardown": [ | ||
626 | "$TC qdisc del dev $DEV1 ingress" | ||
627 | ] | ||
628 | }, | ||
629 | { | ||
630 | "id": "7207", | ||
631 | "name": "Add fw filter with protocol ip", | ||
632 | "category": [ | ||
633 | "filter", | ||
634 | "fw" | ||
635 | ], | ||
636 | "setup": [ | ||
637 | "$TC qdisc add dev $DEV1 ingress" | ||
638 | ], | ||
639 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 handle 3 fw action ok", | ||
640 | "expExitCode": "0", | ||
641 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 3 prio 1 protocol ip fw", | ||
642 | "matchPattern": "filter parent ffff: protocol ip pref 1 fw.*handle 0x3.*gact action pass.*index [0-9]+ ref [0-9]+ bind [0-9]+", | ||
643 | "matchCount": "1", | ||
644 | "teardown": [ | ||
645 | "$TC qdisc del dev $DEV1 ingress" | ||
646 | ] | ||
647 | }, | ||
648 | { | ||
649 | "id": "306d", | ||
650 | "name": "Add fw filter with protocol ipv6", | ||
651 | "category": [ | ||
652 | "filter", | ||
653 | "fw" | ||
654 | ], | ||
655 | "setup": [ | ||
656 | "$TC qdisc add dev $DEV1 ingress" | ||
657 | ], | ||
658 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ipv6 prio 2 handle 4 fw action ok", | ||
659 | "expExitCode": "0", | ||
660 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 2 protocol ipv6 fw", | ||
661 | "matchPattern": "filter parent ffff: protocol ipv6 pref 2 fw.*handle 0x4.*gact action pass.*index [0-9]+ ref [0-9]+ bind [0-9]+", | ||
662 | "matchCount": "1", | ||
663 | "teardown": [ | ||
664 | "$TC qdisc del dev $DEV1 ingress" | ||
665 | ] | ||
666 | }, | ||
667 | { | ||
668 | "id": "9a78", | ||
669 | "name": "Add fw filter with protocol arp", | ||
670 | "category": [ | ||
671 | "filter", | ||
672 | "fw" | ||
673 | ], | ||
674 | "setup": [ | ||
675 | "$TC qdisc add dev $DEV1 ingress" | ||
676 | ], | ||
677 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol arp prio 5 handle 7 fw action drop", | ||
678 | "expExitCode": "0", | ||
679 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 7 prio 5 protocol arp fw", | ||
680 | "matchPattern": "filter parent ffff: protocol arp pref 5 fw.*handle 0x7.*gact action drop.*index [0-9]+ ref [0-9]+ bind [0-9]+", | ||
681 | "matchCount": "1", | ||
682 | "teardown": [ | ||
683 | "$TC qdisc del dev $DEV1 ingress" | ||
684 | ] | ||
685 | }, | ||
686 | { | ||
687 | "id": "1821", | ||
688 | "name": "Add fw filter with protocol 802_3", | ||
689 | "category": [ | ||
690 | "filter", | ||
691 | "fw" | ||
692 | ], | ||
693 | "setup": [ | ||
694 | "$TC qdisc add dev $DEV1 ingress" | ||
695 | ], | ||
696 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol 802_3 handle 1 prio 1 fw action ok", | ||
697 | "expExitCode": "0", | ||
698 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol 802_3 fw", | ||
699 | "matchPattern": "filter parent ffff: protocol 802_3 pref 1 fw.*handle 0x1.*gact action pass", | ||
700 | "matchCount": "1", | ||
701 | "teardown": [ | ||
702 | "$TC qdisc del dev $DEV1 ingress" | ||
703 | ] | ||
704 | }, | ||
705 | { | ||
706 | "id": "2260", | ||
707 | "name": "Add fw filter with invalid protocol", | ||
708 | "category": [ | ||
709 | "filter", | ||
710 | "fw" | ||
711 | ], | ||
712 | "setup": [ | ||
713 | "$TC qdisc add dev $DEV1 ingress" | ||
714 | ], | ||
715 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol igmp handle 1 prio 1 fw action ok", | ||
716 | "expExitCode": "255", | ||
717 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol igmp fw", | ||
718 | "matchPattern": "filter parent ffff: protocol igmp pref 1 fw.*handle 0x1.*gact action pass", | ||
719 | "matchCount": "0", | ||
720 | "teardown": [ | ||
721 | "$TC qdisc del dev $DEV1 ingress" | ||
722 | ] | ||
723 | }, | ||
724 | { | ||
725 | "id": "09d7", | ||
726 | "name": "Add fw filters protocol 802_3 and ip with conflicting priorities", | ||
727 | "category": [ | ||
728 | "filter", | ||
729 | "fw" | ||
730 | ], | ||
731 | "setup": [ | ||
732 | "$TC qdisc add dev $DEV1 ingress", | ||
733 | "$TC filter add dev $DEV1 parent ffff: protocol 802_3 prio 3 handle 7 fw action ok" | ||
734 | ], | ||
735 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 3 handle 8 fw action ok", | ||
736 | "expExitCode": "2", | ||
737 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 8 prio 3 protocol ip fw", | ||
738 | "matchPattern": "filter parent ffff: protocol ip pref 3 fw.*handle 0x8", | ||
739 | "matchCount": "0", | ||
740 | "teardown": [ | ||
741 | "$TC qdisc del dev $DEV1 ingress" | ||
742 | ] | ||
743 | }, | ||
744 | { | ||
745 | "id": "6973", | ||
746 | "name": "Add fw filters with same index, same action", | ||
747 | "category": [ | ||
748 | "filter", | ||
749 | "fw" | ||
750 | ], | ||
751 | "setup": [ | ||
752 | "$TC qdisc add dev $DEV1 ingress", | ||
753 | "$TC filter add dev $DEV1 parent ffff: prio 6 handle 2 fw action continue index 5" | ||
754 | ], | ||
755 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 8 handle 4 fw action continue index 5", | ||
756 | "expExitCode": "0", | ||
757 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 8 protocol all fw", | ||
758 | "matchPattern": "filter parent ffff: protocol all pref 8 fw.*handle 0x4.*gact action continue.*index 5 ref 2 bind 2", | ||
759 | "matchCount": "1", | ||
760 | "teardown": [ | ||
761 | "$TC qdisc del dev $DEV1 ingress" | ||
762 | ] | ||
763 | }, | ||
764 | { | ||
765 | "id": "fc06", | ||
766 | "name": "Add fw filters with action police", | ||
767 | "category": [ | ||
768 | "filter", | ||
769 | "fw" | ||
770 | ], | ||
771 | "setup": [ | ||
772 | "$TC qdisc add dev $DEV1 ingress" | ||
773 | ], | ||
774 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 3 handle 4 fw action police rate 1kbit burst 10k index 5", | ||
775 | "expExitCode": "0", | ||
776 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 3 protocol all fw", | ||
777 | "matchPattern": "filter parent ffff: protocol all pref 3 fw.*handle 0x4.*police 0x5 rate 1Kbit burst 10Kb mtu 2Kb action reclassify overhead 0b.*ref 1 bind 1", | ||
778 | "matchCount": "1", | ||
779 | "teardown": [ | ||
780 | "$TC qdisc del dev $DEV1 ingress" | ||
781 | ] | ||
782 | }, | ||
783 | { | ||
784 | "id": "aac7", | ||
785 | "name": "Add fw filters with action police linklayer atm", | ||
786 | "category": [ | ||
787 | "filter", | ||
788 | "fw" | ||
789 | ], | ||
790 | "setup": [ | ||
791 | "$TC qdisc add dev $DEV1 ingress" | ||
792 | ], | ||
793 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: prio 3 handle 4 fw action police rate 2mbit burst 200k linklayer atm index 8", | ||
794 | "expExitCode": "0", | ||
795 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 3 protocol all fw", | ||
796 | "matchPattern": "filter parent ffff: protocol all pref 3 fw.*handle 0x4.*police 0x8 rate 2Mbit burst 200Kb mtu 2Kb action reclassify overhead 0b linklayer atm.*ref 1 bind 1", | ||
797 | "matchCount": "1", | ||
798 | "teardown": [ | ||
799 | "$TC qdisc del dev $DEV1 ingress" | ||
800 | ] | ||
801 | }, | ||
802 | { | ||
803 | "id": "5339", | ||
804 | "name": "Del entire fw filter", | ||
805 | "category": [ | ||
806 | "filter", | ||
807 | "fw" | ||
808 | ], | ||
809 | "setup": [ | ||
810 | "$TC qdisc add dev $DEV1 ingress", | ||
811 | "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass", | ||
812 | "$TC filter add dev $DEV1 parent ffff: handle 3 prio 9 fw action pass" | ||
813 | ], | ||
814 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff:", | ||
815 | "expExitCode": "0", | ||
816 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
817 | "matchPattern": "protocol all pref.*handle.*gact action pass", | ||
818 | "matchCount": "0", | ||
819 | "teardown": [ | ||
820 | "$TC qdisc del dev $DEV1 ingress" | ||
821 | ] | ||
822 | }, | ||
823 | { | ||
824 | "id": "0e99", | ||
825 | "name": "Del single fw filter x1", | ||
826 | "__comment__": "First of two tests to check that one filter is there and the other isn't", | ||
827 | "category": [ | ||
828 | "filter", | ||
829 | "fw" | ||
830 | ], | ||
831 | "setup": [ | ||
832 | "$TC qdisc add dev $DEV1 ingress", | ||
833 | "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass", | ||
834 | "$TC filter add dev $DEV1 parent ffff: handle 3 prio 9 fw action pass" | ||
835 | ], | ||
836 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 3 prio 9 fw action pass", | ||
837 | "expExitCode": "0", | ||
838 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
839 | "matchPattern": "protocol all pref 7.*handle 0x5.*gact action pass", | ||
840 | "matchCount": "1", | ||
841 | "teardown": [ | ||
842 | "$TC qdisc del dev $DEV1 ingress" | ||
843 | ] | ||
844 | }, | ||
845 | { | ||
846 | "id": "f54c", | ||
847 | "name": "Del single fw filter x2", | ||
848 | "__comment__": "Second of two tests to check that one filter is there and the other isn't", | ||
849 | "category": [ | ||
850 | "filter", | ||
851 | "fw" | ||
852 | ], | ||
853 | "setup": [ | ||
854 | "$TC qdisc add dev $DEV1 ingress", | ||
855 | "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass", | ||
856 | "$TC filter add dev $DEV1 parent ffff: handle 3 prio 9 fw action pass" | ||
857 | ], | ||
858 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 3 prio 9 fw action pass", | ||
859 | "expExitCode": "0", | ||
860 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
861 | "matchPattern": "protocol all pref 9.*handle 0x3.*gact action pass", | ||
862 | "matchCount": "0", | ||
863 | "teardown": [ | ||
864 | "$TC qdisc del dev $DEV1 ingress" | ||
865 | ] | ||
866 | }, | ||
867 | { | ||
868 | "id": "ba94", | ||
869 | "name": "Del fw filter by prio", | ||
870 | "category": [ | ||
871 | "filter", | ||
872 | "fw" | ||
873 | ], | ||
874 | "setup": [ | ||
875 | "$TC qdisc add dev $DEV1 ingress", | ||
876 | "$TC filter add dev $DEV1 parent ffff: handle 1 prio 4 fw action ok", | ||
877 | "$TC filter add dev $DEV1 parent ffff: handle 2 prio 4 fw action ok" | ||
878 | ], | ||
879 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: prio 4", | ||
880 | "expExitCode": "0", | ||
881 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
882 | "matchPattern": "pref 4 fw.*gact action pass", | ||
883 | "matchCount": "0", | ||
884 | "teardown": [ | ||
885 | "$TC qdisc del dev $DEV1 ingress" | ||
886 | ] | ||
887 | }, | ||
888 | { | ||
889 | "id": "4acb", | ||
890 | "name": "Del fw filter by chain", | ||
891 | "category": [ | ||
892 | "filter", | ||
893 | "fw" | ||
894 | ], | ||
895 | "setup": [ | ||
896 | "$TC qdisc add dev $DEV1 ingress", | ||
897 | "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 chain 13 fw action pipe", | ||
898 | "$TC filter add dev $DEV1 parent ffff: handle 3 prio 5 chain 13 fw action pipe" | ||
899 | ], | ||
900 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: chain 13", | ||
901 | "expExitCode": "0", | ||
902 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
903 | "matchPattern": "fw chain 13 handle.*gact action pipe", | ||
904 | "matchCount": "0", | ||
905 | "teardown": [ | ||
906 | "$TC qdisc del dev $DEV1 ingress" | ||
907 | ] | ||
908 | }, | ||
909 | { | ||
910 | "id": "3424", | ||
911 | "name": "Del fw filter by action (invalid)", | ||
912 | "category": [ | ||
913 | "filter", | ||
914 | "fw" | ||
915 | ], | ||
916 | "setup": [ | ||
917 | "$TC qdisc add dev $DEV1 ingress", | ||
918 | "$TC filter add dev $DEV1 parent ffff: handle 2 prio 4 fw action drop" | ||
919 | ], | ||
920 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: fw action drop", | ||
921 | "expExitCode": "2", | ||
922 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 2 prio 4 protocol all fw", | ||
923 | "matchPattern": "handle 0x2.*gact action drop", | ||
924 | "matchCount": "1", | ||
925 | "teardown": [ | ||
926 | "$TC qdisc del dev $DEV1 ingress" | ||
927 | ] | ||
928 | }, | ||
929 | { | ||
930 | "id": "da89", | ||
931 | "name": "Del fw filter by handle (invalid)", | ||
932 | "category": [ | ||
933 | "filter", | ||
934 | "fw" | ||
935 | ], | ||
936 | "setup": [ | ||
937 | "$TC qdisc add dev $DEV1 ingress", | ||
938 | "$TC filter add dev $DEV1 parent ffff: handle 3 prio 4 fw action continue" | ||
939 | ], | ||
940 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: handle 3 fw", | ||
941 | "expExitCode": "2", | ||
942 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 3 prio 4 protocol all fw", | ||
943 | "matchPattern": "handle 0x3.*gact action continue", | ||
944 | "matchCount": "1", | ||
945 | "teardown": [ | ||
946 | "$TC qdisc del dev $DEV1 ingress" | ||
947 | ] | ||
948 | }, | ||
949 | { | ||
950 | "id": "4d95", | ||
951 | "name": "Del fw filter by protocol (invalid)", | ||
952 | "category": [ | ||
953 | "filter", | ||
954 | "fw" | ||
955 | ], | ||
956 | "setup": [ | ||
957 | "$TC qdisc add dev $DEV1 ingress", | ||
958 | "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 protocol arp fw action pipe" | ||
959 | ], | ||
960 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: protocol arp fw", | ||
961 | "expExitCode": "2", | ||
962 | "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 4 prio 2 protocol arp fw", | ||
963 | "matchPattern": "filter parent ffff: protocol arp.*handle 0x4.*gact action pipe", | ||
964 | "matchCount": "1", | ||
965 | "teardown": [ | ||
966 | "$TC qdisc del dev $DEV1 ingress" | ||
967 | ] | ||
968 | }, | ||
969 | { | ||
970 | "id": "4736", | ||
971 | "name": "Del fw filter by flowid (invalid)", | ||
972 | "category": [ | ||
973 | "filter", | ||
974 | "fw" | ||
975 | ], | ||
976 | "setup": [ | ||
977 | "$TC qdisc add dev $DEV1 ingress", | ||
978 | "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 fw action pipe flowid 45" | ||
979 | ], | ||
980 | "cmdUnderTest": "$TC filter del dev $DEV1 parent ffff: fw flowid 45", | ||
981 | "expExitCode": "2", | ||
982 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
983 | "matchPattern": "handle 0x4.*gact action pipe", | ||
984 | "matchCount": "1", | ||
985 | "teardown": [ | ||
986 | "$TC qdisc del dev $DEV1 ingress" | ||
987 | ] | ||
988 | }, | ||
989 | { | ||
990 | "id": "3dcb", | ||
991 | "name": "Replace fw filter action", | ||
992 | "category": [ | ||
993 | "filter", | ||
994 | "fw" | ||
995 | ], | ||
996 | "setup": [ | ||
997 | "$TC qdisc add dev $DEV1 ingress", | ||
998 | "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok" | ||
999 | ], | ||
1000 | "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: handle 1 prio 2 fw action pipe", | ||
1001 | "expExitCode": "0", | ||
1002 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
1003 | "matchPattern": "pref 2 fw.*handle 0x1.*gact action pipe", | ||
1004 | "matchCount": "1", | ||
1005 | "teardown": [ | ||
1006 | "$TC qdisc del dev $DEV1 ingress" | ||
1007 | ] | ||
1008 | }, | ||
1009 | { | ||
1010 | "id": "eb4d", | ||
1011 | "name": "Replace fw filter classid", | ||
1012 | "category": [ | ||
1013 | "filter", | ||
1014 | "fw" | ||
1015 | ], | ||
1016 | "setup": [ | ||
1017 | "$TC qdisc add dev $DEV1 ingress", | ||
1018 | "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok" | ||
1019 | ], | ||
1020 | "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: handle 1 prio 2 fw action pipe classid 2", | ||
1021 | "expExitCode": "0", | ||
1022 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
1023 | "matchPattern": "pref 2 fw.*handle 0x1 classid :2.*gact action pipe", | ||
1024 | "matchCount": "1", | ||
1025 | "teardown": [ | ||
1026 | "$TC qdisc del dev $DEV1 ingress" | ||
1027 | ] | ||
1028 | }, | ||
1029 | { | ||
1030 | "id": "67ec", | ||
1031 | "name": "Replace fw filter index", | ||
1032 | "category": [ | ||
1033 | "filter", | ||
1034 | "fw" | ||
1035 | ], | ||
1036 | "setup": [ | ||
1037 | "$TC qdisc add dev $DEV1 ingress", | ||
1038 | "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok index 3" | ||
1039 | ], | ||
1040 | "cmdUnderTest": "$TC filter replace dev $DEV1 parent ffff: handle 1 prio 2 fw action ok index 16", | ||
1041 | "expExitCode": "0", | ||
1042 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | ||
1043 | "matchPattern": "pref 2 fw.*handle 0x1.*gact action pass.*index 16", | ||
1044 | "matchCount": "1", | ||
1045 | "teardown": [ | ||
1046 | "$TC qdisc del dev $DEV1 ingress" | ||
1047 | ] | ||
1048 | } | ||
1049 | ] | ||
diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json index 5fa02d86b35f..99a5ffca1088 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json | |||
@@ -12,8 +12,8 @@ | |||
12 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 u32 match ip src 127.0.0.1/32 flowid 1:1 action ok", | 12 | "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: protocol ip prio 1 u32 match ip src 127.0.0.1/32 flowid 1:1 action ok", |
13 | "expExitCode": "0", | 13 | "expExitCode": "0", |
14 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", | 14 | "verifyCmd": "$TC filter show dev $DEV1 parent ffff:", |
15 | "matchPattern": "match 7f000002/ffffffff at 12", | 15 | "matchPattern": "match 7f000001/ffffffff at 12", |
16 | "matchCount": "0", | 16 | "matchCount": "1", |
17 | "teardown": [ | 17 | "teardown": [ |
18 | "$TC qdisc del dev $DEV1 ingress" | 18 | "$TC qdisc del dev $DEV1 ingress" |
19 | ] | 19 | ] |
diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c index ca6cd146aafe..dcf73c5dab6e 100644 --- a/tools/testing/selftests/timers/raw_skew.c +++ b/tools/testing/selftests/timers/raw_skew.c | |||
@@ -134,6 +134,11 @@ int main(int argv, char **argc) | |||
134 | printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000))); | 134 | printf(" %lld.%i(act)", ppm/1000, abs((int)(ppm%1000))); |
135 | 135 | ||
136 | if (llabs(eppm - ppm) > 1000) { | 136 | if (llabs(eppm - ppm) > 1000) { |
137 | if (tx1.offset || tx2.offset || | ||
138 | tx1.freq != tx2.freq || tx1.tick != tx2.tick) { | ||
139 | printf(" [SKIP]\n"); | ||
140 | return ksft_exit_skip("The clock was adjusted externally. Shutdown NTPd or other time sync daemons\n"); | ||
141 | } | ||
137 | printf(" [FAILED]\n"); | 142 | printf(" [FAILED]\n"); |
138 | return ksft_exit_fail(); | 143 | return ksft_exit_fail(); |
139 | } | 144 | } |