diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2019-08-09 10:53:39 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-08-09 10:53:39 -0400 |
commit | 0e1c438c44dd9cde56effb44c5f1cfeda72e108d (patch) | |
tree | fa3492d4d7d8b7444e5d8ebe6c78210826333e4b /tools | |
parent | c096397c78f766db972f923433031f2dec01cae0 (diff) | |
parent | cdb2d3ee0436d74fa9092f2df46aaa6f9e03c969 (diff) |
Merge tag 'kvmarm-fixes-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm fixes for 5.3
- A bunch of switch/case fall-through annotation, fixing one actual bug
- Fix PMU reset bug
- Add missing exception class debug strings
Diffstat (limited to 'tools')
228 files changed, 5860 insertions, 840 deletions
diff --git a/tools/Makefile b/tools/Makefile index 3dfd72ae6c1a..68defd7ecf5d 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -19,6 +19,7 @@ help: | |||
19 | @echo ' gpio - GPIO tools' | 19 | @echo ' gpio - GPIO tools' |
20 | @echo ' hv - tools used when in Hyper-V clients' | 20 | @echo ' hv - tools used when in Hyper-V clients' |
21 | @echo ' iio - IIO tools' | 21 | @echo ' iio - IIO tools' |
22 | @echo ' intel-speed-select - Intel Speed Select tool' | ||
22 | @echo ' kvm_stat - top-like utility for displaying kvm statistics' | 23 | @echo ' kvm_stat - top-like utility for displaying kvm statistics' |
23 | @echo ' leds - LEDs tools' | 24 | @echo ' leds - LEDs tools' |
24 | @echo ' liblockdep - user-space wrapper for kernel locking-validator' | 25 | @echo ' liblockdep - user-space wrapper for kernel locking-validator' |
@@ -82,7 +83,7 @@ perf: FORCE | |||
82 | selftests: FORCE | 83 | selftests: FORCE |
83 | $(call descend,testing/$@) | 84 | $(call descend,testing/$@) |
84 | 85 | ||
85 | turbostat x86_energy_perf_policy: FORCE | 86 | turbostat x86_energy_perf_policy intel-speed-select: FORCE |
86 | $(call descend,power/x86/$@) | 87 | $(call descend,power/x86/$@) |
87 | 88 | ||
88 | tmon: FORCE | 89 | tmon: FORCE |
@@ -115,7 +116,7 @@ liblockdep_install: | |||
115 | selftests_install: | 116 | selftests_install: |
116 | $(call descend,testing/$(@:_install=),install) | 117 | $(call descend,testing/$(@:_install=),install) |
117 | 118 | ||
118 | turbostat_install x86_energy_perf_policy_install: | 119 | turbostat_install x86_energy_perf_policy_install intel-speed-select_install: |
119 | $(call descend,power/x86/$(@:_install=),install) | 120 | $(call descend,power/x86/$(@:_install=),install) |
120 | 121 | ||
121 | tmon_install: | 122 | tmon_install: |
@@ -132,7 +133,7 @@ install: acpi_install cgroup_install cpupower_install gpio_install \ | |||
132 | perf_install selftests_install turbostat_install usb_install \ | 133 | perf_install selftests_install turbostat_install usb_install \ |
133 | virtio_install vm_install bpf_install x86_energy_perf_policy_install \ | 134 | virtio_install vm_install bpf_install x86_energy_perf_policy_install \ |
134 | tmon_install freefall_install objtool_install kvm_stat_install \ | 135 | tmon_install freefall_install objtool_install kvm_stat_install \ |
135 | wmi_install pci_install debugging_install | 136 | wmi_install pci_install debugging_install intel-speed-select_install |
136 | 137 | ||
137 | acpi_clean: | 138 | acpi_clean: |
138 | $(call descend,power/acpi,clean) | 139 | $(call descend,power/acpi,clean) |
@@ -162,7 +163,7 @@ perf_clean: | |||
162 | selftests_clean: | 163 | selftests_clean: |
163 | $(call descend,testing/$(@:_clean=),clean) | 164 | $(call descend,testing/$(@:_clean=),clean) |
164 | 165 | ||
165 | turbostat_clean x86_energy_perf_policy_clean: | 166 | turbostat_clean x86_energy_perf_policy_clean intel-speed-select_clean: |
166 | $(call descend,power/x86/$(@:_clean=),clean) | 167 | $(call descend,power/x86/$(@:_clean=),clean) |
167 | 168 | ||
168 | tmon_clean: | 169 | tmon_clean: |
@@ -178,6 +179,7 @@ clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \ | |||
178 | perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ | 179 | perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ |
179 | vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ | 180 | vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ |
180 | freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ | 181 | freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ |
181 | gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean | 182 | gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \ |
183 | intel-speed-select_clean | ||
182 | 184 | ||
183 | .PHONY: FORCE | 185 | .PHONY: FORCE |
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h index 3ef0d9051e10..7031a4bf87a0 100644 --- a/tools/bpf/bpftool/main.h +++ b/tools/bpf/bpftool/main.h | |||
@@ -74,6 +74,7 @@ static const char * const prog_type_name[] = { | |||
74 | [BPF_PROG_TYPE_SK_REUSEPORT] = "sk_reuseport", | 74 | [BPF_PROG_TYPE_SK_REUSEPORT] = "sk_reuseport", |
75 | [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector", | 75 | [BPF_PROG_TYPE_FLOW_DISSECTOR] = "flow_dissector", |
76 | [BPF_PROG_TYPE_CGROUP_SYSCTL] = "cgroup_sysctl", | 76 | [BPF_PROG_TYPE_CGROUP_SYSCTL] = "cgroup_sysctl", |
77 | [BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE] = "raw_tracepoint_writable", | ||
77 | [BPF_PROG_TYPE_CGROUP_SOCKOPT] = "cgroup_sockopt", | 78 | [BPF_PROG_TYPE_CGROUP_SOCKOPT] = "cgroup_sockopt", |
78 | }; | 79 | }; |
79 | 80 | ||
diff --git a/tools/include/linux/zalloc.h b/tools/include/linux/zalloc.h new file mode 100644 index 000000000000..81099c84043f --- /dev/null +++ b/tools/include/linux/zalloc.h | |||
@@ -0,0 +1,12 @@ | |||
1 | // SPDX-License-Identifier: LGPL-2.1 | ||
2 | #ifndef __TOOLS_LINUX_ZALLOC_H | ||
3 | #define __TOOLS_LINUX_ZALLOC_H | ||
4 | |||
5 | #include <stddef.h> | ||
6 | |||
7 | void *zalloc(size_t size); | ||
8 | void __zfree(void **ptr); | ||
9 | |||
10 | #define zfree(ptr) __zfree((void **)(ptr)) | ||
11 | |||
12 | #endif // __TOOLS_LINUX_ZALLOC_H | ||
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index f506c68b2612..4e455018da65 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
@@ -806,7 +806,7 @@ union bpf_attr { | |||
806 | * based on a user-provided identifier for all traffic coming from | 806 | * based on a user-provided identifier for all traffic coming from |
807 | * the tasks belonging to the related cgroup. See also the related | 807 | * the tasks belonging to the related cgroup. See also the related |
808 | * kernel documentation, available from the Linux sources in file | 808 | * kernel documentation, available from the Linux sources in file |
809 | * *Documentation/cgroup-v1/net_cls.rst*. | 809 | * *Documentation/admin-guide/cgroup-v1/net_cls.rst*. |
810 | * | 810 | * |
811 | * The Linux kernel has two versions for cgroups: there are | 811 | * The Linux kernel has two versions for cgroups: there are |
812 | * cgroups v1 and cgroups v2. Both are available to users, who can | 812 | * cgroups v1 and cgroups v2. Both are available to users, who can |
@@ -3245,7 +3245,7 @@ struct bpf_sock_addr { | |||
3245 | __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. | 3245 | __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. |
3246 | * Stored in network byte order. | 3246 | * Stored in network byte order. |
3247 | */ | 3247 | */ |
3248 | __u32 user_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. | 3248 | __u32 user_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write. |
3249 | * Stored in network byte order. | 3249 | * Stored in network byte order. |
3250 | */ | 3250 | */ |
3251 | __u32 user_port; /* Allows 4-byte read and write. | 3251 | __u32 user_port; /* Allows 4-byte read and write. |
@@ -3257,7 +3257,7 @@ struct bpf_sock_addr { | |||
3257 | __u32 msg_src_ip4; /* Allows 1,2,4-byte read and 4-byte write. | 3257 | __u32 msg_src_ip4; /* Allows 1,2,4-byte read and 4-byte write. |
3258 | * Stored in network byte order. | 3258 | * Stored in network byte order. |
3259 | */ | 3259 | */ |
3260 | __u32 msg_src_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. | 3260 | __u32 msg_src_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write. |
3261 | * Stored in network byte order. | 3261 | * Stored in network byte order. |
3262 | */ | 3262 | */ |
3263 | __bpf_md_ptr(struct bpf_sock *, sk); | 3263 | __bpf_md_ptr(struct bpf_sock *, sk); |
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index ed07789b3e62..794dd5064ae8 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -4126,8 +4126,8 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name, | |||
4126 | } | 4126 | } |
4127 | attr.size = sizeof(attr); | 4127 | attr.size = sizeof(attr); |
4128 | attr.type = type; | 4128 | attr.type = type; |
4129 | attr.config1 = (uint64_t)(void *)name; /* kprobe_func or uprobe_path */ | 4129 | attr.config1 = ptr_to_u64(name); /* kprobe_func or uprobe_path */ |
4130 | attr.config2 = offset; /* kprobe_addr or probe_offset */ | 4130 | attr.config2 = offset; /* kprobe_addr or probe_offset */ |
4131 | 4131 | ||
4132 | /* pid filter is meaningful only for uprobes */ | 4132 | /* pid filter is meaningful only for uprobes */ |
4133 | pfd = syscall(__NR_perf_event_open, &attr, | 4133 | pfd = syscall(__NR_perf_event_open, &attr, |
diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index b33740221b7e..5007b5d4fd2c 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c | |||
@@ -517,7 +517,8 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, | |||
517 | err = -errno; | 517 | err = -errno; |
518 | goto out_socket; | 518 | goto out_socket; |
519 | } | 519 | } |
520 | strncpy(xsk->ifname, ifname, IFNAMSIZ); | 520 | strncpy(xsk->ifname, ifname, IFNAMSIZ - 1); |
521 | xsk->ifname[IFNAMSIZ - 1] = '\0'; | ||
521 | 522 | ||
522 | err = xsk_set_xdp_socket_config(&xsk->config, usr_config); | 523 | err = xsk_set_xdp_socket_config(&xsk->config, usr_config); |
523 | if (err) | 524 | if (err) |
diff --git a/tools/lib/zalloc.c b/tools/lib/zalloc.c new file mode 100644 index 000000000000..9c856d59f56e --- /dev/null +++ b/tools/lib/zalloc.c | |||
@@ -0,0 +1,15 @@ | |||
1 | // SPDX-License-Identifier: LGPL-2.1 | ||
2 | |||
3 | #include <stdlib.h> | ||
4 | #include <linux/zalloc.h> | ||
5 | |||
6 | void *zalloc(size_t size) | ||
7 | { | ||
8 | return calloc(1, size); | ||
9 | } | ||
10 | |||
11 | void __zfree(void **ptr) | ||
12 | { | ||
13 | free(*ptr); | ||
14 | *ptr = NULL; | ||
15 | } | ||
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h index 580e344db3dd..ced3765c4f44 100644 --- a/tools/objtool/arch.h +++ b/tools/objtool/arch.h | |||
@@ -11,22 +11,24 @@ | |||
11 | #include "elf.h" | 11 | #include "elf.h" |
12 | #include "cfi.h" | 12 | #include "cfi.h" |
13 | 13 | ||
14 | #define INSN_JUMP_CONDITIONAL 1 | 14 | enum insn_type { |
15 | #define INSN_JUMP_UNCONDITIONAL 2 | 15 | INSN_JUMP_CONDITIONAL, |
16 | #define INSN_JUMP_DYNAMIC 3 | 16 | INSN_JUMP_UNCONDITIONAL, |
17 | #define INSN_CALL 4 | 17 | INSN_JUMP_DYNAMIC, |
18 | #define INSN_CALL_DYNAMIC 5 | 18 | INSN_JUMP_DYNAMIC_CONDITIONAL, |
19 | #define INSN_RETURN 6 | 19 | INSN_CALL, |
20 | #define INSN_CONTEXT_SWITCH 7 | 20 | INSN_CALL_DYNAMIC, |
21 | #define INSN_STACK 8 | 21 | INSN_RETURN, |
22 | #define INSN_BUG 9 | 22 | INSN_CONTEXT_SWITCH, |
23 | #define INSN_NOP 10 | 23 | INSN_STACK, |
24 | #define INSN_STAC 11 | 24 | INSN_BUG, |
25 | #define INSN_CLAC 12 | 25 | INSN_NOP, |
26 | #define INSN_STD 13 | 26 | INSN_STAC, |
27 | #define INSN_CLD 14 | 27 | INSN_CLAC, |
28 | #define INSN_OTHER 15 | 28 | INSN_STD, |
29 | #define INSN_LAST INSN_OTHER | 29 | INSN_CLD, |
30 | INSN_OTHER, | ||
31 | }; | ||
30 | 32 | ||
31 | enum op_dest_type { | 33 | enum op_dest_type { |
32 | OP_DEST_REG, | 34 | OP_DEST_REG, |
@@ -68,7 +70,7 @@ void arch_initial_func_cfi_state(struct cfi_state *state); | |||
68 | 70 | ||
69 | int arch_decode_instruction(struct elf *elf, struct section *sec, | 71 | int arch_decode_instruction(struct elf *elf, struct section *sec, |
70 | unsigned long offset, unsigned int maxlen, | 72 | unsigned long offset, unsigned int maxlen, |
71 | unsigned int *len, unsigned char *type, | 73 | unsigned int *len, enum insn_type *type, |
72 | unsigned long *immediate, struct stack_op *op); | 74 | unsigned long *immediate, struct stack_op *op); |
73 | 75 | ||
74 | bool arch_callee_saved_reg(unsigned char reg); | 76 | bool arch_callee_saved_reg(unsigned char reg); |
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 584568f27a83..0567c47a91b1 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c | |||
@@ -68,7 +68,7 @@ bool arch_callee_saved_reg(unsigned char reg) | |||
68 | 68 | ||
69 | int arch_decode_instruction(struct elf *elf, struct section *sec, | 69 | int arch_decode_instruction(struct elf *elf, struct section *sec, |
70 | unsigned long offset, unsigned int maxlen, | 70 | unsigned long offset, unsigned int maxlen, |
71 | unsigned int *len, unsigned char *type, | 71 | unsigned int *len, enum insn_type *type, |
72 | unsigned long *immediate, struct stack_op *op) | 72 | unsigned long *immediate, struct stack_op *op) |
73 | { | 73 | { |
74 | struct insn insn; | 74 | struct insn insn; |
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 172f99195726..5f26620f13f5 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c | |||
@@ -18,6 +18,8 @@ | |||
18 | 18 | ||
19 | #define FAKE_JUMP_OFFSET -1 | 19 | #define FAKE_JUMP_OFFSET -1 |
20 | 20 | ||
21 | #define C_JUMP_TABLE_SECTION ".rodata..c_jump_table" | ||
22 | |||
21 | struct alternative { | 23 | struct alternative { |
22 | struct list_head list; | 24 | struct list_head list; |
23 | struct instruction *insn; | 25 | struct instruction *insn; |
@@ -95,6 +97,20 @@ static struct instruction *next_insn_same_func(struct objtool_file *file, | |||
95 | for (insn = next_insn_same_sec(file, insn); insn; \ | 97 | for (insn = next_insn_same_sec(file, insn); insn; \ |
96 | insn = next_insn_same_sec(file, insn)) | 98 | insn = next_insn_same_sec(file, insn)) |
97 | 99 | ||
100 | static bool is_sibling_call(struct instruction *insn) | ||
101 | { | ||
102 | /* An indirect jump is either a sibling call or a jump to a table. */ | ||
103 | if (insn->type == INSN_JUMP_DYNAMIC) | ||
104 | return list_empty(&insn->alts); | ||
105 | |||
106 | if (insn->type != INSN_JUMP_CONDITIONAL && | ||
107 | insn->type != INSN_JUMP_UNCONDITIONAL) | ||
108 | return false; | ||
109 | |||
110 | /* add_jump_destinations() sets insn->call_dest for sibling calls. */ | ||
111 | return !!insn->call_dest; | ||
112 | } | ||
113 | |||
98 | /* | 114 | /* |
99 | * This checks to see if the given function is a "noreturn" function. | 115 | * This checks to see if the given function is a "noreturn" function. |
100 | * | 116 | * |
@@ -103,14 +119,9 @@ static struct instruction *next_insn_same_func(struct objtool_file *file, | |||
103 | * | 119 | * |
104 | * For local functions, we have to detect them manually by simply looking for | 120 | * For local functions, we have to detect them manually by simply looking for |
105 | * the lack of a return instruction. | 121 | * the lack of a return instruction. |
106 | * | ||
107 | * Returns: | ||
108 | * -1: error | ||
109 | * 0: no dead end | ||
110 | * 1: dead end | ||
111 | */ | 122 | */ |
112 | static int __dead_end_function(struct objtool_file *file, struct symbol *func, | 123 | static bool __dead_end_function(struct objtool_file *file, struct symbol *func, |
113 | int recursion) | 124 | int recursion) |
114 | { | 125 | { |
115 | int i; | 126 | int i; |
116 | struct instruction *insn; | 127 | struct instruction *insn; |
@@ -136,30 +147,33 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, | |||
136 | "rewind_stack_do_exit", | 147 | "rewind_stack_do_exit", |
137 | }; | 148 | }; |
138 | 149 | ||
150 | if (!func) | ||
151 | return false; | ||
152 | |||
139 | if (func->bind == STB_WEAK) | 153 | if (func->bind == STB_WEAK) |
140 | return 0; | 154 | return false; |
141 | 155 | ||
142 | if (func->bind == STB_GLOBAL) | 156 | if (func->bind == STB_GLOBAL) |
143 | for (i = 0; i < ARRAY_SIZE(global_noreturns); i++) | 157 | for (i = 0; i < ARRAY_SIZE(global_noreturns); i++) |
144 | if (!strcmp(func->name, global_noreturns[i])) | 158 | if (!strcmp(func->name, global_noreturns[i])) |
145 | return 1; | 159 | return true; |
146 | 160 | ||
147 | if (!func->len) | 161 | if (!func->len) |
148 | return 0; | 162 | return false; |
149 | 163 | ||
150 | insn = find_insn(file, func->sec, func->offset); | 164 | insn = find_insn(file, func->sec, func->offset); |
151 | if (!insn->func) | 165 | if (!insn->func) |
152 | return 0; | 166 | return false; |
153 | 167 | ||
154 | func_for_each_insn_all(file, func, insn) { | 168 | func_for_each_insn_all(file, func, insn) { |
155 | empty = false; | 169 | empty = false; |
156 | 170 | ||
157 | if (insn->type == INSN_RETURN) | 171 | if (insn->type == INSN_RETURN) |
158 | return 0; | 172 | return false; |
159 | } | 173 | } |
160 | 174 | ||
161 | if (empty) | 175 | if (empty) |
162 | return 0; | 176 | return false; |
163 | 177 | ||
164 | /* | 178 | /* |
165 | * A function can have a sibling call instead of a return. In that | 179 | * A function can have a sibling call instead of a return. In that |
@@ -167,40 +181,31 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func, | |||
167 | * of the sibling call returns. | 181 | * of the sibling call returns. |
168 | */ | 182 | */ |
169 | func_for_each_insn_all(file, func, insn) { | 183 | func_for_each_insn_all(file, func, insn) { |
170 | if (insn->type == INSN_JUMP_UNCONDITIONAL) { | 184 | if (is_sibling_call(insn)) { |
171 | struct instruction *dest = insn->jump_dest; | 185 | struct instruction *dest = insn->jump_dest; |
172 | 186 | ||
173 | if (!dest) | 187 | if (!dest) |
174 | /* sibling call to another file */ | 188 | /* sibling call to another file */ |
175 | return 0; | 189 | return false; |
176 | |||
177 | if (dest->func && dest->func->pfunc != insn->func->pfunc) { | ||
178 | 190 | ||
179 | /* local sibling call */ | 191 | /* local sibling call */ |
180 | if (recursion == 5) { | 192 | if (recursion == 5) { |
181 | /* | 193 | /* |
182 | * Infinite recursion: two functions | 194 | * Infinite recursion: two functions have |
183 | * have sibling calls to each other. | 195 | * sibling calls to each other. This is a very |
184 | * This is a very rare case. It means | 196 | * rare case. It means they aren't dead ends. |
185 | * they aren't dead ends. | 197 | */ |
186 | */ | 198 | return false; |
187 | return 0; | ||
188 | } | ||
189 | |||
190 | return __dead_end_function(file, dest->func, | ||
191 | recursion + 1); | ||
192 | } | 199 | } |
193 | } | ||
194 | 200 | ||
195 | if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts)) | 201 | return __dead_end_function(file, dest->func, recursion+1); |
196 | /* sibling call */ | 202 | } |
197 | return 0; | ||
198 | } | 203 | } |
199 | 204 | ||
200 | return 1; | 205 | return true; |
201 | } | 206 | } |
202 | 207 | ||
203 | static int dead_end_function(struct objtool_file *file, struct symbol *func) | 208 | static bool dead_end_function(struct objtool_file *file, struct symbol *func) |
204 | { | 209 | { |
205 | return __dead_end_function(file, func, 0); | 210 | return __dead_end_function(file, func, 0); |
206 | } | 211 | } |
@@ -262,19 +267,12 @@ static int decode_instructions(struct objtool_file *file) | |||
262 | if (ret) | 267 | if (ret) |
263 | goto err; | 268 | goto err; |
264 | 269 | ||
265 | if (!insn->type || insn->type > INSN_LAST) { | ||
266 | WARN_FUNC("invalid instruction type %d", | ||
267 | insn->sec, insn->offset, insn->type); | ||
268 | ret = -1; | ||
269 | goto err; | ||
270 | } | ||
271 | |||
272 | hash_add(file->insn_hash, &insn->hash, insn->offset); | 270 | hash_add(file->insn_hash, &insn->hash, insn->offset); |
273 | list_add_tail(&insn->list, &file->insn_list); | 271 | list_add_tail(&insn->list, &file->insn_list); |
274 | } | 272 | } |
275 | 273 | ||
276 | list_for_each_entry(func, &sec->symbol_list, list) { | 274 | list_for_each_entry(func, &sec->symbol_list, list) { |
277 | if (func->type != STT_FUNC) | 275 | if (func->type != STT_FUNC || func->alias != func) |
278 | continue; | 276 | continue; |
279 | 277 | ||
280 | if (!find_insn(file, sec, func->offset)) { | 278 | if (!find_insn(file, sec, func->offset)) { |
@@ -284,8 +282,7 @@ static int decode_instructions(struct objtool_file *file) | |||
284 | } | 282 | } |
285 | 283 | ||
286 | func_for_each_insn(file, func, insn) | 284 | func_for_each_insn(file, func, insn) |
287 | if (!insn->func) | 285 | insn->func = func; |
288 | insn->func = func; | ||
289 | } | 286 | } |
290 | } | 287 | } |
291 | 288 | ||
@@ -488,6 +485,7 @@ static const char *uaccess_safe_builtin[] = { | |||
488 | /* misc */ | 485 | /* misc */ |
489 | "csum_partial_copy_generic", | 486 | "csum_partial_copy_generic", |
490 | "__memcpy_mcsafe", | 487 | "__memcpy_mcsafe", |
488 | "mcsafe_handle_tail", | ||
491 | "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */ | 489 | "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */ |
492 | NULL | 490 | NULL |
493 | }; | 491 | }; |
@@ -505,7 +503,7 @@ static void add_uaccess_safe(struct objtool_file *file) | |||
505 | if (!func) | 503 | if (!func) |
506 | continue; | 504 | continue; |
507 | 505 | ||
508 | func->alias->uaccess_safe = true; | 506 | func->uaccess_safe = true; |
509 | } | 507 | } |
510 | } | 508 | } |
511 | 509 | ||
@@ -577,13 +575,16 @@ static int add_jump_destinations(struct objtool_file *file) | |||
577 | * Retpoline jumps are really dynamic jumps in | 575 | * Retpoline jumps are really dynamic jumps in |
578 | * disguise, so convert them accordingly. | 576 | * disguise, so convert them accordingly. |
579 | */ | 577 | */ |
580 | insn->type = INSN_JUMP_DYNAMIC; | 578 | if (insn->type == INSN_JUMP_UNCONDITIONAL) |
579 | insn->type = INSN_JUMP_DYNAMIC; | ||
580 | else | ||
581 | insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL; | ||
582 | |||
581 | insn->retpoline_safe = true; | 583 | insn->retpoline_safe = true; |
582 | continue; | 584 | continue; |
583 | } else { | 585 | } else { |
584 | /* sibling call */ | 586 | /* external sibling call */ |
585 | insn->call_dest = rela->sym; | 587 | insn->call_dest = rela->sym; |
586 | insn->jump_dest = NULL; | ||
587 | continue; | 588 | continue; |
588 | } | 589 | } |
589 | 590 | ||
@@ -623,7 +624,7 @@ static int add_jump_destinations(struct objtool_file *file) | |||
623 | * However this code can't completely replace the | 624 | * However this code can't completely replace the |
624 | * read_symbols() code because this doesn't detect the | 625 | * read_symbols() code because this doesn't detect the |
625 | * case where the parent function's only reference to a | 626 | * case where the parent function's only reference to a |
626 | * subfunction is through a switch table. | 627 | * subfunction is through a jump table. |
627 | */ | 628 | */ |
628 | if (!strstr(insn->func->name, ".cold.") && | 629 | if (!strstr(insn->func->name, ".cold.") && |
629 | strstr(insn->jump_dest->func->name, ".cold.")) { | 630 | strstr(insn->jump_dest->func->name, ".cold.")) { |
@@ -633,9 +634,8 @@ static int add_jump_destinations(struct objtool_file *file) | |||
633 | } else if (insn->jump_dest->func->pfunc != insn->func->pfunc && | 634 | } else if (insn->jump_dest->func->pfunc != insn->func->pfunc && |
634 | insn->jump_dest->offset == insn->jump_dest->func->offset) { | 635 | insn->jump_dest->offset == insn->jump_dest->func->offset) { |
635 | 636 | ||
636 | /* sibling class */ | 637 | /* internal sibling call */ |
637 | insn->call_dest = insn->jump_dest->func; | 638 | insn->call_dest = insn->jump_dest->func; |
638 | insn->jump_dest = NULL; | ||
639 | } | 639 | } |
640 | } | 640 | } |
641 | } | 641 | } |
@@ -896,20 +896,26 @@ out: | |||
896 | return ret; | 896 | return ret; |
897 | } | 897 | } |
898 | 898 | ||
899 | static int add_switch_table(struct objtool_file *file, struct instruction *insn, | 899 | static int add_jump_table(struct objtool_file *file, struct instruction *insn, |
900 | struct rela *table, struct rela *next_table) | 900 | struct rela *table) |
901 | { | 901 | { |
902 | struct rela *rela = table; | 902 | struct rela *rela = table; |
903 | struct instruction *alt_insn; | 903 | struct instruction *dest_insn; |
904 | struct alternative *alt; | 904 | struct alternative *alt; |
905 | struct symbol *pfunc = insn->func->pfunc; | 905 | struct symbol *pfunc = insn->func->pfunc; |
906 | unsigned int prev_offset = 0; | 906 | unsigned int prev_offset = 0; |
907 | 907 | ||
908 | list_for_each_entry_from(rela, &table->rela_sec->rela_list, list) { | 908 | /* |
909 | if (rela == next_table) | 909 | * Each @rela is a switch table relocation which points to the target |
910 | * instruction. | ||
911 | */ | ||
912 | list_for_each_entry_from(rela, &table->sec->rela_list, list) { | ||
913 | |||
914 | /* Check for the end of the table: */ | ||
915 | if (rela != table && rela->jump_table_start) | ||
910 | break; | 916 | break; |
911 | 917 | ||
912 | /* Make sure the switch table entries are consecutive: */ | 918 | /* Make sure the table entries are consecutive: */ |
913 | if (prev_offset && rela->offset != prev_offset + 8) | 919 | if (prev_offset && rela->offset != prev_offset + 8) |
914 | break; | 920 | break; |
915 | 921 | ||
@@ -918,12 +924,12 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn, | |||
918 | rela->addend == pfunc->offset) | 924 | rela->addend == pfunc->offset) |
919 | break; | 925 | break; |
920 | 926 | ||
921 | alt_insn = find_insn(file, rela->sym->sec, rela->addend); | 927 | dest_insn = find_insn(file, rela->sym->sec, rela->addend); |
922 | if (!alt_insn) | 928 | if (!dest_insn) |
923 | break; | 929 | break; |
924 | 930 | ||
925 | /* Make sure the jmp dest is in the function or subfunction: */ | 931 | /* Make sure the destination is in the same function: */ |
926 | if (alt_insn->func->pfunc != pfunc) | 932 | if (!dest_insn->func || dest_insn->func->pfunc != pfunc) |
927 | break; | 933 | break; |
928 | 934 | ||
929 | alt = malloc(sizeof(*alt)); | 935 | alt = malloc(sizeof(*alt)); |
@@ -932,7 +938,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn, | |||
932 | return -1; | 938 | return -1; |
933 | } | 939 | } |
934 | 940 | ||
935 | alt->insn = alt_insn; | 941 | alt->insn = dest_insn; |
936 | list_add_tail(&alt->list, &insn->alts); | 942 | list_add_tail(&alt->list, &insn->alts); |
937 | prev_offset = rela->offset; | 943 | prev_offset = rela->offset; |
938 | } | 944 | } |
@@ -947,7 +953,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn, | |||
947 | } | 953 | } |
948 | 954 | ||
949 | /* | 955 | /* |
950 | * find_switch_table() - Given a dynamic jump, find the switch jump table in | 956 | * find_jump_table() - Given a dynamic jump, find the switch jump table in |
951 | * .rodata associated with it. | 957 | * .rodata associated with it. |
952 | * | 958 | * |
953 | * There are 3 basic patterns: | 959 | * There are 3 basic patterns: |
@@ -989,13 +995,13 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn, | |||
989 | * | 995 | * |
990 | * NOTE: RETPOLINE made it harder still to decode dynamic jumps. | 996 | * NOTE: RETPOLINE made it harder still to decode dynamic jumps. |
991 | */ | 997 | */ |
992 | static struct rela *find_switch_table(struct objtool_file *file, | 998 | static struct rela *find_jump_table(struct objtool_file *file, |
993 | struct symbol *func, | 999 | struct symbol *func, |
994 | struct instruction *insn) | 1000 | struct instruction *insn) |
995 | { | 1001 | { |
996 | struct rela *text_rela, *rodata_rela; | 1002 | struct rela *text_rela, *table_rela; |
997 | struct instruction *orig_insn = insn; | 1003 | struct instruction *orig_insn = insn; |
998 | struct section *rodata_sec; | 1004 | struct section *table_sec; |
999 | unsigned long table_offset; | 1005 | unsigned long table_offset; |
1000 | 1006 | ||
1001 | /* | 1007 | /* |
@@ -1028,42 +1034,52 @@ static struct rela *find_switch_table(struct objtool_file *file, | |||
1028 | continue; | 1034 | continue; |
1029 | 1035 | ||
1030 | table_offset = text_rela->addend; | 1036 | table_offset = text_rela->addend; |
1031 | rodata_sec = text_rela->sym->sec; | 1037 | table_sec = text_rela->sym->sec; |
1032 | 1038 | ||
1033 | if (text_rela->type == R_X86_64_PC32) | 1039 | if (text_rela->type == R_X86_64_PC32) |
1034 | table_offset += 4; | 1040 | table_offset += 4; |
1035 | 1041 | ||
1036 | /* | 1042 | /* |
1037 | * Make sure the .rodata address isn't associated with a | 1043 | * Make sure the .rodata address isn't associated with a |
1038 | * symbol. gcc jump tables are anonymous data. | 1044 | * symbol. GCC jump tables are anonymous data. |
1045 | * | ||
1046 | * Also support C jump tables which are in the same format as | ||
1047 | * switch jump tables. For objtool to recognize them, they | ||
1048 | * need to be placed in the C_JUMP_TABLE_SECTION section. They | ||
1049 | * have symbols associated with them. | ||
1039 | */ | 1050 | */ |
1040 | if (find_symbol_containing(rodata_sec, table_offset)) | 1051 | if (find_symbol_containing(table_sec, table_offset) && |
1052 | strcmp(table_sec->name, C_JUMP_TABLE_SECTION)) | ||
1041 | continue; | 1053 | continue; |
1042 | 1054 | ||
1043 | rodata_rela = find_rela_by_dest(rodata_sec, table_offset); | 1055 | /* Each table entry has a rela associated with it. */ |
1044 | if (rodata_rela) { | 1056 | table_rela = find_rela_by_dest(table_sec, table_offset); |
1045 | /* | 1057 | if (!table_rela) |
1046 | * Use of RIP-relative switch jumps is quite rare, and | 1058 | continue; |
1047 | * indicates a rare GCC quirk/bug which can leave dead | ||
1048 | * code behind. | ||
1049 | */ | ||
1050 | if (text_rela->type == R_X86_64_PC32) | ||
1051 | file->ignore_unreachables = true; | ||
1052 | 1059 | ||
1053 | return rodata_rela; | 1060 | /* |
1054 | } | 1061 | * Use of RIP-relative switch jumps is quite rare, and |
1062 | * indicates a rare GCC quirk/bug which can leave dead code | ||
1063 | * behind. | ||
1064 | */ | ||
1065 | if (text_rela->type == R_X86_64_PC32) | ||
1066 | file->ignore_unreachables = true; | ||
1067 | |||
1068 | return table_rela; | ||
1055 | } | 1069 | } |
1056 | 1070 | ||
1057 | return NULL; | 1071 | return NULL; |
1058 | } | 1072 | } |
1059 | 1073 | ||
1060 | 1074 | /* | |
1061 | static int add_func_switch_tables(struct objtool_file *file, | 1075 | * First pass: Mark the head of each jump table so that in the next pass, |
1062 | struct symbol *func) | 1076 | * we know when a given jump table ends and the next one starts. |
1077 | */ | ||
1078 | static void mark_func_jump_tables(struct objtool_file *file, | ||
1079 | struct symbol *func) | ||
1063 | { | 1080 | { |
1064 | struct instruction *insn, *last = NULL, *prev_jump = NULL; | 1081 | struct instruction *insn, *last = NULL; |
1065 | struct rela *rela, *prev_rela = NULL; | 1082 | struct rela *rela; |
1066 | int ret; | ||
1067 | 1083 | ||
1068 | func_for_each_insn_all(file, func, insn) { | 1084 | func_for_each_insn_all(file, func, insn) { |
1069 | if (!last) | 1085 | if (!last) |
@@ -1071,7 +1087,7 @@ static int add_func_switch_tables(struct objtool_file *file, | |||
1071 | 1087 | ||
1072 | /* | 1088 | /* |
1073 | * Store back-pointers for unconditional forward jumps such | 1089 | * Store back-pointers for unconditional forward jumps such |
1074 | * that find_switch_table() can back-track using those and | 1090 | * that find_jump_table() can back-track using those and |
1075 | * avoid some potentially confusing code. | 1091 | * avoid some potentially confusing code. |
1076 | */ | 1092 | */ |
1077 | if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && | 1093 | if (insn->type == INSN_JUMP_UNCONDITIONAL && insn->jump_dest && |
@@ -1086,27 +1102,25 @@ static int add_func_switch_tables(struct objtool_file *file, | |||
1086 | if (insn->type != INSN_JUMP_DYNAMIC) | 1102 | if (insn->type != INSN_JUMP_DYNAMIC) |
1087 | continue; | 1103 | continue; |
1088 | 1104 | ||
1089 | rela = find_switch_table(file, func, insn); | 1105 | rela = find_jump_table(file, func, insn); |
1090 | if (!rela) | 1106 | if (rela) { |
1091 | continue; | 1107 | rela->jump_table_start = true; |
1092 | 1108 | insn->jump_table = rela; | |
1093 | /* | ||
1094 | * We found a switch table, but we don't know yet how big it | ||
1095 | * is. Don't add it until we reach the end of the function or | ||
1096 | * the beginning of another switch table in the same function. | ||
1097 | */ | ||
1098 | if (prev_jump) { | ||
1099 | ret = add_switch_table(file, prev_jump, prev_rela, rela); | ||
1100 | if (ret) | ||
1101 | return ret; | ||
1102 | } | 1109 | } |
1103 | |||
1104 | prev_jump = insn; | ||
1105 | prev_rela = rela; | ||
1106 | } | 1110 | } |
1111 | } | ||
1112 | |||
1113 | static int add_func_jump_tables(struct objtool_file *file, | ||
1114 | struct symbol *func) | ||
1115 | { | ||
1116 | struct instruction *insn; | ||
1117 | int ret; | ||
1107 | 1118 | ||
1108 | if (prev_jump) { | 1119 | func_for_each_insn_all(file, func, insn) { |
1109 | ret = add_switch_table(file, prev_jump, prev_rela, NULL); | 1120 | if (!insn->jump_table) |
1121 | continue; | ||
1122 | |||
1123 | ret = add_jump_table(file, insn, insn->jump_table); | ||
1110 | if (ret) | 1124 | if (ret) |
1111 | return ret; | 1125 | return ret; |
1112 | } | 1126 | } |
@@ -1119,7 +1133,7 @@ static int add_func_switch_tables(struct objtool_file *file, | |||
1119 | * section which contains a list of addresses within the function to jump to. | 1133 | * section which contains a list of addresses within the function to jump to. |
1120 | * This finds these jump tables and adds them to the insn->alts lists. | 1134 | * This finds these jump tables and adds them to the insn->alts lists. |
1121 | */ | 1135 | */ |
1122 | static int add_switch_table_alts(struct objtool_file *file) | 1136 | static int add_jump_table_alts(struct objtool_file *file) |
1123 | { | 1137 | { |
1124 | struct section *sec; | 1138 | struct section *sec; |
1125 | struct symbol *func; | 1139 | struct symbol *func; |
@@ -1133,7 +1147,8 @@ static int add_switch_table_alts(struct objtool_file *file) | |||
1133 | if (func->type != STT_FUNC) | 1147 | if (func->type != STT_FUNC) |
1134 | continue; | 1148 | continue; |
1135 | 1149 | ||
1136 | ret = add_func_switch_tables(file, func); | 1150 | mark_func_jump_tables(file, func); |
1151 | ret = add_func_jump_tables(file, func); | ||
1137 | if (ret) | 1152 | if (ret) |
1138 | return ret; | 1153 | return ret; |
1139 | } | 1154 | } |
@@ -1277,13 +1292,18 @@ static void mark_rodata(struct objtool_file *file) | |||
1277 | bool found = false; | 1292 | bool found = false; |
1278 | 1293 | ||
1279 | /* | 1294 | /* |
1280 | * This searches for the .rodata section or multiple .rodata.func_name | 1295 | * Search for the following rodata sections, each of which can |
1281 | * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8 | 1296 | * potentially contain jump tables: |
1282 | * rodata sections are ignored as they don't contain jump tables. | 1297 | * |
1298 | * - .rodata: can contain GCC switch tables | ||
1299 | * - .rodata.<func>: same, if -fdata-sections is being used | ||
1300 | * - .rodata..c_jump_table: contains C annotated jump tables | ||
1301 | * | ||
1302 | * .rodata.str1.* sections are ignored; they don't contain jump tables. | ||
1283 | */ | 1303 | */ |
1284 | for_each_sec(file, sec) { | 1304 | for_each_sec(file, sec) { |
1285 | if (!strncmp(sec->name, ".rodata", 7) && | 1305 | if ((!strncmp(sec->name, ".rodata", 7) && !strstr(sec->name, ".str1.")) || |
1286 | !strstr(sec->name, ".str1.")) { | 1306 | !strcmp(sec->name, C_JUMP_TABLE_SECTION)) { |
1287 | sec->rodata = true; | 1307 | sec->rodata = true; |
1288 | found = true; | 1308 | found = true; |
1289 | } | 1309 | } |
@@ -1325,7 +1345,7 @@ static int decode_sections(struct objtool_file *file) | |||
1325 | if (ret) | 1345 | if (ret) |
1326 | return ret; | 1346 | return ret; |
1327 | 1347 | ||
1328 | ret = add_switch_table_alts(file); | 1348 | ret = add_jump_table_alts(file); |
1329 | if (ret) | 1349 | if (ret) |
1330 | return ret; | 1350 | return ret; |
1331 | 1351 | ||
@@ -1873,12 +1893,12 @@ static bool insn_state_match(struct instruction *insn, struct insn_state *state) | |||
1873 | static inline bool func_uaccess_safe(struct symbol *func) | 1893 | static inline bool func_uaccess_safe(struct symbol *func) |
1874 | { | 1894 | { |
1875 | if (func) | 1895 | if (func) |
1876 | return func->alias->uaccess_safe; | 1896 | return func->uaccess_safe; |
1877 | 1897 | ||
1878 | return false; | 1898 | return false; |
1879 | } | 1899 | } |
1880 | 1900 | ||
1881 | static inline const char *insn_dest_name(struct instruction *insn) | 1901 | static inline const char *call_dest_name(struct instruction *insn) |
1882 | { | 1902 | { |
1883 | if (insn->call_dest) | 1903 | if (insn->call_dest) |
1884 | return insn->call_dest->name; | 1904 | return insn->call_dest->name; |
@@ -1890,13 +1910,13 @@ static int validate_call(struct instruction *insn, struct insn_state *state) | |||
1890 | { | 1910 | { |
1891 | if (state->uaccess && !func_uaccess_safe(insn->call_dest)) { | 1911 | if (state->uaccess && !func_uaccess_safe(insn->call_dest)) { |
1892 | WARN_FUNC("call to %s() with UACCESS enabled", | 1912 | WARN_FUNC("call to %s() with UACCESS enabled", |
1893 | insn->sec, insn->offset, insn_dest_name(insn)); | 1913 | insn->sec, insn->offset, call_dest_name(insn)); |
1894 | return 1; | 1914 | return 1; |
1895 | } | 1915 | } |
1896 | 1916 | ||
1897 | if (state->df) { | 1917 | if (state->df) { |
1898 | WARN_FUNC("call to %s() with DF set", | 1918 | WARN_FUNC("call to %s() with DF set", |
1899 | insn->sec, insn->offset, insn_dest_name(insn)); | 1919 | insn->sec, insn->offset, call_dest_name(insn)); |
1900 | return 1; | 1920 | return 1; |
1901 | } | 1921 | } |
1902 | 1922 | ||
@@ -1920,13 +1940,12 @@ static int validate_sibling_call(struct instruction *insn, struct insn_state *st | |||
1920 | * each instruction and validate all the rules described in | 1940 | * each instruction and validate all the rules described in |
1921 | * tools/objtool/Documentation/stack-validation.txt. | 1941 | * tools/objtool/Documentation/stack-validation.txt. |
1922 | */ | 1942 | */ |
1923 | static int validate_branch(struct objtool_file *file, struct instruction *first, | 1943 | static int validate_branch(struct objtool_file *file, struct symbol *func, |
1924 | struct insn_state state) | 1944 | struct instruction *first, struct insn_state state) |
1925 | { | 1945 | { |
1926 | struct alternative *alt; | 1946 | struct alternative *alt; |
1927 | struct instruction *insn, *next_insn; | 1947 | struct instruction *insn, *next_insn; |
1928 | struct section *sec; | 1948 | struct section *sec; |
1929 | struct symbol *func = NULL; | ||
1930 | int ret; | 1949 | int ret; |
1931 | 1950 | ||
1932 | insn = first; | 1951 | insn = first; |
@@ -1947,9 +1966,6 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
1947 | return 1; | 1966 | return 1; |
1948 | } | 1967 | } |
1949 | 1968 | ||
1950 | if (insn->func) | ||
1951 | func = insn->func->pfunc; | ||
1952 | |||
1953 | if (func && insn->ignore) { | 1969 | if (func && insn->ignore) { |
1954 | WARN_FUNC("BUG: why am I validating an ignored function?", | 1970 | WARN_FUNC("BUG: why am I validating an ignored function?", |
1955 | sec, insn->offset); | 1971 | sec, insn->offset); |
@@ -1971,7 +1987,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
1971 | 1987 | ||
1972 | i = insn; | 1988 | i = insn; |
1973 | save_insn = NULL; | 1989 | save_insn = NULL; |
1974 | func_for_each_insn_continue_reverse(file, insn->func, i) { | 1990 | func_for_each_insn_continue_reverse(file, func, i) { |
1975 | if (i->save) { | 1991 | if (i->save) { |
1976 | save_insn = i; | 1992 | save_insn = i; |
1977 | break; | 1993 | break; |
@@ -2017,7 +2033,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
2017 | if (alt->skip_orig) | 2033 | if (alt->skip_orig) |
2018 | skip_orig = true; | 2034 | skip_orig = true; |
2019 | 2035 | ||
2020 | ret = validate_branch(file, alt->insn, state); | 2036 | ret = validate_branch(file, func, alt->insn, state); |
2021 | if (ret) { | 2037 | if (ret) { |
2022 | if (backtrace) | 2038 | if (backtrace) |
2023 | BT_FUNC("(alt)", insn); | 2039 | BT_FUNC("(alt)", insn); |
@@ -2055,7 +2071,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
2055 | 2071 | ||
2056 | if (state.bp_scratch) { | 2072 | if (state.bp_scratch) { |
2057 | WARN("%s uses BP as a scratch register", | 2073 | WARN("%s uses BP as a scratch register", |
2058 | insn->func->name); | 2074 | func->name); |
2059 | return 1; | 2075 | return 1; |
2060 | } | 2076 | } |
2061 | 2077 | ||
@@ -2067,36 +2083,28 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
2067 | if (ret) | 2083 | if (ret) |
2068 | return ret; | 2084 | return ret; |
2069 | 2085 | ||
2070 | if (insn->type == INSN_CALL) { | 2086 | if (!no_fp && func && !is_fentry_call(insn) && |
2071 | if (is_fentry_call(insn)) | 2087 | !has_valid_stack_frame(&state)) { |
2072 | break; | ||
2073 | |||
2074 | ret = dead_end_function(file, insn->call_dest); | ||
2075 | if (ret == 1) | ||
2076 | return 0; | ||
2077 | if (ret == -1) | ||
2078 | return 1; | ||
2079 | } | ||
2080 | |||
2081 | if (!no_fp && func && !has_valid_stack_frame(&state)) { | ||
2082 | WARN_FUNC("call without frame pointer save/setup", | 2088 | WARN_FUNC("call without frame pointer save/setup", |
2083 | sec, insn->offset); | 2089 | sec, insn->offset); |
2084 | return 1; | 2090 | return 1; |
2085 | } | 2091 | } |
2092 | |||
2093 | if (dead_end_function(file, insn->call_dest)) | ||
2094 | return 0; | ||
2095 | |||
2086 | break; | 2096 | break; |
2087 | 2097 | ||
2088 | case INSN_JUMP_CONDITIONAL: | 2098 | case INSN_JUMP_CONDITIONAL: |
2089 | case INSN_JUMP_UNCONDITIONAL: | 2099 | case INSN_JUMP_UNCONDITIONAL: |
2090 | if (func && !insn->jump_dest) { | 2100 | if (func && is_sibling_call(insn)) { |
2091 | ret = validate_sibling_call(insn, &state); | 2101 | ret = validate_sibling_call(insn, &state); |
2092 | if (ret) | 2102 | if (ret) |
2093 | return ret; | 2103 | return ret; |
2094 | 2104 | ||
2095 | } else if (insn->jump_dest && | 2105 | } else if (insn->jump_dest) { |
2096 | (!func || !insn->jump_dest->func || | 2106 | ret = validate_branch(file, func, |
2097 | insn->jump_dest->func->pfunc == func)) { | 2107 | insn->jump_dest, state); |
2098 | ret = validate_branch(file, insn->jump_dest, | ||
2099 | state); | ||
2100 | if (ret) { | 2108 | if (ret) { |
2101 | if (backtrace) | 2109 | if (backtrace) |
2102 | BT_FUNC("(branch)", insn); | 2110 | BT_FUNC("(branch)", insn); |
@@ -2110,13 +2118,17 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
2110 | break; | 2118 | break; |
2111 | 2119 | ||
2112 | case INSN_JUMP_DYNAMIC: | 2120 | case INSN_JUMP_DYNAMIC: |
2113 | if (func && list_empty(&insn->alts)) { | 2121 | case INSN_JUMP_DYNAMIC_CONDITIONAL: |
2122 | if (func && is_sibling_call(insn)) { | ||
2114 | ret = validate_sibling_call(insn, &state); | 2123 | ret = validate_sibling_call(insn, &state); |
2115 | if (ret) | 2124 | if (ret) |
2116 | return ret; | 2125 | return ret; |
2117 | } | 2126 | } |
2118 | 2127 | ||
2119 | return 0; | 2128 | if (insn->type == INSN_JUMP_DYNAMIC) |
2129 | return 0; | ||
2130 | |||
2131 | break; | ||
2120 | 2132 | ||
2121 | case INSN_CONTEXT_SWITCH: | 2133 | case INSN_CONTEXT_SWITCH: |
2122 | if (func && (!next_insn || !next_insn->hint)) { | 2134 | if (func && (!next_insn || !next_insn->hint)) { |
@@ -2162,7 +2174,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
2162 | break; | 2174 | break; |
2163 | 2175 | ||
2164 | case INSN_CLAC: | 2176 | case INSN_CLAC: |
2165 | if (!state.uaccess && insn->func) { | 2177 | if (!state.uaccess && func) { |
2166 | WARN_FUNC("redundant UACCESS disable", sec, insn->offset); | 2178 | WARN_FUNC("redundant UACCESS disable", sec, insn->offset); |
2167 | return 1; | 2179 | return 1; |
2168 | } | 2180 | } |
@@ -2183,7 +2195,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, | |||
2183 | break; | 2195 | break; |
2184 | 2196 | ||
2185 | case INSN_CLD: | 2197 | case INSN_CLD: |
2186 | if (!state.df && insn->func) | 2198 | if (!state.df && func) |
2187 | WARN_FUNC("redundant CLD", sec, insn->offset); | 2199 | WARN_FUNC("redundant CLD", sec, insn->offset); |
2188 | 2200 | ||
2189 | state.df = false; | 2201 | state.df = false; |
@@ -2222,7 +2234,7 @@ static int validate_unwind_hints(struct objtool_file *file) | |||
2222 | 2234 | ||
2223 | for_each_insn(file, insn) { | 2235 | for_each_insn(file, insn) { |
2224 | if (insn->hint && !insn->visited) { | 2236 | if (insn->hint && !insn->visited) { |
2225 | ret = validate_branch(file, insn, state); | 2237 | ret = validate_branch(file, insn->func, insn, state); |
2226 | if (ret && backtrace) | 2238 | if (ret && backtrace) |
2227 | BT_FUNC("<=== (hint)", insn); | 2239 | BT_FUNC("<=== (hint)", insn); |
2228 | warnings += ret; | 2240 | warnings += ret; |
@@ -2345,16 +2357,25 @@ static int validate_functions(struct objtool_file *file) | |||
2345 | 2357 | ||
2346 | for_each_sec(file, sec) { | 2358 | for_each_sec(file, sec) { |
2347 | list_for_each_entry(func, &sec->symbol_list, list) { | 2359 | list_for_each_entry(func, &sec->symbol_list, list) { |
2348 | if (func->type != STT_FUNC || func->pfunc != func) | 2360 | if (func->type != STT_FUNC) |
2361 | continue; | ||
2362 | |||
2363 | if (!func->len) { | ||
2364 | WARN("%s() is missing an ELF size annotation", | ||
2365 | func->name); | ||
2366 | warnings++; | ||
2367 | } | ||
2368 | |||
2369 | if (func->pfunc != func || func->alias != func) | ||
2349 | continue; | 2370 | continue; |
2350 | 2371 | ||
2351 | insn = find_insn(file, sec, func->offset); | 2372 | insn = find_insn(file, sec, func->offset); |
2352 | if (!insn || insn->ignore) | 2373 | if (!insn || insn->ignore || insn->visited) |
2353 | continue; | 2374 | continue; |
2354 | 2375 | ||
2355 | state.uaccess = func->alias->uaccess_safe; | 2376 | state.uaccess = func->uaccess_safe; |
2356 | 2377 | ||
2357 | ret = validate_branch(file, insn, state); | 2378 | ret = validate_branch(file, func, insn, state); |
2358 | if (ret && backtrace) | 2379 | if (ret && backtrace) |
2359 | BT_FUNC("<=== (func)", insn); | 2380 | BT_FUNC("<=== (func)", insn); |
2360 | warnings += ret; | 2381 | warnings += ret; |
@@ -2407,7 +2428,7 @@ int check(const char *_objname, bool orc) | |||
2407 | 2428 | ||
2408 | objname = _objname; | 2429 | objname = _objname; |
2409 | 2430 | ||
2410 | file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY); | 2431 | file.elf = elf_read(objname, orc ? O_RDWR : O_RDONLY); |
2411 | if (!file.elf) | 2432 | if (!file.elf) |
2412 | return 1; | 2433 | return 1; |
2413 | 2434 | ||
diff --git a/tools/objtool/check.h b/tools/objtool/check.h index cb60b9acf5cf..b881fafcf55d 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h | |||
@@ -31,13 +31,14 @@ struct instruction { | |||
31 | struct section *sec; | 31 | struct section *sec; |
32 | unsigned long offset; | 32 | unsigned long offset; |
33 | unsigned int len; | 33 | unsigned int len; |
34 | unsigned char type; | 34 | enum insn_type type; |
35 | unsigned long immediate; | 35 | unsigned long immediate; |
36 | bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; | 36 | bool alt_group, visited, dead_end, ignore, hint, save, restore, ignore_alts; |
37 | bool retpoline_safe; | 37 | bool retpoline_safe; |
38 | struct symbol *call_dest; | 38 | struct symbol *call_dest; |
39 | struct instruction *jump_dest; | 39 | struct instruction *jump_dest; |
40 | struct instruction *first_jump_src; | 40 | struct instruction *first_jump_src; |
41 | struct rela *jump_table; | ||
41 | struct list_head alts; | 42 | struct list_head alts; |
42 | struct symbol *func; | 43 | struct symbol *func; |
43 | struct stack_op stack_op; | 44 | struct stack_op stack_op; |
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index e99e1be19ad9..edba4745f25a 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c | |||
@@ -278,7 +278,7 @@ static int read_symbols(struct elf *elf) | |||
278 | } | 278 | } |
279 | 279 | ||
280 | if (sym->offset == s->offset) { | 280 | if (sym->offset == s->offset) { |
281 | if (sym->len == s->len && alias == sym) | 281 | if (sym->len && sym->len == s->len && alias == sym) |
282 | alias = s; | 282 | alias = s; |
283 | 283 | ||
284 | if (sym->len >= s->len) { | 284 | if (sym->len >= s->len) { |
@@ -385,7 +385,7 @@ static int read_relas(struct elf *elf) | |||
385 | rela->offset = rela->rela.r_offset; | 385 | rela->offset = rela->rela.r_offset; |
386 | symndx = GELF_R_SYM(rela->rela.r_info); | 386 | symndx = GELF_R_SYM(rela->rela.r_info); |
387 | rela->sym = find_symbol_by_index(elf, symndx); | 387 | rela->sym = find_symbol_by_index(elf, symndx); |
388 | rela->rela_sec = sec; | 388 | rela->sec = sec; |
389 | if (!rela->sym) { | 389 | if (!rela->sym) { |
390 | WARN("can't find rela entry symbol %d for %s", | 390 | WARN("can't find rela entry symbol %d for %s", |
391 | symndx, sec->name); | 391 | symndx, sec->name); |
@@ -401,7 +401,7 @@ static int read_relas(struct elf *elf) | |||
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | struct elf *elf_open(const char *name, int flags) | 404 | struct elf *elf_read(const char *name, int flags) |
405 | { | 405 | { |
406 | struct elf *elf; | 406 | struct elf *elf; |
407 | Elf_Cmd cmd; | 407 | Elf_Cmd cmd; |
@@ -463,7 +463,7 @@ struct section *elf_create_section(struct elf *elf, const char *name, | |||
463 | { | 463 | { |
464 | struct section *sec, *shstrtab; | 464 | struct section *sec, *shstrtab; |
465 | size_t size = entsize * nr; | 465 | size_t size = entsize * nr; |
466 | struct Elf_Scn *s; | 466 | Elf_Scn *s; |
467 | Elf_Data *data; | 467 | Elf_Data *data; |
468 | 468 | ||
469 | sec = malloc(sizeof(*sec)); | 469 | sec = malloc(sizeof(*sec)); |
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h index e44ca5d51871..44150204db4d 100644 --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h | |||
@@ -57,11 +57,12 @@ struct rela { | |||
57 | struct list_head list; | 57 | struct list_head list; |
58 | struct hlist_node hash; | 58 | struct hlist_node hash; |
59 | GElf_Rela rela; | 59 | GElf_Rela rela; |
60 | struct section *rela_sec; | 60 | struct section *sec; |
61 | struct symbol *sym; | 61 | struct symbol *sym; |
62 | unsigned int type; | 62 | unsigned int type; |
63 | unsigned long offset; | 63 | unsigned long offset; |
64 | int addend; | 64 | int addend; |
65 | bool jump_table_start; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | struct elf { | 68 | struct elf { |
@@ -74,7 +75,7 @@ struct elf { | |||
74 | }; | 75 | }; |
75 | 76 | ||
76 | 77 | ||
77 | struct elf *elf_open(const char *name, int flags); | 78 | struct elf *elf_read(const char *name, int flags); |
78 | struct section *find_section_by_name(struct elf *elf, const char *name); | 79 | struct section *find_section_by_name(struct elf *elf, const char *name); |
79 | struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); | 80 | struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); |
80 | struct symbol *find_symbol_by_name(struct elf *elf, const char *name); | 81 | struct symbol *find_symbol_by_name(struct elf *elf, const char *name); |
diff --git a/tools/pci/Makefile b/tools/pci/Makefile index 6876ee4bd78c..4b95a5176355 100644 --- a/tools/pci/Makefile +++ b/tools/pci/Makefile | |||
@@ -18,7 +18,6 @@ ALL_TARGETS := pcitest | |||
18 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) | 18 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) |
19 | 19 | ||
20 | SCRIPTS := pcitest.sh | 20 | SCRIPTS := pcitest.sh |
21 | ALL_SCRIPTS := $(patsubst %,$(OUTPUT)%,$(SCRIPTS)) | ||
22 | 21 | ||
23 | all: $(ALL_PROGRAMS) | 22 | all: $(ALL_PROGRAMS) |
24 | 23 | ||
@@ -47,10 +46,10 @@ clean: | |||
47 | 46 | ||
48 | install: $(ALL_PROGRAMS) | 47 | install: $(ALL_PROGRAMS) |
49 | install -d -m 755 $(DESTDIR)$(bindir); \ | 48 | install -d -m 755 $(DESTDIR)$(bindir); \ |
50 | for program in $(ALL_PROGRAMS) pcitest.sh; do \ | 49 | for program in $(ALL_PROGRAMS); do \ |
51 | install $$program $(DESTDIR)$(bindir); \ | 50 | install $$program $(DESTDIR)$(bindir); \ |
52 | done; \ | 51 | done; \ |
53 | for script in $(ALL_SCRIPTS); do \ | 52 | for script in $(SCRIPTS); do \ |
54 | install $$script $(DESTDIR)$(bindir); \ | 53 | install $$script $(DESTDIR)$(bindir); \ |
55 | done | 54 | done |
56 | 55 | ||
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index cb7a47dfd8b6..cb1e51fcc84e 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c | |||
@@ -36,15 +36,15 @@ struct pci_test { | |||
36 | unsigned long size; | 36 | unsigned long size; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static void run_test(struct pci_test *test) | 39 | static int run_test(struct pci_test *test) |
40 | { | 40 | { |
41 | long ret; | 41 | int ret = -EINVAL; |
42 | int fd; | 42 | int fd; |
43 | 43 | ||
44 | fd = open(test->device, O_RDWR); | 44 | fd = open(test->device, O_RDWR); |
45 | if (fd < 0) { | 45 | if (fd < 0) { |
46 | perror("can't open PCI Endpoint Test device"); | 46 | perror("can't open PCI Endpoint Test device"); |
47 | return; | 47 | return -ENODEV; |
48 | } | 48 | } |
49 | 49 | ||
50 | if (test->barnum >= 0 && test->barnum <= 5) { | 50 | if (test->barnum >= 0 && test->barnum <= 5) { |
@@ -212,7 +212,7 @@ usage: | |||
212 | "\t-r Read buffer test\n" | 212 | "\t-r Read buffer test\n" |
213 | "\t-w Write buffer test\n" | 213 | "\t-w Write buffer test\n" |
214 | "\t-c Copy buffer test\n" | 214 | "\t-c Copy buffer test\n" |
215 | "\t-s <size> Size of buffer {default: 100KB}\n", | 215 | "\t-s <size> Size of buffer {default: 100KB}\n" |
216 | "\t-h Print this help message\n", | 216 | "\t-h Print this help message\n", |
217 | argv[0]); | 217 | argv[0]); |
218 | return -EINVAL; | 218 | return -EINVAL; |
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index b6866a05edd2..ed3ecfa422e1 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt | |||
@@ -194,12 +194,13 @@ PROBE ARGUMENT | |||
194 | -------------- | 194 | -------------- |
195 | Each probe argument follows below syntax. | 195 | Each probe argument follows below syntax. |
196 | 196 | ||
197 | [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE] | 197 | [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE][@user] |
198 | 198 | ||
199 | 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.) | 199 | 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.) |
200 | '$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters. | 200 | '$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters. |
201 | 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo (*). Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal integers (x/x8/x16/x32/x64), signedness casting (u/s), "string" and bitfield are supported. (see TYPES for detail) | 201 | 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo (*). Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal integers (x/x8/x16/x32/x64), signedness casting (u/s), "string" and bitfield are supported. (see TYPES for detail) |
202 | On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid. | 202 | On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid. |
203 | "@user" is a special attribute which means the LOCALVAR will be treated as a user-space memory. This is only valid for kprobe event. | ||
203 | 204 | ||
204 | TYPES | 205 | TYPES |
205 | ----- | 206 | ----- |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 6a5de44b2de9..70f1ff4e2eb4 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -18,3 +18,4 @@ tools/lib/find_bit.c | |||
18 | tools/lib/bitmap.c | 18 | tools/lib/bitmap.c |
19 | tools/lib/str_error_r.c | 19 | tools/lib/str_error_r.c |
20 | tools/lib/vsprintf.c | 20 | tools/lib/vsprintf.c |
21 | tools/lib/zalloc.c | ||
diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c index f64516d5b23e..c7d1a69b894f 100644 --- a/tools/perf/arch/arm/annotate/instructions.c +++ b/tools/perf/arch/arm/annotate/instructions.c | |||
@@ -1,5 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <linux/zalloc.h> | ||
3 | #include <sys/types.h> | 4 | #include <sys/types.h> |
4 | #include <regex.h> | 5 | #include <regex.h> |
5 | 6 | ||
diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c index 1ce6bdbda561..02014740a1aa 100644 --- a/tools/perf/arch/arm/util/auxtrace.c +++ b/tools/perf/arch/arm/util/auxtrace.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <stdbool.h> | 7 | #include <stdbool.h> |
8 | #include <linux/coresight-pmu.h> | 8 | #include <linux/coresight-pmu.h> |
9 | #include <linux/zalloc.h> | ||
9 | 10 | ||
10 | #include "../../util/auxtrace.h" | 11 | #include "../../util/auxtrace.h" |
11 | #include "../../util/evlist.h" | 12 | #include "../../util/evlist.h" |
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 2b83cc8e4796..4208974c24f8 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/log2.h> | 13 | #include <linux/log2.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/zalloc.h> | ||
15 | 16 | ||
16 | #include "cs-etm.h" | 17 | #include "cs-etm.h" |
17 | #include "../../perf.h" | 18 | #include "../../perf.h" |
diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 5ccfce87e693..2c009aa74633 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/types.h> | 8 | #include <linux/types.h> |
9 | #include <linux/bitops.h> | 9 | #include <linux/bitops.h> |
10 | #include <linux/log2.h> | 10 | #include <linux/log2.h> |
11 | #include <linux/zalloc.h> | ||
11 | #include <time.h> | 12 | #include <time.h> |
12 | 13 | ||
13 | #include "../../util/cpumap.h" | 14 | #include "../../util/cpumap.h" |
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index f3824ca7c20b..1a9e22f78c22 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c | |||
@@ -1,9 +1,10 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #include <stdlib.h> | ||
3 | #include "common.h" | 4 | #include "common.h" |
4 | #include "../util/env.h" | 5 | #include "../util/env.h" |
5 | #include "../util/util.h" | ||
6 | #include "../util/debug.h" | 6 | #include "../util/debug.h" |
7 | #include <linux/zalloc.h> | ||
7 | 8 | ||
8 | const char *const arc_triplets[] = { | 9 | const char *const arc_triplets[] = { |
9 | "arc-linux-", | 10 | "arc-linux-", |
diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c index 34d5134681d9..f14102b85509 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c | |||
@@ -2,12 +2,14 @@ | |||
2 | #include <errno.h> | 2 | #include <errno.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <regex.h> | 4 | #include <regex.h> |
5 | #include <linux/zalloc.h> | ||
5 | 6 | ||
6 | #include "../../perf.h" | 7 | #include "../../perf.h" |
7 | #include "../../util/util.h" | ||
8 | #include "../../util/perf_regs.h" | 8 | #include "../../util/perf_regs.h" |
9 | #include "../../util/debug.h" | 9 | #include "../../util/debug.h" |
10 | 10 | ||
11 | #include <linux/kernel.h> | ||
12 | |||
11 | const struct sample_reg sample_reg_masks[] = { | 13 | const struct sample_reg sample_reg_masks[] = { |
12 | SMPL_REG(r0, PERF_REG_POWERPC_R0), | 14 | SMPL_REG(r0, PERF_REG_POWERPC_R0), |
13 | SMPL_REG(r1, PERF_REG_POWERPC_R1), | 15 | SMPL_REG(r1, PERF_REG_POWERPC_R1), |
diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index 44c857388897..0fe1be93f375 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
4 | #include <linux/bitops.h> | 4 | #include <linux/bitops.h> |
5 | #include <linux/log2.h> | 5 | #include <linux/log2.h> |
6 | #include <linux/zalloc.h> | ||
6 | 7 | ||
7 | #include "../../util/evlist.h" | 8 | #include "../../util/evlist.h" |
8 | #include "../../util/auxtrace.h" | 9 | #include "../../util/auxtrace.h" |
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c index a25896135abe..8b0b018d896a 100644 --- a/tools/perf/arch/s390/util/header.c +++ b/tools/perf/arch/s390/util/header.c | |||
@@ -12,9 +12,10 @@ | |||
12 | #include <stdio.h> | 12 | #include <stdio.h> |
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/kernel.h> | ||
16 | #include <linux/zalloc.h> | ||
15 | 17 | ||
16 | #include "../../util/header.h" | 18 | #include "../../util/header.h" |
17 | #include "../../util/util.h" | ||
18 | 19 | ||
19 | #define SYSINFO_MANU "Manufacturer:" | 20 | #define SYSINFO_MANU "Manufacturer:" |
20 | #define SYSINFO_TYPE "Type:" | 21 | #define SYSINFO_TYPE "Type:" |
diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index 675a0213044d..a3a0b6884779 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c | |||
@@ -1,11 +1,11 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/types.h> | 2 | #include <linux/types.h> |
3 | #include <linux/string.h> | 3 | #include <linux/string.h> |
4 | #include <linux/zalloc.h> | ||
4 | 5 | ||
5 | #include "../../util/machine.h" | 6 | #include "../../util/machine.h" |
6 | #include "../../util/tool.h" | 7 | #include "../../util/tool.h" |
7 | #include "../../util/map.h" | 8 | #include "../../util/map.h" |
8 | #include "../../util/util.h" | ||
9 | #include "../../util/debug.h" | 9 | #include "../../util/debug.h" |
10 | 10 | ||
11 | #if defined(__x86_64__) | 11 | #if defined(__x86_64__) |
diff --git a/tools/perf/arch/x86/util/intel-bts.c b/tools/perf/arch/x86/util/intel-bts.c index e6d4d9591c79..ec5c1bb84095 100644 --- a/tools/perf/arch/x86/util/intel-bts.c +++ b/tools/perf/arch/x86/util/intel-bts.c | |||
@@ -9,12 +9,12 @@ | |||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
11 | #include <linux/log2.h> | 11 | #include <linux/log2.h> |
12 | #include <linux/zalloc.h> | ||
12 | 13 | ||
13 | #include "../../util/cpumap.h" | 14 | #include "../../util/cpumap.h" |
14 | #include "../../util/evsel.h" | 15 | #include "../../util/evsel.h" |
15 | #include "../../util/evlist.h" | 16 | #include "../../util/evlist.h" |
16 | #include "../../util/session.h" | 17 | #include "../../util/session.h" |
17 | #include "../../util/util.h" | ||
18 | #include "../../util/pmu.h" | 18 | #include "../../util/pmu.h" |
19 | #include "../../util/debug.h" | 19 | #include "../../util/debug.h" |
20 | #include "../../util/tsc.h" | 20 | #include "../../util/tsc.h" |
diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 9804098dcefb..609088c01e3a 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/bitops.h> | 11 | #include <linux/bitops.h> |
12 | #include <linux/log2.h> | 12 | #include <linux/log2.h> |
13 | #include <linux/zalloc.h> | ||
13 | #include <cpuid.h> | 14 | #include <cpuid.h> |
14 | 15 | ||
15 | #include "../../perf.h" | 16 | #include "../../perf.h" |
@@ -25,7 +26,6 @@ | |||
25 | #include "../../util/auxtrace.h" | 26 | #include "../../util/auxtrace.h" |
26 | #include "../../util/tsc.h" | 27 | #include "../../util/tsc.h" |
27 | #include "../../util/intel-pt.h" | 28 | #include "../../util/intel-pt.h" |
28 | #include "../../util/util.h" | ||
29 | 29 | ||
30 | #define KiB(x) ((x) * 1024) | 30 | #define KiB(x) ((x) * 1024) |
31 | #define MiB(x) ((x) * 1024 * 1024) | 31 | #define MiB(x) ((x) * 1024 * 1024) |
diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index 3666c0076df9..0d7b77ff0ae6 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c | |||
@@ -2,9 +2,9 @@ | |||
2 | #include <errno.h> | 2 | #include <errno.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <regex.h> | 4 | #include <regex.h> |
5 | #include <linux/zalloc.h> | ||
5 | 6 | ||
6 | #include "../../perf.h" | 7 | #include "../../perf.h" |
7 | #include "../../util/util.h" | ||
8 | #include "../../util/perf_regs.h" | 8 | #include "../../util/perf_regs.h" |
9 | #include "../../util/debug.h" | 9 | #include "../../util/debug.h" |
10 | 10 | ||
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index 9aa3a674829b..a80797763e1f 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <stdlib.h> | 18 | #include <stdlib.h> |
19 | #include <linux/compiler.h> | 19 | #include <linux/compiler.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/zalloc.h> | ||
21 | #include <sys/time.h> | 22 | #include <sys/time.h> |
22 | 23 | ||
23 | #include "../util/stat.h" | 24 | #include "../util/stat.h" |
@@ -214,7 +215,7 @@ int bench_futex_hash(int argc, const char **argv) | |||
214 | &worker[i].futex[nfutexes-1], t); | 215 | &worker[i].futex[nfutexes-1], t); |
215 | } | 216 | } |
216 | 217 | ||
217 | free(worker[i].futex); | 218 | zfree(&worker[i].futex); |
218 | } | 219 | } |
219 | 220 | ||
220 | print_summary(); | 221 | print_summary(); |
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 8e9c4753e304..d02330a69745 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <subcmd/parse-options.h> | 12 | #include <subcmd/parse-options.h> |
13 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/zalloc.h> | ||
15 | #include <errno.h> | 16 | #include <errno.h> |
16 | #include "bench.h" | 17 | #include "bench.h" |
17 | #include "futex.h" | 18 | #include "futex.h" |
@@ -217,7 +218,7 @@ int bench_futex_lock_pi(int argc, const char **argv) | |||
217 | worker[i].tid, worker[i].futex, t); | 218 | worker[i].tid, worker[i].futex, t); |
218 | 219 | ||
219 | if (multi) | 220 | if (multi) |
220 | free(worker[i].futex); | 221 | zfree(&worker[i].futex); |
221 | } | 222 | } |
222 | 223 | ||
223 | print_summary(); | 224 | print_summary(); |
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c index 0251dd348124..64dc994c72ea 100644 --- a/tools/perf/bench/mem-functions.c +++ b/tools/perf/bench/mem-functions.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include "debug.h" | 10 | #include "debug.h" |
11 | #include "../perf.h" | 11 | #include "../perf.h" |
12 | #include "../util/util.h" | ||
13 | #include <subcmd/parse-options.h> | 12 | #include <subcmd/parse-options.h> |
14 | #include "../util/header.h" | 13 | #include "../util/header.h" |
15 | #include "../util/cloexec.h" | 14 | #include "../util/cloexec.h" |
@@ -24,6 +23,7 @@ | |||
24 | #include <sys/time.h> | 23 | #include <sys/time.h> |
25 | #include <errno.h> | 24 | #include <errno.h> |
26 | #include <linux/time64.h> | 25 | #include <linux/time64.h> |
26 | #include <linux/zalloc.h> | ||
27 | 27 | ||
28 | #define K 1024 | 28 | #define K 1024 |
29 | 29 | ||
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index a7784554a80d..a640ca7aaada 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include "../perf.h" | 12 | #include "../perf.h" |
13 | #include "../builtin.h" | 13 | #include "../builtin.h" |
14 | #include "../util/util.h" | ||
15 | #include <subcmd/parse-options.h> | 14 | #include <subcmd/parse-options.h> |
16 | #include "../util/cloexec.h" | 15 | #include "../util/cloexec.h" |
17 | 16 | ||
@@ -35,6 +34,7 @@ | |||
35 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
36 | #include <linux/time64.h> | 35 | #include <linux/time64.h> |
37 | #include <linux/numa.h> | 36 | #include <linux/numa.h> |
37 | #include <linux/zalloc.h> | ||
38 | 38 | ||
39 | #include <numa.h> | 39 | #include <numa.h> |
40 | #include <numaif.h> | 40 | #include <numaif.h> |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 77deb3a40596..e0aa14faf2b5 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -8,11 +8,11 @@ | |||
8 | */ | 8 | */ |
9 | #include "builtin.h" | 9 | #include "builtin.h" |
10 | 10 | ||
11 | #include "util/util.h" | ||
12 | #include "util/color.h" | 11 | #include "util/color.h" |
13 | #include <linux/list.h> | 12 | #include <linux/list.h> |
14 | #include "util/cache.h" | 13 | #include "util/cache.h" |
15 | #include <linux/rbtree.h> | 14 | #include <linux/rbtree.h> |
15 | #include <linux/zalloc.h> | ||
16 | #include "util/symbol.h" | 16 | #include "util/symbol.h" |
17 | 17 | ||
18 | #include "perf.h" | 18 | #include "perf.h" |
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index 334c77ffc1d9..b8e7c38ef221 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c | |||
@@ -17,7 +17,6 @@ | |||
17 | * epoll ... Event poll performance | 17 | * epoll ... Event poll performance |
18 | */ | 18 | */ |
19 | #include "perf.h" | 19 | #include "perf.h" |
20 | #include "util/util.h" | ||
21 | #include <subcmd/parse-options.h> | 20 | #include <subcmd/parse-options.h> |
22 | #include "builtin.h" | 21 | #include "builtin.h" |
23 | #include "bench/bench.h" | 22 | #include "bench/bench.h" |
@@ -26,6 +25,7 @@ | |||
26 | #include <stdlib.h> | 25 | #include <stdlib.h> |
27 | #include <string.h> | 26 | #include <string.h> |
28 | #include <sys/prctl.h> | 27 | #include <sys/prctl.h> |
28 | #include <linux/zalloc.h> | ||
29 | 29 | ||
30 | typedef int (*bench_fn_t)(int argc, const char **argv); | 30 | typedef int (*bench_fn_t)(int argc, const char **argv); |
31 | 31 | ||
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 9e6cc868bdb4..e3776f5c2e01 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c | |||
@@ -15,9 +15,9 @@ | |||
15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/stringify.h> | 17 | #include <linux/stringify.h> |
18 | #include <linux/zalloc.h> | ||
18 | #include <asm/bug.h> | 19 | #include <asm/bug.h> |
19 | #include <sys/param.h> | 20 | #include <sys/param.h> |
20 | #include "util.h" | ||
21 | #include "debug.h" | 21 | #include "debug.h" |
22 | #include "builtin.h" | 22 | #include "builtin.h" |
23 | #include <subcmd/parse-options.h> | 23 | #include <subcmd/parse-options.h> |
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index d76f831f94c7..6c1284c87aaa 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "util/debug.h" | 15 | #include "util/debug.h" |
16 | #include "util/config.h" | 16 | #include "util/config.h" |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <stdlib.h> | ||
18 | 19 | ||
19 | static bool use_system_config, use_user_config; | 20 | static bool use_system_config, use_user_config; |
20 | 21 | ||
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index f924b46910b5..f6f5dd15bea7 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -16,12 +16,12 @@ | |||
16 | #include "util/tool.h" | 16 | #include "util/tool.h" |
17 | #include "util/sort.h" | 17 | #include "util/sort.h" |
18 | #include "util/symbol.h" | 18 | #include "util/symbol.h" |
19 | #include "util/util.h" | ||
20 | #include "util/data.h" | 19 | #include "util/data.h" |
21 | #include "util/config.h" | 20 | #include "util/config.h" |
22 | #include "util/time-utils.h" | 21 | #include "util/time-utils.h" |
23 | #include "util/annotate.h" | 22 | #include "util/annotate.h" |
24 | #include "util/map.h" | 23 | #include "util/map.h" |
24 | #include <linux/zalloc.h> | ||
25 | 25 | ||
26 | #include <errno.h> | 26 | #include <errno.h> |
27 | #include <inttypes.h> | 27 | #include <inttypes.h> |
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 9c228c55e1fb..66d5a6658daf 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c | |||
@@ -431,7 +431,7 @@ static void delete_filter_func(struct list_head *head) | |||
431 | struct filter_entry *pos, *tmp; | 431 | struct filter_entry *pos, *tmp; |
432 | 432 | ||
433 | list_for_each_entry_safe(pos, tmp, head, list) { | 433 | list_for_each_entry_safe(pos, tmp, head, list) { |
434 | list_del(&pos->list); | 434 | list_del_init(&pos->list); |
435 | free(pos); | 435 | free(pos); |
436 | } | 436 | } |
437 | } | 437 | } |
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 3d29d0524a89..a83af92fb0d1 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c | |||
@@ -14,8 +14,10 @@ | |||
14 | #include <subcmd/help.h> | 14 | #include <subcmd/help.h> |
15 | #include "util/debug.h" | 15 | #include "util/debug.h" |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/zalloc.h> | ||
17 | #include <errno.h> | 18 | #include <errno.h> |
18 | #include <stdio.h> | 19 | #include <stdio.h> |
20 | #include <stdlib.h> | ||
19 | #include <sys/types.h> | 21 | #include <sys/types.h> |
20 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
21 | #include <unistd.h> | 23 | #include <unistd.h> |
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 8e0e06d3edfc..f4591a1438b4 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -224,7 +224,7 @@ static int perf_event__repipe_sample(struct perf_tool *tool, | |||
224 | struct perf_evsel *evsel, | 224 | struct perf_evsel *evsel, |
225 | struct machine *machine) | 225 | struct machine *machine) |
226 | { | 226 | { |
227 | if (evsel->handler) { | 227 | if (evsel && evsel->handler) { |
228 | inject_handler f = evsel->handler; | 228 | inject_handler f = evsel->handler; |
229 | return f(tool, event, sample, evsel, machine); | 229 | return f(tool, event, sample, evsel, machine); |
230 | } | 230 | } |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 9bd3829de76d..9e5e60898083 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | #include "util/evlist.h" | 5 | #include "util/evlist.h" |
6 | #include "util/evsel.h" | 6 | #include "util/evsel.h" |
7 | #include "util/util.h" | ||
8 | #include "util/config.h" | 7 | #include "util/config.h" |
9 | #include "util/map.h" | 8 | #include "util/map.h" |
10 | #include "util/symbol.h" | 9 | #include "util/symbol.h" |
@@ -26,6 +25,7 @@ | |||
26 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
27 | #include <linux/rbtree.h> | 26 | #include <linux/rbtree.h> |
28 | #include <linux/string.h> | 27 | #include <linux/string.h> |
28 | #include <linux/zalloc.h> | ||
29 | #include <errno.h> | 29 | #include <errno.h> |
30 | #include <inttypes.h> | 30 | #include <inttypes.h> |
31 | #include <locale.h> | 31 | #include <locale.h> |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index dbb6f737a3e2..b33c83489120 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include "util/evsel.h" | 5 | #include "util/evsel.h" |
6 | #include "util/evlist.h" | 6 | #include "util/evlist.h" |
7 | #include "util/term.h" | 7 | #include "util/term.h" |
8 | #include "util/util.h" | ||
9 | #include "util/cache.h" | 8 | #include "util/cache.h" |
10 | #include "util/symbol.h" | 9 | #include "util/symbol.h" |
11 | #include "util/thread.h" | 10 | #include "util/thread.h" |
@@ -32,6 +31,7 @@ | |||
32 | 31 | ||
33 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
34 | #include <linux/time64.h> | 33 | #include <linux/time64.h> |
34 | #include <linux/zalloc.h> | ||
35 | #include <errno.h> | 35 | #include <errno.h> |
36 | #include <inttypes.h> | 36 | #include <inttypes.h> |
37 | #include <poll.h> | 37 | #include <poll.h> |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index b9810a8d350a..574e30ec6d7c 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | #include "util/evlist.h" | 7 | #include "util/evlist.h" |
8 | #include "util/evsel.h" | 8 | #include "util/evsel.h" |
9 | #include "util/util.h" | ||
10 | #include "util/cache.h" | 9 | #include "util/cache.h" |
11 | #include "util/symbol.h" | 10 | #include "util/symbol.h" |
12 | #include "util/thread.h" | 11 | #include "util/thread.h" |
@@ -30,6 +29,7 @@ | |||
30 | #include <linux/list.h> | 29 | #include <linux/list.h> |
31 | #include <linux/hash.h> | 30 | #include <linux/hash.h> |
32 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/zalloc.h> | ||
33 | 33 | ||
34 | static struct perf_session *session; | 34 | static struct perf_session *session; |
35 | 35 | ||
@@ -454,7 +454,7 @@ broken: | |||
454 | /* broken lock sequence, discard it */ | 454 | /* broken lock sequence, discard it */ |
455 | ls->discard = 1; | 455 | ls->discard = 1; |
456 | bad_hist[BROKEN_ACQUIRE]++; | 456 | bad_hist[BROKEN_ACQUIRE]++; |
457 | list_del(&seq->list); | 457 | list_del_init(&seq->list); |
458 | free(seq); | 458 | free(seq); |
459 | goto end; | 459 | goto end; |
460 | default: | 460 | default: |
@@ -515,7 +515,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel, | |||
515 | /* broken lock sequence, discard it */ | 515 | /* broken lock sequence, discard it */ |
516 | ls->discard = 1; | 516 | ls->discard = 1; |
517 | bad_hist[BROKEN_ACQUIRED]++; | 517 | bad_hist[BROKEN_ACQUIRED]++; |
518 | list_del(&seq->list); | 518 | list_del_init(&seq->list); |
519 | free(seq); | 519 | free(seq); |
520 | goto end; | 520 | goto end; |
521 | default: | 521 | default: |
@@ -570,7 +570,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel, | |||
570 | /* broken lock sequence, discard it */ | 570 | /* broken lock sequence, discard it */ |
571 | ls->discard = 1; | 571 | ls->discard = 1; |
572 | bad_hist[BROKEN_CONTENDED]++; | 572 | bad_hist[BROKEN_CONTENDED]++; |
573 | list_del(&seq->list); | 573 | list_del_init(&seq->list); |
574 | free(seq); | 574 | free(seq); |
575 | goto end; | 575 | goto end; |
576 | default: | 576 | default: |
@@ -639,7 +639,7 @@ static int report_lock_release_event(struct perf_evsel *evsel, | |||
639 | 639 | ||
640 | ls->nr_release++; | 640 | ls->nr_release++; |
641 | free_seq: | 641 | free_seq: |
642 | list_del(&seq->list); | 642 | list_del_init(&seq->list); |
643 | free(seq); | 643 | free(seq); |
644 | end: | 644 | end: |
645 | return 0; | 645 | return 0; |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 8bb124e55c6d..6418782951a4 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include "perf.h" | 19 | #include "perf.h" |
20 | #include "builtin.h" | 20 | #include "builtin.h" |
21 | #include "namespaces.h" | 21 | #include "namespaces.h" |
22 | #include "util/util.h" | ||
23 | #include "util/strlist.h" | 22 | #include "util/strlist.h" |
24 | #include "util/strfilter.h" | 23 | #include "util/strfilter.h" |
25 | #include "util/symbol.h" | 24 | #include "util/symbol.h" |
@@ -28,6 +27,7 @@ | |||
28 | #include "util/probe-finder.h" | 27 | #include "util/probe-finder.h" |
29 | #include "util/probe-event.h" | 28 | #include "util/probe-event.h" |
30 | #include "util/probe-file.h" | 29 | #include "util/probe-file.h" |
30 | #include <linux/zalloc.h> | ||
31 | 31 | ||
32 | #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" | 32 | #define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" |
33 | #define DEFAULT_FUNC_FILTER "!_*" | 33 | #define DEFAULT_FUNC_FILTER "!_*" |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dca55997934e..8779cee58185 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include "perf.h" | 11 | #include "perf.h" |
12 | 12 | ||
13 | #include "util/build-id.h" | 13 | #include "util/build-id.h" |
14 | #include "util/util.h" | ||
15 | #include <subcmd/parse-options.h> | 14 | #include <subcmd/parse-options.h> |
16 | #include "util/parse-events.h" | 15 | #include "util/parse-events.h" |
17 | #include "util/config.h" | 16 | #include "util/config.h" |
@@ -54,6 +53,7 @@ | |||
54 | #include <sys/mman.h> | 53 | #include <sys/mman.h> |
55 | #include <sys/wait.h> | 54 | #include <sys/wait.h> |
56 | #include <linux/time64.h> | 55 | #include <linux/time64.h> |
56 | #include <linux/zalloc.h> | ||
57 | 57 | ||
58 | struct switch_output { | 58 | struct switch_output { |
59 | bool enabled; | 59 | bool enabled; |
@@ -1110,7 +1110,7 @@ record__switch_output(struct record *rec, bool at_exit) | |||
1110 | rec->switch_output.cur_file = n; | 1110 | rec->switch_output.cur_file = n; |
1111 | if (rec->switch_output.filenames[n]) { | 1111 | if (rec->switch_output.filenames[n]) { |
1112 | remove(rec->switch_output.filenames[n]); | 1112 | remove(rec->switch_output.filenames[n]); |
1113 | free(rec->switch_output.filenames[n]); | 1113 | zfree(&rec->switch_output.filenames[n]); |
1114 | } | 1114 | } |
1115 | rec->switch_output.filenames[n] = new_filename; | 1115 | rec->switch_output.filenames[n] = new_filename; |
1116 | } else { | 1116 | } else { |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index aef59f318a67..abf0b9b8f566 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -8,7 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | #include "builtin.h" | 9 | #include "builtin.h" |
10 | 10 | ||
11 | #include "util/util.h" | ||
12 | #include "util/config.h" | 11 | #include "util/config.h" |
13 | 12 | ||
14 | #include "util/annotate.h" | 13 | #include "util/annotate.h" |
@@ -16,6 +15,7 @@ | |||
16 | #include <linux/list.h> | 15 | #include <linux/list.h> |
17 | #include <linux/rbtree.h> | 16 | #include <linux/rbtree.h> |
18 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/zalloc.h> | ||
19 | #include "util/map.h" | 19 | #include "util/map.h" |
20 | #include "util/symbol.h" | 20 | #include "util/symbol.h" |
21 | #include "util/callchain.h" | 21 | #include "util/callchain.h" |
@@ -298,7 +298,7 @@ static int process_read_event(struct perf_tool *tool, | |||
298 | struct report *rep = container_of(tool, struct report, tool); | 298 | struct report *rep = container_of(tool, struct report, tool); |
299 | 299 | ||
300 | if (rep->show_threads) { | 300 | if (rep->show_threads) { |
301 | const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; | 301 | const char *name = perf_evsel__name(evsel); |
302 | int err = perf_read_values_add_value(&rep->show_threads_values, | 302 | int err = perf_read_values_add_value(&rep->show_threads_values, |
303 | event->read.pid, event->read.tid, | 303 | event->read.pid, event->read.tid, |
304 | evsel->idx, | 304 | evsel->idx, |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 1519989961ff..56d1907b1215 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -2,7 +2,6 @@ | |||
2 | #include "builtin.h" | 2 | #include "builtin.h" |
3 | #include "perf.h" | 3 | #include "perf.h" |
4 | 4 | ||
5 | #include "util/util.h" | ||
6 | #include "util/evlist.h" | 5 | #include "util/evlist.h" |
7 | #include "util/cache.h" | 6 | #include "util/cache.h" |
8 | #include "util/evsel.h" | 7 | #include "util/evsel.h" |
@@ -26,6 +25,7 @@ | |||
26 | 25 | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/log2.h> | 27 | #include <linux/log2.h> |
28 | #include <linux/zalloc.h> | ||
29 | #include <sys/prctl.h> | 29 | #include <sys/prctl.h> |
30 | #include <sys/resource.h> | 30 | #include <sys/resource.h> |
31 | #include <inttypes.h> | 31 | #include <inttypes.h> |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 2f6232f1bfdc..8f24865596af 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include "util/symbol.h" | 14 | #include "util/symbol.h" |
15 | #include "util/thread.h" | 15 | #include "util/thread.h" |
16 | #include "util/trace-event.h" | 16 | #include "util/trace-event.h" |
17 | #include "util/util.h" | ||
18 | #include "util/evlist.h" | 17 | #include "util/evlist.h" |
19 | #include "util/evsel.h" | 18 | #include "util/evsel.h" |
20 | #include "util/sort.h" | 19 | #include "util/sort.h" |
@@ -34,6 +33,7 @@ | |||
34 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
35 | #include <linux/stringify.h> | 34 | #include <linux/stringify.h> |
36 | #include <linux/time64.h> | 35 | #include <linux/time64.h> |
36 | #include <linux/zalloc.h> | ||
37 | #include <sys/utsname.h> | 37 | #include <sys/utsname.h> |
38 | #include "asm/bug.h" | 38 | #include "asm/bug.h" |
39 | #include "util/mem-events.h" | 39 | #include "util/mem-events.h" |
@@ -2289,6 +2289,12 @@ static int process_switch_event(struct perf_tool *tool, | |||
2289 | if (perf_event__process_switch(tool, event, sample, machine) < 0) | 2289 | if (perf_event__process_switch(tool, event, sample, machine) < 0) |
2290 | return -1; | 2290 | return -1; |
2291 | 2291 | ||
2292 | if (scripting_ops && scripting_ops->process_switch) | ||
2293 | scripting_ops->process_switch(event, sample, machine); | ||
2294 | |||
2295 | if (!script->show_switch_events) | ||
2296 | return 0; | ||
2297 | |||
2292 | thread = machine__findnew_thread(machine, sample->pid, | 2298 | thread = machine__findnew_thread(machine, sample->pid, |
2293 | sample->tid); | 2299 | sample->tid); |
2294 | if (thread == NULL) { | 2300 | if (thread == NULL) { |
@@ -2467,7 +2473,7 @@ static int __cmd_script(struct perf_script *script) | |||
2467 | script->tool.mmap = process_mmap_event; | 2473 | script->tool.mmap = process_mmap_event; |
2468 | script->tool.mmap2 = process_mmap2_event; | 2474 | script->tool.mmap2 = process_mmap2_event; |
2469 | } | 2475 | } |
2470 | if (script->show_switch_events) | 2476 | if (script->show_switch_events || (scripting_ops && scripting_ops->process_switch)) |
2471 | script->tool.context_switch = process_switch_event; | 2477 | script->tool.context_switch = process_switch_event; |
2472 | if (script->show_namespace_events) | 2478 | if (script->show_namespace_events) |
2473 | script->tool.namespaces = process_namespaces_event; | 2479 | script->tool.namespaces = process_namespaces_event; |
@@ -3752,7 +3758,8 @@ int cmd_script(int argc, const char **argv) | |||
3752 | goto out_delete; | 3758 | goto out_delete; |
3753 | 3759 | ||
3754 | uname(&uts); | 3760 | uname(&uts); |
3755 | if (!strcmp(uts.machine, session->header.env.arch) || | 3761 | if (data.is_pipe || /* assume pipe_mode indicates native_arch */ |
3762 | !strcmp(uts.machine, session->header.env.arch) || | ||
3756 | (!strcmp(uts.machine, "x86_64") && | 3763 | (!strcmp(uts.machine, "x86_64") && |
3757 | !strcmp(session->header.env.arch, "i386"))) | 3764 | !strcmp(session->header.env.arch, "i386"))) |
3758 | native_arch = true; | 3765 | native_arch = true; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e5e19b461061..b55a534b4de0 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include "perf.h" | 43 | #include "perf.h" |
44 | #include "builtin.h" | 44 | #include "builtin.h" |
45 | #include "util/cgroup.h" | 45 | #include "util/cgroup.h" |
46 | #include "util/util.h" | ||
47 | #include <subcmd/parse-options.h> | 46 | #include <subcmd/parse-options.h> |
48 | #include "util/parse-events.h" | 47 | #include "util/parse-events.h" |
49 | #include "util/pmu.h" | 48 | #include "util/pmu.h" |
@@ -67,6 +66,7 @@ | |||
67 | #include "asm/bug.h" | 66 | #include "asm/bug.h" |
68 | 67 | ||
69 | #include <linux/time64.h> | 68 | #include <linux/time64.h> |
69 | #include <linux/zalloc.h> | ||
70 | #include <api/fs/fs.h> | 70 | #include <api/fs/fs.h> |
71 | #include <errno.h> | 71 | #include <errno.h> |
72 | #include <signal.h> | 72 | #include <signal.h> |
@@ -1349,8 +1349,8 @@ static int add_default_attributes(void) | |||
1349 | fprintf(stderr, | 1349 | fprintf(stderr, |
1350 | "Cannot set up top down events %s: %d\n", | 1350 | "Cannot set up top down events %s: %d\n", |
1351 | str, err); | 1351 | str, err); |
1352 | free(str); | ||
1353 | parse_events_print_error(&errinfo, str); | 1352 | parse_events_print_error(&errinfo, str); |
1353 | free(str); | ||
1354 | return -1; | 1354 | return -1; |
1355 | } | 1355 | } |
1356 | } else { | 1356 | } else { |
@@ -1586,7 +1586,7 @@ static void runtime_stat_delete(struct perf_stat_config *config) | |||
1586 | for (i = 0; i < config->stats_num; i++) | 1586 | for (i = 0; i < config->stats_num; i++) |
1587 | runtime_stat__exit(&config->stats[i]); | 1587 | runtime_stat__exit(&config->stats[i]); |
1588 | 1588 | ||
1589 | free(config->stats); | 1589 | zfree(&config->stats); |
1590 | } | 1590 | } |
1591 | 1591 | ||
1592 | static const char * const stat_report_usage[] = { | 1592 | static const char * const stat_report_usage[] = { |
@@ -2003,7 +2003,7 @@ int cmd_stat(int argc, const char **argv) | |||
2003 | perf_stat__exit_aggr_mode(); | 2003 | perf_stat__exit_aggr_mode(); |
2004 | perf_evlist__free_stats(evsel_list); | 2004 | perf_evlist__free_stats(evsel_list); |
2005 | out: | 2005 | out: |
2006 | free(stat_config.walltime_run); | 2006 | zfree(&stat_config.walltime_run); |
2007 | 2007 | ||
2008 | if (smi_cost && smi_reset) | 2008 | if (smi_cost && smi_reset) |
2009 | sysfs__write_int(FREEZE_ON_SMI_PATH, 0); | 2009 | sysfs__write_int(FREEZE_ON_SMI_PATH, 0); |
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 145a19668114..4bde3fa245d1 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c | |||
@@ -13,9 +13,6 @@ | |||
13 | #include <traceevent/event-parse.h> | 13 | #include <traceevent/event-parse.h> |
14 | 14 | ||
15 | #include "builtin.h" | 15 | #include "builtin.h" |
16 | |||
17 | #include "util/util.h" | ||
18 | |||
19 | #include "util/color.h" | 16 | #include "util/color.h" |
20 | #include <linux/list.h> | 17 | #include <linux/list.h> |
21 | #include "util/cache.h" | 18 | #include "util/cache.h" |
@@ -24,6 +21,7 @@ | |||
24 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
25 | #include <linux/rbtree.h> | 22 | #include <linux/rbtree.h> |
26 | #include <linux/time64.h> | 23 | #include <linux/time64.h> |
24 | #include <linux/zalloc.h> | ||
27 | #include "util/symbol.h" | 25 | #include "util/symbol.h" |
28 | #include "util/thread.h" | 26 | #include "util/thread.h" |
29 | #include "util/callchain.h" | 27 | #include "util/callchain.h" |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6d40a4ef58c5..b46b3c9f57a0 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -101,7 +101,7 @@ static void perf_top__resize(struct perf_top *top) | |||
101 | 101 | ||
102 | static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) | 102 | static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) |
103 | { | 103 | { |
104 | struct perf_evsel *evsel = hists_to_evsel(he->hists); | 104 | struct perf_evsel *evsel; |
105 | struct symbol *sym; | 105 | struct symbol *sym; |
106 | struct annotation *notes; | 106 | struct annotation *notes; |
107 | struct map *map; | 107 | struct map *map; |
@@ -110,6 +110,8 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) | |||
110 | if (!he || !he->ms.sym) | 110 | if (!he || !he->ms.sym) |
111 | return -1; | 111 | return -1; |
112 | 112 | ||
113 | evsel = hists_to_evsel(he->hists); | ||
114 | |||
113 | sym = he->ms.sym; | 115 | sym = he->ms.sym; |
114 | map = he->ms.map; | 116 | map = he->ms.map; |
115 | 117 | ||
@@ -226,7 +228,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, | |||
226 | static void perf_top__show_details(struct perf_top *top) | 228 | static void perf_top__show_details(struct perf_top *top) |
227 | { | 229 | { |
228 | struct hist_entry *he = top->sym_filter_entry; | 230 | struct hist_entry *he = top->sym_filter_entry; |
229 | struct perf_evsel *evsel = hists_to_evsel(he->hists); | 231 | struct perf_evsel *evsel; |
230 | struct annotation *notes; | 232 | struct annotation *notes; |
231 | struct symbol *symbol; | 233 | struct symbol *symbol; |
232 | int more; | 234 | int more; |
@@ -234,6 +236,8 @@ static void perf_top__show_details(struct perf_top *top) | |||
234 | if (!he) | 236 | if (!he) |
235 | return; | 237 | return; |
236 | 238 | ||
239 | evsel = hists_to_evsel(he->hists); | ||
240 | |||
237 | symbol = he->ms.sym; | 241 | symbol = he->ms.sym; |
238 | notes = symbol__annotation(symbol); | 242 | notes = symbol__annotation(symbol); |
239 | 243 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d0eb7224dd36..4f0bbffee05f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <api/fs/tracing_path.h> | 19 | #include <api/fs/tracing_path.h> |
20 | #include <bpf/bpf.h> | 20 | #include <bpf/bpf.h> |
21 | #include "util/bpf_map.h" | 21 | #include "util/bpf_map.h" |
22 | #include "util/rlimit.h" | ||
22 | #include "builtin.h" | 23 | #include "builtin.h" |
23 | #include "util/cgroup.h" | 24 | #include "util/cgroup.h" |
24 | #include "util/color.h" | 25 | #include "util/color.h" |
@@ -61,6 +62,7 @@ | |||
61 | #include <linux/random.h> | 62 | #include <linux/random.h> |
62 | #include <linux/stringify.h> | 63 | #include <linux/stringify.h> |
63 | #include <linux/time64.h> | 64 | #include <linux/time64.h> |
65 | #include <linux/zalloc.h> | ||
64 | #include <fcntl.h> | 66 | #include <fcntl.h> |
65 | #include <sys/sysmacros.h> | 67 | #include <sys/sysmacros.h> |
66 | 68 | ||
@@ -1038,10 +1040,10 @@ static struct thread_trace *thread_trace__new(void) | |||
1038 | { | 1040 | { |
1039 | struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); | 1041 | struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); |
1040 | 1042 | ||
1041 | if (ttrace) | 1043 | if (ttrace) { |
1042 | ttrace->files.max = -1; | 1044 | ttrace->files.max = -1; |
1043 | 1045 | ttrace->syscall_stats = intlist__new(NULL); | |
1044 | ttrace->syscall_stats = intlist__new(NULL); | 1046 | } |
1045 | 1047 | ||
1046 | return ttrace; | 1048 | return ttrace; |
1047 | } | 1049 | } |
@@ -3863,6 +3865,15 @@ int cmd_trace(int argc, const char **argv) | |||
3863 | goto out; | 3865 | goto out; |
3864 | } | 3866 | } |
3865 | 3867 | ||
3868 | /* | ||
3869 | * Parsing .perfconfig may entail creating a BPF event, that may need | ||
3870 | * to create BPF maps, so bump RLIM_MEMLOCK as the default 64K setting | ||
3871 | * is too small. This affects just this process, not touching the | ||
3872 | * global setting. If it fails we'll get something in 'perf trace -v' | ||
3873 | * to help diagnose the problem. | ||
3874 | */ | ||
3875 | rlimit__bump_memlock(); | ||
3876 | |||
3866 | err = perf_config(trace__config, &trace); | 3877 | err = perf_config(trace__config, &trace); |
3867 | if (err) | 3878 | if (err) |
3868 | goto out; | 3879 | goto out; |
diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c index f470144d1a70..bf114ca9ca87 100644 --- a/tools/perf/builtin-version.c +++ b/tools/perf/builtin-version.c | |||
@@ -19,6 +19,7 @@ static struct version version; | |||
19 | static struct option version_options[] = { | 19 | static struct option version_options[] = { |
20 | OPT_BOOLEAN(0, "build-options", &version.build_options, | 20 | OPT_BOOLEAN(0, "build-options", &version.build_options, |
21 | "display the build options"), | 21 | "display the build options"), |
22 | OPT_END(), | ||
22 | }; | 23 | }; |
23 | 24 | ||
24 | static const char * const version_usage[] = { | 25 | static const char * const version_usage[] = { |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 2123b3cc4dcf..97e2628ea5dd 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "util/bpf-loader.h" | 18 | #include "util/bpf-loader.h" |
19 | #include "util/debug.h" | 19 | #include "util/debug.h" |
20 | #include "util/event.h" | 20 | #include "util/event.h" |
21 | #include "util/util.h" | ||
22 | #include <api/fs/fs.h> | 21 | #include <api/fs/fs.h> |
23 | #include <api/fs/tracing_path.h> | 22 | #include <api/fs/tracing_path.h> |
24 | #include <errno.h> | 23 | #include <errno.h> |
@@ -30,6 +29,7 @@ | |||
30 | #include <sys/stat.h> | 29 | #include <sys/stat.h> |
31 | #include <unistd.h> | 30 | #include <unistd.h> |
32 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/zalloc.h> | ||
33 | 33 | ||
34 | const char perf_usage_string[] = | 34 | const char perf_usage_string[] = |
35 | "perf [--version] [--help] [OPTIONS] COMMAND [ARGS]"; | 35 | "perf [--version] [--help] [OPTIONS] COMMAND [ARGS]"; |
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json b/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json new file mode 100644 index 000000000000..17fb5241928b --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_m8561/basic.json | |||
@@ -0,0 +1,58 @@ | |||
1 | [ | ||
2 | { | ||
3 | "Unit": "CPU-M-CF", | ||
4 | "EventCode": "0", | ||
5 | "EventName": "CPU_CYCLES", | ||
6 | "BriefDescription": "CPU Cycles", | ||
7 | "PublicDescription": "Cycle Count" | ||
8 | }, | ||
9 | { | ||
10 | "Unit": "CPU-M-CF", | ||
11 | "EventCode": "1", | ||
12 | "EventName": "INSTRUCTIONS", | ||
13 | "BriefDescription": "Instructions", | ||
14 | "PublicDescription": "Instruction Count" | ||
15 | }, | ||
16 | { | ||
17 | "Unit": "CPU-M-CF", | ||
18 | "EventCode": "2", | ||
19 | "EventName": "L1I_DIR_WRITES", | ||
20 | "BriefDescription": "L1I Directory Writes", | ||
21 | "PublicDescription": "Level-1 I-Cache Directory Write Count" | ||
22 | }, | ||
23 | { | ||
24 | "Unit": "CPU-M-CF", | ||
25 | "EventCode": "3", | ||
26 | "EventName": "L1I_PENALTY_CYCLES", | ||
27 | "BriefDescription": "L1I Penalty Cycles", | ||
28 | "PublicDescription": "Level-1 I-Cache Penalty Cycle Count" | ||
29 | }, | ||
30 | { | ||
31 | "Unit": "CPU-M-CF", | ||
32 | "EventCode": "4", | ||
33 | "EventName": "L1D_DIR_WRITES", | ||
34 | "BriefDescription": "L1D Directory Writes", | ||
35 | "PublicDescription": "Level-1 D-Cache Directory Write Count" | ||
36 | }, | ||
37 | { | ||
38 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "5", | ||
40 | "EventName": "L1D_PENALTY_CYCLES", | ||
41 | "BriefDescription": "L1D Penalty Cycles", | ||
42 | "PublicDescription": "Level-1 D-Cache Penalty Cycle Count" | ||
43 | }, | ||
44 | { | ||
45 | "Unit": "CPU-M-CF", | ||
46 | "EventCode": "32", | ||
47 | "EventName": "PROBLEM_STATE_CPU_CYCLES", | ||
48 | "BriefDescription": "Problem-State CPU Cycles", | ||
49 | "PublicDescription": "Problem-State Cycle Count" | ||
50 | }, | ||
51 | { | ||
52 | "Unit": "CPU-M-CF", | ||
53 | "EventCode": "33", | ||
54 | "EventName": "PROBLEM_STATE_INSTRUCTIONS", | ||
55 | "BriefDescription": "Problem-State Instructions", | ||
56 | "PublicDescription": "Problem-State Instruction Count" | ||
57 | }, | ||
58 | ] | ||
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json new file mode 100644 index 000000000000..db286f19e7b6 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto.json | |||
@@ -0,0 +1,114 @@ | |||
1 | [ | ||
2 | { | ||
3 | "Unit": "CPU-M-CF", | ||
4 | "EventCode": "64", | ||
5 | "EventName": "PRNG_FUNCTIONS", | ||
6 | "BriefDescription": "PRNG Functions", | ||
7 | "PublicDescription": "Total number of the PRNG functions issued by the CPU" | ||
8 | }, | ||
9 | { | ||
10 | "Unit": "CPU-M-CF", | ||
11 | "EventCode": "65", | ||
12 | "EventName": "PRNG_CYCLES", | ||
13 | "BriefDescription": "PRNG Cycles", | ||
14 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing PRNG functions issued by the CPU" | ||
15 | }, | ||
16 | { | ||
17 | "Unit": "CPU-M-CF", | ||
18 | "EventCode": "66", | ||
19 | "EventName": "PRNG_BLOCKED_FUNCTIONS", | ||
20 | "BriefDescription": "PRNG Blocked Functions", | ||
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" | ||
22 | }, | ||
23 | { | ||
24 | "Unit": "CPU-M-CF", | ||
25 | "EventCode": "67", | ||
26 | "EventName": "PRNG_BLOCKED_CYCLES", | ||
27 | "BriefDescription": "PRNG Blocked Cycles", | ||
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" | ||
29 | }, | ||
30 | { | ||
31 | "Unit": "CPU-M-CF", | ||
32 | "EventCode": "68", | ||
33 | "EventName": "SHA_FUNCTIONS", | ||
34 | "BriefDescription": "SHA Functions", | ||
35 | "PublicDescription": "Total number of SHA functions issued by the CPU" | ||
36 | }, | ||
37 | { | ||
38 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "69", | ||
40 | "EventName": "SHA_CYCLES", | ||
41 | "BriefDescription": "SHA Cycles", | ||
42 | "PublicDescription": "Total number of CPU cycles when the SHA coprocessor is busy performing the SHA functions issued by the CPU" | ||
43 | }, | ||
44 | { | ||
45 | "Unit": "CPU-M-CF", | ||
46 | "EventCode": "70", | ||
47 | "EventName": "SHA_BLOCKED_FUNCTIONS", | ||
48 | "BriefDescription": "SHA Blocked Functions", | ||
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" | ||
50 | }, | ||
51 | { | ||
52 | "Unit": "CPU-M-CF", | ||
53 | "EventCode": "71", | ||
54 | "EventName": "SHA_BLOCKED_CYCLES", | ||
55 | "BriefDescription": "SHA Bloced Cycles", | ||
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" | ||
57 | }, | ||
58 | { | ||
59 | "Unit": "CPU-M-CF", | ||
60 | "EventCode": "72", | ||
61 | "EventName": "DEA_FUNCTIONS", | ||
62 | "BriefDescription": "DEA Functions", | ||
63 | "PublicDescription": "Total number of the DEA functions issued by the CPU" | ||
64 | }, | ||
65 | { | ||
66 | "Unit": "CPU-M-CF", | ||
67 | "EventCode": "73", | ||
68 | "EventName": "DEA_CYCLES", | ||
69 | "BriefDescription": "DEA Cycles", | ||
70 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the DEA functions issued by the CPU" | ||
71 | }, | ||
72 | { | ||
73 | "Unit": "CPU-M-CF", | ||
74 | "EventCode": "74", | ||
75 | "EventName": "DEA_BLOCKED_FUNCTIONS", | ||
76 | "BriefDescription": "DEA Blocked Functions", | ||
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" | ||
78 | }, | ||
79 | { | ||
80 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "75", | ||
82 | "EventName": "DEA_BLOCKED_CYCLES", | ||
83 | "BriefDescription": "DEA Blocked Cycles", | ||
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" | ||
85 | }, | ||
86 | { | ||
87 | "Unit": "CPU-M-CF", | ||
88 | "EventCode": "76", | ||
89 | "EventName": "AES_FUNCTIONS", | ||
90 | "BriefDescription": "AES Functions", | ||
91 | "PublicDescription": "Total number of AES functions issued by the CPU" | ||
92 | }, | ||
93 | { | ||
94 | "Unit": "CPU-M-CF", | ||
95 | "EventCode": "77", | ||
96 | "EventName": "AES_CYCLES", | ||
97 | "BriefDescription": "AES Cycles", | ||
98 | "PublicDescription": "Total number of CPU cycles when the DEA/AES coprocessor is busy performing the AES functions issued by the CPU" | ||
99 | }, | ||
100 | { | ||
101 | "Unit": "CPU-M-CF", | ||
102 | "EventCode": "78", | ||
103 | "EventName": "AES_BLOCKED_FUNCTIONS", | ||
104 | "BriefDescription": "AES Blocked Functions", | ||
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" | ||
106 | }, | ||
107 | { | ||
108 | "Unit": "CPU-M-CF", | ||
109 | "EventCode": "79", | ||
110 | "EventName": "AES_BLOCKED_CYCLES", | ||
111 | "BriefDescription": "AES Blocked Cycles", | ||
112 | "PublicDescription": "Total number of CPU cycles blocked for the AES functions issued by the CPU because the DEA/AES coprocessor is busy performing a function issued by another CPU" | ||
113 | }, | ||
114 | ] | ||
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json new file mode 100644 index 000000000000..5e36bc2468d0 --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_m8561/crypto6.json | |||
@@ -0,0 +1,30 @@ | |||
1 | [ | ||
2 | { | ||
3 | "Unit": "CPU-M-CF", | ||
4 | "EventCode": "80", | ||
5 | "EventName": "ECC_FUNCTION_COUNT", | ||
6 | "BriefDescription": "ECC Function Count", | ||
7 | "PublicDescription": "Long ECC function Count" | ||
8 | }, | ||
9 | { | ||
10 | "Unit": "CPU-M-CF", | ||
11 | "EventCode": "81", | ||
12 | "EventName": "ECC_CYCLES_COUNT", | ||
13 | "BriefDescription": "ECC Cycles Count", | ||
14 | "PublicDescription": "Long ECC Function cycles count" | ||
15 | }, | ||
16 | { | ||
17 | "Unit": "CPU-M-CF", | ||
18 | "EventCode": "82", | ||
19 | "EventName": "ECC_BLOCKED_FUNCTION_COUNT", | ||
20 | "BriefDescription": "Ecc Blocked Function Count", | ||
21 | "PublicDescription": "Long ECC blocked function count" | ||
22 | }, | ||
23 | { | ||
24 | "Unit": "CPU-M-CF", | ||
25 | "EventCode": "83", | ||
26 | "EventName": "ECC_BLOCKED_CYCLES_COUNT", | ||
27 | "BriefDescription": "ECC Blocked Cycles Count", | ||
28 | "PublicDescription": "Long ECC blocked cycles count" | ||
29 | }, | ||
30 | ] | ||
diff --git a/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json b/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json new file mode 100644 index 000000000000..89e070727e1b --- /dev/null +++ b/tools/perf/pmu-events/arch/s390/cf_m8561/extended.json | |||
@@ -0,0 +1,373 @@ | |||
1 | [ | ||
2 | { | ||
3 | "Unit": "CPU-M-CF", | ||
4 | "EventCode": "128", | ||
5 | "EventName": "L1D_RO_EXCL_WRITES", | ||
6 | "BriefDescription": "L1D Read-only Exclusive Writes", | ||
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" | ||
8 | }, | ||
9 | { | ||
10 | "Unit": "CPU-M-CF", | ||
11 | "EventCode": "129", | ||
12 | "EventName": "DTLB2_WRITES", | ||
13 | "BriefDescription": "DTLB2 Writes", | ||
14 | "PublicDescription": "A translation has been written into The Translation Lookaside Buffer 2 (TLB2) and the request was made by the data cache" | ||
15 | }, | ||
16 | { | ||
17 | "Unit": "CPU-M-CF", | ||
18 | "EventCode": "130", | ||
19 | "EventName": "DTLB2_MISSES", | ||
20 | "BriefDescription": "DTLB2 Misses", | ||
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" | ||
22 | }, | ||
23 | { | ||
24 | "Unit": "CPU-M-CF", | ||
25 | "EventCode": "131", | ||
26 | "EventName": "DTLB2_HPAGE_WRITES", | ||
27 | "BriefDescription": "DTLB2 One-Megabyte Page Writes", | ||
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" | ||
29 | }, | ||
30 | { | ||
31 | "Unit": "CPU-M-CF", | ||
32 | "EventCode": "132", | ||
33 | "EventName": "DTLB2_GPAGE_WRITES", | ||
34 | "BriefDescription": "DTLB2 Two-Gigabyte Page Writes", | ||
35 | "PublicDescription": "A translation entry for a two-gigabyte page was written into the Level-2 TLB" | ||
36 | }, | ||
37 | { | ||
38 | "Unit": "CPU-M-CF", | ||
39 | "EventCode": "133", | ||
40 | "EventName": "L1D_L2D_SOURCED_WRITES", | ||
41 | "BriefDescription": "L1D L2D Sourced Writes", | ||
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" | ||
43 | }, | ||
44 | { | ||
45 | "Unit": "CPU-M-CF", | ||
46 | "EventCode": "134", | ||
47 | "EventName": "ITLB2_WRITES", | ||
48 | "BriefDescription": "ITLB2 Writes", | ||
49 | "PublicDescription": "A translation entry has been written into the Translation Lookaside Buffer 2 (TLB2) and the request was made by the instruction cache" | ||
50 | }, | ||
51 | { | ||
52 | "Unit": "CPU-M-CF", | ||
53 | "EventCode": "135", | ||
54 | "EventName": "ITLB2_MISSES", | ||
55 | "BriefDescription": "ITLB2 Misses", | ||
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" | ||
57 | }, | ||
58 | { | ||
59 | "Unit": "CPU-M-CF", | ||
60 | "EventCode": "136", | ||
61 | "EventName": "L1I_L2I_SOURCED_WRITES", | ||
62 | "BriefDescription": "L1I L2I Sourced Writes", | ||
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" | ||
64 | }, | ||
65 | { | ||
66 | "Unit": "CPU-M-CF", | ||
67 | "EventCode": "137", | ||
68 | "EventName": "TLB2_PTE_WRITES", | ||
69 | "BriefDescription": "TLB2 PTE Writes", | ||
70 | "PublicDescription": "A translation entry was written into the Page Table Entry array in the Level-2 TLB" | ||
71 | }, | ||
72 | { | ||
73 | "Unit": "CPU-M-CF", | ||
74 | "EventCode": "138", | ||
75 | "EventName": "TLB2_CRSTE_WRITES", | ||
76 | "BriefDescription": "TLB2 CRSTE Writes", | ||
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" | ||
78 | }, | ||
79 | { | ||
80 | "Unit": "CPU-M-CF", | ||
81 | "EventCode": "139", | ||
82 | "EventName": "TLB2_ENGINES_BUSY", | ||
83 | "BriefDescription": "TLB2 Engines Busy", | ||
84 | "PublicDescription": "The number of Level-2 TLB translation engines busy in a cycle" | ||
85 | }, | ||
86 | { | ||
87 | "Unit": "CPU-M-CF", | ||
88 | "EventCode": "140", | ||
89 | "EventName": "TX_C_TEND", | ||
90 | "BriefDescription": "Completed TEND instructions in constrained TX mode", | ||
91 | "PublicDescription": "A TEND instruction has completed in a constrained transactional-execution mode" | ||
92 | }, | ||
93 | { | ||
94 | "Unit": "CPU-M-CF", | ||
95 | "EventCode": "141", | ||
96 | "EventName": "TX_NC_TEND", | ||
97 | "BriefDescription": "Completed TEND instructions in non-constrained TX mode", | ||
98 | "PublicDescription": "A TEND instruction has completed in a non-constrained transactional-execution mode" | ||
99 | }, | ||
100 | { | ||
101 | "Unit": "CPU-M-CF", | ||
102 | "EventCode": "143", | ||
103 | "EventName": "L1C_TLB2_MISSES", | ||
104 | "BriefDescription": "L1C TLB2 Misses", | ||
105 | "PublicDescription": "Increments by one for any cycle where a level-1 cache or level-2 TLB miss is in progress" | ||
106 | }, | ||
107 | { | ||
108 | "Unit": "CPU-M-CF", | ||
109 | "EventCode": "144", | ||
110 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES", | ||
111 | "BriefDescription": "L1D On-Chip L3 Sourced Writes", | ||
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" | ||
113 | }, | ||
114 | { | ||
115 | "Unit": "CPU-M-CF", | ||
116 | "EventCode": "145", | ||
117 | "EventName": "L1D_ONCHIP_MEMORY_SOURCED_WRITES", | ||
118 | "BriefDescription": "L1D On-Chip Memory Sourced Writes", | ||
119 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from On-Chip memory" | ||
120 | }, | ||
121 | { | ||
122 | "Unit": "CPU-M-CF", | ||
123 | "EventCode": "146", | ||
124 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_IV", | ||
125 | "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 an On-Chip Level-3 cache with intervention" | ||
127 | }, | ||
128 | { | ||
129 | "Unit": "CPU-M-CF", | ||
130 | "EventCode": "147", | ||
131 | "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES", | ||
132 | "BriefDescription": "L1D On-Cluster L3 Sourced Writes", | ||
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" | ||
134 | }, | ||
135 | { | ||
136 | "Unit": "CPU-M-CF", | ||
137 | "EventCode": "148", | ||
138 | "EventName": "L1D_ONCLUSTER_MEMORY_SOURCED_WRITES", | ||
139 | "BriefDescription": "L1D On-Cluster Memory Sourced Writes", | ||
140 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from an On-Cluster memory" | ||
141 | }, | ||
142 | { | ||
143 | "Unit": "CPU-M-CF", | ||
144 | "EventCode": "149", | ||
145 | "EventName": "L1D_ONCLUSTER_L3_SOURCED_WRITES_IV", | ||
146 | "BriefDescription": "L1D On-Cluster L3 Sourced Writes 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" | ||
148 | }, | ||
149 | { | ||
150 | "Unit": "CPU-M-CF", | ||
151 | "EventCode": "150", | ||
152 | "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES", | ||
153 | "BriefDescription": "L1D Off-Cluster L3 Sourced Writes", | ||
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" | ||
155 | }, | ||
156 | { | ||
157 | "Unit": "CPU-M-CF", | ||
158 | "EventCode": "151", | ||
159 | "EventName": "L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES", | ||
160 | "BriefDescription": "L1D Off-Cluster Memory Sourced Writes", | ||
161 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Cluster memory" | ||
162 | }, | ||
163 | { | ||
164 | "Unit": "CPU-M-CF", | ||
165 | "EventCode": "152", | ||
166 | "EventName": "L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV", | ||
167 | "BriefDescription": "L1D Off-Cluster 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-Cluster Level-3 cache with intervention" | ||
169 | }, | ||
170 | { | ||
171 | "Unit": "CPU-M-CF", | ||
172 | "EventCode": "153", | ||
173 | "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES", | ||
174 | "BriefDescription": "L1D Off-Drawer L3 Sourced Writes", | ||
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" | ||
176 | }, | ||
177 | { | ||
178 | "Unit": "CPU-M-CF", | ||
179 | "EventCode": "154", | ||
180 | "EventName": "L1D_OFFDRAWER_MEMORY_SOURCED_WRITES", | ||
181 | "BriefDescription": "L1D Off-Drawer Memory Sourced Writes", | ||
182 | "PublicDescription": "A directory write to the Level-1 Data cache directory where the returned cache line was sourced from Off-Drawer memory" | ||
183 | }, | ||
184 | { | ||
185 | "Unit": "CPU-M-CF", | ||
186 | "EventCode": "155", | ||
187 | "EventName": "L1D_OFFDRAWER_L3_SOURCED_WRITES_IV", | ||
188 | "BriefDescription": "L1D Off-Drawer L3 Sourced Writes 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" | ||
190 | }, | ||
191 | { | ||
192 | "Unit": "CPU-M-CF", | ||
193 | "EventCode": "156", | ||
194 | "EventName": "L1D_ONDRAWER_L4_SOURCED_WRITES", | ||
195 | "BriefDescription": "L1D On-Drawer L4 Sourced Writes", | ||
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" | ||
197 | }, | ||
198 | { | ||
199 | "Unit": "CPU-M-CF", | ||
200 | "EventCode": "157", | ||
201 | "EventName": "L1D_OFFDRAWER_L4_SOURCED_WRITES", | ||
202 | "BriefDescription": "L1D Off-Drawer L4 Sourced Writes", | ||
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" | ||
204 | }, | ||
205 | { | ||
206 | "Unit": "CPU-M-CF", | ||
207 | "EventCode": "158", | ||
208 | "EventName": "L1D_ONCHIP_L3_SOURCED_WRITES_RO", | ||
209 | "BriefDescription": "L1D On-Chip L3 Sourced Writes read-only", | ||
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" | ||
211 | }, | ||
212 | { | ||
213 | "Unit": "CPU-M-CF", | ||
214 | "EventCode": "162", | ||
215 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES", | ||
216 | "BriefDescription": "L1I On-Chip L3 Sourced Writes", | ||
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" | ||
218 | }, | ||
219 | { | ||
220 | "Unit": "CPU-M-CF", | ||
221 | "EventCode": "163", | ||
222 | "EventName": "L1I_ONCHIP_MEMORY_SOURCED_WRITES", | ||
223 | "BriefDescription": "L1I On-Chip Memory Sourced Writes", | ||
224 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache ine was sourced from On-Chip memory" | ||
225 | }, | ||
226 | { | ||
227 | "Unit": "CPU-M-CF", | ||
228 | "EventCode": "164", | ||
229 | "EventName": "L1I_ONCHIP_L3_SOURCED_WRITES_IV", | ||
230 | "BriefDescription": "L1I On-Chip L3 Sourced Writes 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" | ||
232 | }, | ||
233 | { | ||
234 | "Unit": "CPU-M-CF", | ||
235 | "EventCode": "165", | ||
236 | "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES", | ||
237 | "BriefDescription": "L1I On-Cluster L3 Sourced Writes", | ||
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" | ||
239 | }, | ||
240 | { | ||
241 | "Unit": "CPU-M-CF", | ||
242 | "EventCode": "166", | ||
243 | "EventName": "L1I_ONCLUSTER_MEMORY_SOURCED_WRITES", | ||
244 | "BriefDescription": "L1I On-Cluster Memory Sourced Writes", | ||
245 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from an On-Cluster memory" | ||
246 | }, | ||
247 | { | ||
248 | "Unit": "CPU-M-CF", | ||
249 | "EventCode": "167", | ||
250 | "EventName": "L1I_ONCLUSTER_L3_SOURCED_WRITES_IV", | ||
251 | "BriefDescription": "L1I On-Cluster 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 On-Cluster Level-3 cache with intervention" | ||
253 | }, | ||
254 | { | ||
255 | "Unit": "CPU-M-CF", | ||
256 | "EventCode": "168", | ||
257 | "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES", | ||
258 | "BriefDescription": "L1I Off-Cluster L3 Sourced Writes", | ||
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" | ||
260 | }, | ||
261 | { | ||
262 | "Unit": "CPU-M-CF", | ||
263 | "EventCode": "169", | ||
264 | "EventName": "L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES", | ||
265 | "BriefDescription": "L1I Off-Cluster Memory Sourced Writes", | ||
266 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Cluster memory" | ||
267 | }, | ||
268 | { | ||
269 | "Unit": "CPU-M-CF", | ||
270 | "EventCode": "170", | ||
271 | "EventName": "L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV", | ||
272 | "BriefDescription": "L1I Off-Cluster L3 Sourced Writes 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" | ||
274 | }, | ||
275 | { | ||
276 | "Unit": "CPU-M-CF", | ||
277 | "EventCode": "171", | ||
278 | "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES", | ||
279 | "BriefDescription": "L1I Off-Drawer L3 Sourced Writes", | ||
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" | ||
281 | }, | ||
282 | { | ||
283 | "Unit": "CPU-M-CF", | ||
284 | "EventCode": "172", | ||
285 | "EventName": "L1I_OFFDRAWER_MEMORY_SOURCED_WRITES", | ||
286 | "BriefDescription": "L1I Off-Drawer Memory Sourced Writes", | ||
287 | "PublicDescription": "A directory write to the Level-1 Instruction cache directory where the returned cache line was sourced from Off-Drawer memory" | ||
288 | }, | ||
289 | { | ||
290 | "Unit": "CPU-M-CF", | ||
291 | "EventCode": "173", | ||
292 | "EventName": "L1I_OFFDRAWER_L3_SOURCED_WRITES_IV", | ||
293 | "BriefDescription": "L1I Off-Drawer L3 Sourced Writes 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" | ||
295 | }, | ||
296 | { | ||
297 | "Unit": "CPU-M-CF", | ||
298 | "EventCode": "174", | ||
299 | "EventName": "L1I_ONDRAWER_L4_SOURCED_WRITES", | ||
300 | "BriefDescription": "L1I On-Drawer L4 Sourced Writes", | ||
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" | ||
302 | }, | ||
303 | { | ||
304 | "Unit": "CPU-M-CF", | ||
305 | "EventCode": "175", | ||
306 | "EventName": "L1I_OFFDRAWER_L4_SOURCED_WRITES", | ||
307 | "BriefDescription": "L1I Off-Drawer L4 Sourced Writes", | ||
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" | ||
309 | }, | ||
310 | { | ||
311 | "Unit": "CPU-M-CF", | ||
312 | "EventCode": "224", | ||
313 | "EventName": "BCD_DFP_EXECUTION_SLOTS", | ||
314 | "BriefDescription": "BCD DFP Execution Slots", | ||
315 | "PublicDescription": "Count of floating point execution slots used for finished Binary Coded Decimal to Decimal Floating Point conversions. Instructions: CDZT, CXZT, CZDT, CZXT" | ||
316 | }, | ||
317 | { | ||
318 | "Unit": "CPU-M-CF", | ||
319 | "EventCode": "225", | ||
320 | "EventName": "VX_BCD_EXECUTION_SLOTS", | ||
321 | "BriefDescription": "VX BCD Execution Slots", | ||
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" | ||
323 | }, | ||
324 | { | ||
325 | "Unit": "CPU-M-CF", | ||
326 | "EventCode": "226", | ||
327 | "EventName": "DECIMAL_INSTRUCTIONS", | ||
328 | "BriefDescription": "Decimal Instructions", | ||
329 | "PublicDescription": "Decimal instructions dispatched. Instructions: CVB, CVD, AP, CP, DP, ED, EDMK, MP, SRP, SP, ZAP" | ||
330 | }, | ||
331 | { | ||
332 | "Unit": "CPU-M-CF", | ||
333 | "EventCode": "232", | ||
334 | "EventName": "LAST_HOST_TRANSLATIONS", | ||
335 | "BriefDescription": "Last host translation done", | ||
336 | "PublicDescription": "Last Host Translation done" | ||
337 | }, | ||
338 | { | ||
339 | "Unit": "CPU-M-CF", | ||
340 | "EventCode": "243", | ||
341 | "EventName": "TX_NC_TABORT", | ||
342 | "BriefDescription": "Aborted transactions in non-constrained TX mode", | ||
343 | "PublicDescription": "A transaction abort has occurred in a non-constrained transactional-execution mode" | ||
344 | }, | ||
345 | { | ||
346 | "Unit": "CPU-M-CF", | ||
347 | "EventCode": "244", | ||
348 | "EventName": "TX_C_TABORT_NO_SPECIAL", | ||
349 | "BriefDescription": "Aborted transactions in constrained TX mode not using special completion logic", | ||
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" | ||
351 | }, | ||
352 | { | ||
353 | "Unit": "CPU-M-CF", | ||
354 | "EventCode": "245", | ||
355 | "EventName": "TX_C_TABORT_SPECIAL", | ||
356 | "BriefDescription": "Aborted transactions in constrained TX mode using special completion logic", | ||
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" | ||
358 | }, | ||
359 | { | ||
360 | "Unit": "CPU-M-CF", | ||
361 | "EventCode": "448", | ||
362 | "EventName": "MT_DIAG_CYCLES_ONE_THR_ACTIVE", | ||
363 | "BriefDescription": "Cycle count with one thread active", | ||
364 | "PublicDescription": "Cycle count with one thread active" | ||
365 | }, | ||
366 | { | ||
367 | "Unit": "CPU-M-CF", | ||
368 | "EventCode": "449", | ||
369 | "EventName": "MT_DIAG_CYCLES_TWO_THR_ACTIVE", | ||
370 | "BriefDescription": "Cycle count with two threads active", | ||
371 | "PublicDescription": "Cycle count with two threads active" | ||
372 | }, | ||
373 | ] | ||
diff --git a/tools/perf/pmu-events/arch/s390/mapfile.csv b/tools/perf/pmu-events/arch/s390/mapfile.csv index 78bcf7f8e206..bd3fc577139c 100644 --- a/tools/perf/pmu-events/arch/s390/mapfile.csv +++ b/tools/perf/pmu-events/arch/s390/mapfile.csv | |||
@@ -4,3 +4,4 @@ Family-model,Version,Filename,EventType | |||
4 | ^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core | 4 | ^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core |
5 | ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core | 5 | ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core |
6 | ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core | 6 | ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core |
7 | ^IBM.856[12].*3\.6.[[:xdigit:]]+$,3,cf_m8561,core | ||
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 287a6f10ca48..1a91a197cafb 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c | |||
@@ -407,7 +407,7 @@ static void free_arch_std_events(void) | |||
407 | 407 | ||
408 | list_for_each_entry_safe(es, next, &arch_std_events, list) { | 408 | list_for_each_entry_safe(es, next, &arch_std_events, list) { |
409 | FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD); | 409 | FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD); |
410 | list_del(&es->list); | 410 | list_del_init(&es->list); |
411 | free(es); | 411 | free(es); |
412 | } | 412 | } |
413 | } | 413 | } |
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 4447f0d7c754..7bd73a904b4e 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py | |||
@@ -353,7 +353,10 @@ do_query(query, 'CREATE TABLE threads (' | |||
353 | 'tid integer)') | 353 | 'tid integer)') |
354 | do_query(query, 'CREATE TABLE comms (' | 354 | do_query(query, 'CREATE TABLE comms (' |
355 | 'id bigint NOT NULL,' | 355 | 'id bigint NOT NULL,' |
356 | 'comm varchar(16))') | 356 | 'comm varchar(16),' |
357 | 'c_thread_id bigint,' | ||
358 | 'c_time bigint,' | ||
359 | 'exec_flag boolean)') | ||
357 | do_query(query, 'CREATE TABLE comm_threads (' | 360 | do_query(query, 'CREATE TABLE comm_threads (' |
358 | 'id bigint NOT NULL,' | 361 | 'id bigint NOT NULL,' |
359 | 'comm_id bigint,' | 362 | 'comm_id bigint,' |
@@ -479,6 +482,17 @@ do_query(query, 'CREATE TABLE pwrx (' | |||
479 | 'last_cstate integer,' | 482 | 'last_cstate integer,' |
480 | 'wake_reason integer)') | 483 | 'wake_reason integer)') |
481 | 484 | ||
485 | do_query(query, 'CREATE TABLE context_switches (' | ||
486 | 'id bigint NOT NULL,' | ||
487 | 'machine_id bigint,' | ||
488 | 'time bigint,' | ||
489 | 'cpu integer,' | ||
490 | 'thread_out_id bigint,' | ||
491 | 'comm_out_id bigint,' | ||
492 | 'thread_in_id bigint,' | ||
493 | 'comm_in_id bigint,' | ||
494 | 'flags integer)') | ||
495 | |||
482 | do_query(query, 'CREATE VIEW machines_view AS ' | 496 | do_query(query, 'CREATE VIEW machines_view AS ' |
483 | 'SELECT ' | 497 | 'SELECT ' |
484 | 'id,' | 498 | 'id,' |
@@ -692,6 +706,29 @@ do_query(query, 'CREATE VIEW power_events_view AS ' | |||
692 | ' INNER JOIN selected_events ON selected_events.id = samples.evsel_id' | 706 | ' INNER JOIN selected_events ON selected_events.id = samples.evsel_id' |
693 | ' ORDER BY samples.id') | 707 | ' ORDER BY samples.id') |
694 | 708 | ||
709 | do_query(query, 'CREATE VIEW context_switches_view AS ' | ||
710 | 'SELECT ' | ||
711 | 'context_switches.id,' | ||
712 | 'context_switches.machine_id,' | ||
713 | 'context_switches.time,' | ||
714 | 'context_switches.cpu,' | ||
715 | 'th_out.pid AS pid_out,' | ||
716 | 'th_out.tid AS tid_out,' | ||
717 | 'comm_out.comm AS comm_out,' | ||
718 | 'th_in.pid AS pid_in,' | ||
719 | 'th_in.tid AS tid_in,' | ||
720 | 'comm_in.comm AS comm_in,' | ||
721 | 'CASE WHEN context_switches.flags = 0 THEN \'in\'' | ||
722 | ' WHEN context_switches.flags = 1 THEN \'out\'' | ||
723 | ' WHEN context_switches.flags = 3 THEN \'out preempt\'' | ||
724 | ' ELSE CAST ( context_switches.flags AS VARCHAR(11) )' | ||
725 | 'END AS flags' | ||
726 | ' FROM context_switches' | ||
727 | ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id' | ||
728 | ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id' | ||
729 | ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id' | ||
730 | ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id') | ||
731 | |||
695 | file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0) | 732 | file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0) |
696 | file_trailer = b"\377\377" | 733 | file_trailer = b"\377\377" |
697 | 734 | ||
@@ -756,6 +793,7 @@ mwait_file = open_output_file("mwait_table.bin") | |||
756 | pwre_file = open_output_file("pwre_table.bin") | 793 | pwre_file = open_output_file("pwre_table.bin") |
757 | exstop_file = open_output_file("exstop_table.bin") | 794 | exstop_file = open_output_file("exstop_table.bin") |
758 | pwrx_file = open_output_file("pwrx_table.bin") | 795 | pwrx_file = open_output_file("pwrx_table.bin") |
796 | context_switches_file = open_output_file("context_switches_table.bin") | ||
759 | 797 | ||
760 | def trace_begin(): | 798 | def trace_begin(): |
761 | printdate("Writing to intermediate files...") | 799 | printdate("Writing to intermediate files...") |
@@ -763,7 +801,7 @@ def trace_begin(): | |||
763 | evsel_table(0, "unknown") | 801 | evsel_table(0, "unknown") |
764 | machine_table(0, 0, "unknown") | 802 | machine_table(0, 0, "unknown") |
765 | thread_table(0, 0, 0, -1, -1) | 803 | thread_table(0, 0, 0, -1, -1) |
766 | comm_table(0, "unknown") | 804 | comm_table(0, "unknown", 0, 0, 0) |
767 | dso_table(0, 0, "unknown", "unknown", "") | 805 | dso_table(0, 0, "unknown", "unknown", "") |
768 | symbol_table(0, 0, 0, 0, 0, "unknown") | 806 | symbol_table(0, 0, 0, 0, 0, "unknown") |
769 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | 807 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
@@ -804,6 +842,7 @@ def trace_end(): | |||
804 | copy_output_file(pwre_file, "pwre") | 842 | copy_output_file(pwre_file, "pwre") |
805 | copy_output_file(exstop_file, "exstop") | 843 | copy_output_file(exstop_file, "exstop") |
806 | copy_output_file(pwrx_file, "pwrx") | 844 | copy_output_file(pwrx_file, "pwrx") |
845 | copy_output_file(context_switches_file, "context_switches") | ||
807 | 846 | ||
808 | printdate("Removing intermediate files...") | 847 | printdate("Removing intermediate files...") |
809 | remove_output_file(evsel_file) | 848 | remove_output_file(evsel_file) |
@@ -825,6 +864,7 @@ def trace_end(): | |||
825 | remove_output_file(pwre_file) | 864 | remove_output_file(pwre_file) |
826 | remove_output_file(exstop_file) | 865 | remove_output_file(exstop_file) |
827 | remove_output_file(pwrx_file) | 866 | remove_output_file(pwrx_file) |
867 | remove_output_file(context_switches_file) | ||
828 | os.rmdir(output_dir_name) | 868 | os.rmdir(output_dir_name) |
829 | printdate("Adding primary keys") | 869 | printdate("Adding primary keys") |
830 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') | 870 | do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') |
@@ -846,11 +886,14 @@ def trace_end(): | |||
846 | do_query(query, 'ALTER TABLE pwre ADD PRIMARY KEY (id)') | 886 | do_query(query, 'ALTER TABLE pwre ADD PRIMARY KEY (id)') |
847 | do_query(query, 'ALTER TABLE exstop ADD PRIMARY KEY (id)') | 887 | do_query(query, 'ALTER TABLE exstop ADD PRIMARY KEY (id)') |
848 | do_query(query, 'ALTER TABLE pwrx ADD PRIMARY KEY (id)') | 888 | do_query(query, 'ALTER TABLE pwrx ADD PRIMARY KEY (id)') |
889 | do_query(query, 'ALTER TABLE context_switches ADD PRIMARY KEY (id)') | ||
849 | 890 | ||
850 | printdate("Adding foreign keys") | 891 | printdate("Adding foreign keys") |
851 | do_query(query, 'ALTER TABLE threads ' | 892 | do_query(query, 'ALTER TABLE threads ' |
852 | 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' | 893 | 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' |
853 | 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') | 894 | 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') |
895 | do_query(query, 'ALTER TABLE comms ' | ||
896 | 'ADD CONSTRAINT threadfk FOREIGN KEY (c_thread_id) REFERENCES threads (id)') | ||
854 | do_query(query, 'ALTER TABLE comm_threads ' | 897 | do_query(query, 'ALTER TABLE comm_threads ' |
855 | 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' | 898 | 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' |
856 | 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id)') | 899 | 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id)') |
@@ -881,6 +924,8 @@ def trace_end(): | |||
881 | 'ADD CONSTRAINT parent_call_pathfk FOREIGN KEY (parent_call_path_id) REFERENCES call_paths (id)') | 924 | 'ADD CONSTRAINT parent_call_pathfk FOREIGN KEY (parent_call_path_id) REFERENCES call_paths (id)') |
882 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') | 925 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') |
883 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') | 926 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') |
927 | do_query(query, 'ALTER TABLE comms ADD has_calls boolean') | ||
928 | do_query(query, 'UPDATE comms SET has_calls = TRUE WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)') | ||
884 | do_query(query, 'ALTER TABLE ptwrite ' | 929 | do_query(query, 'ALTER TABLE ptwrite ' |
885 | 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') | 930 | 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') |
886 | do_query(query, 'ALTER TABLE cbr ' | 931 | do_query(query, 'ALTER TABLE cbr ' |
@@ -893,18 +938,26 @@ def trace_end(): | |||
893 | 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') | 938 | 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') |
894 | do_query(query, 'ALTER TABLE pwrx ' | 939 | do_query(query, 'ALTER TABLE pwrx ' |
895 | 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') | 940 | 'ADD CONSTRAINT idfk FOREIGN KEY (id) REFERENCES samples (id)') |
941 | do_query(query, 'ALTER TABLE context_switches ' | ||
942 | 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' | ||
943 | 'ADD CONSTRAINT toutfk FOREIGN KEY (thread_out_id) REFERENCES threads (id),' | ||
944 | 'ADD CONSTRAINT tinfk FOREIGN KEY (thread_in_id) REFERENCES threads (id),' | ||
945 | 'ADD CONSTRAINT coutfk FOREIGN KEY (comm_out_id) REFERENCES comms (id),' | ||
946 | 'ADD CONSTRAINT cinfk FOREIGN KEY (comm_in_id) REFERENCES comms (id)') | ||
896 | 947 | ||
897 | printdate("Dropping unused tables") | 948 | printdate("Dropping unused tables") |
898 | if is_table_empty("ptwrite"): | 949 | if is_table_empty("ptwrite"): |
899 | drop("ptwrite") | 950 | drop("ptwrite") |
900 | if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): | 951 | if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): |
952 | do_query(query, 'DROP VIEW power_events_view'); | ||
901 | drop("mwait") | 953 | drop("mwait") |
902 | drop("pwre") | 954 | drop("pwre") |
903 | drop("exstop") | 955 | drop("exstop") |
904 | drop("pwrx") | 956 | drop("pwrx") |
905 | do_query(query, 'DROP VIEW power_events_view'); | ||
906 | if is_table_empty("cbr"): | 957 | if is_table_empty("cbr"): |
907 | drop("cbr") | 958 | drop("cbr") |
959 | if is_table_empty("context_switches"): | ||
960 | drop("context_switches") | ||
908 | 961 | ||
909 | if (unhandled_count): | 962 | if (unhandled_count): |
910 | printdate("Warning: ", unhandled_count, " unhandled events") | 963 | printdate("Warning: ", unhandled_count, " unhandled events") |
@@ -935,11 +988,11 @@ def thread_table(thread_id, machine_id, process_id, pid, tid, *x): | |||
935 | value = struct.pack("!hiqiqiqiiii", 5, 8, thread_id, 8, machine_id, 8, process_id, 4, pid, 4, tid) | 988 | value = struct.pack("!hiqiqiqiiii", 5, 8, thread_id, 8, machine_id, 8, process_id, 4, pid, 4, tid) |
936 | thread_file.write(value) | 989 | thread_file.write(value) |
937 | 990 | ||
938 | def comm_table(comm_id, comm_str, *x): | 991 | def comm_table(comm_id, comm_str, thread_id, time, exec_flag, *x): |
939 | comm_str = toserverstr(comm_str) | 992 | comm_str = toserverstr(comm_str) |
940 | n = len(comm_str) | 993 | n = len(comm_str) |
941 | fmt = "!hiqi" + str(n) + "s" | 994 | fmt = "!hiqi" + str(n) + "s" + "iqiqiB" |
942 | value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) | 995 | value = struct.pack(fmt, 5, 8, comm_id, n, comm_str, 8, thread_id, 8, time, 1, exec_flag) |
943 | comm_file.write(value) | 996 | comm_file.write(value) |
944 | 997 | ||
945 | def comm_thread_table(comm_thread_id, comm_id, thread_id, *x): | 998 | def comm_thread_table(comm_thread_id, comm_id, thread_id, *x): |
@@ -1051,3 +1104,8 @@ def synth_data(id, config, raw_buf, *x): | |||
1051 | pwrx(id, raw_buf) | 1104 | pwrx(id, raw_buf) |
1052 | elif config == 5: | 1105 | elif config == 5: |
1053 | cbr(id, raw_buf) | 1106 | cbr(id, raw_buf) |
1107 | |||
1108 | def context_switch_table(id, machine_id, time, cpu, thread_out_id, comm_out_id, thread_in_id, comm_in_id, flags, *x): | ||
1109 | fmt = "!hiqiqiqiiiqiqiqiqii" | ||
1110 | value = struct.pack(fmt, 9, 8, id, 8, machine_id, 8, time, 4, cpu, 8, thread_out_id, 8, comm_out_id, 8, thread_in_id, 8, comm_in_id, 4, flags) | ||
1111 | context_switches_file.write(value) | ||
diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py index 3222a83f4184..8043a7272a56 100644 --- a/tools/perf/scripts/python/export-to-sqlite.py +++ b/tools/perf/scripts/python/export-to-sqlite.py | |||
@@ -177,7 +177,10 @@ do_query(query, 'CREATE TABLE threads (' | |||
177 | 'tid integer)') | 177 | 'tid integer)') |
178 | do_query(query, 'CREATE TABLE comms (' | 178 | do_query(query, 'CREATE TABLE comms (' |
179 | 'id integer NOT NULL PRIMARY KEY,' | 179 | 'id integer NOT NULL PRIMARY KEY,' |
180 | 'comm varchar(16))') | 180 | 'comm varchar(16),' |
181 | 'c_thread_id bigint,' | ||
182 | 'c_time bigint,' | ||
183 | 'exec_flag boolean)') | ||
181 | do_query(query, 'CREATE TABLE comm_threads (' | 184 | do_query(query, 'CREATE TABLE comm_threads (' |
182 | 'id integer NOT NULL PRIMARY KEY,' | 185 | 'id integer NOT NULL PRIMARY KEY,' |
183 | 'comm_id bigint,' | 186 | 'comm_id bigint,' |
@@ -303,6 +306,17 @@ do_query(query, 'CREATE TABLE pwrx (' | |||
303 | 'last_cstate integer,' | 306 | 'last_cstate integer,' |
304 | 'wake_reason integer)') | 307 | 'wake_reason integer)') |
305 | 308 | ||
309 | do_query(query, 'CREATE TABLE context_switches (' | ||
310 | 'id integer NOT NULL PRIMARY KEY,' | ||
311 | 'machine_id bigint,' | ||
312 | 'time bigint,' | ||
313 | 'cpu integer,' | ||
314 | 'thread_out_id bigint,' | ||
315 | 'comm_out_id bigint,' | ||
316 | 'thread_in_id bigint,' | ||
317 | 'comm_in_id bigint,' | ||
318 | 'flags integer)') | ||
319 | |||
306 | # printf was added to sqlite in version 3.8.3 | 320 | # printf was added to sqlite in version 3.8.3 |
307 | sqlite_has_printf = False | 321 | sqlite_has_printf = False |
308 | try: | 322 | try: |
@@ -527,6 +541,29 @@ do_query(query, 'CREATE VIEW power_events_view AS ' | |||
527 | ' INNER JOIN selected_events ON selected_events.id = evsel_id' | 541 | ' INNER JOIN selected_events ON selected_events.id = evsel_id' |
528 | ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')') | 542 | ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')') |
529 | 543 | ||
544 | do_query(query, 'CREATE VIEW context_switches_view AS ' | ||
545 | 'SELECT ' | ||
546 | 'context_switches.id,' | ||
547 | 'context_switches.machine_id,' | ||
548 | 'context_switches.time,' | ||
549 | 'context_switches.cpu,' | ||
550 | 'th_out.pid AS pid_out,' | ||
551 | 'th_out.tid AS tid_out,' | ||
552 | 'comm_out.comm AS comm_out,' | ||
553 | 'th_in.pid AS pid_in,' | ||
554 | 'th_in.tid AS tid_in,' | ||
555 | 'comm_in.comm AS comm_in,' | ||
556 | 'CASE WHEN context_switches.flags = 0 THEN \'in\'' | ||
557 | ' WHEN context_switches.flags = 1 THEN \'out\'' | ||
558 | ' WHEN context_switches.flags = 3 THEN \'out preempt\'' | ||
559 | ' ELSE context_switches.flags ' | ||
560 | 'END AS flags' | ||
561 | ' FROM context_switches' | ||
562 | ' INNER JOIN threads AS th_out ON th_out.id = context_switches.thread_out_id' | ||
563 | ' INNER JOIN threads AS th_in ON th_in.id = context_switches.thread_in_id' | ||
564 | ' INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id' | ||
565 | ' INNER JOIN comms AS comm_in ON comm_in.id = context_switches.comm_in_id') | ||
566 | |||
530 | do_query(query, 'END TRANSACTION') | 567 | do_query(query, 'END TRANSACTION') |
531 | 568 | ||
532 | evsel_query = QSqlQuery(db) | 569 | evsel_query = QSqlQuery(db) |
@@ -536,7 +573,7 @@ machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)") | |||
536 | thread_query = QSqlQuery(db) | 573 | thread_query = QSqlQuery(db) |
537 | thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") | 574 | thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") |
538 | comm_query = QSqlQuery(db) | 575 | comm_query = QSqlQuery(db) |
539 | comm_query.prepare("INSERT INTO comms VALUES (?, ?)") | 576 | comm_query.prepare("INSERT INTO comms VALUES (?, ?, ?, ?, ?)") |
540 | comm_thread_query = QSqlQuery(db) | 577 | comm_thread_query = QSqlQuery(db) |
541 | comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") | 578 | comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") |
542 | dso_query = QSqlQuery(db) | 579 | dso_query = QSqlQuery(db) |
@@ -568,6 +605,8 @@ exstop_query = QSqlQuery(db) | |||
568 | exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)") | 605 | exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)") |
569 | pwrx_query = QSqlQuery(db) | 606 | pwrx_query = QSqlQuery(db) |
570 | pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)") | 607 | pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)") |
608 | context_switch_query = QSqlQuery(db) | ||
609 | context_switch_query.prepare("INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)") | ||
571 | 610 | ||
572 | def trace_begin(): | 611 | def trace_begin(): |
573 | printdate("Writing records...") | 612 | printdate("Writing records...") |
@@ -576,7 +615,7 @@ def trace_begin(): | |||
576 | evsel_table(0, "unknown") | 615 | evsel_table(0, "unknown") |
577 | machine_table(0, 0, "unknown") | 616 | machine_table(0, 0, "unknown") |
578 | thread_table(0, 0, 0, -1, -1) | 617 | thread_table(0, 0, 0, -1, -1) |
579 | comm_table(0, "unknown") | 618 | comm_table(0, "unknown", 0, 0, 0) |
580 | dso_table(0, 0, "unknown", "unknown", "") | 619 | dso_table(0, 0, "unknown", "unknown", "") |
581 | symbol_table(0, 0, 0, 0, 0, "unknown") | 620 | symbol_table(0, 0, 0, 0, 0, "unknown") |
582 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | 621 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
@@ -603,18 +642,22 @@ def trace_end(): | |||
603 | if perf_db_export_calls: | 642 | if perf_db_export_calls: |
604 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') | 643 | do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') |
605 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') | 644 | do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') |
645 | do_query(query, 'ALTER TABLE comms ADD has_calls boolean') | ||
646 | do_query(query, 'UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)') | ||
606 | 647 | ||
607 | printdate("Dropping unused tables") | 648 | printdate("Dropping unused tables") |
608 | if is_table_empty("ptwrite"): | 649 | if is_table_empty("ptwrite"): |
609 | drop("ptwrite") | 650 | drop("ptwrite") |
610 | if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): | 651 | if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"): |
652 | do_query(query, 'DROP VIEW power_events_view'); | ||
611 | drop("mwait") | 653 | drop("mwait") |
612 | drop("pwre") | 654 | drop("pwre") |
613 | drop("exstop") | 655 | drop("exstop") |
614 | drop("pwrx") | 656 | drop("pwrx") |
615 | do_query(query, 'DROP VIEW power_events_view'); | ||
616 | if is_table_empty("cbr"): | 657 | if is_table_empty("cbr"): |
617 | drop("cbr") | 658 | drop("cbr") |
659 | if is_table_empty("context_switches"): | ||
660 | drop("context_switches") | ||
618 | 661 | ||
619 | if (unhandled_count): | 662 | if (unhandled_count): |
620 | printdate("Warning: ", unhandled_count, " unhandled events") | 663 | printdate("Warning: ", unhandled_count, " unhandled events") |
@@ -642,7 +685,7 @@ def thread_table(*x): | |||
642 | bind_exec(thread_query, 5, x) | 685 | bind_exec(thread_query, 5, x) |
643 | 686 | ||
644 | def comm_table(*x): | 687 | def comm_table(*x): |
645 | bind_exec(comm_query, 2, x) | 688 | bind_exec(comm_query, 5, x) |
646 | 689 | ||
647 | def comm_thread_table(*x): | 690 | def comm_thread_table(*x): |
648 | bind_exec(comm_thread_query, 3, x) | 691 | bind_exec(comm_thread_query, 3, x) |
@@ -748,3 +791,6 @@ def synth_data(id, config, raw_buf, *x): | |||
748 | pwrx(id, raw_buf) | 791 | pwrx(id, raw_buf) |
749 | elif config == 5: | 792 | elif config == 5: |
750 | cbr(id, raw_buf) | 793 | cbr(id, raw_buf) |
794 | |||
795 | def context_switch_table(*x): | ||
796 | bind_exec(context_switch_query, 9, x) | ||
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py index 6e7934f2ac9a..61b3911d91e6 100755 --- a/tools/perf/scripts/python/exported-sql-viewer.py +++ b/tools/perf/scripts/python/exported-sql-viewer.py | |||
@@ -392,7 +392,7 @@ class FindBar(): | |||
392 | self.hbox.addWidget(self.close_button) | 392 | self.hbox.addWidget(self.close_button) |
393 | 393 | ||
394 | self.bar = QWidget() | 394 | self.bar = QWidget() |
395 | self.bar.setLayout(self.hbox); | 395 | self.bar.setLayout(self.hbox) |
396 | self.bar.hide() | 396 | self.bar.hide() |
397 | 397 | ||
398 | def Widget(self): | 398 | def Widget(self): |
@@ -470,7 +470,7 @@ class CallGraphLevelItemBase(object): | |||
470 | self.params = params | 470 | self.params = params |
471 | self.row = row | 471 | self.row = row |
472 | self.parent_item = parent_item | 472 | self.parent_item = parent_item |
473 | self.query_done = False; | 473 | self.query_done = False |
474 | self.child_count = 0 | 474 | self.child_count = 0 |
475 | self.child_items = [] | 475 | self.child_items = [] |
476 | if parent_item: | 476 | if parent_item: |
@@ -517,7 +517,7 @@ class CallGraphLevelTwoPlusItemBase(CallGraphLevelItemBase): | |||
517 | self.time = time | 517 | self.time = time |
518 | 518 | ||
519 | def Select(self): | 519 | def Select(self): |
520 | self.query_done = True; | 520 | self.query_done = True |
521 | query = QSqlQuery(self.glb.db) | 521 | query = QSqlQuery(self.glb.db) |
522 | if self.params.have_ipc: | 522 | if self.params.have_ipc: |
523 | ipc_str = ", SUM(insn_count), SUM(cyc_count)" | 523 | ipc_str = ", SUM(insn_count), SUM(cyc_count)" |
@@ -604,7 +604,7 @@ class CallGraphLevelOneItem(CallGraphLevelItemBase): | |||
604 | self.dbid = comm_id | 604 | self.dbid = comm_id |
605 | 605 | ||
606 | def Select(self): | 606 | def Select(self): |
607 | self.query_done = True; | 607 | self.query_done = True |
608 | query = QSqlQuery(self.glb.db) | 608 | query = QSqlQuery(self.glb.db) |
609 | QueryExec(query, "SELECT thread_id, pid, tid" | 609 | QueryExec(query, "SELECT thread_id, pid, tid" |
610 | " FROM comm_threads" | 610 | " FROM comm_threads" |
@@ -622,9 +622,12 @@ class CallGraphRootItem(CallGraphLevelItemBase): | |||
622 | def __init__(self, glb, params): | 622 | def __init__(self, glb, params): |
623 | super(CallGraphRootItem, self).__init__(glb, params, 0, None) | 623 | super(CallGraphRootItem, self).__init__(glb, params, 0, None) |
624 | self.dbid = 0 | 624 | self.dbid = 0 |
625 | self.query_done = True; | 625 | self.query_done = True |
626 | if_has_calls = "" | ||
627 | if IsSelectable(glb.db, "comms", columns = "has_calls"): | ||
628 | if_has_calls = " WHERE has_calls = TRUE" | ||
626 | query = QSqlQuery(glb.db) | 629 | query = QSqlQuery(glb.db) |
627 | QueryExec(query, "SELECT id, comm FROM comms") | 630 | QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls) |
628 | while query.next(): | 631 | while query.next(): |
629 | if not query.value(0): | 632 | if not query.value(0): |
630 | continue | 633 | continue |
@@ -793,7 +796,7 @@ class CallTreeLevelTwoPlusItemBase(CallGraphLevelItemBase): | |||
793 | self.time = time | 796 | self.time = time |
794 | 797 | ||
795 | def Select(self): | 798 | def Select(self): |
796 | self.query_done = True; | 799 | self.query_done = True |
797 | if self.calls_id == 0: | 800 | if self.calls_id == 0: |
798 | comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id) | 801 | comm_thread = " AND comm_id = " + str(self.comm_id) + " AND thread_id = " + str(self.thread_id) |
799 | else: | 802 | else: |
@@ -881,7 +884,7 @@ class CallTreeLevelOneItem(CallGraphLevelItemBase): | |||
881 | self.dbid = comm_id | 884 | self.dbid = comm_id |
882 | 885 | ||
883 | def Select(self): | 886 | def Select(self): |
884 | self.query_done = True; | 887 | self.query_done = True |
885 | query = QSqlQuery(self.glb.db) | 888 | query = QSqlQuery(self.glb.db) |
886 | QueryExec(query, "SELECT thread_id, pid, tid" | 889 | QueryExec(query, "SELECT thread_id, pid, tid" |
887 | " FROM comm_threads" | 890 | " FROM comm_threads" |
@@ -899,9 +902,12 @@ class CallTreeRootItem(CallGraphLevelItemBase): | |||
899 | def __init__(self, glb, params): | 902 | def __init__(self, glb, params): |
900 | super(CallTreeRootItem, self).__init__(glb, params, 0, None) | 903 | super(CallTreeRootItem, self).__init__(glb, params, 0, None) |
901 | self.dbid = 0 | 904 | self.dbid = 0 |
902 | self.query_done = True; | 905 | self.query_done = True |
906 | if_has_calls = "" | ||
907 | if IsSelectable(glb.db, "comms", columns = "has_calls"): | ||
908 | if_has_calls = " WHERE has_calls = TRUE" | ||
903 | query = QSqlQuery(glb.db) | 909 | query = QSqlQuery(glb.db) |
904 | QueryExec(query, "SELECT id, comm FROM comms") | 910 | QueryExec(query, "SELECT id, comm FROM comms" + if_has_calls) |
905 | while query.next(): | 911 | while query.next(): |
906 | if not query.value(0): | 912 | if not query.value(0): |
907 | continue | 913 | continue |
@@ -971,7 +977,7 @@ class VBox(): | |||
971 | 977 | ||
972 | def __init__(self, w1, w2, w3=None): | 978 | def __init__(self, w1, w2, w3=None): |
973 | self.vbox = QWidget() | 979 | self.vbox = QWidget() |
974 | self.vbox.setLayout(QVBoxLayout()); | 980 | self.vbox.setLayout(QVBoxLayout()) |
975 | 981 | ||
976 | self.vbox.layout().setContentsMargins(0, 0, 0, 0) | 982 | self.vbox.layout().setContentsMargins(0, 0, 0, 0) |
977 | 983 | ||
@@ -1391,7 +1397,7 @@ class FetchMoreRecordsBar(): | |||
1391 | self.hbox.addWidget(self.close_button) | 1397 | self.hbox.addWidget(self.close_button) |
1392 | 1398 | ||
1393 | self.bar = QWidget() | 1399 | self.bar = QWidget() |
1394 | self.bar.setLayout(self.hbox); | 1400 | self.bar.setLayout(self.hbox) |
1395 | self.bar.show() | 1401 | self.bar.show() |
1396 | 1402 | ||
1397 | self.in_progress = False | 1403 | self.in_progress = False |
@@ -2206,7 +2212,7 @@ class ReportDialogBase(QDialog): | |||
2206 | self.vbox.addLayout(self.grid) | 2212 | self.vbox.addLayout(self.grid) |
2207 | self.vbox.addLayout(self.hbox) | 2213 | self.vbox.addLayout(self.hbox) |
2208 | 2214 | ||
2209 | self.setLayout(self.vbox); | 2215 | self.setLayout(self.vbox) |
2210 | 2216 | ||
2211 | def Ok(self): | 2217 | def Ok(self): |
2212 | vars = self.report_vars | 2218 | vars = self.report_vars |
@@ -3139,7 +3145,7 @@ class AboutDialog(QDialog): | |||
3139 | self.vbox = QVBoxLayout() | 3145 | self.vbox = QVBoxLayout() |
3140 | self.vbox.addWidget(self.text) | 3146 | self.vbox.addWidget(self.text) |
3141 | 3147 | ||
3142 | self.setLayout(self.vbox); | 3148 | self.setLayout(self.vbox) |
3143 | 3149 | ||
3144 | # Font resize | 3150 | # Font resize |
3145 | 3151 | ||
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 66a82badc1d1..c3bec9d2c201 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <subcmd/parse-options.h> | 21 | #include <subcmd/parse-options.h> |
22 | #include "string2.h" | 22 | #include "string2.h" |
23 | #include "symbol.h" | 23 | #include "symbol.h" |
24 | #include "util/rlimit.h" | ||
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/string.h> | 26 | #include <linux/string.h> |
26 | #include <subcmd/exec-cmd.h> | 27 | #include <subcmd/exec-cmd.h> |
@@ -727,6 +728,11 @@ int cmd_test(int argc, const char **argv) | |||
727 | 728 | ||
728 | if (skip != NULL) | 729 | if (skip != NULL) |
729 | skiplist = intlist__new(skip); | 730 | skiplist = intlist__new(skip); |
731 | /* | ||
732 | * Tests that create BPF maps, for instance, need more than the 64K | ||
733 | * default: | ||
734 | */ | ||
735 | rlimit__bump_memlock(); | ||
730 | 736 | ||
731 | return __cmd_test(argc, argv, skiplist); | 737 | return __cmd_test(argc, argv, skiplist); |
732 | } | 738 | } |
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 077c306c1cae..f33709a79335 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
4 | #include <linux/zalloc.h> | ||
4 | #include <inttypes.h> | 5 | #include <inttypes.h> |
5 | #include <unistd.h> | 6 | #include <unistd.h> |
6 | #include "tests.h" | 7 | #include "tests.h" |
@@ -115,8 +116,8 @@ noinline int test_dwarf_unwind__thread(struct thread *thread) | |||
115 | } | 116 | } |
116 | 117 | ||
117 | out: | 118 | out: |
118 | free(sample.user_stack.data); | 119 | zfree(&sample.user_stack.data); |
119 | free(sample.user_regs.regs); | 120 | zfree(&sample.user_regs.regs); |
120 | return err; | 121 | return err; |
121 | } | 122 | } |
122 | 123 | ||
diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 9acc1e80b936..ee1d88650e69 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include "util/expr.h" | 3 | #include "util/expr.h" |
4 | #include "tests.h" | 4 | #include "tests.h" |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | #include <linux/zalloc.h> | ||
6 | 7 | ||
7 | static int test(struct parse_ctx *ctx, const char *e, double val2) | 8 | static int test(struct parse_ctx *ctx, const char *e, double val2) |
8 | { | 9 | { |
@@ -58,7 +59,7 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) | |||
58 | TEST_ASSERT_VAL("find other", other[3] == NULL); | 59 | TEST_ASSERT_VAL("find other", other[3] == NULL); |
59 | 60 | ||
60 | for (i = 0; i < num_other; i++) | 61 | for (i = 0; i < num_other; i++) |
61 | free((void *)other[i]); | 62 | zfree(&other[i]); |
62 | free((void *)other); | 63 | free((void *)other); |
63 | 64 | ||
64 | return 0; | 65 | return 0; |
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index a039f93199e5..ca5a5f94ce79 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c | |||
@@ -1,5 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #include <stdlib.h> | ||
3 | #include <bpf/libbpf.h> | 4 | #include <bpf/libbpf.h> |
4 | #include <util/llvm-utils.h> | 5 | #include <util/llvm-utils.h> |
5 | #include <util/cache.h> | 6 | #include <util/cache.h> |
diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index d23ff1b68eba..520cc91af256 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <linux/bitmap.h> | 3 | #include <linux/bitmap.h> |
4 | #include <linux/zalloc.h> | ||
4 | #include "cpumap.h" | 5 | #include "cpumap.h" |
5 | #include "mem2node.h" | 6 | #include "mem2node.h" |
6 | #include "tests.h" | 7 | #include "tests.h" |
@@ -67,7 +68,7 @@ int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused) | |||
67 | T("failed: mem2node__node", -1 == mem2node__node(&map, 0x1050)); | 68 | T("failed: mem2node__node", -1 == mem2node__node(&map, 0x1050)); |
68 | 69 | ||
69 | for (i = 0; i < ARRAY_SIZE(nodes); i++) | 70 | for (i = 0; i < ARRAY_SIZE(nodes); i++) |
70 | free(nodes[i].set); | 71 | zfree(&nodes[i].set); |
71 | 72 | ||
72 | mem2node__exit(&map); | 73 | mem2node__exit(&map); |
73 | return 0; | 74 | return 0; |
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index ba87e6e8d18c..0a4301a5155c 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c | |||
@@ -53,7 +53,7 @@ static void *thread_fn(void *arg) | |||
53 | { | 53 | { |
54 | struct thread_data *td = arg; | 54 | struct thread_data *td = arg; |
55 | ssize_t ret; | 55 | ssize_t ret; |
56 | int go; | 56 | int go = 0; |
57 | 57 | ||
58 | if (thread_init(td)) | 58 | if (thread_init(td)) |
59 | return NULL; | 59 | return NULL; |
diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index 236ce0d6c826..361714e2583c 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
3 | #include <inttypes.h> | 3 | #include <inttypes.h> |
4 | #include <stdlib.h> | ||
4 | #include <linux/bitops.h> | 5 | #include <linux/bitops.h> |
5 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
6 | #include <linux/types.h> | 7 | #include <linux/types.h> |
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 9b5be51e5e7b..6cdab5f4812a 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <errno.h> | 4 | #include <errno.h> |
5 | #include <time.h> | 5 | #include <time.h> |
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include <linux/zalloc.h> | ||
7 | 8 | ||
8 | #include "parse-events.h" | 9 | #include "parse-events.h" |
9 | #include "evlist.h" | 10 | #include "evlist.h" |
@@ -237,7 +238,7 @@ static void free_event_nodes(struct list_head *events) | |||
237 | 238 | ||
238 | while (!list_empty(events)) { | 239 | while (!list_empty(events)) { |
239 | node = list_entry(events->next, struct event_node, list); | 240 | node = list_entry(events->next, struct event_node, list); |
240 | list_del(&node->list); | 241 | list_del_init(&node->list); |
241 | free(node); | 242 | free(node); |
242 | } | 243 | } |
243 | } | 244 | } |
diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index 4de1939b58ba..ccc17aced49e 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include "tests.h" | 6 | #include "tests.h" |
7 | #include "thread_map.h" | 7 | #include "thread_map.h" |
8 | #include "debug.h" | 8 | #include "debug.h" |
9 | #include <linux/zalloc.h> | ||
9 | 10 | ||
10 | #define NAME (const char *) "perf" | 11 | #define NAME (const char *) "perf" |
11 | #define NAMEUL (unsigned long) NAME | 12 | #define NAMEUL (unsigned long) NAME |
@@ -133,7 +134,7 @@ int test__thread_map_remove(struct test *test __maybe_unused, int subtest __mayb | |||
133 | thread_map__remove(threads, 0)); | 134 | thread_map__remove(threads, 0)); |
134 | 135 | ||
135 | for (i = 0; i < threads->nr; i++) | 136 | for (i = 0; i < threads->nr; i++) |
136 | free(threads->map[i].comm); | 137 | zfree(&threads->map[i].comm); |
137 | 138 | ||
138 | free(threads); | 139 | free(threads); |
139 | return 0; | 140 | return 0; |
diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index f101576d1c72..5e8834fc7dec 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/rbtree.h> | 3 | #include <linux/rbtree.h> |
4 | #include <inttypes.h> | 4 | #include <inttypes.h> |
5 | #include <string.h> | 5 | #include <string.h> |
6 | #include <stdlib.h> | ||
6 | #include "map.h" | 7 | #include "map.h" |
7 | #include "symbol.h" | 8 | #include "symbol.h" |
8 | #include "util.h" | 9 | #include "util.h" |
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 55ff05a46e0b..f80c51d53565 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c | |||
@@ -1,5 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "../util.h" | ||
3 | #include "../string2.h" | 2 | #include "../string2.h" |
4 | #include "../config.h" | 3 | #include "../config.h" |
5 | #include "../../perf.h" | 4 | #include "../../perf.h" |
@@ -17,6 +16,7 @@ | |||
17 | #include "keysyms.h" | 16 | #include "keysyms.h" |
18 | #include "../color.h" | 17 | #include "../color.h" |
19 | #include <linux/ctype.h> | 18 | #include <linux/ctype.h> |
19 | #include <linux/zalloc.h> | ||
20 | 20 | ||
21 | static int ui_browser__percent_color(struct ui_browser *browser, | 21 | static int ui_browser__percent_color(struct ui_browser *browser, |
22 | double percent, bool current) | 22 | double percent, bool current) |
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index aa5932e1d62e..dc1444136658 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <stdarg.h> | 6 | #include <stdarg.h> |
7 | #include <sys/types.h> | ||
7 | 8 | ||
8 | #define HE_COLORSET_TOP 50 | 9 | #define HE_COLORSET_TOP 50 |
9 | #define HE_COLORSET_MEDIUM 51 | 10 | #define HE_COLORSET_MEDIUM 51 |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index b0d089a95dac..e67880bf1efe 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -1,5 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "../../util/util.h" | ||
3 | #include "../browser.h" | 2 | #include "../browser.h" |
4 | #include "../helpline.h" | 3 | #include "../helpline.h" |
5 | #include "../ui.h" | 4 | #include "../ui.h" |
@@ -15,6 +14,7 @@ | |||
15 | #include <pthread.h> | 14 | #include <pthread.h> |
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/zalloc.h> | ||
18 | #include <sys/ttydefaults.h> | 18 | #include <sys/ttydefaults.h> |
19 | #include <asm/bug.h> | 19 | #include <asm/bug.h> |
20 | 20 | ||
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 33e67aa91347..a94eb0755e8b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <sys/ttydefaults.h> | 10 | #include <sys/ttydefaults.h> |
11 | #include <linux/time64.h> | 11 | #include <linux/time64.h> |
12 | #include <linux/zalloc.h> | ||
12 | 13 | ||
13 | #include "../../util/callchain.h" | 14 | #include "../../util/callchain.h" |
14 | #include "../../util/evsel.h" | 15 | #include "../../util/evsel.h" |
@@ -18,7 +19,6 @@ | |||
18 | #include "../../util/symbol.h" | 19 | #include "../../util/symbol.h" |
19 | #include "../../util/pstack.h" | 20 | #include "../../util/pstack.h" |
20 | #include "../../util/sort.h" | 21 | #include "../../util/sort.h" |
21 | #include "../../util/util.h" | ||
22 | #include "../../util/top.h" | 22 | #include "../../util/top.h" |
23 | #include "../../util/thread.h" | 23 | #include "../../util/thread.h" |
24 | #include "../../arch/common.h" | 24 | #include "../../arch/common.h" |
@@ -639,7 +639,11 @@ int hist_browser__run(struct hist_browser *browser, const char *help, | |||
639 | switch (key) { | 639 | switch (key) { |
640 | case K_TIMER: { | 640 | case K_TIMER: { |
641 | u64 nr_entries; | 641 | u64 nr_entries; |
642 | hbt->timer(hbt->arg); | 642 | |
643 | WARN_ON_ONCE(!hbt); | ||
644 | |||
645 | if (hbt) | ||
646 | hbt->timer(hbt->arg); | ||
643 | 647 | ||
644 | if (hist_browser__has_filter(browser) || | 648 | if (hist_browser__has_filter(browser) || |
645 | symbol_conf.report_hierarchy) | 649 | symbol_conf.report_hierarchy) |
@@ -2821,7 +2825,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
2821 | { | 2825 | { |
2822 | struct hists *hists = evsel__hists(evsel); | 2826 | struct hists *hists = evsel__hists(evsel); |
2823 | struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts); | 2827 | struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts); |
2824 | struct branch_info *bi; | 2828 | struct branch_info *bi = NULL; |
2825 | #define MAX_OPTIONS 16 | 2829 | #define MAX_OPTIONS 16 |
2826 | char *options[MAX_OPTIONS]; | 2830 | char *options[MAX_OPTIONS]; |
2827 | struct popup_action actions[MAX_OPTIONS]; | 2831 | struct popup_action actions[MAX_OPTIONS]; |
@@ -3087,7 +3091,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
3087 | goto skip_annotation; | 3091 | goto skip_annotation; |
3088 | 3092 | ||
3089 | if (sort__mode == SORT_MODE__BRANCH) { | 3093 | if (sort__mode == SORT_MODE__BRANCH) { |
3090 | bi = browser->he_selection->branch_info; | 3094 | |
3095 | if (browser->he_selection) | ||
3096 | bi = browser->he_selection->branch_info; | ||
3091 | 3097 | ||
3092 | if (bi == NULL) | 3098 | if (bi == NULL) |
3093 | goto skip_annotation; | 3099 | goto skip_annotation; |
@@ -3271,7 +3277,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, | |||
3271 | 3277 | ||
3272 | switch (key) { | 3278 | switch (key) { |
3273 | case K_TIMER: | 3279 | case K_TIMER: |
3274 | hbt->timer(hbt->arg); | 3280 | if (hbt) |
3281 | hbt->timer(hbt->arg); | ||
3275 | 3282 | ||
3276 | if (!menu->lost_events_warned && | 3283 | if (!menu->lost_events_warned && |
3277 | menu->lost_events && | 3284 | menu->lost_events && |
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 5f6529c9eb8e..4c545b92e20d 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <elf.h> | 2 | #include <elf.h> |
3 | #include <inttypes.h> | 3 | #include <inttypes.h> |
4 | #include <sys/ttydefaults.h> | 4 | #include <sys/ttydefaults.h> |
5 | #include <stdlib.h> | ||
5 | #include <string.h> | 6 | #include <string.h> |
6 | #include <linux/bitops.h> | 7 | #include <linux/bitops.h> |
7 | #include "../../util/util.h" | 8 | #include "../../util/util.h" |
diff --git a/tools/perf/ui/browsers/res_sample.c b/tools/perf/ui/browsers/res_sample.c index c0dd73176d42..8aa3547bb9ff 100644 --- a/tools/perf/ui/browsers/res_sample.c +++ b/tools/perf/ui/browsers/res_sample.c | |||
@@ -1,6 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Display a menu with individual samples to browse with perf script */ | 2 | /* Display a menu with individual samples to browse with perf script */ |
3 | #include "util.h" | ||
4 | #include "hist.h" | 3 | #include "hist.h" |
5 | #include "evsel.h" | 4 | #include "evsel.h" |
6 | #include "hists.h" | 5 | #include "hists.h" |
@@ -8,6 +7,7 @@ | |||
8 | #include "config.h" | 7 | #include "config.h" |
9 | #include "time-utils.h" | 8 | #include "time-utils.h" |
10 | #include <linux/time64.h> | 9 | #include <linux/time64.h> |
10 | #include <linux/zalloc.h> | ||
11 | 11 | ||
12 | static u64 context_len = 10 * NSEC_PER_MSEC; | 12 | static u64 context_len = 10 * NSEC_PER_MSEC; |
13 | 13 | ||
@@ -46,14 +46,14 @@ int res_sample_browse(struct res_sample *res_samples, int num_res, | |||
46 | if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf, | 46 | if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf, |
47 | res_samples[i].cpu, res_samples[i].tid) < 0) { | 47 | res_samples[i].cpu, res_samples[i].tid) < 0) { |
48 | while (--i >= 0) | 48 | while (--i >= 0) |
49 | free(names[i]); | 49 | zfree(&names[i]); |
50 | free(names); | 50 | free(names); |
51 | return -1; | 51 | return -1; |
52 | } | 52 | } |
53 | } | 53 | } |
54 | choice = ui__popup_menu(num_res, names); | 54 | choice = ui__popup_menu(num_res, names); |
55 | for (i = 0; i < num_res; i++) | 55 | for (i = 0; i < num_res; i++) |
56 | free(names[i]); | 56 | zfree(&names[i]); |
57 | free(names); | 57 | free(names); |
58 | 58 | ||
59 | if (choice < 0 || choice >= num_res) | 59 | if (choice < 0 || choice >= num_res) |
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index 27cf3ab88d13..4d565cc14076 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c | |||
@@ -1,12 +1,12 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "../../util/sort.h" | 2 | #include "../../util/sort.h" |
3 | #include "../../util/util.h" | ||
4 | #include "../../util/hist.h" | 3 | #include "../../util/hist.h" |
5 | #include "../../util/debug.h" | 4 | #include "../../util/debug.h" |
6 | #include "../../util/symbol.h" | 5 | #include "../../util/symbol.h" |
7 | #include "../browser.h" | 6 | #include "../browser.h" |
8 | #include "../libslang.h" | 7 | #include "../libslang.h" |
9 | #include "config.h" | 8 | #include "config.h" |
9 | #include <linux/zalloc.h> | ||
10 | 10 | ||
11 | #define SCRIPT_NAMELEN 128 | 11 | #define SCRIPT_NAMELEN 128 |
12 | #define SCRIPT_MAX_NO 64 | 12 | #define SCRIPT_MAX_NO 64 |
@@ -142,7 +142,7 @@ static int list_scripts(char *script_name, bool *custom, | |||
142 | out: | 142 | out: |
143 | free(buf); | 143 | free(buf); |
144 | for (i = 0; i < max_std; i++) | 144 | for (i = 0; i < max_std; i++) |
145 | free(paths[i]); | 145 | zfree(&paths[i]); |
146 | return ret; | 146 | return ret; |
147 | } | 147 | } |
148 | 148 | ||
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index df49c9ba1785..3af87c18a914 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c | |||
@@ -152,7 +152,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym, | |||
152 | gtk_container_add(GTK_CONTAINER(window), view); | 152 | gtk_container_add(GTK_CONTAINER(window), view); |
153 | 153 | ||
154 | list_for_each_entry_safe(pos, n, ¬es->src->source, al.node) { | 154 | list_for_each_entry_safe(pos, n, ¬es->src->source, al.node) { |
155 | list_del(&pos->al.node); | 155 | list_del_init(&pos->al.node); |
156 | disasm_line__free(pos); | 156 | disasm_line__free(pos); |
157 | } | 157 | } |
158 | 158 | ||
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index 7250d8101c8f..c28bdb7517ac 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c | |||
@@ -1,11 +1,10 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "../util.h" | 2 | #include "../util.h" |
3 | #include "../../util/util.h" | ||
4 | #include "../../util/debug.h" | 3 | #include "../../util/debug.h" |
5 | #include "gtk.h" | 4 | #include "gtk.h" |
6 | 5 | ||
7 | #include <string.h> | 6 | #include <string.h> |
8 | 7 | #include <linux/zalloc.h> | |
9 | 8 | ||
10 | struct perf_gtk_context *pgctx; | 9 | struct perf_gtk_context *pgctx; |
11 | 10 | ||
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 89393c79d870..ee7ea6deed21 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <linux/string.h> | 3 | #include <linux/string.h> |
4 | 4 | ||
5 | #include "../../util/callchain.h" | 5 | #include "../../util/callchain.h" |
6 | #include "../../util/util.h" | ||
7 | #include "../../util/hist.h" | 6 | #include "../../util/hist.h" |
8 | #include "../../util/map.h" | 7 | #include "../../util/map.h" |
9 | #include "../../util/map_groups.h" | 8 | #include "../../util/map_groups.h" |
@@ -14,6 +13,7 @@ | |||
14 | #include "../../util/string2.h" | 13 | #include "../../util/string2.h" |
15 | #include "../../util/thread.h" | 14 | #include "../../util/thread.h" |
16 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/zalloc.h> | ||
17 | 17 | ||
18 | static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) | 18 | static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) |
19 | { | 19 | { |
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index d4ac41679721..3ad0d3363ac6 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <errno.h> | 2 | #include <errno.h> |
3 | #include <signal.h> | 3 | #include <signal.h> |
4 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | #include <stdlib.h> | ||
5 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
6 | #ifdef HAVE_BACKTRACE_SUPPORT | 7 | #ifdef HAVE_BACKTRACE_SUPPORT |
7 | #include <execinfo.h> | 8 | #include <execinfo.h> |
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index b9794d6185af..fe5e571816fc 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c | |||
@@ -1,8 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "../../util/util.h" | ||
3 | #include <signal.h> | 2 | #include <signal.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
5 | #include <string.h> | 4 | #include <string.h> |
5 | #include <stdlib.h> | ||
6 | #include <sys/ttydefaults.h> | 6 | #include <sys/ttydefaults.h> |
7 | 7 | ||
8 | #include "../../util/cache.h" | 8 | #include "../../util/cache.h" |
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index d3408a463060..14f812bb07a7 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build | |||
@@ -20,11 +20,13 @@ perf-y += parse-events.o | |||
20 | perf-y += perf_regs.o | 20 | perf-y += perf_regs.o |
21 | perf-y += path.o | 21 | perf-y += path.o |
22 | perf-y += print_binary.o | 22 | perf-y += print_binary.o |
23 | perf-y += rlimit.o | ||
23 | perf-y += argv_split.o | 24 | perf-y += argv_split.o |
24 | perf-y += rbtree.o | 25 | perf-y += rbtree.o |
25 | perf-y += libstring.o | 26 | perf-y += libstring.o |
26 | perf-y += bitmap.o | 27 | perf-y += bitmap.o |
27 | perf-y += hweight.o | 28 | perf-y += hweight.o |
29 | perf-y += zalloc.o | ||
28 | perf-y += smt.o | 30 | perf-y += smt.o |
29 | perf-y += strbuf.o | 31 | perf-y += strbuf.o |
30 | perf-y += string.o | 32 | perf-y += string.o |
@@ -241,3 +243,7 @@ $(OUTPUT)util/hweight.o: ../lib/hweight.c FORCE | |||
241 | $(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE | 243 | $(OUTPUT)util/vsprintf.o: ../lib/vsprintf.c FORCE |
242 | $(call rule_mkdir) | 244 | $(call rule_mkdir) |
243 | $(call if_changed_dep,cc_o_c) | 245 | $(call if_changed_dep,cc_o_c) |
246 | |||
247 | $(OUTPUT)util/zalloc.o: ../lib/zalloc.c FORCE | ||
248 | $(call rule_mkdir) | ||
249 | $(call if_changed_dep,cc_o_c) | ||
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index ec7aaf31c2b2..ac9ad2330f93 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -1119,16 +1119,14 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) | |||
1119 | *namep = strdup(name); | 1119 | *namep = strdup(name); |
1120 | 1120 | ||
1121 | if (*namep == NULL) | 1121 | if (*namep == NULL) |
1122 | goto out_free_name; | 1122 | goto out; |
1123 | 1123 | ||
1124 | (*rawp)[0] = tmp; | 1124 | (*rawp)[0] = tmp; |
1125 | *rawp = skip_spaces(*rawp); | 1125 | *rawp = skip_spaces(*rawp); |
1126 | 1126 | ||
1127 | return 0; | 1127 | return 0; |
1128 | 1128 | ||
1129 | out_free_name: | 1129 | out: |
1130 | free((void *)namep); | ||
1131 | *namep = NULL; | ||
1132 | return -1; | 1130 | return -1; |
1133 | } | 1131 | } |
1134 | 1132 | ||
@@ -1237,8 +1235,7 @@ void disasm_line__free(struct disasm_line *dl) | |||
1237 | dl->ins.ops->free(&dl->ops); | 1235 | dl->ins.ops->free(&dl->ops); |
1238 | else | 1236 | else |
1239 | ins__delete(&dl->ops); | 1237 | ins__delete(&dl->ops); |
1240 | free((void *)dl->ins.name); | 1238 | zfree(&dl->ins.name); |
1241 | dl->ins.name = NULL; | ||
1242 | annotation_line__delete(&dl->al); | 1239 | annotation_line__delete(&dl->al); |
1243 | } | 1240 | } |
1244 | 1241 | ||
@@ -1589,7 +1586,7 @@ static void delete_last_nop(struct symbol *sym) | |||
1589 | return; | 1586 | return; |
1590 | } | 1587 | } |
1591 | 1588 | ||
1592 | list_del(&dl->al.node); | 1589 | list_del_init(&dl->al.node); |
1593 | disasm_line__free(dl); | 1590 | disasm_line__free(dl); |
1594 | } | 1591 | } |
1595 | } | 1592 | } |
@@ -2466,7 +2463,7 @@ void annotated_source__purge(struct annotated_source *as) | |||
2466 | struct annotation_line *al, *n; | 2463 | struct annotation_line *al, *n; |
2467 | 2464 | ||
2468 | list_for_each_entry_safe(al, n, &as->source, node) { | 2465 | list_for_each_entry_safe(al, n, &as->source, node) { |
2469 | list_del(&al->node); | 2466 | list_del_init(&al->node); |
2470 | disasm_line__free(disasm_line(al)); | 2467 | disasm_line__free(disasm_line(al)); |
2471 | } | 2468 | } |
2472 | } | 2469 | } |
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c index 6067267cc76c..a314e5b26e9d 100644 --- a/tools/perf/util/arm-spe.c +++ b/tools/perf/util/arm-spe.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include <linux/log2.h> | 14 | #include <linux/log2.h> |
15 | #include <linux/zalloc.h> | ||
15 | 16 | ||
16 | #include "cpumap.h" | 17 | #include "cpumap.h" |
17 | #include "color.h" | 18 | #include "color.h" |
@@ -19,7 +20,6 @@ | |||
19 | #include "evlist.h" | 20 | #include "evlist.h" |
20 | #include "machine.h" | 21 | #include "machine.h" |
21 | #include "session.h" | 22 | #include "session.h" |
22 | #include "util.h" | ||
23 | #include "thread.h" | 23 | #include "thread.h" |
24 | #include "debug.h" | 24 | #include "debug.h" |
25 | #include "auxtrace.h" | 25 | #include "auxtrace.h" |
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index bc215fe0b4b4..ec0af36697c4 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c | |||
@@ -24,9 +24,9 @@ | |||
24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
25 | #include <stdio.h> | 25 | #include <stdio.h> |
26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
27 | #include <linux/zalloc.h> | ||
27 | 28 | ||
28 | #include "../perf.h" | 29 | #include "../perf.h" |
29 | #include "util.h" | ||
30 | #include "evlist.h" | 30 | #include "evlist.h" |
31 | #include "dso.h" | 31 | #include "dso.h" |
32 | #include "map.h" | 32 | #include "map.h" |
@@ -408,7 +408,7 @@ void auxtrace_queues__free(struct auxtrace_queues *queues) | |||
408 | 408 | ||
409 | buffer = list_entry(queues->queue_array[i].head.next, | 409 | buffer = list_entry(queues->queue_array[i].head.next, |
410 | struct auxtrace_buffer, list); | 410 | struct auxtrace_buffer, list); |
411 | list_del(&buffer->list); | 411 | list_del_init(&buffer->list); |
412 | auxtrace_buffer__free(buffer); | 412 | auxtrace_buffer__free(buffer); |
413 | } | 413 | } |
414 | } | 414 | } |
@@ -612,7 +612,7 @@ void auxtrace_index__free(struct list_head *head) | |||
612 | struct auxtrace_index *auxtrace_index, *n; | 612 | struct auxtrace_index *auxtrace_index, *n; |
613 | 613 | ||
614 | list_for_each_entry_safe(auxtrace_index, n, head, list) { | 614 | list_for_each_entry_safe(auxtrace_index, n, head, list) { |
615 | list_del(&auxtrace_index->list); | 615 | list_del_init(&auxtrace_index->list); |
616 | free(auxtrace_index); | 616 | free(auxtrace_index); |
617 | } | 617 | } |
618 | } | 618 | } |
@@ -1413,7 +1413,7 @@ void auxtrace_cache__free(struct auxtrace_cache *c) | |||
1413 | return; | 1413 | return; |
1414 | 1414 | ||
1415 | auxtrace_cache__drop(c); | 1415 | auxtrace_cache__drop(c); |
1416 | free(c->hashtable); | 1416 | zfree(&c->hashtable); |
1417 | free(c); | 1417 | free(c); |
1418 | } | 1418 | } |
1419 | 1419 | ||
@@ -1459,12 +1459,11 @@ void *auxtrace_cache__lookup(struct auxtrace_cache *c, u32 key) | |||
1459 | 1459 | ||
1460 | static void addr_filter__free_str(struct addr_filter *filt) | 1460 | static void addr_filter__free_str(struct addr_filter *filt) |
1461 | { | 1461 | { |
1462 | free(filt->str); | 1462 | zfree(&filt->str); |
1463 | filt->action = NULL; | 1463 | filt->action = NULL; |
1464 | filt->sym_from = NULL; | 1464 | filt->sym_from = NULL; |
1465 | filt->sym_to = NULL; | 1465 | filt->sym_to = NULL; |
1466 | filt->filename = NULL; | 1466 | filt->filename = NULL; |
1467 | filt->str = NULL; | ||
1468 | } | 1467 | } |
1469 | 1468 | ||
1470 | static struct addr_filter *addr_filter__new(void) | 1469 | static struct addr_filter *addr_filter__new(void) |
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 251d9ea6252f..c61974a50aa5 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/zalloc.h> | ||
15 | #include <errno.h> | 16 | #include <errno.h> |
16 | #include "perf.h" | 17 | #include "perf.h" |
17 | #include "debug.h" | 18 | #include "debug.h" |
@@ -828,7 +829,7 @@ static void | |||
828 | bpf_map_op__delete(struct bpf_map_op *op) | 829 | bpf_map_op__delete(struct bpf_map_op *op) |
829 | { | 830 | { |
830 | if (!list_empty(&op->list)) | 831 | if (!list_empty(&op->list)) |
831 | list_del(&op->list); | 832 | list_del_init(&op->list); |
832 | if (op->key_type == BPF_MAP_KEY_RANGES) | 833 | if (op->key_type == BPF_MAP_KEY_RANGES) |
833 | parse_events__clear_array(&op->k.array); | 834 | parse_events__clear_array(&op->k.array); |
834 | free(op); | 835 | free(op); |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 89c6913dfc25..f1abfab7aa8c 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "strlist.h" | 30 | #include "strlist.h" |
31 | 31 | ||
32 | #include <linux/ctype.h> | 32 | #include <linux/ctype.h> |
33 | #include <linux/zalloc.h> | ||
33 | 34 | ||
34 | static bool no_buildid_cache; | 35 | static bool no_buildid_cache; |
35 | 36 | ||
diff --git a/tools/perf/util/call-path.c b/tools/perf/util/call-path.c index c5b90300304d..5c60b8be1cf6 100644 --- a/tools/perf/util/call-path.c +++ b/tools/perf/util/call-path.c | |||
@@ -6,8 +6,9 @@ | |||
6 | 6 | ||
7 | #include <linux/rbtree.h> | 7 | #include <linux/rbtree.h> |
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/zalloc.h> | ||
10 | #include <stdlib.h> | ||
9 | 11 | ||
10 | #include "util.h" | ||
11 | #include "call-path.h" | 12 | #include "call-path.h" |
12 | 13 | ||
13 | static void call_path__init(struct call_path *cp, struct call_path *parent, | 14 | static void call_path__init(struct call_path *cp, struct call_path *parent, |
@@ -39,7 +40,7 @@ void call_path_root__free(struct call_path_root *cpr) | |||
39 | struct call_path_block *pos, *n; | 40 | struct call_path_block *pos, *n; |
40 | 41 | ||
41 | list_for_each_entry_safe(pos, n, &cpr->blocks, node) { | 42 | list_for_each_entry_safe(pos, n, &cpr->blocks, node) { |
42 | list_del(&pos->node); | 43 | list_del_init(&pos->node); |
43 | free(pos); | 44 | free(pos); |
44 | } | 45 | } |
45 | free(cpr); | 46 | free(cpr); |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index abb608b09269..8d7d8f62fcca 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -16,11 +16,11 @@ | |||
16 | #include <stdbool.h> | 16 | #include <stdbool.h> |
17 | #include <errno.h> | 17 | #include <errno.h> |
18 | #include <math.h> | 18 | #include <math.h> |
19 | #include <linux/zalloc.h> | ||
19 | 20 | ||
20 | #include "asm/bug.h" | 21 | #include "asm/bug.h" |
21 | 22 | ||
22 | #include "hist.h" | 23 | #include "hist.h" |
23 | #include "util.h" | ||
24 | #include "sort.h" | 24 | #include "sort.h" |
25 | #include "machine.h" | 25 | #include "machine.h" |
26 | #include "map.h" | 26 | #include "map.h" |
@@ -636,7 +636,7 @@ add_child(struct callchain_node *parent, | |||
636 | struct callchain_list *call, *tmp; | 636 | struct callchain_list *call, *tmp; |
637 | 637 | ||
638 | list_for_each_entry_safe(call, tmp, &new->val, list) { | 638 | list_for_each_entry_safe(call, tmp, &new->val, list) { |
639 | list_del(&call->list); | 639 | list_del_init(&call->list); |
640 | map__zput(call->ms.map); | 640 | map__zput(call->ms.map); |
641 | free(call); | 641 | free(call); |
642 | } | 642 | } |
@@ -1002,7 +1002,7 @@ merge_chain_branch(struct callchain_cursor *cursor, | |||
1002 | callchain_cursor_append(cursor, list->ip, | 1002 | callchain_cursor_append(cursor, list->ip, |
1003 | list->ms.map, list->ms.sym, | 1003 | list->ms.map, list->ms.sym, |
1004 | false, NULL, 0, 0, 0, list->srcline); | 1004 | false, NULL, 0, 0, 0, list->srcline); |
1005 | list_del(&list->list); | 1005 | list_del_init(&list->list); |
1006 | map__zput(list->ms.map); | 1006 | map__zput(list->ms.map); |
1007 | free(list); | 1007 | free(list); |
1008 | } | 1008 | } |
@@ -1453,13 +1453,13 @@ static void free_callchain_node(struct callchain_node *node) | |||
1453 | struct rb_node *n; | 1453 | struct rb_node *n; |
1454 | 1454 | ||
1455 | list_for_each_entry_safe(list, tmp, &node->parent_val, list) { | 1455 | list_for_each_entry_safe(list, tmp, &node->parent_val, list) { |
1456 | list_del(&list->list); | 1456 | list_del_init(&list->list); |
1457 | map__zput(list->ms.map); | 1457 | map__zput(list->ms.map); |
1458 | free(list); | 1458 | free(list); |
1459 | } | 1459 | } |
1460 | 1460 | ||
1461 | list_for_each_entry_safe(list, tmp, &node->val, list) { | 1461 | list_for_each_entry_safe(list, tmp, &node->val, list) { |
1462 | list_del(&list->list); | 1462 | list_del_init(&list->list); |
1463 | map__zput(list->ms.map); | 1463 | map__zput(list->ms.map); |
1464 | free(list); | 1464 | free(list); |
1465 | } | 1465 | } |
@@ -1544,7 +1544,7 @@ int callchain_node__make_parent_list(struct callchain_node *node) | |||
1544 | 1544 | ||
1545 | out: | 1545 | out: |
1546 | list_for_each_entry_safe(chain, new, &head, list) { | 1546 | list_for_each_entry_safe(chain, new, &head, list) { |
1547 | list_del(&chain->list); | 1547 | list_del_init(&chain->list); |
1548 | map__zput(chain->ms.map); | 1548 | map__zput(chain->ms.map); |
1549 | free(chain); | 1549 | free(chain); |
1550 | } | 1550 | } |
diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index ccd02634a616..484c29830a81 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c | |||
@@ -1,11 +1,11 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "util.h" | ||
3 | #include "../perf.h" | 2 | #include "../perf.h" |
4 | #include <subcmd/parse-options.h> | 3 | #include <subcmd/parse-options.h> |
5 | #include "evsel.h" | 4 | #include "evsel.h" |
6 | #include "cgroup.h" | 5 | #include "cgroup.h" |
7 | #include "evlist.h" | 6 | #include "evlist.h" |
8 | #include <linux/stringify.h> | 7 | #include <linux/stringify.h> |
8 | #include <linux/zalloc.h> | ||
9 | #include <sys/types.h> | 9 | #include <sys/types.h> |
10 | #include <sys/stat.h> | 10 | #include <sys/stat.h> |
11 | #include <fcntl.h> | 11 | #include <fcntl.h> |
@@ -124,7 +124,7 @@ static struct cgroup *cgroup__new(const char *name) | |||
124 | return cgroup; | 124 | return cgroup; |
125 | 125 | ||
126 | out_free_name: | 126 | out_free_name: |
127 | free(cgroup->name); | 127 | zfree(&cgroup->name); |
128 | out_err: | 128 | out_err: |
129 | free(cgroup); | 129 | free(cgroup); |
130 | return NULL; | 130 | return NULL; |
diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index 1066de92af12..afb8d4fd2644 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c | |||
@@ -1,12 +1,12 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "comm.h" | 2 | #include "comm.h" |
3 | #include "util.h" | ||
4 | #include <errno.h> | 3 | #include <errno.h> |
5 | #include <stdlib.h> | 4 | #include <stdlib.h> |
6 | #include <stdio.h> | 5 | #include <stdio.h> |
7 | #include <string.h> | 6 | #include <string.h> |
8 | #include <linux/refcount.h> | 7 | #include <linux/refcount.h> |
9 | #include <linux/rbtree.h> | 8 | #include <linux/rbtree.h> |
9 | #include <linux/zalloc.h> | ||
10 | #include "rwsem.h" | 10 | #include "rwsem.h" |
11 | 11 | ||
12 | struct comm_str { | 12 | struct comm_str { |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 752cce853e51..042ffbc8c53f 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -11,7 +11,6 @@ | |||
11 | */ | 11 | */ |
12 | #include <errno.h> | 12 | #include <errno.h> |
13 | #include <sys/param.h> | 13 | #include <sys/param.h> |
14 | #include "util.h" | ||
15 | #include "cache.h" | 14 | #include "cache.h" |
16 | #include "callchain.h" | 15 | #include "callchain.h" |
17 | #include <subcmd/exec-cmd.h> | 16 | #include <subcmd/exec-cmd.h> |
@@ -23,7 +22,7 @@ | |||
23 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
24 | #include <unistd.h> | 23 | #include <unistd.h> |
25 | #include <linux/string.h> | 24 | #include <linux/string.h> |
26 | 25 | #include <linux/zalloc.h> | |
27 | #include <linux/ctype.h> | 26 | #include <linux/ctype.h> |
28 | 27 | ||
29 | #define MAXNAME (256) | 28 | #define MAXNAME (256) |
diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c index 03032b410c29..88be9c4365e0 100644 --- a/tools/perf/util/counts.c +++ b/tools/perf/util/counts.c | |||
@@ -3,7 +3,7 @@ | |||
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include "evsel.h" | 4 | #include "evsel.h" |
5 | #include "counts.h" | 5 | #include "counts.h" |
6 | #include "util.h" | 6 | #include <linux/zalloc.h> |
7 | 7 | ||
8 | struct perf_counts *perf_counts__new(int ncpus, int nthreads) | 8 | struct perf_counts *perf_counts__new(int ncpus, int nthreads) |
9 | { | 9 | { |
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 0d8fbedf7bd5..3acfbe34ebaf 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c | |||
@@ -1,5 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "util.h" | ||
3 | #include <api/fs/fs.h> | 2 | #include <api/fs/fs.h> |
4 | #include "../perf.h" | 3 | #include "../perf.h" |
5 | #include "cpumap.h" | 4 | #include "cpumap.h" |
@@ -11,6 +10,7 @@ | |||
11 | #include "asm/bug.h" | 10 | #include "asm/bug.h" |
12 | 11 | ||
13 | #include <linux/ctype.h> | 12 | #include <linux/ctype.h> |
13 | #include <linux/zalloc.h> | ||
14 | 14 | ||
15 | static int max_cpu_num; | 15 | static int max_cpu_num; |
16 | static int max_present_cpu_num; | 16 | static int max_present_cpu_num; |
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c index 26e73a4bd4fe..64336a280967 100644 --- a/tools/perf/util/cputopo.c +++ b/tools/perf/util/cputopo.c | |||
@@ -2,11 +2,12 @@ | |||
2 | #include <sys/param.h> | 2 | #include <sys/param.h> |
3 | #include <sys/utsname.h> | 3 | #include <sys/utsname.h> |
4 | #include <inttypes.h> | 4 | #include <inttypes.h> |
5 | #include <stdlib.h> | ||
5 | #include <api/fs/fs.h> | 6 | #include <api/fs/fs.h> |
7 | #include <linux/zalloc.h> | ||
6 | 8 | ||
7 | #include "cputopo.h" | 9 | #include "cputopo.h" |
8 | #include "cpumap.h" | 10 | #include "cpumap.h" |
9 | #include "util.h" | ||
10 | #include "env.h" | 11 | #include "env.h" |
11 | 12 | ||
12 | #define CORE_SIB_FMT \ | 13 | #define CORE_SIB_FMT \ |
@@ -343,7 +344,7 @@ void numa_topology__delete(struct numa_topology *tp) | |||
343 | u32 i; | 344 | u32 i; |
344 | 345 | ||
345 | for (i = 0; i < tp->nr; i++) | 346 | for (i = 0; i < tp->nr; i++) |
346 | free(tp->nodes[i].cpus); | 347 | zfree(&tp->nodes[i].cpus); |
347 | 348 | ||
348 | free(tp); | 349 | free(tp); |
349 | } | 350 | } |
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 bb45e23018ee..37d7c492b155 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/err.h> | 9 | #include <linux/err.h> |
10 | #include <linux/list.h> | 10 | #include <linux/list.h> |
11 | #include <linux/zalloc.h> | ||
11 | #include <stdlib.h> | 12 | #include <stdlib.h> |
12 | #include <opencsd/c_api/opencsd_c_api.h> | 13 | #include <opencsd/c_api/opencsd_c_api.h> |
13 | #include <opencsd/etmv4/trc_pkt_types_etmv4.h> | 14 | #include <opencsd/etmv4/trc_pkt_types_etmv4.h> |
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 0c7776b51045..3d1c34fc4d68 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/log2.h> | 12 | #include <linux/log2.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/zalloc.h> | ||
14 | 15 | ||
15 | #include <opencsd/ocsd_if_types.h> | 16 | #include <opencsd/ocsd_if_types.h> |
16 | #include <stdlib.h> | 17 | #include <stdlib.h> |
@@ -554,8 +555,7 @@ static void cs_etm__free_traceid_queues(struct cs_etm_queue *etmq) | |||
554 | etmq->traceid_queues_list = NULL; | 555 | etmq->traceid_queues_list = NULL; |
555 | 556 | ||
556 | /* finally free the traceid_queues array */ | 557 | /* finally free the traceid_queues array */ |
557 | free(etmq->traceid_queues); | 558 | zfree(&etmq->traceid_queues); |
558 | etmq->traceid_queues = NULL; | ||
559 | } | 559 | } |
560 | 560 | ||
561 | static void cs_etm__free_queue(void *priv) | 561 | static void cs_etm__free_queue(void *priv) |
@@ -2460,7 +2460,7 @@ int cs_etm__process_auxtrace_info(union perf_event *event, | |||
2460 | 2460 | ||
2461 | /* Something went wrong, no need to continue */ | 2461 | /* Something went wrong, no need to continue */ |
2462 | if (!inode) { | 2462 | if (!inode) { |
2463 | err = PTR_ERR(inode); | 2463 | err = -ENOMEM; |
2464 | goto err_free_metadata; | 2464 | goto err_free_metadata; |
2465 | } | 2465 | } |
2466 | 2466 | ||
@@ -2517,8 +2517,10 @@ int cs_etm__process_auxtrace_info(union perf_event *event, | |||
2517 | session->auxtrace = &etm->auxtrace; | 2517 | session->auxtrace = &etm->auxtrace; |
2518 | 2518 | ||
2519 | etm->unknown_thread = thread__new(999999999, 999999999); | 2519 | etm->unknown_thread = thread__new(999999999, 999999999); |
2520 | if (!etm->unknown_thread) | 2520 | if (!etm->unknown_thread) { |
2521 | err = -ENOMEM; | ||
2521 | goto err_free_queues; | 2522 | goto err_free_queues; |
2523 | } | ||
2522 | 2524 | ||
2523 | /* | 2525 | /* |
2524 | * Initialize list node so that at thread__zput() we can avoid | 2526 | * Initialize list node so that at thread__zput() we can avoid |
@@ -2530,15 +2532,17 @@ int cs_etm__process_auxtrace_info(union perf_event *event, | |||
2530 | if (err) | 2532 | if (err) |
2531 | goto err_delete_thread; | 2533 | goto err_delete_thread; |
2532 | 2534 | ||
2533 | if (thread__init_map_groups(etm->unknown_thread, etm->machine)) | 2535 | if (thread__init_map_groups(etm->unknown_thread, etm->machine)) { |
2536 | err = -ENOMEM; | ||
2534 | goto err_delete_thread; | 2537 | goto err_delete_thread; |
2538 | } | ||
2535 | 2539 | ||
2536 | if (dump_trace) { | 2540 | if (dump_trace) { |
2537 | cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); | 2541 | cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu); |
2538 | return 0; | 2542 | return 0; |
2539 | } | 2543 | } |
2540 | 2544 | ||
2541 | if (session->itrace_synth_opts && session->itrace_synth_opts->set) { | 2545 | if (session->itrace_synth_opts->set) { |
2542 | etm->synth_opts = *session->itrace_synth_opts; | 2546 | etm->synth_opts = *session->itrace_synth_opts; |
2543 | } else { | 2547 | } else { |
2544 | itrace_synth_opts__set_default(&etm->synth_opts, | 2548 | itrace_synth_opts__set_default(&etm->synth_opts, |
@@ -2568,12 +2572,12 @@ err_free_etm: | |||
2568 | err_free_metadata: | 2572 | err_free_metadata: |
2569 | /* No need to check @metadata[j], free(NULL) is supported */ | 2573 | /* No need to check @metadata[j], free(NULL) is supported */ |
2570 | for (j = 0; j < num_cpu; j++) | 2574 | for (j = 0; j < num_cpu; j++) |
2571 | free(metadata[j]); | 2575 | zfree(&metadata[j]); |
2572 | zfree(&metadata); | 2576 | zfree(&metadata); |
2573 | err_free_traceid_list: | 2577 | err_free_traceid_list: |
2574 | intlist__delete(traceid_list); | 2578 | intlist__delete(traceid_list); |
2575 | err_free_hdr: | 2579 | err_free_hdr: |
2576 | zfree(&hdr); | 2580 | zfree(&hdr); |
2577 | 2581 | ||
2578 | return -EINVAL; | 2582 | return err; |
2579 | } | 2583 | } |
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 7b06e7373b9e..ddbcd59f2d9b 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <inttypes.h> | 10 | #include <inttypes.h> |
11 | #include <linux/compiler.h> | 11 | #include <linux/compiler.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/zalloc.h> | ||
13 | #include <babeltrace/ctf-writer/writer.h> | 14 | #include <babeltrace/ctf-writer/writer.h> |
14 | #include <babeltrace/ctf-writer/clock.h> | 15 | #include <babeltrace/ctf-writer/clock.h> |
15 | #include <babeltrace/ctf-writer/stream.h> | 16 | #include <babeltrace/ctf-writer/stream.h> |
@@ -22,7 +23,6 @@ | |||
22 | #include "asm/bug.h" | 23 | #include "asm/bug.h" |
23 | #include "data-convert-bt.h" | 24 | #include "data-convert-bt.h" |
24 | #include "session.h" | 25 | #include "session.h" |
25 | #include "util.h" | ||
26 | #include "debug.h" | 26 | #include "debug.h" |
27 | #include "tool.h" | 27 | #include "tool.h" |
28 | #include "evlist.h" | 28 | #include "evlist.h" |
@@ -1353,7 +1353,7 @@ static void free_streams(struct ctf_writer *cw) | |||
1353 | for (cpu = 0; cpu < cw->stream_cnt; cpu++) | 1353 | for (cpu = 0; cpu < cw->stream_cnt; cpu++) |
1354 | ctf_stream__delete(cw->stream[cpu]); | 1354 | ctf_stream__delete(cw->stream[cpu]); |
1355 | 1355 | ||
1356 | free(cw->stream); | 1356 | zfree(&cw->stream); |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | static int ctf_writer__setup_env(struct ctf_writer *cw, | 1359 | static int ctf_writer__setup_env(struct ctf_writer *cw, |
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 6a64f713710d..1d1b97a92c3f 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/compiler.h> | 2 | #include <linux/compiler.h> |
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/zalloc.h> | ||
4 | #include <sys/types.h> | 5 | #include <sys/types.h> |
5 | #include <sys/stat.h> | 6 | #include <sys/stat.h> |
6 | #include <errno.h> | 7 | #include <errno.h> |
@@ -20,7 +21,7 @@ static void close_dir(struct perf_data_file *files, int nr) | |||
20 | { | 21 | { |
21 | while (--nr >= 1) { | 22 | while (--nr >= 1) { |
22 | close(files[nr].fd); | 23 | close(files[nr].fd); |
23 | free(files[nr].path); | 24 | zfree(&files[nr].path); |
24 | } | 25 | } |
25 | free(files); | 26 | free(files); |
26 | } | 27 | } |
diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 2182f552aac6..ffbb3e7d3288 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <stdlib.h> | ||
8 | 9 | ||
9 | #include "evsel.h" | 10 | #include "evsel.h" |
10 | #include "machine.h" | 11 | #include "machine.h" |
@@ -13,76 +14,20 @@ | |||
13 | #include "symbol.h" | 14 | #include "symbol.h" |
14 | #include "map.h" | 15 | #include "map.h" |
15 | #include "event.h" | 16 | #include "event.h" |
16 | #include "util.h" | ||
17 | #include "thread-stack.h" | 17 | #include "thread-stack.h" |
18 | #include "callchain.h" | 18 | #include "callchain.h" |
19 | #include "call-path.h" | 19 | #include "call-path.h" |
20 | #include "db-export.h" | 20 | #include "db-export.h" |
21 | 21 | #include <linux/zalloc.h> | |
22 | struct deferred_export { | ||
23 | struct list_head node; | ||
24 | struct comm *comm; | ||
25 | }; | ||
26 | |||
27 | static int db_export__deferred(struct db_export *dbe) | ||
28 | { | ||
29 | struct deferred_export *de; | ||
30 | int err; | ||
31 | |||
32 | while (!list_empty(&dbe->deferred)) { | ||
33 | de = list_entry(dbe->deferred.next, struct deferred_export, | ||
34 | node); | ||
35 | err = dbe->export_comm(dbe, de->comm); | ||
36 | list_del(&de->node); | ||
37 | free(de); | ||
38 | if (err) | ||
39 | return err; | ||
40 | } | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static void db_export__free_deferred(struct db_export *dbe) | ||
46 | { | ||
47 | struct deferred_export *de; | ||
48 | |||
49 | while (!list_empty(&dbe->deferred)) { | ||
50 | de = list_entry(dbe->deferred.next, struct deferred_export, | ||
51 | node); | ||
52 | list_del(&de->node); | ||
53 | free(de); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | static int db_export__defer_comm(struct db_export *dbe, struct comm *comm) | ||
58 | { | ||
59 | struct deferred_export *de; | ||
60 | |||
61 | de = zalloc(sizeof(struct deferred_export)); | ||
62 | if (!de) | ||
63 | return -ENOMEM; | ||
64 | |||
65 | de->comm = comm; | ||
66 | list_add_tail(&de->node, &dbe->deferred); | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | 22 | ||
71 | int db_export__init(struct db_export *dbe) | 23 | int db_export__init(struct db_export *dbe) |
72 | { | 24 | { |
73 | memset(dbe, 0, sizeof(struct db_export)); | 25 | memset(dbe, 0, sizeof(struct db_export)); |
74 | INIT_LIST_HEAD(&dbe->deferred); | ||
75 | return 0; | 26 | return 0; |
76 | } | 27 | } |
77 | 28 | ||
78 | int db_export__flush(struct db_export *dbe) | ||
79 | { | ||
80 | return db_export__deferred(dbe); | ||
81 | } | ||
82 | |||
83 | void db_export__exit(struct db_export *dbe) | 29 | void db_export__exit(struct db_export *dbe) |
84 | { | 30 | { |
85 | db_export__free_deferred(dbe); | ||
86 | call_return_processor__free(dbe->crp); | 31 | call_return_processor__free(dbe->crp); |
87 | dbe->crp = NULL; | 32 | dbe->crp = NULL; |
88 | } | 33 | } |
@@ -114,71 +59,73 @@ int db_export__machine(struct db_export *dbe, struct machine *machine) | |||
114 | } | 59 | } |
115 | 60 | ||
116 | int db_export__thread(struct db_export *dbe, struct thread *thread, | 61 | int db_export__thread(struct db_export *dbe, struct thread *thread, |
117 | struct machine *machine, struct comm *comm) | 62 | struct machine *machine, struct thread *main_thread) |
118 | { | 63 | { |
119 | struct thread *main_thread; | ||
120 | u64 main_thread_db_id = 0; | 64 | u64 main_thread_db_id = 0; |
121 | int err; | ||
122 | 65 | ||
123 | if (thread->db_id) | 66 | if (thread->db_id) |
124 | return 0; | 67 | return 0; |
125 | 68 | ||
126 | thread->db_id = ++dbe->thread_last_db_id; | 69 | thread->db_id = ++dbe->thread_last_db_id; |
127 | 70 | ||
128 | if (thread->pid_ != -1) { | 71 | if (main_thread) |
129 | if (thread->pid_ == thread->tid) { | ||
130 | main_thread = thread; | ||
131 | } else { | ||
132 | main_thread = machine__findnew_thread(machine, | ||
133 | thread->pid_, | ||
134 | thread->pid_); | ||
135 | if (!main_thread) | ||
136 | return -ENOMEM; | ||
137 | err = db_export__thread(dbe, main_thread, machine, | ||
138 | comm); | ||
139 | if (err) | ||
140 | goto out_put; | ||
141 | if (comm) { | ||
142 | err = db_export__comm_thread(dbe, comm, thread); | ||
143 | if (err) | ||
144 | goto out_put; | ||
145 | } | ||
146 | } | ||
147 | main_thread_db_id = main_thread->db_id; | 72 | main_thread_db_id = main_thread->db_id; |
148 | if (main_thread != thread) | ||
149 | thread__put(main_thread); | ||
150 | } | ||
151 | 73 | ||
152 | if (dbe->export_thread) | 74 | if (dbe->export_thread) |
153 | return dbe->export_thread(dbe, thread, main_thread_db_id, | 75 | return dbe->export_thread(dbe, thread, main_thread_db_id, |
154 | machine); | 76 | machine); |
155 | 77 | ||
156 | return 0; | 78 | return 0; |
79 | } | ||
157 | 80 | ||
158 | out_put: | 81 | static int __db_export__comm(struct db_export *dbe, struct comm *comm, |
159 | thread__put(main_thread); | 82 | struct thread *thread) |
160 | return err; | 83 | { |
84 | comm->db_id = ++dbe->comm_last_db_id; | ||
85 | |||
86 | if (dbe->export_comm) | ||
87 | return dbe->export_comm(dbe, comm, thread); | ||
88 | |||
89 | return 0; | ||
161 | } | 90 | } |
162 | 91 | ||
163 | int db_export__comm(struct db_export *dbe, struct comm *comm, | 92 | int db_export__comm(struct db_export *dbe, struct comm *comm, |
164 | struct thread *main_thread) | 93 | struct thread *thread) |
94 | { | ||
95 | if (comm->db_id) | ||
96 | return 0; | ||
97 | |||
98 | return __db_export__comm(dbe, comm, thread); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Export the "exec" comm. The "exec" comm is the program / application command | ||
103 | * name at the time it first executes. It is used to group threads for the same | ||
104 | * program. Note that the main thread pid (or thread group id tgid) cannot be | ||
105 | * used because it does not change when a new program is exec'ed. | ||
106 | */ | ||
107 | int db_export__exec_comm(struct db_export *dbe, struct comm *comm, | ||
108 | struct thread *main_thread) | ||
165 | { | 109 | { |
166 | int err; | 110 | int err; |
167 | 111 | ||
168 | if (comm->db_id) | 112 | if (comm->db_id) |
169 | return 0; | 113 | return 0; |
170 | 114 | ||
171 | comm->db_id = ++dbe->comm_last_db_id; | 115 | err = __db_export__comm(dbe, comm, main_thread); |
172 | 116 | if (err) | |
173 | if (dbe->export_comm) { | 117 | return err; |
174 | if (main_thread->comm_set) | ||
175 | err = dbe->export_comm(dbe, comm); | ||
176 | else | ||
177 | err = db_export__defer_comm(dbe, comm); | ||
178 | if (err) | ||
179 | return err; | ||
180 | } | ||
181 | 118 | ||
119 | /* | ||
120 | * Record the main thread for this comm. Note that the main thread can | ||
121 | * have many "exec" comms because there will be a new one every time it | ||
122 | * exec's. An "exec" comm however will only ever have 1 main thread. | ||
123 | * That is different to any other threads for that same program because | ||
124 | * exec() will effectively kill them, so the relationship between the | ||
125 | * "exec" comm and non-main threads is 1-to-1. That is why | ||
126 | * db_export__comm_thread() is called here for the main thread, but it | ||
127 | * is called for non-main threads when they are exported. | ||
128 | */ | ||
182 | return db_export__comm_thread(dbe, comm, main_thread); | 129 | return db_export__comm_thread(dbe, comm, main_thread); |
183 | } | 130 | } |
184 | 131 | ||
@@ -339,11 +286,65 @@ int db_export__branch_type(struct db_export *dbe, u32 branch_type, | |||
339 | return 0; | 286 | return 0; |
340 | } | 287 | } |
341 | 288 | ||
289 | static int db_export__threads(struct db_export *dbe, struct thread *thread, | ||
290 | struct thread *main_thread, | ||
291 | struct machine *machine, struct comm **comm_ptr) | ||
292 | { | ||
293 | struct comm *comm = NULL; | ||
294 | struct comm *curr_comm; | ||
295 | int err; | ||
296 | |||
297 | if (main_thread) { | ||
298 | /* | ||
299 | * A thread has a reference to the main thread, so export the | ||
300 | * main thread first. | ||
301 | */ | ||
302 | err = db_export__thread(dbe, main_thread, machine, main_thread); | ||
303 | if (err) | ||
304 | return err; | ||
305 | /* | ||
306 | * Export comm before exporting the non-main thread because | ||
307 | * db_export__comm_thread() can be called further below. | ||
308 | */ | ||
309 | comm = machine__thread_exec_comm(machine, main_thread); | ||
310 | if (comm) { | ||
311 | err = db_export__exec_comm(dbe, comm, main_thread); | ||
312 | if (err) | ||
313 | return err; | ||
314 | *comm_ptr = comm; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | if (thread != main_thread) { | ||
319 | /* | ||
320 | * For a non-main thread, db_export__comm_thread() must be | ||
321 | * called only if thread has not previously been exported. | ||
322 | */ | ||
323 | bool export_comm_thread = comm && !thread->db_id; | ||
324 | |||
325 | err = db_export__thread(dbe, thread, machine, main_thread); | ||
326 | if (err) | ||
327 | return err; | ||
328 | |||
329 | if (export_comm_thread) { | ||
330 | err = db_export__comm_thread(dbe, comm, thread); | ||
331 | if (err) | ||
332 | return err; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | curr_comm = thread__comm(thread); | ||
337 | if (curr_comm) | ||
338 | return db_export__comm(dbe, curr_comm, thread); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
342 | int db_export__sample(struct db_export *dbe, union perf_event *event, | 343 | int db_export__sample(struct db_export *dbe, union perf_event *event, |
343 | struct perf_sample *sample, struct perf_evsel *evsel, | 344 | struct perf_sample *sample, struct perf_evsel *evsel, |
344 | struct addr_location *al) | 345 | struct addr_location *al) |
345 | { | 346 | { |
346 | struct thread* thread = al->thread; | 347 | struct thread *thread = al->thread; |
347 | struct export_sample es = { | 348 | struct export_sample es = { |
348 | .event = event, | 349 | .event = event, |
349 | .sample = sample, | 350 | .sample = sample, |
@@ -363,19 +364,13 @@ int db_export__sample(struct db_export *dbe, union perf_event *event, | |||
363 | return err; | 364 | return err; |
364 | 365 | ||
365 | main_thread = thread__main_thread(al->machine, thread); | 366 | main_thread = thread__main_thread(al->machine, thread); |
366 | if (main_thread) | ||
367 | comm = machine__thread_exec_comm(al->machine, main_thread); | ||
368 | 367 | ||
369 | err = db_export__thread(dbe, thread, al->machine, comm); | 368 | err = db_export__threads(dbe, thread, main_thread, al->machine, &comm); |
370 | if (err) | 369 | if (err) |
371 | goto out_put; | 370 | goto out_put; |
372 | 371 | ||
373 | if (comm) { | 372 | if (comm) |
374 | err = db_export__comm(dbe, comm, main_thread); | ||
375 | if (err) | ||
376 | goto out_put; | ||
377 | es.comm_db_id = comm->db_id; | 373 | es.comm_db_id = comm->db_id; |
378 | } | ||
379 | 374 | ||
380 | es.db_id = ++dbe->sample_last_db_id; | 375 | es.db_id = ++dbe->sample_last_db_id; |
381 | 376 | ||
@@ -524,3 +519,92 @@ int db_export__call_return(struct db_export *dbe, struct call_return *cr, | |||
524 | 519 | ||
525 | return 0; | 520 | return 0; |
526 | } | 521 | } |
522 | |||
523 | static int db_export__pid_tid(struct db_export *dbe, struct machine *machine, | ||
524 | pid_t pid, pid_t tid, u64 *db_id, | ||
525 | struct comm **comm_ptr, bool *is_idle) | ||
526 | { | ||
527 | struct thread *thread = machine__find_thread(machine, pid, tid); | ||
528 | struct thread *main_thread; | ||
529 | int err = 0; | ||
530 | |||
531 | if (!thread || !thread->comm_set) | ||
532 | goto out_put; | ||
533 | |||
534 | *is_idle = !thread->pid_ && !thread->tid; | ||
535 | |||
536 | main_thread = thread__main_thread(machine, thread); | ||
537 | |||
538 | err = db_export__threads(dbe, thread, main_thread, machine, comm_ptr); | ||
539 | |||
540 | *db_id = thread->db_id; | ||
541 | |||
542 | thread__put(main_thread); | ||
543 | out_put: | ||
544 | thread__put(thread); | ||
545 | |||
546 | return err; | ||
547 | } | ||
548 | |||
549 | int db_export__switch(struct db_export *dbe, union perf_event *event, | ||
550 | struct perf_sample *sample, struct machine *machine) | ||
551 | { | ||
552 | bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT; | ||
553 | bool out_preempt = out && | ||
554 | (event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT); | ||
555 | int flags = out | (out_preempt << 1); | ||
556 | bool is_idle_a = false, is_idle_b = false; | ||
557 | u64 th_a_id = 0, th_b_id = 0; | ||
558 | u64 comm_out_id, comm_in_id; | ||
559 | struct comm *comm_a = NULL; | ||
560 | struct comm *comm_b = NULL; | ||
561 | u64 th_out_id, th_in_id; | ||
562 | u64 db_id; | ||
563 | int err; | ||
564 | |||
565 | err = db_export__machine(dbe, machine); | ||
566 | if (err) | ||
567 | return err; | ||
568 | |||
569 | err = db_export__pid_tid(dbe, machine, sample->pid, sample->tid, | ||
570 | &th_a_id, &comm_a, &is_idle_a); | ||
571 | if (err) | ||
572 | return err; | ||
573 | |||
574 | if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) { | ||
575 | pid_t pid = event->context_switch.next_prev_pid; | ||
576 | pid_t tid = event->context_switch.next_prev_tid; | ||
577 | |||
578 | err = db_export__pid_tid(dbe, machine, pid, tid, &th_b_id, | ||
579 | &comm_b, &is_idle_b); | ||
580 | if (err) | ||
581 | return err; | ||
582 | } | ||
583 | |||
584 | /* | ||
585 | * Do not export if both threads are unknown (i.e. not being traced), | ||
586 | * or one is unknown and the other is the idle task. | ||
587 | */ | ||
588 | if ((!th_a_id || is_idle_a) && (!th_b_id || is_idle_b)) | ||
589 | return 0; | ||
590 | |||
591 | db_id = ++dbe->context_switch_last_db_id; | ||
592 | |||
593 | if (out) { | ||
594 | th_out_id = th_a_id; | ||
595 | th_in_id = th_b_id; | ||
596 | comm_out_id = comm_a ? comm_a->db_id : 0; | ||
597 | comm_in_id = comm_b ? comm_b->db_id : 0; | ||
598 | } else { | ||
599 | th_out_id = th_b_id; | ||
600 | th_in_id = th_a_id; | ||
601 | comm_out_id = comm_b ? comm_b->db_id : 0; | ||
602 | comm_in_id = comm_a ? comm_a->db_id : 0; | ||
603 | } | ||
604 | |||
605 | if (dbe->export_context_switch) | ||
606 | return dbe->export_context_switch(dbe, db_id, machine, sample, | ||
607 | th_out_id, comm_out_id, | ||
608 | th_in_id, comm_in_id, flags); | ||
609 | return 0; | ||
610 | } | ||
diff --git a/tools/perf/util/db-export.h b/tools/perf/util/db-export.h index e8a64028a386..ba1f62a5fe10 100644 --- a/tools/perf/util/db-export.h +++ b/tools/perf/util/db-export.h | |||
@@ -43,7 +43,8 @@ struct db_export { | |||
43 | int (*export_machine)(struct db_export *dbe, struct machine *machine); | 43 | int (*export_machine)(struct db_export *dbe, struct machine *machine); |
44 | int (*export_thread)(struct db_export *dbe, struct thread *thread, | 44 | int (*export_thread)(struct db_export *dbe, struct thread *thread, |
45 | u64 main_thread_db_id, struct machine *machine); | 45 | u64 main_thread_db_id, struct machine *machine); |
46 | int (*export_comm)(struct db_export *dbe, struct comm *comm); | 46 | int (*export_comm)(struct db_export *dbe, struct comm *comm, |
47 | struct thread *thread); | ||
47 | int (*export_comm_thread)(struct db_export *dbe, u64 db_id, | 48 | int (*export_comm_thread)(struct db_export *dbe, u64 db_id, |
48 | struct comm *comm, struct thread *thread); | 49 | struct comm *comm, struct thread *thread); |
49 | int (*export_dso)(struct db_export *dbe, struct dso *dso, | 50 | int (*export_dso)(struct db_export *dbe, struct dso *dso, |
@@ -56,6 +57,11 @@ struct db_export { | |||
56 | int (*export_call_path)(struct db_export *dbe, struct call_path *cp); | 57 | int (*export_call_path)(struct db_export *dbe, struct call_path *cp); |
57 | int (*export_call_return)(struct db_export *dbe, | 58 | int (*export_call_return)(struct db_export *dbe, |
58 | struct call_return *cr); | 59 | struct call_return *cr); |
60 | int (*export_context_switch)(struct db_export *dbe, u64 db_id, | ||
61 | struct machine *machine, | ||
62 | struct perf_sample *sample, | ||
63 | u64 th_out_id, u64 comm_out_id, | ||
64 | u64 th_in_id, u64 comm_in_id, int flags); | ||
59 | struct call_return_processor *crp; | 65 | struct call_return_processor *crp; |
60 | struct call_path_root *cpr; | 66 | struct call_path_root *cpr; |
61 | u64 evsel_last_db_id; | 67 | u64 evsel_last_db_id; |
@@ -68,18 +74,19 @@ struct db_export { | |||
68 | u64 sample_last_db_id; | 74 | u64 sample_last_db_id; |
69 | u64 call_path_last_db_id; | 75 | u64 call_path_last_db_id; |
70 | u64 call_return_last_db_id; | 76 | u64 call_return_last_db_id; |
71 | struct list_head deferred; | 77 | u64 context_switch_last_db_id; |
72 | }; | 78 | }; |
73 | 79 | ||
74 | int db_export__init(struct db_export *dbe); | 80 | int db_export__init(struct db_export *dbe); |
75 | int db_export__flush(struct db_export *dbe); | ||
76 | void db_export__exit(struct db_export *dbe); | 81 | void db_export__exit(struct db_export *dbe); |
77 | int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel); | 82 | int db_export__evsel(struct db_export *dbe, struct perf_evsel *evsel); |
78 | int db_export__machine(struct db_export *dbe, struct machine *machine); | 83 | int db_export__machine(struct db_export *dbe, struct machine *machine); |
79 | int db_export__thread(struct db_export *dbe, struct thread *thread, | 84 | int db_export__thread(struct db_export *dbe, struct thread *thread, |
80 | struct machine *machine, struct comm *comm); | 85 | struct machine *machine, struct thread *main_thread); |
81 | int db_export__comm(struct db_export *dbe, struct comm *comm, | 86 | int db_export__comm(struct db_export *dbe, struct comm *comm, |
82 | struct thread *main_thread); | 87 | struct thread *thread); |
88 | int db_export__exec_comm(struct db_export *dbe, struct comm *comm, | ||
89 | struct thread *main_thread); | ||
83 | int db_export__comm_thread(struct db_export *dbe, struct comm *comm, | 90 | int db_export__comm_thread(struct db_export *dbe, struct comm *comm, |
84 | struct thread *thread); | 91 | struct thread *thread); |
85 | int db_export__dso(struct db_export *dbe, struct dso *dso, | 92 | int db_export__dso(struct db_export *dbe, struct dso *dso, |
@@ -97,5 +104,7 @@ int db_export__branch_types(struct db_export *dbe); | |||
97 | int db_export__call_path(struct db_export *dbe, struct call_path *cp); | 104 | int db_export__call_path(struct db_export *dbe, struct call_path *cp); |
98 | int db_export__call_return(struct db_export *dbe, struct call_return *cr, | 105 | int db_export__call_return(struct db_export *dbe, struct call_return *cr, |
99 | u64 *parent_db_id); | 106 | u64 *parent_db_id); |
107 | int db_export__switch(struct db_export *dbe, union perf_event *event, | ||
108 | struct perf_sample *sample, struct machine *machine); | ||
100 | 109 | ||
101 | #endif | 110 | #endif |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 3cc578343f48..3780fe42453b 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <string.h> | 7 | #include <string.h> |
8 | #include <stdarg.h> | 8 | #include <stdarg.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
10 | #include <stdlib.h> | ||
10 | #include <sys/wait.h> | 11 | #include <sys/wait.h> |
11 | #include <api/debug.h> | 12 | #include <api/debug.h> |
12 | #include <linux/time64.h> | 13 | #include <linux/time64.h> |
diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c index 5b4900d67c80..763328c151e9 100644 --- a/tools/perf/util/demangle-java.c +++ b/tools/perf/util/demangle-java.c | |||
@@ -1,14 +1,15 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <sys/types.h> | 2 | #include <sys/types.h> |
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <stdlib.h> | ||
4 | #include <string.h> | 5 | #include <string.h> |
5 | #include "util.h" | ||
6 | #include "debug.h" | 6 | #include "debug.h" |
7 | #include "symbol.h" | 7 | #include "symbol.h" |
8 | 8 | ||
9 | #include "demangle-java.h" | 9 | #include "demangle-java.h" |
10 | 10 | ||
11 | #include <linux/ctype.h> | 11 | #include <linux/ctype.h> |
12 | #include <linux/kernel.h> | ||
12 | 13 | ||
13 | enum { | 14 | enum { |
14 | MODE_PREFIX = 0, | 15 | MODE_PREFIX = 0, |
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index c7fde04400f7..ebc9d46c15a7 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <asm/bug.h> | 2 | #include <asm/bug.h> |
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
5 | #include <linux/zalloc.h> | ||
5 | #include <sys/time.h> | 6 | #include <sys/time.h> |
6 | #include <sys/resource.h> | 7 | #include <sys/resource.h> |
7 | #include <sys/types.h> | 8 | #include <sys/types.h> |
@@ -21,7 +22,7 @@ | |||
21 | #include "dso.h" | 22 | #include "dso.h" |
22 | #include "machine.h" | 23 | #include "machine.h" |
23 | #include "auxtrace.h" | 24 | #include "auxtrace.h" |
24 | #include "util.h" | 25 | #include "util.h" /* O_CLOEXEC for older systems */ |
25 | #include "debug.h" | 26 | #include "debug.h" |
26 | #include "string2.h" | 27 | #include "string2.h" |
27 | #include "vdso.h" | 28 | #include "vdso.h" |
@@ -433,7 +434,7 @@ static void dso__list_add(struct dso *dso) | |||
433 | 434 | ||
434 | static void dso__list_del(struct dso *dso) | 435 | static void dso__list_del(struct dso *dso) |
435 | { | 436 | { |
436 | list_del(&dso->data.open_entry); | 437 | list_del_init(&dso->data.open_entry); |
437 | WARN_ONCE(dso__data_open_cnt <= 0, | 438 | WARN_ONCE(dso__data_open_cnt <= 0, |
438 | "DSO data fd counter out of bounds."); | 439 | "DSO data fd counter out of bounds."); |
439 | dso__data_open_cnt--; | 440 | dso__data_open_cnt--; |
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 218bfea8f8a8..03b2de1f5a35 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
@@ -6,7 +6,7 @@ | |||
6 | #include <errno.h> | 6 | #include <errno.h> |
7 | #include <inttypes.h> | 7 | #include <inttypes.h> |
8 | #include <stdbool.h> | 8 | #include <stdbool.h> |
9 | #include "util.h" | 9 | #include <stdlib.h> |
10 | #include "debug.h" | 10 | #include "debug.h" |
11 | #include "dwarf-aux.h" | 11 | #include "dwarf-aux.h" |
12 | #include "string2.h" | 12 | #include "string2.h" |
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index 22eee8942527..9909ec40c6d2 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c | |||
@@ -2,11 +2,12 @@ | |||
2 | #include "cpumap.h" | 2 | #include "cpumap.h" |
3 | #include "env.h" | 3 | #include "env.h" |
4 | #include <linux/ctype.h> | 4 | #include <linux/ctype.h> |
5 | #include "util.h" | 5 | #include <linux/zalloc.h> |
6 | #include "bpf-event.h" | 6 | #include "bpf-event.h" |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <sys/utsname.h> | 8 | #include <sys/utsname.h> |
9 | #include <bpf/libbpf.h> | 9 | #include <bpf/libbpf.h> |
10 | #include <stdlib.h> | ||
10 | 11 | ||
11 | struct perf_env perf_env; | 12 | struct perf_env perf_env; |
12 | 13 | ||
@@ -186,7 +187,7 @@ void perf_env__exit(struct perf_env *env) | |||
186 | zfree(&env->caches); | 187 | zfree(&env->caches); |
187 | 188 | ||
188 | for (i = 0; i < env->nr_memory_nodes; i++) | 189 | for (i = 0; i < env->nr_memory_nodes; i++) |
189 | free(env->memory_nodes[i].set); | 190 | zfree(&env->memory_nodes[i].set); |
190 | zfree(&env->memory_nodes); | 191 | zfree(&env->memory_nodes); |
191 | } | 192 | } |
192 | 193 | ||
@@ -286,9 +287,9 @@ int perf_env__nr_cpus_avail(struct perf_env *env) | |||
286 | 287 | ||
287 | void cpu_cache_level__free(struct cpu_cache_level *cache) | 288 | void cpu_cache_level__free(struct cpu_cache_level *cache) |
288 | { | 289 | { |
289 | free(cache->type); | 290 | zfree(&cache->type); |
290 | free(cache->map); | 291 | zfree(&cache->map); |
291 | free(cache->size); | 292 | zfree(&cache->size); |
292 | } | 293 | } |
293 | 294 | ||
294 | /* | 295 | /* |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index e1d0c5ba1f92..f1f4848947ce 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ | 11 | #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ |
12 | #include <api/fs/fs.h> | 12 | #include <api/fs/fs.h> |
13 | #include <linux/perf_event.h> | 13 | #include <linux/perf_event.h> |
14 | #include <linux/zalloc.h> | ||
14 | #include "event.h" | 15 | #include "event.h" |
15 | #include "debug.h" | 16 | #include "debug.h" |
16 | #include "hist.h" | 17 | #include "hist.h" |
@@ -855,7 +856,7 @@ free_threads: | |||
855 | free(synthesize_threads); | 856 | free(synthesize_threads); |
856 | free_dirent: | 857 | free_dirent: |
857 | for (i = 0; i < n; i++) | 858 | for (i = 0; i < n; i++) |
858 | free(dirent[i]); | 859 | zfree(&dirent[i]); |
859 | free(dirent); | 860 | free(dirent); |
860 | 861 | ||
861 | return err; | 862 | return err; |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a474ede17cd6..b0364d923f76 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * Parts came from builtin-{top,stat,record}.c, see those files for further | 5 | * Parts came from builtin-{top,stat,record}.c, see those files for further |
6 | * copyright notes. | 6 | * copyright notes. |
7 | */ | 7 | */ |
8 | #include "util.h" | ||
9 | #include <api/fs/fs.h> | 8 | #include <api/fs/fs.h> |
10 | #include <errno.h> | 9 | #include <errno.h> |
11 | #include <inttypes.h> | 10 | #include <inttypes.h> |
@@ -33,6 +32,7 @@ | |||
33 | #include <linux/hash.h> | 32 | #include <linux/hash.h> |
34 | #include <linux/log2.h> | 33 | #include <linux/log2.h> |
35 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/zalloc.h> | ||
36 | 36 | ||
37 | #ifdef LACKS_SIGQUEUE_PROTOTYPE | 37 | #ifdef LACKS_SIGQUEUE_PROTOTYPE |
38 | int sigqueue(pid_t pid, int sig, const union sigval value); | 38 | int sigqueue(pid_t pid, int sig, const union sigval value); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7fb4ae82f34c..ebb46da4dfe5 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/perf_event.h> | 17 | #include <linux/perf_event.h> |
18 | #include <linux/compiler.h> | 18 | #include <linux/compiler.h> |
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/zalloc.h> | ||
20 | #include <sys/ioctl.h> | 21 | #include <sys/ioctl.h> |
21 | #include <sys/resource.h> | 22 | #include <sys/resource.h> |
22 | #include <sys/types.h> | 23 | #include <sys/types.h> |
@@ -27,7 +28,6 @@ | |||
27 | #include "event.h" | 28 | #include "event.h" |
28 | #include "evsel.h" | 29 | #include "evsel.h" |
29 | #include "evlist.h" | 30 | #include "evlist.h" |
30 | #include "util.h" | ||
31 | #include "cpumap.h" | 31 | #include "cpumap.h" |
32 | #include "thread_map.h" | 32 | #include "thread_map.h" |
33 | #include "target.h" | 33 | #include "target.h" |
@@ -1298,7 +1298,7 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel) | |||
1298 | struct perf_evsel_config_term *term, *h; | 1298 | struct perf_evsel_config_term *term, *h; |
1299 | 1299 | ||
1300 | list_for_each_entry_safe(term, h, &evsel->config_terms, list) { | 1300 | list_for_each_entry_safe(term, h, &evsel->config_terms, list) { |
1301 | list_del(&term->list); | 1301 | list_del_init(&term->list); |
1302 | free(term); | 1302 | free(term); |
1303 | } | 1303 | } |
1304 | } | 1304 | } |
diff --git a/tools/perf/util/get_current_dir_name.c b/tools/perf/util/get_current_dir_name.c index 267aa609a582..01f32f26552d 100644 --- a/tools/perf/util/get_current_dir_name.c +++ b/tools/perf/util/get_current_dir_name.c | |||
@@ -1,8 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: LGPL-2.1 |
2 | // Copyright (C) 2018, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | 2 | // Copyright (C) 2018, 2019 Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> |
3 | // | 3 | // |
4 | #ifndef HAVE_GET_CURRENT_DIR_NAME | 4 | #ifndef HAVE_GET_CURRENT_DIR_NAME |
5 | #include "util.h" | 5 | #include "get_current_dir_name.h" |
6 | #include <unistd.h> | 6 | #include <unistd.h> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <stdlib.h> | 8 | #include <stdlib.h> |
diff --git a/tools/perf/util/get_current_dir_name.h b/tools/perf/util/get_current_dir_name.h new file mode 100644 index 000000000000..69f7d5537d32 --- /dev/null +++ b/tools/perf/util/get_current_dir_name.h | |||
@@ -0,0 +1,8 @@ | |||
1 | // SPDX-License-Identifier: LGPL-2.1 | ||
2 | // Copyright (C) 2018, 2019 Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> | ||
3 | // | ||
4 | #ifndef __PERF_GET_CURRENT_DIR_NAME_H | ||
5 | #ifndef HAVE_GET_CURRENT_DIR_NAME | ||
6 | char *get_current_dir_name(void); | ||
7 | #endif // HAVE_GET_CURRENT_DIR_NAME | ||
8 | #endif // __PERF_GET_CURRENT_DIR_NAME_H | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 6a93ff5d8db5..c24db7f4909c 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -1,7 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <errno.h> | 2 | #include <errno.h> |
3 | #include <inttypes.h> | 3 | #include <inttypes.h> |
4 | #include "util.h" | ||
5 | #include "string2.h" | 4 | #include "string2.h" |
6 | #include <sys/param.h> | 5 | #include <sys/param.h> |
7 | #include <sys/types.h> | 6 | #include <sys/types.h> |
@@ -15,6 +14,7 @@ | |||
15 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
16 | #include <linux/string.h> | 15 | #include <linux/string.h> |
17 | #include <linux/stringify.h> | 16 | #include <linux/stringify.h> |
17 | #include <linux/zalloc.h> | ||
18 | #include <sys/stat.h> | 18 | #include <sys/stat.h> |
19 | #include <sys/utsname.h> | 19 | #include <sys/utsname.h> |
20 | #include <linux/time64.h> | 20 | #include <linux/time64.h> |
@@ -1052,7 +1052,7 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev | |||
1052 | 1052 | ||
1053 | scnprintf(file, PATH_MAX, "%s/size", path); | 1053 | scnprintf(file, PATH_MAX, "%s/size", path); |
1054 | if (sysfs__read_str(file, &cache->size, &len)) { | 1054 | if (sysfs__read_str(file, &cache->size, &len)) { |
1055 | free(cache->type); | 1055 | zfree(&cache->type); |
1056 | return -1; | 1056 | return -1; |
1057 | } | 1057 | } |
1058 | 1058 | ||
@@ -1061,8 +1061,8 @@ static int cpu_cache_level__read(struct cpu_cache_level *cache, u32 cpu, u16 lev | |||
1061 | 1061 | ||
1062 | scnprintf(file, PATH_MAX, "%s/shared_cpu_list", path); | 1062 | scnprintf(file, PATH_MAX, "%s/shared_cpu_list", path); |
1063 | if (sysfs__read_str(file, &cache->map, &len)) { | 1063 | if (sysfs__read_str(file, &cache->map, &len)) { |
1064 | free(cache->map); | 1064 | zfree(&cache->map); |
1065 | free(cache->type); | 1065 | zfree(&cache->type); |
1066 | return -1; | 1066 | return -1; |
1067 | } | 1067 | } |
1068 | 1068 | ||
diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c index 4f07a5ba5030..ab9e16123626 100644 --- a/tools/perf/util/help-unknown-cmd.c +++ b/tools/perf/util/help-unknown-cmd.c | |||
@@ -3,9 +3,11 @@ | |||
3 | #include "config.h" | 3 | #include "config.h" |
4 | #include <poll.h> | 4 | #include <poll.h> |
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <stdlib.h> | ||
6 | #include <subcmd/help.h> | 7 | #include <subcmd/help.h> |
7 | #include "../builtin.h" | 8 | #include "../builtin.h" |
8 | #include "levenshtein.h" | 9 | #include "levenshtein.h" |
10 | #include <linux/zalloc.h> | ||
9 | 11 | ||
10 | static int autocorrect; | 12 | static int autocorrect; |
11 | 13 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 27cecb59f866..f24fd1954f6c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -1,6 +1,5 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "callchain.h" | 2 | #include "callchain.h" |
3 | #include "util.h" | ||
4 | #include "build-id.h" | 3 | #include "build-id.h" |
5 | #include "hist.h" | 4 | #include "hist.h" |
6 | #include "map.h" | 5 | #include "map.h" |
@@ -20,6 +19,7 @@ | |||
20 | #include <inttypes.h> | 19 | #include <inttypes.h> |
21 | #include <sys/param.h> | 20 | #include <sys/param.h> |
22 | #include <linux/time64.h> | 21 | #include <linux/time64.h> |
22 | #include <linux/zalloc.h> | ||
23 | 23 | ||
24 | static bool hists__filter_entry_by_dso(struct hists *hists, | 24 | static bool hists__filter_entry_by_dso(struct hists *hists, |
25 | struct hist_entry *he); | 25 | struct hist_entry *he); |
@@ -472,16 +472,16 @@ static int hist_entry__init(struct hist_entry *he, | |||
472 | return 0; | 472 | return 0; |
473 | 473 | ||
474 | err_srcline: | 474 | err_srcline: |
475 | free(he->srcline); | 475 | zfree(&he->srcline); |
476 | 476 | ||
477 | err_rawdata: | 477 | err_rawdata: |
478 | free(he->raw_data); | 478 | zfree(&he->raw_data); |
479 | 479 | ||
480 | err_infos: | 480 | err_infos: |
481 | if (he->branch_info) { | 481 | if (he->branch_info) { |
482 | map__put(he->branch_info->from.map); | 482 | map__put(he->branch_info->from.map); |
483 | map__put(he->branch_info->to.map); | 483 | map__put(he->branch_info->to.map); |
484 | free(he->branch_info); | 484 | zfree(&he->branch_info); |
485 | } | 485 | } |
486 | if (he->mem_info) { | 486 | if (he->mem_info) { |
487 | map__put(he->mem_info->iaddr.map); | 487 | map__put(he->mem_info->iaddr.map); |
@@ -489,7 +489,7 @@ err_infos: | |||
489 | } | 489 | } |
490 | err: | 490 | err: |
491 | map__zput(he->ms.map); | 491 | map__zput(he->ms.map); |
492 | free(he->stat_acc); | 492 | zfree(&he->stat_acc); |
493 | return -ENOMEM; | 493 | return -ENOMEM; |
494 | } | 494 | } |
495 | 495 | ||
@@ -1254,10 +1254,10 @@ void hist_entry__delete(struct hist_entry *he) | |||
1254 | zfree(&he->stat_acc); | 1254 | zfree(&he->stat_acc); |
1255 | free_srcline(he->srcline); | 1255 | free_srcline(he->srcline); |
1256 | if (he->srcfile && he->srcfile[0]) | 1256 | if (he->srcfile && he->srcfile[0]) |
1257 | free(he->srcfile); | 1257 | zfree(&he->srcfile); |
1258 | free_callchain(he->callchain); | 1258 | free_callchain(he->callchain); |
1259 | free(he->trace_output); | 1259 | zfree(&he->trace_output); |
1260 | free(he->raw_data); | 1260 | zfree(&he->raw_data); |
1261 | ops->free(he); | 1261 | ops->free(he); |
1262 | } | 1262 | } |
1263 | 1263 | ||
@@ -2741,10 +2741,10 @@ static void hists_evsel__exit(struct perf_evsel *evsel) | |||
2741 | 2741 | ||
2742 | list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) { | 2742 | list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) { |
2743 | perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) { | 2743 | perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) { |
2744 | list_del(&fmt->list); | 2744 | list_del_init(&fmt->list); |
2745 | free(fmt); | 2745 | free(fmt); |
2746 | } | 2746 | } |
2747 | list_del(&node->list); | 2747 | list_del_init(&node->list); |
2748 | free(node); | 2748 | free(node); |
2749 | } | 2749 | } |
2750 | } | 2750 | } |
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index e32dbffebb2f..5560e95afdda 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include <linux/log2.h> | 14 | #include <linux/log2.h> |
15 | #include <linux/zalloc.h> | ||
15 | 16 | ||
16 | #include "cpumap.h" | 17 | #include "cpumap.h" |
17 | #include "color.h" | 18 | #include "color.h" |
@@ -21,7 +22,6 @@ | |||
21 | #include "map.h" | 22 | #include "map.h" |
22 | #include "symbol.h" | 23 | #include "symbol.h" |
23 | #include "session.h" | 24 | #include "session.h" |
24 | #include "util.h" | ||
25 | #include "thread.h" | 25 | #include "thread.h" |
26 | #include "thread-stack.h" | 26 | #include "thread-stack.h" |
27 | #include "debug.h" | 27 | #include "debug.h" |
@@ -891,13 +891,12 @@ int intel_bts_process_auxtrace_info(union perf_event *event, | |||
891 | if (dump_trace) | 891 | if (dump_trace) |
892 | return 0; | 892 | return 0; |
893 | 893 | ||
894 | if (session->itrace_synth_opts && session->itrace_synth_opts->set) { | 894 | if (session->itrace_synth_opts->set) { |
895 | bts->synth_opts = *session->itrace_synth_opts; | 895 | bts->synth_opts = *session->itrace_synth_opts; |
896 | } else { | 896 | } else { |
897 | itrace_synth_opts__set_default(&bts->synth_opts, | 897 | itrace_synth_opts__set_default(&bts->synth_opts, |
898 | session->itrace_synth_opts->default_no_sample); | 898 | session->itrace_synth_opts->default_no_sample); |
899 | if (session->itrace_synth_opts) | 899 | bts->synth_opts.thread_stack = |
900 | bts->synth_opts.thread_stack = | ||
901 | session->itrace_synth_opts->thread_stack; | 900 | session->itrace_synth_opts->thread_stack; |
902 | } | 901 | } |
903 | 902 | ||
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c index 4d14e78c5927..3bfdf2b7a96a 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | |||
@@ -14,9 +14,9 @@ | |||
14 | #include <stdint.h> | 14 | #include <stdint.h> |
15 | #include <inttypes.h> | 15 | #include <inttypes.h> |
16 | #include <linux/compiler.h> | 16 | #include <linux/compiler.h> |
17 | #include <linux/zalloc.h> | ||
17 | 18 | ||
18 | #include "../cache.h" | 19 | #include "../cache.h" |
19 | #include "../util.h" | ||
20 | #include "../auxtrace.h" | 20 | #include "../auxtrace.h" |
21 | 21 | ||
22 | #include "intel-pt-insn-decoder.h" | 22 | #include "intel-pt-insn-decoder.h" |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 470aaae9d930..df061599fef4 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <errno.h> | 10 | #include <errno.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/zalloc.h> | ||
13 | 14 | ||
14 | #include "../perf.h" | 15 | #include "../perf.h" |
15 | #include "session.h" | 16 | #include "session.h" |
@@ -22,7 +23,6 @@ | |||
22 | #include "evsel.h" | 23 | #include "evsel.h" |
23 | #include "map.h" | 24 | #include "map.h" |
24 | #include "color.h" | 25 | #include "color.h" |
25 | #include "util.h" | ||
26 | #include "thread.h" | 26 | #include "thread.h" |
27 | #include "thread-stack.h" | 27 | #include "thread-stack.h" |
28 | #include "symbol.h" | 28 | #include "symbol.h" |
@@ -3210,7 +3210,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
3210 | goto err_delete_thread; | 3210 | goto err_delete_thread; |
3211 | } | 3211 | } |
3212 | 3212 | ||
3213 | if (session->itrace_synth_opts && session->itrace_synth_opts->set) { | 3213 | if (session->itrace_synth_opts->set) { |
3214 | pt->synth_opts = *session->itrace_synth_opts; | 3214 | pt->synth_opts = *session->itrace_synth_opts; |
3215 | } else { | 3215 | } else { |
3216 | itrace_synth_opts__set_default(&pt->synth_opts, | 3216 | itrace_synth_opts__set_default(&pt->synth_opts, |
@@ -3220,8 +3220,7 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
3220 | pt->synth_opts.branches = false; | 3220 | pt->synth_opts.branches = false; |
3221 | pt->synth_opts.callchain = true; | 3221 | pt->synth_opts.callchain = true; |
3222 | } | 3222 | } |
3223 | if (session->itrace_synth_opts) | 3223 | pt->synth_opts.thread_stack = |
3224 | pt->synth_opts.thread_stack = | ||
3225 | session->itrace_synth_opts->thread_stack; | 3224 | session->itrace_synth_opts->thread_stack; |
3226 | } | 3225 | } |
3227 | 3226 | ||
@@ -3241,11 +3240,9 @@ int intel_pt_process_auxtrace_info(union perf_event *event, | |||
3241 | pt->cbr2khz = tsc_freq / pt->max_non_turbo_ratio / 1000; | 3240 | pt->cbr2khz = tsc_freq / pt->max_non_turbo_ratio / 1000; |
3242 | } | 3241 | } |
3243 | 3242 | ||
3244 | if (session->itrace_synth_opts) { | 3243 | err = intel_pt_setup_time_ranges(pt, session->itrace_synth_opts); |
3245 | err = intel_pt_setup_time_ranges(pt, session->itrace_synth_opts); | 3244 | if (err) |
3246 | if (err) | 3245 | goto err_delete_thread; |
3247 | goto err_delete_thread; | ||
3248 | } | ||
3249 | 3246 | ||
3250 | if (pt->synth_opts.calls) | 3247 | if (pt->synth_opts.calls) |
3251 | pt->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | | 3248 | pt->branches_filter |= PERF_IP_FLAG_CALL | PERF_IP_FLAG_ASYNC | |
diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 28908afedec4..18c34f0c1966 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "../builtin.h" | 29 | #include "../builtin.h" |
30 | 30 | ||
31 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
32 | #include <linux/zalloc.h> | ||
32 | 33 | ||
33 | struct jit_buf_desc { | 34 | struct jit_buf_desc { |
34 | struct perf_data *output; | 35 | struct perf_data *output; |
@@ -431,14 +432,12 @@ static int jit_repipe_code_load(struct jit_buf_desc *jd, union jr_entry *jr) | |||
431 | jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size); | 432 | jd->unwinding_data, jd->eh_frame_hdr_size, jd->unwinding_size); |
432 | 433 | ||
433 | if (jd->debug_data && jd->nr_debug_entries) { | 434 | if (jd->debug_data && jd->nr_debug_entries) { |
434 | free(jd->debug_data); | 435 | zfree(&jd->debug_data); |
435 | jd->debug_data = NULL; | ||
436 | jd->nr_debug_entries = 0; | 436 | jd->nr_debug_entries = 0; |
437 | } | 437 | } |
438 | 438 | ||
439 | if (jd->unwinding_data && jd->eh_frame_hdr_size) { | 439 | if (jd->unwinding_data && jd->eh_frame_hdr_size) { |
440 | free(jd->unwinding_data); | 440 | zfree(&jd->unwinding_data); |
441 | jd->unwinding_data = NULL; | ||
442 | jd->eh_frame_hdr_size = 0; | 441 | jd->eh_frame_hdr_size = 0; |
443 | jd->unwinding_mapped_size = 0; | 442 | jd->unwinding_mapped_size = 0; |
444 | jd->unwinding_size = 0; | 443 | jd->unwinding_size = 0; |
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 5b0b60f00275..9f0470ecbca9 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <stdio.h> | 9 | #include <stdio.h> |
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
12 | #include <linux/zalloc.h> | ||
12 | #include "debug.h" | 13 | #include "debug.h" |
13 | #include "llvm-utils.h" | 14 | #include "llvm-utils.h" |
14 | #include "config.h" | 15 | #include "config.h" |
@@ -352,8 +353,7 @@ void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) | |||
352 | " \toption in [llvm] to \"\" to suppress this detection.\n\n", | 353 | " \toption in [llvm] to \"\" to suppress this detection.\n\n", |
353 | *kbuild_dir); | 354 | *kbuild_dir); |
354 | 355 | ||
355 | free(*kbuild_dir); | 356 | zfree(kbuild_dir); |
356 | *kbuild_dir = NULL; | ||
357 | goto errout; | 357 | goto errout; |
358 | } | 358 | } |
359 | 359 | ||
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 147ed85ea2bc..cf826eca3aaf 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include "strlist.h" | 15 | #include "strlist.h" |
16 | #include "thread.h" | 16 | #include "thread.h" |
17 | #include "vdso.h" | 17 | #include "vdso.h" |
18 | #include "util.h" | ||
19 | #include <stdbool.h> | 18 | #include <stdbool.h> |
20 | #include <sys/types.h> | 19 | #include <sys/types.h> |
21 | #include <sys/stat.h> | 20 | #include <sys/stat.h> |
@@ -28,6 +27,7 @@ | |||
28 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
29 | #include <symbol/kallsyms.h> | 28 | #include <symbol/kallsyms.h> |
30 | #include <linux/mman.h> | 29 | #include <linux/mman.h> |
30 | #include <linux/zalloc.h> | ||
31 | 31 | ||
32 | static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock); | 32 | static void __machine__remove_thread(struct machine *machine, struct thread *th, bool lock); |
33 | 33 | ||
@@ -810,7 +810,7 @@ struct map *machine__findnew_module_map(struct machine *machine, u64 start, | |||
810 | out: | 810 | out: |
811 | /* put the dso here, corresponding to machine__findnew_module_dso */ | 811 | /* put the dso here, corresponding to machine__findnew_module_dso */ |
812 | dso__put(dso); | 812 | dso__put(dso); |
813 | free(m.name); | 813 | zfree(&m.name); |
814 | return map; | 814 | return map; |
815 | } | 815 | } |
816 | 816 | ||
@@ -1350,7 +1350,7 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg, | |||
1350 | if (m.kmod) | 1350 | if (m.kmod) |
1351 | ret = map_groups__set_module_path(mg, path, &m); | 1351 | ret = map_groups__set_module_path(mg, path, &m); |
1352 | 1352 | ||
1353 | free(m.name); | 1353 | zfree(&m.name); |
1354 | 1354 | ||
1355 | if (ret) | 1355 | if (ret) |
1356 | goto out; | 1356 | goto out; |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 6fce983c6115..668410b1d426 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -12,10 +12,10 @@ | |||
12 | #include "thread.h" | 12 | #include "thread.h" |
13 | #include "vdso.h" | 13 | #include "vdso.h" |
14 | #include "build-id.h" | 14 | #include "build-id.h" |
15 | #include "util.h" | ||
16 | #include "debug.h" | 15 | #include "debug.h" |
17 | #include "machine.h" | 16 | #include "machine.h" |
18 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/zalloc.h> | ||
19 | #include "srcline.h" | 19 | #include "srcline.h" |
20 | #include "namespaces.h" | 20 | #include "namespaces.h" |
21 | #include "unwind.h" | 21 | #include "unwind.h" |
@@ -476,8 +476,11 @@ int map__fprintf_srccode(struct map *map, u64 addr, | |||
476 | goto out_free_line; | 476 | goto out_free_line; |
477 | 477 | ||
478 | ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); | 478 | ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); |
479 | state->srcfile = srcfile; | 479 | |
480 | state->line = line; | 480 | if (state) { |
481 | state->srcfile = srcfile; | ||
482 | state->line = line; | ||
483 | } | ||
481 | return ret; | 484 | return ret; |
482 | 485 | ||
483 | out_free_line: | 486 | out_free_line: |
diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c index c6fd81c02586..cacc2fc4dcbd 100644 --- a/tools/perf/util/mem2node.c +++ b/tools/perf/util/mem2node.c | |||
@@ -1,8 +1,8 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <inttypes.h> | 2 | #include <inttypes.h> |
3 | #include <linux/bitmap.h> | 3 | #include <linux/bitmap.h> |
4 | #include <linux/zalloc.h> | ||
4 | #include "mem2node.h" | 5 | #include "mem2node.h" |
5 | #include "util.h" | ||
6 | 6 | ||
7 | struct phys_entry { | 7 | struct phys_entry { |
8 | struct rb_node rb_node; | 8 | struct rb_node rb_node; |
diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index d8164574cb16..416a9015405e 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "strlist.h" | 18 | #include "strlist.h" |
19 | #include <assert.h> | 19 | #include <assert.h> |
20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
21 | #include <linux/zalloc.h> | ||
21 | 22 | ||
22 | struct metric_event *metricgroup__lookup(struct rblist *metric_events, | 23 | struct metric_event *metricgroup__lookup(struct rblist *metric_events, |
23 | struct perf_evsel *evsel, | 24 | struct perf_evsel *evsel, |
@@ -235,7 +236,7 @@ static struct rb_node *mep_new(struct rblist *rl __maybe_unused, | |||
235 | goto out_name; | 236 | goto out_name; |
236 | return &me->nd; | 237 | return &me->nd; |
237 | out_name: | 238 | out_name: |
238 | free((char *)me->name); | 239 | zfree(&me->name); |
239 | out_me: | 240 | out_me: |
240 | free(me); | 241 | free(me); |
241 | return NULL; | 242 | return NULL; |
@@ -263,7 +264,7 @@ static void mep_delete(struct rblist *rl __maybe_unused, | |||
263 | struct mep *me = container_of(nd, struct mep, nd); | 264 | struct mep *me = container_of(nd, struct mep, nd); |
264 | 265 | ||
265 | strlist__delete(me->metrics); | 266 | strlist__delete(me->metrics); |
266 | free((void *)me->name); | 267 | zfree(&me->name); |
267 | free(me); | 268 | free(me); |
268 | } | 269 | } |
269 | 270 | ||
@@ -489,8 +490,9 @@ static void metricgroup__free_egroups(struct list_head *group_list) | |||
489 | 490 | ||
490 | list_for_each_entry_safe (eg, egtmp, group_list, nd) { | 491 | list_for_each_entry_safe (eg, egtmp, group_list, nd) { |
491 | for (i = 0; i < eg->idnum; i++) | 492 | for (i = 0; i < eg->idnum; i++) |
492 | free((char *)eg->ids[i]); | 493 | zfree(&eg->ids[i]); |
493 | free(eg->ids); | 494 | zfree(&eg->ids); |
495 | list_del_init(&eg->nd); | ||
494 | free(eg); | 496 | free(eg); |
495 | } | 497 | } |
496 | } | 498 | } |
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c index 768c632b0d82..9f0b6391af33 100644 --- a/tools/perf/util/mmap.c +++ b/tools/perf/util/mmap.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <sys/mman.h> | 9 | #include <sys/mman.h> |
10 | #include <inttypes.h> | 10 | #include <inttypes.h> |
11 | #include <asm/bug.h> | 11 | #include <asm/bug.h> |
12 | #include <linux/zalloc.h> | ||
12 | #ifdef HAVE_LIBNUMA_SUPPORT | 13 | #ifdef HAVE_LIBNUMA_SUPPORT |
13 | #include <numaif.h> | 14 | #include <numaif.h> |
14 | #endif | 15 | #endif |
diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 023c4efd788d..46d3a7754897 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c | |||
@@ -5,8 +5,8 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include "namespaces.h" | 7 | #include "namespaces.h" |
8 | #include "util.h" | ||
9 | #include "event.h" | 8 | #include "event.h" |
9 | #include "get_current_dir_name.h" | ||
10 | #include <sys/types.h> | 10 | #include <sys/types.h> |
11 | #include <sys/stat.h> | 11 | #include <sys/stat.h> |
12 | #include <fcntl.h> | 12 | #include <fcntl.h> |
@@ -17,6 +17,7 @@ | |||
17 | #include <string.h> | 17 | #include <string.h> |
18 | #include <unistd.h> | 18 | #include <unistd.h> |
19 | #include <asm/bug.h> | 19 | #include <asm/bug.h> |
20 | #include <linux/zalloc.h> | ||
20 | 21 | ||
21 | struct namespaces *namespaces__new(struct namespaces_event *event) | 22 | struct namespaces *namespaces__new(struct namespaces_event *event) |
22 | { | 23 | { |
diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 15a5a276c478..004430c0de93 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h | |||
@@ -13,6 +13,10 @@ | |||
13 | #include <linux/refcount.h> | 13 | #include <linux/refcount.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | 15 | ||
16 | #ifndef HAVE_SETNS_SUPPORT | ||
17 | int setns(int fd, int nstype); | ||
18 | #endif | ||
19 | |||
16 | struct namespaces_event; | 20 | struct namespaces_event; |
17 | 21 | ||
18 | struct namespaces { | 22 | struct namespaces { |
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 989fed6f43b5..bb5f34b7ab44 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c | |||
@@ -138,7 +138,7 @@ static struct ordered_event *alloc_event(struct ordered_events *oe, | |||
138 | 138 | ||
139 | if (!list_empty(cache)) { | 139 | if (!list_empty(cache)) { |
140 | new = list_entry(cache->next, struct ordered_event, list); | 140 | new = list_entry(cache->next, struct ordered_event, list); |
141 | list_del(&new->list); | 141 | list_del_init(&new->list); |
142 | } else if (oe->buffer) { | 142 | } else if (oe->buffer) { |
143 | new = &oe->buffer->event[oe->buffer_idx]; | 143 | new = &oe->buffer->event[oe->buffer_idx]; |
144 | if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) | 144 | if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) |
@@ -394,13 +394,13 @@ void ordered_events__free(struct ordered_events *oe) | |||
394 | * yet, we need to free only allocated ones ... | 394 | * yet, we need to free only allocated ones ... |
395 | */ | 395 | */ |
396 | if (oe->buffer) { | 396 | if (oe->buffer) { |
397 | list_del(&oe->buffer->list); | 397 | list_del_init(&oe->buffer->list); |
398 | ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe); | 398 | ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe); |
399 | } | 399 | } |
400 | 400 | ||
401 | /* ... and continue with the rest */ | 401 | /* ... and continue with the rest */ |
402 | list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) { | 402 | list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) { |
403 | list_del(&buffer->list); | 403 | list_del_init(&buffer->list); |
404 | ordered_events_buffer__free(buffer, MAX_SAMPLE_BUFFER, oe); | 404 | ordered_events_buffer__free(buffer, MAX_SAMPLE_BUFFER, oe); |
405 | } | 405 | } |
406 | } | 406 | } |
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index bd779d9f4d1e..726e8d9e8c54 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c | |||
@@ -1,9 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "perf.h" | 2 | #include "perf.h" |
3 | #include "util/util.h" | ||
4 | #include "util/debug.h" | 3 | #include "util/debug.h" |
5 | #include <subcmd/parse-options.h> | 4 | #include <subcmd/parse-options.h> |
6 | #include "util/parse-branch-options.h" | 5 | #include "util/parse-branch-options.h" |
6 | #include <stdlib.h> | ||
7 | 7 | ||
8 | #define BRANCH_OPT(n, m) \ | 8 | #define BRANCH_OPT(n, m) \ |
9 | { .name = n, .mode = (m) } | 9 | { .name = n, .mode = (m) } |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index cf0b9b81c5aa..371ff3aee769 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/hw_breakpoint.h> | 2 | #include <linux/hw_breakpoint.h> |
3 | #include <linux/err.h> | 3 | #include <linux/err.h> |
4 | #include <linux/zalloc.h> | ||
4 | #include <dirent.h> | 5 | #include <dirent.h> |
5 | #include <errno.h> | 6 | #include <errno.h> |
6 | #include <sys/ioctl.h> | 7 | #include <sys/ioctl.h> |
@@ -651,7 +652,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, | |||
651 | pr_debug("Failed to add BPF event %s:%s\n", | 652 | pr_debug("Failed to add BPF event %s:%s\n", |
652 | group, event); | 653 | group, event); |
653 | list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { | 654 | list_for_each_entry_safe(evsel, tmp, &new_evsels, node) { |
654 | list_del(&evsel->node); | 655 | list_del_init(&evsel->node); |
655 | perf_evsel__delete(evsel); | 656 | perf_evsel__delete(evsel); |
656 | } | 657 | } |
657 | return err; | 658 | return err; |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 6ad8d4914969..f1c36ed1cf36 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
@@ -480,7 +480,6 @@ event_bpf_file: | |||
480 | PE_BPF_OBJECT opt_event_config | 480 | PE_BPF_OBJECT opt_event_config |
481 | { | 481 | { |
482 | struct parse_events_state *parse_state = _parse_state; | 482 | struct parse_events_state *parse_state = _parse_state; |
483 | struct parse_events_error *error = parse_state->error; | ||
484 | struct list_head *list; | 483 | struct list_head *list; |
485 | 484 | ||
486 | ALLOC_LIST(list); | 485 | ALLOC_LIST(list); |
@@ -626,7 +625,6 @@ PE_TERM | |||
626 | PE_NAME array '=' PE_NAME | 625 | PE_NAME array '=' PE_NAME |
627 | { | 626 | { |
628 | struct parse_events_term *term; | 627 | struct parse_events_term *term; |
629 | int i; | ||
630 | 628 | ||
631 | ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, | 629 | ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
632 | $1, $4, &@1, &@4)); | 630 | $1, $4, &@1, &@4)); |
diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c index 08581e276225..ef46c2848808 100644 --- a/tools/perf/util/parse-regs-options.c +++ b/tools/perf/util/parse-regs-options.c | |||
@@ -1,8 +1,12 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "perf.h" | 2 | #include <stdbool.h> |
3 | #include "util/util.h" | 3 | #include <stdlib.h> |
4 | #include <stdint.h> | ||
5 | #include <string.h> | ||
6 | #include <stdio.h> | ||
4 | #include "util/debug.h" | 7 | #include "util/debug.h" |
5 | #include <subcmd/parse-options.h> | 8 | #include <subcmd/parse-options.h> |
9 | #include "util/perf_regs.h" | ||
6 | #include "util/parse-regs-options.h" | 10 | #include "util/parse-regs-options.h" |
7 | 11 | ||
8 | static int | 12 | static int |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 55f4de6442e3..f32b710347db 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/list.h> | 2 | #include <linux/list.h> |
3 | #include <linux/compiler.h> | 3 | #include <linux/compiler.h> |
4 | #include <linux/string.h> | 4 | #include <linux/string.h> |
5 | #include <linux/zalloc.h> | ||
5 | #include <sys/types.h> | 6 | #include <sys/types.h> |
6 | #include <errno.h> | 7 | #include <errno.h> |
7 | #include <fcntl.h> | 8 | #include <fcntl.h> |
@@ -14,7 +15,6 @@ | |||
14 | #include <api/fs/fs.h> | 15 | #include <api/fs/fs.h> |
15 | #include <locale.h> | 16 | #include <locale.h> |
16 | #include <regex.h> | 17 | #include <regex.h> |
17 | #include "util.h" | ||
18 | #include "pmu.h" | 18 | #include "pmu.h" |
19 | #include "parse-events.h" | 19 | #include "parse-events.h" |
20 | #include "cpumap.h" | 20 | #include "cpumap.h" |
@@ -1245,7 +1245,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, | |||
1245 | info->metric_expr = alias->metric_expr; | 1245 | info->metric_expr = alias->metric_expr; |
1246 | info->metric_name = alias->metric_name; | 1246 | info->metric_name = alias->metric_name; |
1247 | 1247 | ||
1248 | list_del(&term->list); | 1248 | list_del_init(&term->list); |
1249 | free(term); | 1249 | free(term); |
1250 | } | 1250 | } |
1251 | 1251 | ||
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 6f24eaf6e504..cd1eb73cfe83 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <limits.h> | 19 | #include <limits.h> |
20 | #include <elf.h> | 20 | #include <elf.h> |
21 | 21 | ||
22 | #include "util.h" | ||
23 | #include "event.h" | 22 | #include "event.h" |
24 | #include "namespaces.h" | 23 | #include "namespaces.h" |
25 | #include "strlist.h" | 24 | #include "strlist.h" |
@@ -40,6 +39,7 @@ | |||
40 | #include "string2.h" | 39 | #include "string2.h" |
41 | 40 | ||
42 | #include <linux/ctype.h> | 41 | #include <linux/ctype.h> |
42 | #include <linux/zalloc.h> | ||
43 | 43 | ||
44 | #define PERFPROBE_GROUP "probe" | 44 | #define PERFPROBE_GROUP "probe" |
45 | 45 | ||
@@ -214,9 +214,9 @@ out: | |||
214 | 214 | ||
215 | static void clear_perf_probe_point(struct perf_probe_point *pp) | 215 | static void clear_perf_probe_point(struct perf_probe_point *pp) |
216 | { | 216 | { |
217 | free(pp->file); | 217 | zfree(&pp->file); |
218 | free(pp->function); | 218 | zfree(&pp->function); |
219 | free(pp->lazy_line); | 219 | zfree(&pp->lazy_line); |
220 | } | 220 | } |
221 | 221 | ||
222 | static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) | 222 | static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) |
@@ -1175,12 +1175,11 @@ int show_available_vars(struct perf_probe_event *pevs __maybe_unused, | |||
1175 | 1175 | ||
1176 | void line_range__clear(struct line_range *lr) | 1176 | void line_range__clear(struct line_range *lr) |
1177 | { | 1177 | { |
1178 | free(lr->function); | 1178 | zfree(&lr->function); |
1179 | free(lr->file); | 1179 | zfree(&lr->file); |
1180 | free(lr->path); | 1180 | zfree(&lr->path); |
1181 | free(lr->comp_dir); | 1181 | zfree(&lr->comp_dir); |
1182 | intlist__delete(lr->line_list); | 1182 | intlist__delete(lr->line_list); |
1183 | memset(lr, 0, sizeof(*lr)); | ||
1184 | } | 1183 | } |
1185 | 1184 | ||
1186 | int line_range__init(struct line_range *lr) | 1185 | int line_range__init(struct line_range *lr) |
@@ -1563,6 +1562,17 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg) | |||
1563 | str = tmp + 1; | 1562 | str = tmp + 1; |
1564 | } | 1563 | } |
1565 | 1564 | ||
1565 | tmp = strchr(str, '@'); | ||
1566 | if (tmp && tmp != str && strcmp(tmp + 1, "user")) { /* user attr */ | ||
1567 | if (!user_access_is_supported()) { | ||
1568 | semantic_error("ftrace does not support user access\n"); | ||
1569 | return -EINVAL; | ||
1570 | } | ||
1571 | *tmp = '\0'; | ||
1572 | arg->user_access = true; | ||
1573 | pr_debug("user_access "); | ||
1574 | } | ||
1575 | |||
1566 | tmp = strchr(str, ':'); | 1576 | tmp = strchr(str, ':'); |
1567 | if (tmp) { /* Type setting */ | 1577 | if (tmp) { /* Type setting */ |
1568 | *tmp = '\0'; | 1578 | *tmp = '\0'; |
@@ -2203,15 +2213,15 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
2203 | struct perf_probe_arg_field *field, *next; | 2213 | struct perf_probe_arg_field *field, *next; |
2204 | int i; | 2214 | int i; |
2205 | 2215 | ||
2206 | free(pev->event); | 2216 | zfree(&pev->event); |
2207 | free(pev->group); | 2217 | zfree(&pev->group); |
2208 | free(pev->target); | 2218 | zfree(&pev->target); |
2209 | clear_perf_probe_point(&pev->point); | 2219 | clear_perf_probe_point(&pev->point); |
2210 | 2220 | ||
2211 | for (i = 0; i < pev->nargs; i++) { | 2221 | for (i = 0; i < pev->nargs; i++) { |
2212 | free(pev->args[i].name); | 2222 | zfree(&pev->args[i].name); |
2213 | free(pev->args[i].var); | 2223 | zfree(&pev->args[i].var); |
2214 | free(pev->args[i].type); | 2224 | zfree(&pev->args[i].type); |
2215 | field = pev->args[i].field; | 2225 | field = pev->args[i].field; |
2216 | while (field) { | 2226 | while (field) { |
2217 | next = field->next; | 2227 | next = field->next; |
@@ -2220,8 +2230,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
2220 | field = next; | 2230 | field = next; |
2221 | } | 2231 | } |
2222 | } | 2232 | } |
2223 | free(pev->args); | 2233 | zfree(&pev->args); |
2224 | memset(pev, 0, sizeof(*pev)); | ||
2225 | } | 2234 | } |
2226 | 2235 | ||
2227 | #define strdup_or_goto(str, label) \ | 2236 | #define strdup_or_goto(str, label) \ |
@@ -2302,15 +2311,15 @@ void clear_probe_trace_event(struct probe_trace_event *tev) | |||
2302 | struct probe_trace_arg_ref *ref, *next; | 2311 | struct probe_trace_arg_ref *ref, *next; |
2303 | int i; | 2312 | int i; |
2304 | 2313 | ||
2305 | free(tev->event); | 2314 | zfree(&tev->event); |
2306 | free(tev->group); | 2315 | zfree(&tev->group); |
2307 | free(tev->point.symbol); | 2316 | zfree(&tev->point.symbol); |
2308 | free(tev->point.realname); | 2317 | zfree(&tev->point.realname); |
2309 | free(tev->point.module); | 2318 | zfree(&tev->point.module); |
2310 | for (i = 0; i < tev->nargs; i++) { | 2319 | for (i = 0; i < tev->nargs; i++) { |
2311 | free(tev->args[i].name); | 2320 | zfree(&tev->args[i].name); |
2312 | free(tev->args[i].value); | 2321 | zfree(&tev->args[i].value); |
2313 | free(tev->args[i].type); | 2322 | zfree(&tev->args[i].type); |
2314 | ref = tev->args[i].ref; | 2323 | ref = tev->args[i].ref; |
2315 | while (ref) { | 2324 | while (ref) { |
2316 | next = ref->next; | 2325 | next = ref->next; |
@@ -2318,8 +2327,7 @@ void clear_probe_trace_event(struct probe_trace_event *tev) | |||
2318 | ref = next; | 2327 | ref = next; |
2319 | } | 2328 | } |
2320 | } | 2329 | } |
2321 | free(tev->args); | 2330 | zfree(&tev->args); |
2322 | memset(tev, 0, sizeof(*tev)); | ||
2323 | } | 2331 | } |
2324 | 2332 | ||
2325 | struct kprobe_blacklist_node { | 2333 | struct kprobe_blacklist_node { |
@@ -2336,8 +2344,8 @@ static void kprobe_blacklist__delete(struct list_head *blacklist) | |||
2336 | while (!list_empty(blacklist)) { | 2344 | while (!list_empty(blacklist)) { |
2337 | node = list_first_entry(blacklist, | 2345 | node = list_first_entry(blacklist, |
2338 | struct kprobe_blacklist_node, list); | 2346 | struct kprobe_blacklist_node, list); |
2339 | list_del(&node->list); | 2347 | list_del_init(&node->list); |
2340 | free(node->symbol); | 2348 | zfree(&node->symbol); |
2341 | free(node); | 2349 | free(node); |
2342 | } | 2350 | } |
2343 | } | 2351 | } |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 05c8d571a901..96a319cd2378 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -37,6 +37,7 @@ struct probe_trace_point { | |||
37 | struct probe_trace_arg_ref { | 37 | struct probe_trace_arg_ref { |
38 | struct probe_trace_arg_ref *next; /* Next reference */ | 38 | struct probe_trace_arg_ref *next; /* Next reference */ |
39 | long offset; /* Offset value */ | 39 | long offset; /* Offset value */ |
40 | bool user_access; /* User-memory access */ | ||
40 | }; | 41 | }; |
41 | 42 | ||
42 | /* kprobe-tracer and uprobe-tracer tracing argument */ | 43 | /* kprobe-tracer and uprobe-tracer tracing argument */ |
@@ -82,6 +83,7 @@ struct perf_probe_arg { | |||
82 | char *var; /* Variable name */ | 83 | char *var; /* Variable name */ |
83 | char *type; /* Type name */ | 84 | char *type; /* Type name */ |
84 | struct perf_probe_arg_field *field; /* Structure fields */ | 85 | struct perf_probe_arg_field *field; /* Structure fields */ |
86 | bool user_access; /* User-memory access */ | ||
85 | }; | 87 | }; |
86 | 88 | ||
87 | /* Perf probe probing event (point + arg) */ | 89 | /* Perf probe probing event (point + arg) */ |
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 0ed1900454eb..5b4d49382932 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c | |||
@@ -10,8 +10,8 @@ | |||
10 | #include <sys/types.h> | 10 | #include <sys/types.h> |
11 | #include <sys/uio.h> | 11 | #include <sys/uio.h> |
12 | #include <unistd.h> | 12 | #include <unistd.h> |
13 | #include <linux/zalloc.h> | ||
13 | #include "namespaces.h" | 14 | #include "namespaces.h" |
14 | #include "util.h" | ||
15 | #include "event.h" | 15 | #include "event.h" |
16 | #include "strlist.h" | 16 | #include "strlist.h" |
17 | #include "strfilter.h" | 17 | #include "strfilter.h" |
@@ -1005,6 +1005,7 @@ enum ftrace_readme { | |||
1005 | FTRACE_README_PROBE_TYPE_X = 0, | 1005 | FTRACE_README_PROBE_TYPE_X = 0, |
1006 | FTRACE_README_KRETPROBE_OFFSET, | 1006 | FTRACE_README_KRETPROBE_OFFSET, |
1007 | FTRACE_README_UPROBE_REF_CTR, | 1007 | FTRACE_README_UPROBE_REF_CTR, |
1008 | FTRACE_README_USER_ACCESS, | ||
1008 | FTRACE_README_END, | 1009 | FTRACE_README_END, |
1009 | }; | 1010 | }; |
1010 | 1011 | ||
@@ -1017,6 +1018,7 @@ static struct { | |||
1017 | DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"), | 1018 | DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"), |
1018 | DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), | 1019 | DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), |
1019 | DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"), | 1020 | DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"), |
1021 | DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*[u]<offset>*"), | ||
1020 | }; | 1022 | }; |
1021 | 1023 | ||
1022 | static bool scan_ftrace_readme(enum ftrace_readme type) | 1024 | static bool scan_ftrace_readme(enum ftrace_readme type) |
@@ -1077,3 +1079,8 @@ bool uprobe_ref_ctr_is_supported(void) | |||
1077 | { | 1079 | { |
1078 | return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR); | 1080 | return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR); |
1079 | } | 1081 | } |
1082 | |||
1083 | bool user_access_is_supported(void) | ||
1084 | { | ||
1085 | return scan_ftrace_readme(FTRACE_README_USER_ACCESS); | ||
1086 | } | ||
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h index 2a249182f2a6..986c1c94f64f 100644 --- a/tools/perf/util/probe-file.h +++ b/tools/perf/util/probe-file.h | |||
@@ -70,6 +70,7 @@ int probe_cache__show_all_caches(struct strfilter *filter); | |||
70 | bool probe_type_is_available(enum probe_type type); | 70 | bool probe_type_is_available(enum probe_type type); |
71 | bool kretprobe_offset_is_supported(void); | 71 | bool kretprobe_offset_is_supported(void); |
72 | bool uprobe_ref_ctr_is_supported(void); | 72 | bool uprobe_ref_ctr_is_supported(void); |
73 | bool user_access_is_supported(void); | ||
73 | #else /* ! HAVE_LIBELF_SUPPORT */ | 74 | #else /* ! HAVE_LIBELF_SUPPORT */ |
74 | static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) | 75 | static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) |
75 | { | 76 | { |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 6b40cc691a2d..025fc4491993 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -19,11 +19,11 @@ | |||
19 | #include <dwarf-regs.h> | 19 | #include <dwarf-regs.h> |
20 | 20 | ||
21 | #include <linux/bitops.h> | 21 | #include <linux/bitops.h> |
22 | #include <linux/zalloc.h> | ||
22 | #include "event.h" | 23 | #include "event.h" |
23 | #include "dso.h" | 24 | #include "dso.h" |
24 | #include "debug.h" | 25 | #include "debug.h" |
25 | #include "intlist.h" | 26 | #include "intlist.h" |
26 | #include "util.h" | ||
27 | #include "strlist.h" | 27 | #include "strlist.h" |
28 | #include "symbol.h" | 28 | #include "symbol.h" |
29 | #include "probe-finder.h" | 29 | #include "probe-finder.h" |
@@ -280,7 +280,7 @@ static_var: | |||
280 | 280 | ||
281 | static int convert_variable_type(Dwarf_Die *vr_die, | 281 | static int convert_variable_type(Dwarf_Die *vr_die, |
282 | struct probe_trace_arg *tvar, | 282 | struct probe_trace_arg *tvar, |
283 | const char *cast) | 283 | const char *cast, bool user_access) |
284 | { | 284 | { |
285 | struct probe_trace_arg_ref **ref_ptr = &tvar->ref; | 285 | struct probe_trace_arg_ref **ref_ptr = &tvar->ref; |
286 | Dwarf_Die type; | 286 | Dwarf_Die type; |
@@ -320,7 +320,8 @@ static int convert_variable_type(Dwarf_Die *vr_die, | |||
320 | pr_debug("%s type is %s.\n", | 320 | pr_debug("%s type is %s.\n", |
321 | dwarf_diename(vr_die), dwarf_diename(&type)); | 321 | dwarf_diename(vr_die), dwarf_diename(&type)); |
322 | 322 | ||
323 | if (cast && strcmp(cast, "string") == 0) { /* String type */ | 323 | if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) { |
324 | /* String type */ | ||
324 | ret = dwarf_tag(&type); | 325 | ret = dwarf_tag(&type); |
325 | if (ret != DW_TAG_pointer_type && | 326 | if (ret != DW_TAG_pointer_type && |
326 | ret != DW_TAG_array_type) { | 327 | ret != DW_TAG_array_type) { |
@@ -343,6 +344,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, | |||
343 | pr_warning("Out of memory error\n"); | 344 | pr_warning("Out of memory error\n"); |
344 | return -ENOMEM; | 345 | return -ENOMEM; |
345 | } | 346 | } |
347 | (*ref_ptr)->user_access = user_access; | ||
346 | } | 348 | } |
347 | if (!die_compare_name(&type, "char") && | 349 | if (!die_compare_name(&type, "char") && |
348 | !die_compare_name(&type, "unsigned char")) { | 350 | !die_compare_name(&type, "unsigned char")) { |
@@ -397,7 +399,7 @@ formatted: | |||
397 | static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, | 399 | static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, |
398 | struct perf_probe_arg_field *field, | 400 | struct perf_probe_arg_field *field, |
399 | struct probe_trace_arg_ref **ref_ptr, | 401 | struct probe_trace_arg_ref **ref_ptr, |
400 | Dwarf_Die *die_mem) | 402 | Dwarf_Die *die_mem, bool user_access) |
401 | { | 403 | { |
402 | struct probe_trace_arg_ref *ref = *ref_ptr; | 404 | struct probe_trace_arg_ref *ref = *ref_ptr; |
403 | Dwarf_Die type; | 405 | Dwarf_Die type; |
@@ -434,6 +436,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, | |||
434 | *ref_ptr = ref; | 436 | *ref_ptr = ref; |
435 | } | 437 | } |
436 | ref->offset += dwarf_bytesize(&type) * field->index; | 438 | ref->offset += dwarf_bytesize(&type) * field->index; |
439 | ref->user_access = user_access; | ||
437 | goto next; | 440 | goto next; |
438 | } else if (tag == DW_TAG_pointer_type) { | 441 | } else if (tag == DW_TAG_pointer_type) { |
439 | /* Check the pointer and dereference */ | 442 | /* Check the pointer and dereference */ |
@@ -505,17 +508,18 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, | |||
505 | } | 508 | } |
506 | } | 509 | } |
507 | ref->offset += (long)offs; | 510 | ref->offset += (long)offs; |
511 | ref->user_access = user_access; | ||
508 | 512 | ||
509 | /* If this member is unnamed, we need to reuse this field */ | 513 | /* If this member is unnamed, we need to reuse this field */ |
510 | if (!dwarf_diename(die_mem)) | 514 | if (!dwarf_diename(die_mem)) |
511 | return convert_variable_fields(die_mem, varname, field, | 515 | return convert_variable_fields(die_mem, varname, field, |
512 | &ref, die_mem); | 516 | &ref, die_mem, user_access); |
513 | 517 | ||
514 | next: | 518 | next: |
515 | /* Converting next field */ | 519 | /* Converting next field */ |
516 | if (field->next) | 520 | if (field->next) |
517 | return convert_variable_fields(die_mem, field->name, | 521 | return convert_variable_fields(die_mem, field->name, |
518 | field->next, &ref, die_mem); | 522 | field->next, &ref, die_mem, user_access); |
519 | else | 523 | else |
520 | return 0; | 524 | return 0; |
521 | } | 525 | } |
@@ -541,11 +545,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) | |||
541 | else if (ret == 0 && pf->pvar->field) { | 545 | else if (ret == 0 && pf->pvar->field) { |
542 | ret = convert_variable_fields(vr_die, pf->pvar->var, | 546 | ret = convert_variable_fields(vr_die, pf->pvar->var, |
543 | pf->pvar->field, &pf->tvar->ref, | 547 | pf->pvar->field, &pf->tvar->ref, |
544 | &die_mem); | 548 | &die_mem, pf->pvar->user_access); |
545 | vr_die = &die_mem; | 549 | vr_die = &die_mem; |
546 | } | 550 | } |
547 | if (ret == 0) | 551 | if (ret == 0) |
548 | ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); | 552 | ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type, |
553 | pf->pvar->user_access); | ||
549 | /* *expr will be cached in libdw. Don't free it. */ | 554 | /* *expr will be cached in libdw. Don't free it. */ |
550 | return ret; | 555 | return ret; |
551 | } | 556 | } |
diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c index 797fe1ae2d2e..28de8a4c2ce8 100644 --- a/tools/perf/util/pstack.c +++ b/tools/perf/util/pstack.c | |||
@@ -5,10 +5,10 @@ | |||
5 | * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com> | 5 | * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com> |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "util.h" | ||
9 | #include "pstack.h" | 8 | #include "pstack.h" |
10 | #include "debug.h" | 9 | #include "debug.h" |
11 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/zalloc.h> | ||
12 | #include <stdlib.h> | 12 | #include <stdlib.h> |
13 | 13 | ||
14 | struct pstack { | 14 | struct pstack { |
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 2237bac9fadb..ceb8afdf9a89 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources | |||
@@ -18,6 +18,7 @@ util/namespaces.c | |||
18 | ../lib/hweight.c | 18 | ../lib/hweight.c |
19 | ../lib/string.c | 19 | ../lib/string.c |
20 | ../lib/vsprintf.c | 20 | ../lib/vsprintf.c |
21 | ../lib/zalloc.c | ||
21 | util/thread_map.c | 22 | util/thread_map.c |
22 | util/util.c | 23 | util/util.c |
23 | util/xyarray.c | 24 | util/xyarray.c |
diff --git a/tools/perf/util/rlimit.c b/tools/perf/util/rlimit.c new file mode 100644 index 000000000000..13521d392a22 --- /dev/null +++ b/tools/perf/util/rlimit.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* SPDX-License-Identifier: LGPL-2.1 */ | ||
2 | |||
3 | #include "util/debug.h" | ||
4 | #include "util/rlimit.h" | ||
5 | #include <sys/time.h> | ||
6 | #include <sys/resource.h> | ||
7 | |||
8 | /* | ||
9 | * Bump the memlock so that we can get bpf maps of a reasonable size, | ||
10 | * like the ones used with 'perf trace' and with 'perf test bpf', | ||
11 | * improve this to some specific request if needed. | ||
12 | */ | ||
13 | void rlimit__bump_memlock(void) | ||
14 | { | ||
15 | struct rlimit rlim; | ||
16 | |||
17 | if (getrlimit(RLIMIT_MEMLOCK, &rlim) == 0) { | ||
18 | rlim.rlim_cur *= 4; | ||
19 | rlim.rlim_max *= 4; | ||
20 | |||
21 | if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { | ||
22 | rlim.rlim_cur /= 2; | ||
23 | rlim.rlim_max /= 2; | ||
24 | |||
25 | if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) | ||
26 | pr_debug("Couldn't bump rlimit(MEMLOCK), failures may take place when creating BPF maps, etc\n"); | ||
27 | } | ||
28 | } | ||
29 | } | ||
diff --git a/tools/perf/util/rlimit.h b/tools/perf/util/rlimit.h new file mode 100644 index 000000000000..9f59d8e710a3 --- /dev/null +++ b/tools/perf/util/rlimit.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __PERF_RLIMIT_H_ | ||
2 | #define __PERF_RLIMIT_H_ | ||
3 | /* SPDX-License-Identifier: LGPL-2.1 */ | ||
4 | |||
5 | void rlimit__bump_memlock(void); | ||
6 | #endif // __PERF_RLIMIT_H_ | ||
diff --git a/tools/perf/util/s390-cpumsf.c b/tools/perf/util/s390-cpumsf.c index 10d36d9b7909..83d2e149ef19 100644 --- a/tools/perf/util/s390-cpumsf.c +++ b/tools/perf/util/s390-cpumsf.c | |||
@@ -146,6 +146,7 @@ | |||
146 | #include <linux/types.h> | 146 | #include <linux/types.h> |
147 | #include <linux/bitops.h> | 147 | #include <linux/bitops.h> |
148 | #include <linux/log2.h> | 148 | #include <linux/log2.h> |
149 | #include <linux/zalloc.h> | ||
149 | 150 | ||
150 | #include <sys/stat.h> | 151 | #include <sys/stat.h> |
151 | #include <sys/types.h> | 152 | #include <sys/types.h> |
@@ -156,7 +157,6 @@ | |||
156 | #include "evlist.h" | 157 | #include "evlist.h" |
157 | #include "machine.h" | 158 | #include "machine.h" |
158 | #include "session.h" | 159 | #include "session.h" |
159 | #include "util.h" | ||
160 | #include "thread.h" | 160 | #include "thread.h" |
161 | #include "debug.h" | 161 | #include "debug.h" |
162 | #include "auxtrace.h" | 162 | #include "auxtrace.h" |
@@ -756,7 +756,7 @@ static int s390_cpumsf_run_decoder(struct s390_cpumsf_queue *sfq, | |||
756 | */ | 756 | */ |
757 | if (err) { | 757 | if (err) { |
758 | sfq->buffer = NULL; | 758 | sfq->buffer = NULL; |
759 | list_del(&buffer->list); | 759 | list_del_init(&buffer->list); |
760 | auxtrace_buffer__free(buffer); | 760 | auxtrace_buffer__free(buffer); |
761 | if (err > 0) /* Buffer done, no error */ | 761 | if (err > 0) /* Buffer done, no error */ |
762 | err = 0; | 762 | err = 0; |
@@ -1044,7 +1044,7 @@ static void s390_cpumsf_free(struct perf_session *session) | |||
1044 | auxtrace_heap__free(&sf->heap); | 1044 | auxtrace_heap__free(&sf->heap); |
1045 | s390_cpumsf_free_queues(session); | 1045 | s390_cpumsf_free_queues(session); |
1046 | session->auxtrace = NULL; | 1046 | session->auxtrace = NULL; |
1047 | free(sf->logdir); | 1047 | zfree(&sf->logdir); |
1048 | free(sf); | 1048 | free(sf); |
1049 | } | 1049 | } |
1050 | 1050 | ||
@@ -1101,8 +1101,7 @@ static int s390_cpumsf__config(const char *var, const char *value, void *cb) | |||
1101 | if (rc == -1 || !S_ISDIR(stbuf.st_mode)) { | 1101 | if (rc == -1 || !S_ISDIR(stbuf.st_mode)) { |
1102 | pr_err("Missing auxtrace log directory %s," | 1102 | pr_err("Missing auxtrace log directory %s," |
1103 | " continue with current directory...\n", value); | 1103 | " continue with current directory...\n", value); |
1104 | free(sf->logdir); | 1104 | zfree(&sf->logdir); |
1105 | sf->logdir = NULL; | ||
1106 | } | 1105 | } |
1107 | return 1; | 1106 | return 1; |
1108 | } | 1107 | } |
@@ -1162,7 +1161,7 @@ err_free_queues: | |||
1162 | auxtrace_queues__free(&sf->queues); | 1161 | auxtrace_queues__free(&sf->queues); |
1163 | session->auxtrace = NULL; | 1162 | session->auxtrace = NULL; |
1164 | err_free: | 1163 | err_free: |
1165 | free(sf->logdir); | 1164 | zfree(&sf->logdir); |
1166 | free(sf); | 1165 | free(sf); |
1167 | return err; | 1166 | return err; |
1168 | } | 1167 | } |
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 112bed65232f..25dc1d765553 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -113,6 +113,7 @@ struct tables { | |||
113 | PyObject *call_path_handler; | 113 | PyObject *call_path_handler; |
114 | PyObject *call_return_handler; | 114 | PyObject *call_return_handler; |
115 | PyObject *synth_handler; | 115 | PyObject *synth_handler; |
116 | PyObject *context_switch_handler; | ||
116 | bool db_export_mode; | 117 | bool db_export_mode; |
117 | }; | 118 | }; |
118 | 119 | ||
@@ -1011,15 +1012,19 @@ static int python_export_thread(struct db_export *dbe, struct thread *thread, | |||
1011 | return 0; | 1012 | return 0; |
1012 | } | 1013 | } |
1013 | 1014 | ||
1014 | static int python_export_comm(struct db_export *dbe, struct comm *comm) | 1015 | static int python_export_comm(struct db_export *dbe, struct comm *comm, |
1016 | struct thread *thread) | ||
1015 | { | 1017 | { |
1016 | struct tables *tables = container_of(dbe, struct tables, dbe); | 1018 | struct tables *tables = container_of(dbe, struct tables, dbe); |
1017 | PyObject *t; | 1019 | PyObject *t; |
1018 | 1020 | ||
1019 | t = tuple_new(2); | 1021 | t = tuple_new(5); |
1020 | 1022 | ||
1021 | tuple_set_u64(t, 0, comm->db_id); | 1023 | tuple_set_u64(t, 0, comm->db_id); |
1022 | tuple_set_string(t, 1, comm__str(comm)); | 1024 | tuple_set_string(t, 1, comm__str(comm)); |
1025 | tuple_set_u64(t, 2, thread->db_id); | ||
1026 | tuple_set_u64(t, 3, comm->start); | ||
1027 | tuple_set_s32(t, 4, comm->exec); | ||
1023 | 1028 | ||
1024 | call_object(tables->comm_handler, t, "comm_table"); | 1029 | call_object(tables->comm_handler, t, "comm_table"); |
1025 | 1030 | ||
@@ -1233,6 +1238,34 @@ static int python_export_call_return(struct db_export *dbe, | |||
1233 | return 0; | 1238 | return 0; |
1234 | } | 1239 | } |
1235 | 1240 | ||
1241 | static int python_export_context_switch(struct db_export *dbe, u64 db_id, | ||
1242 | struct machine *machine, | ||
1243 | struct perf_sample *sample, | ||
1244 | u64 th_out_id, u64 comm_out_id, | ||
1245 | u64 th_in_id, u64 comm_in_id, int flags) | ||
1246 | { | ||
1247 | struct tables *tables = container_of(dbe, struct tables, dbe); | ||
1248 | PyObject *t; | ||
1249 | |||
1250 | t = tuple_new(9); | ||
1251 | |||
1252 | tuple_set_u64(t, 0, db_id); | ||
1253 | tuple_set_u64(t, 1, machine->db_id); | ||
1254 | tuple_set_u64(t, 2, sample->time); | ||
1255 | tuple_set_s32(t, 3, sample->cpu); | ||
1256 | tuple_set_u64(t, 4, th_out_id); | ||
1257 | tuple_set_u64(t, 5, comm_out_id); | ||
1258 | tuple_set_u64(t, 6, th_in_id); | ||
1259 | tuple_set_u64(t, 7, comm_in_id); | ||
1260 | tuple_set_s32(t, 8, flags); | ||
1261 | |||
1262 | call_object(tables->context_switch_handler, t, "context_switch"); | ||
1263 | |||
1264 | Py_DECREF(t); | ||
1265 | |||
1266 | return 0; | ||
1267 | } | ||
1268 | |||
1236 | static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, | 1269 | static int python_process_call_return(struct call_return *cr, u64 *parent_db_id, |
1237 | void *data) | 1270 | void *data) |
1238 | { | 1271 | { |
@@ -1296,6 +1329,16 @@ static void python_process_event(union perf_event *event, | |||
1296 | } | 1329 | } |
1297 | } | 1330 | } |
1298 | 1331 | ||
1332 | static void python_process_switch(union perf_event *event, | ||
1333 | struct perf_sample *sample, | ||
1334 | struct machine *machine) | ||
1335 | { | ||
1336 | struct tables *tables = &tables_global; | ||
1337 | |||
1338 | if (tables->db_export_mode) | ||
1339 | db_export__switch(&tables->dbe, event, sample, machine); | ||
1340 | } | ||
1341 | |||
1299 | static void get_handler_name(char *str, size_t size, | 1342 | static void get_handler_name(char *str, size_t size, |
1300 | struct perf_evsel *evsel) | 1343 | struct perf_evsel *evsel) |
1301 | { | 1344 | { |
@@ -1511,6 +1554,7 @@ static void set_table_handlers(struct tables *tables) | |||
1511 | SET_TABLE_HANDLER(sample); | 1554 | SET_TABLE_HANDLER(sample); |
1512 | SET_TABLE_HANDLER(call_path); | 1555 | SET_TABLE_HANDLER(call_path); |
1513 | SET_TABLE_HANDLER(call_return); | 1556 | SET_TABLE_HANDLER(call_return); |
1557 | SET_TABLE_HANDLER(context_switch); | ||
1514 | 1558 | ||
1515 | /* | 1559 | /* |
1516 | * Synthesized events are samples but with architecture-specific data | 1560 | * Synthesized events are samples but with architecture-specific data |
@@ -1620,9 +1664,7 @@ error: | |||
1620 | 1664 | ||
1621 | static int python_flush_script(void) | 1665 | static int python_flush_script(void) |
1622 | { | 1666 | { |
1623 | struct tables *tables = &tables_global; | 1667 | return 0; |
1624 | |||
1625 | return db_export__flush(&tables->dbe); | ||
1626 | } | 1668 | } |
1627 | 1669 | ||
1628 | /* | 1670 | /* |
@@ -1831,6 +1873,7 @@ struct scripting_ops python_scripting_ops = { | |||
1831 | .flush_script = python_flush_script, | 1873 | .flush_script = python_flush_script, |
1832 | .stop_script = python_stop_script, | 1874 | .stop_script = python_stop_script, |
1833 | .process_event = python_process_event, | 1875 | .process_event = python_process_event, |
1876 | .process_switch = python_process_switch, | ||
1834 | .process_stat = python_process_stat, | 1877 | .process_stat = python_process_stat, |
1835 | .process_stat_interval = python_process_stat_interval, | 1878 | .process_stat_interval = python_process_stat_interval, |
1836 | .generate_script = python_generate_script, | 1879 | .generate_script = python_generate_script, |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 54cf163347f7..d0fd6c614e68 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <errno.h> | 2 | #include <errno.h> |
3 | #include <inttypes.h> | 3 | #include <inttypes.h> |
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | #include <linux/zalloc.h> | ||
5 | #include <traceevent/event-parse.h> | 6 | #include <traceevent/event-parse.h> |
6 | #include <api/fs/fs.h> | 7 | #include <api/fs/fs.h> |
7 | 8 | ||
@@ -18,7 +19,6 @@ | |||
18 | #include "session.h" | 19 | #include "session.h" |
19 | #include "tool.h" | 20 | #include "tool.h" |
20 | #include "sort.h" | 21 | #include "sort.h" |
21 | #include "util.h" | ||
22 | #include "cpumap.h" | 22 | #include "cpumap.h" |
23 | #include "perf_regs.h" | 23 | #include "perf_regs.h" |
24 | #include "asm/bug.h" | 24 | #include "asm/bug.h" |
@@ -1246,9 +1246,12 @@ static void dump_read(struct perf_evsel *evsel, union perf_event *event) | |||
1246 | return; | 1246 | return; |
1247 | 1247 | ||
1248 | printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, | 1248 | printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, |
1249 | evsel ? perf_evsel__name(evsel) : "FAIL", | 1249 | perf_evsel__name(evsel), |
1250 | event->read.value); | 1250 | event->read.value); |
1251 | 1251 | ||
1252 | if (!evsel) | ||
1253 | return; | ||
1254 | |||
1252 | read_format = evsel->attr.read_format; | 1255 | read_format = evsel->attr.read_format; |
1253 | 1256 | ||
1254 | if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) | 1257 | if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) |
diff --git a/tools/perf/util/setns.c b/tools/perf/util/setns.c index ce8fc290fce8..48f9c0af63b2 100644 --- a/tools/perf/util/setns.c +++ b/tools/perf/util/setns.c | |||
@@ -1,4 +1,6 @@ | |||
1 | #include "util.h" | 1 | // SPDX-License-Identifier: LGPL-2.1 |
2 | |||
3 | #include "namespaces.h" | ||
2 | #include <unistd.h> | 4 | #include <unistd.h> |
3 | #include <sys/syscall.h> | 5 | #include <sys/syscall.h> |
4 | 6 | ||
diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c index 684b155c222a..adfcf1ff464c 100644 --- a/tools/perf/util/srccode.c +++ b/tools/perf/util/srccode.c | |||
@@ -4,7 +4,8 @@ | |||
4 | * Copyright (c) 2017, Intel Corporation. | 4 | * Copyright (c) 2017, Intel Corporation. |
5 | * Author: Andi Kleen | 5 | * Author: Andi Kleen |
6 | */ | 6 | */ |
7 | #include "linux/list.h" | 7 | #include <linux/list.h> |
8 | #include <linux/zalloc.h> | ||
8 | #include <stdlib.h> | 9 | #include <stdlib.h> |
9 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
10 | #include <sys/stat.h> | 11 | #include <sys/stat.h> |
@@ -82,12 +83,12 @@ static void fill_lines(char **lines, int maxline, char *map, int maplen) | |||
82 | 83 | ||
83 | static void free_srcfile(struct srcfile *sf) | 84 | static void free_srcfile(struct srcfile *sf) |
84 | { | 85 | { |
85 | list_del(&sf->nd); | 86 | list_del_init(&sf->nd); |
86 | hlist_del(&sf->hash_nd); | 87 | hlist_del(&sf->hash_nd); |
87 | map_total_sz -= sf->maplen; | 88 | map_total_sz -= sf->maplen; |
88 | munmap(sf->map, sf->maplen); | 89 | munmap(sf->map, sf->maplen); |
89 | free(sf->lines); | 90 | zfree(&sf->lines); |
90 | free(sf->fn); | 91 | zfree(&sf->fn); |
91 | free(sf); | 92 | free(sf); |
92 | num_srcfiles--; | 93 | num_srcfiles--; |
93 | } | 94 | } |
@@ -153,7 +154,7 @@ static struct srcfile *find_srcfile(char *fn) | |||
153 | out_map: | 154 | out_map: |
154 | munmap(h->map, sz); | 155 | munmap(h->map, sz); |
155 | out_fn: | 156 | out_fn: |
156 | free(h->fn); | 157 | zfree(&h->fn); |
157 | out_h: | 158 | out_h: |
158 | free(h); | 159 | free(h); |
159 | return NULL; | 160 | return NULL; |
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index dcad75daf5e4..6ccf6f6d09df 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c | |||
@@ -6,9 +6,9 @@ | |||
6 | 6 | ||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
9 | #include <linux/zalloc.h> | ||
9 | 10 | ||
10 | #include "util/dso.h" | 11 | #include "util/dso.h" |
11 | #include "util/util.h" | ||
12 | #include "util/debug.h" | 12 | #include "util/debug.h" |
13 | #include "util/callchain.h" | 13 | #include "util/callchain.h" |
14 | #include "util/symbol_conf.h" | 14 | #include "util/symbol_conf.h" |
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index cb891e5c2969..656065af4971 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "evlist.h" | 8 | #include "evlist.h" |
9 | #include "expr.h" | 9 | #include "expr.h" |
10 | #include "metricgroup.h" | 10 | #include "metricgroup.h" |
11 | #include <linux/zalloc.h> | ||
11 | 12 | ||
12 | /* | 13 | /* |
13 | * AGGR_GLOBAL: Use CPU 0 | 14 | * AGGR_GLOBAL: Use CPU 0 |
@@ -775,7 +776,7 @@ static void generic_metric(struct perf_stat_config *config, | |||
775 | print_metric(config, ctxp, NULL, NULL, "", 0); | 776 | print_metric(config, ctxp, NULL, NULL, "", 0); |
776 | 777 | ||
777 | for (i = 1; i < pctx.num_ids; i++) | 778 | for (i = 1; i < pctx.num_ids; i++) |
778 | free((void *)pctx.ids[i].name); | 779 | zfree(&pctx.ids[i].name); |
779 | } | 780 | } |
780 | 781 | ||
781 | void perf_stat__print_shadow_stats(struct perf_stat_config *config, | 782 | void perf_stat__print_shadow_stats(struct perf_stat_config *config, |
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index d91fe754b6d2..db8a6cf336be 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include "evlist.h" | 6 | #include "evlist.h" |
7 | #include "evsel.h" | 7 | #include "evsel.h" |
8 | #include "thread_map.h" | 8 | #include "thread_map.h" |
9 | #include <linux/zalloc.h> | ||
9 | 10 | ||
10 | void update_stats(struct stats *stats, u64 val) | 11 | void update_stats(struct stats *stats, u64 val) |
11 | { | 12 | { |
@@ -132,7 +133,7 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) | |||
132 | struct perf_stat_evsel *ps = evsel->stats; | 133 | struct perf_stat_evsel *ps = evsel->stats; |
133 | 134 | ||
134 | if (ps) | 135 | if (ps) |
135 | free(ps->group_data); | 136 | zfree(&ps->group_data); |
136 | zfree(&evsel->stats); | 137 | zfree(&evsel->stats); |
137 | } | 138 | } |
138 | 139 | ||
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 23092fd6451d..2ce0dc887364 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c | |||
@@ -1,8 +1,9 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "debug.h" | 2 | #include "debug.h" |
3 | #include "util.h" | ||
4 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/zalloc.h> | ||
5 | #include <errno.h> | 5 | #include <errno.h> |
6 | #include <stdlib.h> | ||
6 | 7 | ||
7 | /* | 8 | /* |
8 | * Used as the default ->buf value, so that people can always assume | 9 | * Used as the default ->buf value, so that people can always assume |
diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c index 90ea2b209cbb..78aa4c3b990d 100644 --- a/tools/perf/util/strfilter.c +++ b/tools/perf/util/strfilter.c | |||
@@ -1,11 +1,12 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "util.h" | ||
3 | #include "string2.h" | 2 | #include "string2.h" |
4 | #include "strfilter.h" | 3 | #include "strfilter.h" |
5 | 4 | ||
6 | #include <errno.h> | 5 | #include <errno.h> |
6 | #include <stdlib.h> | ||
7 | #include <linux/ctype.h> | 7 | #include <linux/ctype.h> |
8 | #include <linux/string.h> | 8 | #include <linux/string.h> |
9 | #include <linux/zalloc.h> | ||
9 | 10 | ||
10 | /* Operators */ | 11 | /* Operators */ |
11 | static const char *OP_and = "&"; /* Logical AND */ | 12 | static const char *OP_and = "&"; /* Logical AND */ |
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index af45c6fd97db..8a868cbeffae 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
@@ -4,12 +4,12 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "strlist.h" | 6 | #include "strlist.h" |
7 | #include "util.h" | ||
8 | #include <errno.h> | 7 | #include <errno.h> |
9 | #include <stdio.h> | 8 | #include <stdio.h> |
10 | #include <stdlib.h> | 9 | #include <stdlib.h> |
11 | #include <string.h> | 10 | #include <string.h> |
12 | #include <unistd.h> | 11 | #include <unistd.h> |
12 | #include <linux/zalloc.h> | ||
13 | 13 | ||
14 | static | 14 | static |
15 | struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) | 15 | struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) |
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c index fab8a048d31b..76cc54000483 100644 --- a/tools/perf/util/svghelper.c +++ b/tools/perf/util/svghelper.c | |||
@@ -15,10 +15,10 @@ | |||
15 | #include <string.h> | 15 | #include <string.h> |
16 | #include <linux/bitmap.h> | 16 | #include <linux/bitmap.h> |
17 | #include <linux/time64.h> | 17 | #include <linux/time64.h> |
18 | #include <linux/zalloc.h> | ||
18 | 19 | ||
19 | #include "perf.h" | 20 | #include "perf.h" |
20 | #include "svghelper.h" | 21 | #include "svghelper.h" |
21 | #include "util.h" | ||
22 | #include "cpumap.h" | 22 | #include "cpumap.h" |
23 | 23 | ||
24 | static u64 first_time, last_time; | 24 | static u64 first_time, last_time; |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 62008756d8cc..7d504dc22108 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <fcntl.h> | 2 | #include <fcntl.h> |
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <errno.h> | 4 | #include <errno.h> |
5 | #include <stdlib.h> | ||
5 | #include <string.h> | 6 | #include <string.h> |
6 | #include <unistd.h> | 7 | #include <unistd.h> |
7 | #include <inttypes.h> | 8 | #include <inttypes.h> |
@@ -16,6 +17,7 @@ | |||
16 | #include "debug.h" | 17 | #include "debug.h" |
17 | #include "util.h" | 18 | #include "util.h" |
18 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
20 | #include <linux/zalloc.h> | ||
19 | #include <symbol/kallsyms.h> | 21 | #include <symbol/kallsyms.h> |
20 | 22 | ||
21 | #ifndef EM_AARCH64 | 23 | #ifndef EM_AARCH64 |
@@ -1476,7 +1478,7 @@ static void kcore_copy__free_phdrs(struct kcore_copy_info *kci) | |||
1476 | struct phdr_data *p, *tmp; | 1478 | struct phdr_data *p, *tmp; |
1477 | 1479 | ||
1478 | list_for_each_entry_safe(p, tmp, &kci->phdrs, node) { | 1480 | list_for_each_entry_safe(p, tmp, &kci->phdrs, node) { |
1479 | list_del(&p->node); | 1481 | list_del_init(&p->node); |
1480 | free(p); | 1482 | free(p); |
1481 | } | 1483 | } |
1482 | } | 1484 | } |
@@ -1499,7 +1501,7 @@ static void kcore_copy__free_syms(struct kcore_copy_info *kci) | |||
1499 | struct sym_data *s, *tmp; | 1501 | struct sym_data *s, *tmp; |
1500 | 1502 | ||
1501 | list_for_each_entry_safe(s, tmp, &kci->syms, node) { | 1503 | list_for_each_entry_safe(s, tmp, &kci->syms, node) { |
1502 | list_del(&s->node); | 1504 | list_del_init(&s->node); |
1503 | free(s); | 1505 | free(s); |
1504 | } | 1506 | } |
1505 | } | 1507 | } |
@@ -2131,11 +2133,11 @@ static int populate_sdt_note(Elf **elf, const char *data, size_t len, | |||
2131 | return 0; | 2133 | return 0; |
2132 | 2134 | ||
2133 | out_free_args: | 2135 | out_free_args: |
2134 | free(tmp->args); | 2136 | zfree(&tmp->args); |
2135 | out_free_name: | 2137 | out_free_name: |
2136 | free(tmp->name); | 2138 | zfree(&tmp->name); |
2137 | out_free_prov: | 2139 | out_free_prov: |
2138 | free(tmp->provider); | 2140 | zfree(&tmp->provider); |
2139 | out_free_note: | 2141 | out_free_note: |
2140 | free(tmp); | 2142 | free(tmp); |
2141 | out_err: | 2143 | out_err: |
@@ -2250,9 +2252,9 @@ int cleanup_sdt_note_list(struct list_head *sdt_notes) | |||
2250 | int nr_free = 0; | 2252 | int nr_free = 0; |
2251 | 2253 | ||
2252 | list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) { | 2254 | list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) { |
2253 | list_del(&pos->note_list); | 2255 | list_del_init(&pos->note_list); |
2254 | free(pos->name); | 2256 | zfree(&pos->name); |
2255 | free(pos->provider); | 2257 | zfree(&pos->provider); |
2256 | free(pos); | 2258 | free(pos); |
2257 | nr_free++; | 2259 | nr_free++; |
2258 | } | 2260 | } |
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 17edbd4f6f85..3bc8b7e3300e 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
@@ -7,9 +7,10 @@ | |||
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | #include <fcntl.h> | 8 | #include <fcntl.h> |
9 | #include <string.h> | 9 | #include <string.h> |
10 | #include <stdlib.h> | ||
10 | #include <byteswap.h> | 11 | #include <byteswap.h> |
11 | #include <sys/stat.h> | 12 | #include <sys/stat.h> |
12 | 13 | #include <linux/zalloc.h> | |
13 | 14 | ||
14 | static bool check_need_swap(int file_endian) | 15 | static bool check_need_swap(int file_endian) |
15 | { | 16 | { |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index ae2ce255e848..173f3378aaa0 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "header.h" | 26 | #include "header.h" |
27 | #include "path.h" | 27 | #include "path.h" |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/zalloc.h> | ||
29 | 30 | ||
30 | #include <elf.h> | 31 | #include <elf.h> |
31 | #include <limits.h> | 32 | #include <limits.h> |
diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index c2037ac533f3..022a9c670338 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c | |||
@@ -10,9 +10,9 @@ | |||
10 | #include <linux/compiler.h> | 10 | #include <linux/compiler.h> |
11 | 11 | ||
12 | #ifdef HAVE_SYSCALL_TABLE_SUPPORT | 12 | #ifdef HAVE_SYSCALL_TABLE_SUPPORT |
13 | #include <linux/zalloc.h> | ||
13 | #include <string.h> | 14 | #include <string.h> |
14 | #include "string2.h" | 15 | #include "string2.h" |
15 | #include "util.h" | ||
16 | 16 | ||
17 | #if defined(__x86_64__) | 17 | #if defined(__x86_64__) |
18 | #include <asm/syscalls_64.c> | 18 | #include <asm/syscalls_64.c> |
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 3852d07c49bd..3adc65480349 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c | |||
@@ -10,9 +10,9 @@ | |||
10 | #include "debug.h" | 10 | #include "debug.h" |
11 | 11 | ||
12 | #include <pwd.h> | 12 | #include <pwd.h> |
13 | #include <stdlib.h> | ||
13 | #include <string.h> | 14 | #include <string.h> |
14 | 15 | ||
15 | |||
16 | enum target_errno target__validate(struct target *target) | 16 | enum target_errno target__validate(struct target *target) |
17 | { | 17 | { |
18 | enum target_errno ret = TARGET_ERRNO__SUCCESS; | 18 | enum target_errno ret = TARGET_ERRNO__SUCCESS; |
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 6ff1ff4d4ce7..15134ac9b8f1 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c | |||
@@ -7,12 +7,13 @@ | |||
7 | #include <linux/rbtree.h> | 7 | #include <linux/rbtree.h> |
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/log2.h> | 9 | #include <linux/log2.h> |
10 | #include <linux/zalloc.h> | ||
10 | #include <errno.h> | 11 | #include <errno.h> |
12 | #include <stdlib.h> | ||
11 | #include "thread.h" | 13 | #include "thread.h" |
12 | #include "event.h" | 14 | #include "event.h" |
13 | #include "machine.h" | 15 | #include "machine.h" |
14 | #include "env.h" | 16 | #include "env.h" |
15 | #include "util.h" | ||
16 | #include "debug.h" | 17 | #include "debug.h" |
17 | #include "symbol.h" | 18 | #include "symbol.h" |
18 | #include "comm.h" | 19 | #include "comm.h" |
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 3e29a4e8b5e6..873ab505ca80 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c | |||
@@ -5,10 +5,10 @@ | |||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <string.h> | 6 | #include <string.h> |
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/zalloc.h> | ||
8 | #include "session.h" | 9 | #include "session.h" |
9 | #include "thread.h" | 10 | #include "thread.h" |
10 | #include "thread-stack.h" | 11 | #include "thread-stack.h" |
11 | #include "util.h" | ||
12 | #include "debug.h" | 12 | #include "debug.h" |
13 | #include "namespaces.h" | 13 | #include "namespaces.h" |
14 | #include "comm.h" | 14 | #include "comm.h" |
@@ -93,14 +93,14 @@ void thread__delete(struct thread *thread) | |||
93 | down_write(&thread->namespaces_lock); | 93 | down_write(&thread->namespaces_lock); |
94 | list_for_each_entry_safe(namespaces, tmp_namespaces, | 94 | list_for_each_entry_safe(namespaces, tmp_namespaces, |
95 | &thread->namespaces_list, list) { | 95 | &thread->namespaces_list, list) { |
96 | list_del(&namespaces->list); | 96 | list_del_init(&namespaces->list); |
97 | namespaces__free(namespaces); | 97 | namespaces__free(namespaces); |
98 | } | 98 | } |
99 | up_write(&thread->namespaces_lock); | 99 | up_write(&thread->namespaces_lock); |
100 | 100 | ||
101 | down_write(&thread->comm_lock); | 101 | down_write(&thread->comm_lock); |
102 | list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { | 102 | list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) { |
103 | list_del(&comm->list); | 103 | list_del_init(&comm->list); |
104 | comm__free(comm); | 104 | comm__free(comm); |
105 | } | 105 | } |
106 | up_write(&thread->comm_lock); | 106 | up_write(&thread->comm_lock); |
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 281bf06f10f2..5b3511f2b6b1 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c | |||
@@ -13,9 +13,9 @@ | |||
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include <api/fs/fs.h> | 14 | #include <api/fs/fs.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/zalloc.h> | ||
16 | #include "asm/bug.h" | 17 | #include "asm/bug.h" |
17 | #include "thread_map.h" | 18 | #include "thread_map.h" |
18 | #include "util.h" | ||
19 | #include "debug.h" | 19 | #include "debug.h" |
20 | #include "event.h" | 20 | #include "event.h" |
21 | 21 | ||
@@ -480,7 +480,7 @@ int thread_map__remove(struct thread_map *threads, int idx) | |||
480 | /* | 480 | /* |
481 | * Free the 'idx' item and shift the rest up. | 481 | * Free the 'idx' item and shift the rest up. |
482 | */ | 482 | */ |
483 | free(threads->map[idx].comm); | 483 | zfree(&threads->map[idx].comm); |
484 | 484 | ||
485 | for (i = idx; i < threads->nr - 1; i++) | 485 | for (i = idx; i < threads->nr - 1; i++) |
486 | threads->map[i] = threads->map[i + 1]; | 486 | threads->map[i] = threads->map[i + 1]; |
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 806a11b334d3..4550015b9d5d 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <stdbool.h> | 18 | #include <stdbool.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/zalloc.h> | ||
21 | 22 | ||
22 | #include "../perf.h" | 23 | #include "../perf.h" |
23 | #include "trace-event.h" | 24 | #include "trace-event.h" |
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index b023db136ef3..ba58f69777a1 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
@@ -12,8 +12,8 @@ | |||
12 | 12 | ||
13 | #include "../perf.h" | 13 | #include "../perf.h" |
14 | #include "debug.h" | 14 | #include "debug.h" |
15 | #include "util.h" | ||
16 | #include "trace-event.h" | 15 | #include "trace-event.h" |
16 | #include <linux/zalloc.h> | ||
17 | 17 | ||
18 | struct scripting_context *scripting_context; | 18 | struct scripting_context *scripting_context; |
19 | 19 | ||
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index d9b0a942090a..c7002fe11673 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
@@ -81,6 +81,9 @@ struct scripting_ops { | |||
81 | struct perf_sample *sample, | 81 | struct perf_sample *sample, |
82 | struct perf_evsel *evsel, | 82 | struct perf_evsel *evsel, |
83 | struct addr_location *al); | 83 | struct addr_location *al); |
84 | void (*process_switch)(union perf_event *event, | ||
85 | struct perf_sample *sample, | ||
86 | struct machine *machine); | ||
84 | void (*process_stat)(struct perf_stat_config *config, | 87 | void (*process_stat)(struct perf_stat_config *config, |
85 | struct perf_evsel *evsel, u64 tstamp); | 88 | struct perf_evsel *evsel, u64 tstamp); |
86 | void (*process_stat_interval)(u64 tstamp); | 89 | void (*process_stat_interval)(u64 tstamp); |
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 407d0167b942..28f71ca6ce1c 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "symbol.h" | 12 | #include "symbol.h" |
13 | #include "thread.h" | 13 | #include "thread.h" |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/zalloc.h> | ||
15 | #include "event.h" | 16 | #include "event.h" |
16 | #include "perf_regs.h" | 17 | #include "perf_regs.h" |
17 | #include "callchain.h" | 18 | #include "callchain.h" |
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 25e1406b1f8b..71a788921b62 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <unistd.h> | 25 | #include <unistd.h> |
26 | #include <sys/mman.h> | 26 | #include <sys/mman.h> |
27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
28 | #include <linux/zalloc.h> | ||
28 | #ifndef REMOTE_UNWIND_LIBUNWIND | 29 | #ifndef REMOTE_UNWIND_LIBUNWIND |
29 | #include <libunwind.h> | 30 | #include <libunwind.h> |
30 | #include <libunwind-ptrace.h> | 31 | #include <libunwind-ptrace.h> |
@@ -345,7 +346,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso, | |||
345 | __func__, | 346 | __func__, |
346 | dso->symsrc_filename, | 347 | dso->symsrc_filename, |
347 | debuglink); | 348 | debuglink); |
348 | free(dso->symsrc_filename); | 349 | zfree(&dso->symsrc_filename); |
349 | } | 350 | } |
350 | dso->symsrc_filename = debuglink; | 351 | dso->symsrc_filename = debuglink; |
351 | } else { | 352 | } else { |
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c index 070d25ceea6a..3949a60b00ae 100644 --- a/tools/perf/util/usage.c +++ b/tools/perf/util/usage.c | |||
@@ -9,6 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | #include "util.h" | 10 | #include "util.h" |
11 | #include "debug.h" | 11 | #include "debug.h" |
12 | #include <stdio.h> | ||
13 | #include <stdlib.h> | ||
14 | #include <linux/compiler.h> | ||
12 | 15 | ||
13 | static __noreturn void usage_builtin(const char *err) | 16 | static __noreturn void usage_builtin(const char *err) |
14 | { | 17 | { |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 125e215dd3d8..dc7a469921e9 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #include <fcntl.h> | 9 | #include <fcntl.h> |
10 | #include <stdbool.h> | 10 | #include <stdbool.h> |
11 | #include <stddef.h> | 11 | #include <stddef.h> |
12 | #include <stdlib.h> | ||
13 | #include <stdarg.h> | ||
14 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
15 | #include <sys/types.h> | 13 | #include <sys/types.h> |
16 | 14 | ||
@@ -18,13 +16,6 @@ | |||
18 | void usage(const char *err) __noreturn; | 16 | void usage(const char *err) __noreturn; |
19 | void die(const char *err, ...) __noreturn __printf(1, 2); | 17 | void die(const char *err, ...) __noreturn __printf(1, 2); |
20 | 18 | ||
21 | static inline void *zalloc(size_t size) | ||
22 | { | ||
23 | return calloc(1, size); | ||
24 | } | ||
25 | |||
26 | #define zfree(ptr) ({ free(*ptr); *ptr = NULL; }) | ||
27 | |||
28 | struct dirent; | 19 | struct dirent; |
29 | struct nsinfo; | 20 | struct nsinfo; |
30 | struct strlist; | 21 | struct strlist; |
@@ -59,18 +50,10 @@ int fetch_kernel_version(unsigned int *puint, | |||
59 | 50 | ||
60 | const char *perf_tip(const char *dirpath); | 51 | const char *perf_tip(const char *dirpath); |
61 | 52 | ||
62 | #ifndef HAVE_GET_CURRENT_DIR_NAME | ||
63 | char *get_current_dir_name(void); | ||
64 | #endif | ||
65 | |||
66 | #ifndef HAVE_SCHED_GETCPU_SUPPORT | 53 | #ifndef HAVE_SCHED_GETCPU_SUPPORT |
67 | int sched_getcpu(void); | 54 | int sched_getcpu(void); |
68 | #endif | 55 | #endif |
69 | 56 | ||
70 | #ifndef HAVE_SETNS_SUPPORT | ||
71 | int setns(int fd, int nstype); | ||
72 | #endif | ||
73 | |||
74 | extern bool perf_singlethreaded; | 57 | extern bool perf_singlethreaded; |
75 | 58 | ||
76 | void perf_set_singlethreaded(void); | 59 | void perf_set_singlethreaded(void); |
diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 4b7a303e4ba8..c59154e2d124 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c | |||
@@ -3,8 +3,8 @@ | |||
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <errno.h> | 5 | #include <errno.h> |
6 | #include <linux/zalloc.h> | ||
6 | 7 | ||
7 | #include "util.h" | ||
8 | #include "values.h" | 8 | #include "values.h" |
9 | #include "debug.h" | 9 | #include "debug.h" |
10 | 10 | ||
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 5031b7b22bbd..7f427bab6c12 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "machine.h" | 16 | #include "machine.h" |
17 | #include "thread.h" | 17 | #include "thread.h" |
18 | #include "linux/string.h" | 18 | #include "linux/string.h" |
19 | #include <linux/zalloc.h> | ||
19 | #include "debug.h" | 20 | #include "debug.h" |
20 | 21 | ||
21 | /* | 22 | /* |
diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c index dc95154f5646..86889ebc3514 100644 --- a/tools/perf/util/xyarray.c +++ b/tools/perf/util/xyarray.c | |||
@@ -1,8 +1,8 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include "xyarray.h" | 2 | #include "xyarray.h" |
3 | #include "util.h" | ||
4 | #include <stdlib.h> | 3 | #include <stdlib.h> |
5 | #include <string.h> | 4 | #include <string.h> |
5 | #include <linux/zalloc.h> | ||
6 | 6 | ||
7 | struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size) | 7 | struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size) |
8 | { | 8 | { |
diff --git a/tools/power/cpupower/debug/kernel/Makefile b/tools/power/cpupower/debug/kernel/Makefile index c23e5a6ceb7e..7b5c43684be1 100644 --- a/tools/power/cpupower/debug/kernel/Makefile +++ b/tools/power/cpupower/debug/kernel/Makefile | |||
@@ -12,8 +12,8 @@ default: | |||
12 | $(MAKE) -C $(KDIR) M=$(CURDIR) | 12 | $(MAKE) -C $(KDIR) M=$(CURDIR) |
13 | 13 | ||
14 | clean: | 14 | clean: |
15 | - rm -rf *.o *.ko .tmp-versions .*.cmd .*.mod.* *.mod.c | 15 | - rm -rf *.o *.ko .*.cmd .*.mod.* *.mod.c |
16 | - rm -rf .tmp_versions* Module.symvers modules.order | 16 | - rm -rf Module.symvers modules.order |
17 | 17 | ||
18 | install: default | 18 | install: default |
19 | install -d $(KMISC) | 19 | install -d $(KMISC) |
diff --git a/tools/power/x86/intel-speed-select/.gitignore b/tools/power/x86/intel-speed-select/.gitignore new file mode 100644 index 000000000000..f61145925ce9 --- /dev/null +++ b/tools/power/x86/intel-speed-select/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | include/ | ||
2 | intel-speed-select | ||
diff --git a/tools/power/x86/intel-speed-select/Build b/tools/power/x86/intel-speed-select/Build new file mode 100644 index 000000000000..b61456d75190 --- /dev/null +++ b/tools/power/x86/intel-speed-select/Build | |||
@@ -0,0 +1 @@ | |||
intel-speed-select-y += isst-config.o isst-core.o isst-display.o | |||
diff --git a/tools/power/x86/intel-speed-select/Makefile b/tools/power/x86/intel-speed-select/Makefile new file mode 100644 index 000000000000..12c6939dca2a --- /dev/null +++ b/tools/power/x86/intel-speed-select/Makefile | |||
@@ -0,0 +1,56 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | include ../../../scripts/Makefile.include | ||
3 | |||
4 | bindir ?= /usr/bin | ||
5 | |||
6 | ifeq ($(srctree),) | ||
7 | srctree := $(patsubst %/,%,$(dir $(CURDIR))) | ||
8 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
9 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
10 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
11 | endif | ||
12 | |||
13 | # Do not use make's built-in rules | ||
14 | # (this improves performance and avoids hard-to-debug behaviour); | ||
15 | MAKEFLAGS += -r | ||
16 | |||
17 | override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | ||
18 | |||
19 | ALL_TARGETS := intel-speed-select | ||
20 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) | ||
21 | |||
22 | all: $(ALL_PROGRAMS) | ||
23 | |||
24 | export srctree OUTPUT CC LD CFLAGS | ||
25 | include $(srctree)/tools/build/Makefile.include | ||
26 | |||
27 | # | ||
28 | # We need the following to be outside of kernel tree | ||
29 | # | ||
30 | $(OUTPUT)include/linux/isst_if.h: ../../../../include/uapi/linux/isst_if.h | ||
31 | mkdir -p $(OUTPUT)include/linux 2>&1 || true | ||
32 | ln -sf $(CURDIR)/../../../../include/uapi/linux/isst_if.h $@ | ||
33 | |||
34 | prepare: $(OUTPUT)include/linux/isst_if.h | ||
35 | |||
36 | ISST_IN := $(OUTPUT)intel-speed-select-in.o | ||
37 | |||
38 | $(ISST_IN): prepare FORCE | ||
39 | $(Q)$(MAKE) $(build)=intel-speed-select | ||
40 | $(OUTPUT)intel-speed-select: $(ISST_IN) | ||
41 | $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ | ||
42 | |||
43 | clean: | ||
44 | rm -f $(ALL_PROGRAMS) | ||
45 | rm -rf $(OUTPUT)include/linux/isst_if.h | ||
46 | find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete | ||
47 | |||
48 | install: $(ALL_PROGRAMS) | ||
49 | install -d -m 755 $(DESTDIR)$(bindir); \ | ||
50 | for program in $(ALL_PROGRAMS); do \ | ||
51 | install $$program $(DESTDIR)$(bindir); \ | ||
52 | done | ||
53 | |||
54 | FORCE: | ||
55 | |||
56 | .PHONY: all install clean FORCE prepare | ||
diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c new file mode 100644 index 000000000000..91c5ad1685a1 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst-config.c | |||
@@ -0,0 +1,1607 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Intel Speed Select -- Enumerate and control features | ||
4 | * Copyright (c) 2019 Intel Corporation. | ||
5 | */ | ||
6 | |||
7 | #include <linux/isst_if.h> | ||
8 | |||
9 | #include "isst.h" | ||
10 | |||
11 | struct process_cmd_struct { | ||
12 | char *feature; | ||
13 | char *command; | ||
14 | void (*process_fn)(void); | ||
15 | }; | ||
16 | |||
17 | static const char *version_str = "v1.0"; | ||
18 | static const int supported_api_ver = 1; | ||
19 | static struct isst_if_platform_info isst_platform_info; | ||
20 | static char *progname; | ||
21 | static int debug_flag; | ||
22 | static FILE *outf; | ||
23 | |||
24 | static int cpu_model; | ||
25 | |||
26 | #define MAX_CPUS_IN_ONE_REQ 64 | ||
27 | static short max_target_cpus; | ||
28 | static unsigned short target_cpus[MAX_CPUS_IN_ONE_REQ]; | ||
29 | |||
30 | static int topo_max_cpus; | ||
31 | static size_t present_cpumask_size; | ||
32 | static cpu_set_t *present_cpumask; | ||
33 | static size_t target_cpumask_size; | ||
34 | static cpu_set_t *target_cpumask; | ||
35 | static int tdp_level = 0xFF; | ||
36 | static int fact_bucket = 0xFF; | ||
37 | static int fact_avx = 0xFF; | ||
38 | static unsigned long long fact_trl; | ||
39 | static int out_format_json; | ||
40 | static int cmd_help; | ||
41 | |||
42 | /* clos related */ | ||
43 | static int current_clos = -1; | ||
44 | static int clos_epp = -1; | ||
45 | static int clos_prop_prio = -1; | ||
46 | static int clos_min = -1; | ||
47 | static int clos_max = -1; | ||
48 | static int clos_desired = -1; | ||
49 | static int clos_priority_type; | ||
50 | |||
51 | struct _cpu_map { | ||
52 | unsigned short core_id; | ||
53 | unsigned short pkg_id; | ||
54 | unsigned short die_id; | ||
55 | unsigned short punit_cpu; | ||
56 | unsigned short punit_cpu_core; | ||
57 | }; | ||
58 | struct _cpu_map *cpu_map; | ||
59 | |||
60 | void debug_printf(const char *format, ...) | ||
61 | { | ||
62 | va_list args; | ||
63 | |||
64 | va_start(args, format); | ||
65 | |||
66 | if (debug_flag) | ||
67 | vprintf(format, args); | ||
68 | |||
69 | va_end(args); | ||
70 | } | ||
71 | |||
72 | static void update_cpu_model(void) | ||
73 | { | ||
74 | unsigned int ebx, ecx, edx; | ||
75 | unsigned int fms, family; | ||
76 | |||
77 | __cpuid(1, fms, ebx, ecx, edx); | ||
78 | family = (fms >> 8) & 0xf; | ||
79 | cpu_model = (fms >> 4) & 0xf; | ||
80 | if (family == 6 || family == 0xf) | ||
81 | cpu_model += ((fms >> 16) & 0xf) << 4; | ||
82 | } | ||
83 | |||
84 | /* Open a file, and exit on failure */ | ||
85 | static FILE *fopen_or_exit(const char *path, const char *mode) | ||
86 | { | ||
87 | FILE *filep = fopen(path, mode); | ||
88 | |||
89 | if (!filep) | ||
90 | err(1, "%s: open failed", path); | ||
91 | |||
92 | return filep; | ||
93 | } | ||
94 | |||
95 | /* Parse a file containing a single int */ | ||
96 | static int parse_int_file(int fatal, const char *fmt, ...) | ||
97 | { | ||
98 | va_list args; | ||
99 | char path[PATH_MAX]; | ||
100 | FILE *filep; | ||
101 | int value; | ||
102 | |||
103 | va_start(args, fmt); | ||
104 | vsnprintf(path, sizeof(path), fmt, args); | ||
105 | va_end(args); | ||
106 | if (fatal) { | ||
107 | filep = fopen_or_exit(path, "r"); | ||
108 | } else { | ||
109 | filep = fopen(path, "r"); | ||
110 | if (!filep) | ||
111 | return -1; | ||
112 | } | ||
113 | if (fscanf(filep, "%d", &value) != 1) | ||
114 | err(1, "%s: failed to parse number from file", path); | ||
115 | fclose(filep); | ||
116 | |||
117 | return value; | ||
118 | } | ||
119 | |||
120 | int cpufreq_sysfs_present(void) | ||
121 | { | ||
122 | DIR *dir; | ||
123 | |||
124 | dir = opendir("/sys/devices/system/cpu/cpu0/cpufreq"); | ||
125 | if (dir) { | ||
126 | closedir(dir); | ||
127 | return 1; | ||
128 | } | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | int out_format_is_json(void) | ||
134 | { | ||
135 | return out_format_json; | ||
136 | } | ||
137 | |||
138 | int get_physical_package_id(int cpu) | ||
139 | { | ||
140 | return parse_int_file( | ||
141 | 1, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", | ||
142 | cpu); | ||
143 | } | ||
144 | |||
145 | int get_physical_core_id(int cpu) | ||
146 | { | ||
147 | return parse_int_file( | ||
148 | 1, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); | ||
149 | } | ||
150 | |||
151 | int get_physical_die_id(int cpu) | ||
152 | { | ||
153 | int ret; | ||
154 | |||
155 | ret = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/topology/die_id", | ||
156 | cpu); | ||
157 | if (ret < 0) | ||
158 | ret = 0; | ||
159 | |||
160 | return ret; | ||
161 | } | ||
162 | |||
163 | int get_topo_max_cpus(void) | ||
164 | { | ||
165 | return topo_max_cpus; | ||
166 | } | ||
167 | |||
168 | #define MAX_PACKAGE_COUNT 8 | ||
169 | #define MAX_DIE_PER_PACKAGE 2 | ||
170 | static void for_each_online_package_in_set(void (*callback)(int, void *, void *, | ||
171 | void *, void *), | ||
172 | void *arg1, void *arg2, void *arg3, | ||
173 | void *arg4) | ||
174 | { | ||
175 | int max_packages[MAX_PACKAGE_COUNT * MAX_PACKAGE_COUNT]; | ||
176 | int pkg_index = 0, i; | ||
177 | |||
178 | memset(max_packages, 0xff, sizeof(max_packages)); | ||
179 | for (i = 0; i < topo_max_cpus; ++i) { | ||
180 | int j, online, pkg_id, die_id = 0, skip = 0; | ||
181 | |||
182 | if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) | ||
183 | continue; | ||
184 | if (i) | ||
185 | online = parse_int_file( | ||
186 | 1, "/sys/devices/system/cpu/cpu%d/online", i); | ||
187 | else | ||
188 | online = | ||
189 | 1; /* online entry for CPU 0 needs some special configs */ | ||
190 | |||
191 | die_id = get_physical_die_id(i); | ||
192 | if (die_id < 0) | ||
193 | die_id = 0; | ||
194 | pkg_id = get_physical_package_id(i); | ||
195 | /* Create an unique id for package, die combination to store */ | ||
196 | pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id); | ||
197 | |||
198 | for (j = 0; j < pkg_index; ++j) { | ||
199 | if (max_packages[j] == pkg_id) { | ||
200 | skip = 1; | ||
201 | break; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | if (!skip && online && callback) { | ||
206 | callback(i, arg1, arg2, arg3, arg4); | ||
207 | max_packages[pkg_index++] = pkg_id; | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | static void for_each_online_target_cpu_in_set( | ||
213 | void (*callback)(int, void *, void *, void *, void *), void *arg1, | ||
214 | void *arg2, void *arg3, void *arg4) | ||
215 | { | ||
216 | int i; | ||
217 | |||
218 | for (i = 0; i < topo_max_cpus; ++i) { | ||
219 | int online; | ||
220 | |||
221 | if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) | ||
222 | continue; | ||
223 | if (i) | ||
224 | online = parse_int_file( | ||
225 | 1, "/sys/devices/system/cpu/cpu%d/online", i); | ||
226 | else | ||
227 | online = | ||
228 | 1; /* online entry for CPU 0 needs some special configs */ | ||
229 | |||
230 | if (online && callback) | ||
231 | callback(i, arg1, arg2, arg3, arg4); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | #define BITMASK_SIZE 32 | ||
236 | static void set_max_cpu_num(void) | ||
237 | { | ||
238 | FILE *filep; | ||
239 | unsigned long dummy; | ||
240 | |||
241 | topo_max_cpus = 0; | ||
242 | filep = fopen_or_exit( | ||
243 | "/sys/devices/system/cpu/cpu0/topology/thread_siblings", "r"); | ||
244 | while (fscanf(filep, "%lx,", &dummy) == 1) | ||
245 | topo_max_cpus += BITMASK_SIZE; | ||
246 | fclose(filep); | ||
247 | topo_max_cpus--; /* 0 based */ | ||
248 | |||
249 | debug_printf("max cpus %d\n", topo_max_cpus); | ||
250 | } | ||
251 | |||
252 | size_t alloc_cpu_set(cpu_set_t **cpu_set) | ||
253 | { | ||
254 | cpu_set_t *_cpu_set; | ||
255 | size_t size; | ||
256 | |||
257 | _cpu_set = CPU_ALLOC((topo_max_cpus + 1)); | ||
258 | if (_cpu_set == NULL) | ||
259 | err(3, "CPU_ALLOC"); | ||
260 | size = CPU_ALLOC_SIZE((topo_max_cpus + 1)); | ||
261 | CPU_ZERO_S(size, _cpu_set); | ||
262 | |||
263 | *cpu_set = _cpu_set; | ||
264 | return size; | ||
265 | } | ||
266 | |||
267 | void free_cpu_set(cpu_set_t *cpu_set) | ||
268 | { | ||
269 | CPU_FREE(cpu_set); | ||
270 | } | ||
271 | |||
272 | static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; | ||
273 | static void set_cpu_present_cpu_mask(void) | ||
274 | { | ||
275 | size_t size; | ||
276 | DIR *dir; | ||
277 | int i; | ||
278 | |||
279 | size = alloc_cpu_set(&present_cpumask); | ||
280 | present_cpumask_size = size; | ||
281 | for (i = 0; i < topo_max_cpus; ++i) { | ||
282 | char buffer[256]; | ||
283 | |||
284 | snprintf(buffer, sizeof(buffer), | ||
285 | "/sys/devices/system/cpu/cpu%d", i); | ||
286 | dir = opendir(buffer); | ||
287 | if (dir) { | ||
288 | int pkg_id, die_id; | ||
289 | |||
290 | CPU_SET_S(i, size, present_cpumask); | ||
291 | die_id = get_physical_die_id(i); | ||
292 | if (die_id < 0) | ||
293 | die_id = 0; | ||
294 | |||
295 | pkg_id = get_physical_package_id(i); | ||
296 | if (pkg_id < MAX_PACKAGE_COUNT && | ||
297 | die_id < MAX_DIE_PER_PACKAGE) | ||
298 | cpu_cnt[pkg_id][die_id]++; | ||
299 | } | ||
300 | closedir(dir); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | int get_cpu_count(int pkg_id, int die_id) | ||
305 | { | ||
306 | if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) | ||
307 | return cpu_cnt[pkg_id][die_id] + 1; | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static void set_cpu_target_cpu_mask(void) | ||
313 | { | ||
314 | size_t size; | ||
315 | int i; | ||
316 | |||
317 | size = alloc_cpu_set(&target_cpumask); | ||
318 | target_cpumask_size = size; | ||
319 | for (i = 0; i < max_target_cpus; ++i) { | ||
320 | if (!CPU_ISSET_S(target_cpus[i], present_cpumask_size, | ||
321 | present_cpumask)) | ||
322 | continue; | ||
323 | |||
324 | CPU_SET_S(target_cpus[i], size, target_cpumask); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | static void create_cpu_map(void) | ||
329 | { | ||
330 | const char *pathname = "/dev/isst_interface"; | ||
331 | int i, fd = 0; | ||
332 | struct isst_if_cpu_maps map; | ||
333 | |||
334 | cpu_map = malloc(sizeof(*cpu_map) * topo_max_cpus); | ||
335 | if (!cpu_map) | ||
336 | err(3, "cpumap"); | ||
337 | |||
338 | fd = open(pathname, O_RDWR); | ||
339 | if (fd < 0) | ||
340 | err(-1, "%s open failed", pathname); | ||
341 | |||
342 | for (i = 0; i < topo_max_cpus; ++i) { | ||
343 | if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) | ||
344 | continue; | ||
345 | |||
346 | map.cmd_count = 1; | ||
347 | map.cpu_map[0].logical_cpu = i; | ||
348 | |||
349 | debug_printf(" map logical_cpu:%d\n", | ||
350 | map.cpu_map[0].logical_cpu); | ||
351 | if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) { | ||
352 | perror("ISST_IF_GET_PHY_ID"); | ||
353 | fprintf(outf, "Error: map logical_cpu:%d\n", | ||
354 | map.cpu_map[0].logical_cpu); | ||
355 | continue; | ||
356 | } | ||
357 | cpu_map[i].core_id = get_physical_core_id(i); | ||
358 | cpu_map[i].pkg_id = get_physical_package_id(i); | ||
359 | cpu_map[i].die_id = get_physical_die_id(i); | ||
360 | cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu; | ||
361 | cpu_map[i].punit_cpu_core = (map.cpu_map[0].physical_cpu >> | ||
362 | 1); // shift to get core id | ||
363 | |||
364 | debug_printf( | ||
365 | "map logical_cpu:%d core: %d die:%d pkg:%d punit_cpu:%d punit_core:%d\n", | ||
366 | i, cpu_map[i].core_id, cpu_map[i].die_id, | ||
367 | cpu_map[i].pkg_id, cpu_map[i].punit_cpu, | ||
368 | cpu_map[i].punit_cpu_core); | ||
369 | } | ||
370 | |||
371 | if (fd) | ||
372 | close(fd); | ||
373 | } | ||
374 | |||
375 | int find_logical_cpu(int pkg_id, int die_id, int punit_core_id) | ||
376 | { | ||
377 | int i; | ||
378 | |||
379 | for (i = 0; i < topo_max_cpus; ++i) { | ||
380 | if (cpu_map[i].pkg_id == pkg_id && | ||
381 | cpu_map[i].die_id == die_id && | ||
382 | cpu_map[i].punit_cpu_core == punit_core_id) | ||
383 | return i; | ||
384 | } | ||
385 | |||
386 | return -EINVAL; | ||
387 | } | ||
388 | |||
389 | void set_cpu_mask_from_punit_coremask(int cpu, unsigned long long core_mask, | ||
390 | size_t core_cpumask_size, | ||
391 | cpu_set_t *core_cpumask, int *cpu_cnt) | ||
392 | { | ||
393 | int i, cnt = 0; | ||
394 | int die_id, pkg_id; | ||
395 | |||
396 | *cpu_cnt = 0; | ||
397 | die_id = get_physical_die_id(cpu); | ||
398 | pkg_id = get_physical_package_id(cpu); | ||
399 | |||
400 | for (i = 0; i < 64; ++i) { | ||
401 | if (core_mask & BIT(i)) { | ||
402 | int j; | ||
403 | |||
404 | for (j = 0; j < topo_max_cpus; ++j) { | ||
405 | if (cpu_map[j].pkg_id == pkg_id && | ||
406 | cpu_map[j].die_id == die_id && | ||
407 | cpu_map[j].punit_cpu_core == i) { | ||
408 | CPU_SET_S(j, core_cpumask_size, | ||
409 | core_cpumask); | ||
410 | ++cnt; | ||
411 | } | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | |||
416 | *cpu_cnt = cnt; | ||
417 | } | ||
418 | |||
419 | int find_phy_core_num(int logical_cpu) | ||
420 | { | ||
421 | if (logical_cpu < topo_max_cpus) | ||
422 | return cpu_map[logical_cpu].punit_cpu_core; | ||
423 | |||
424 | return -EINVAL; | ||
425 | } | ||
426 | |||
427 | static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, | ||
428 | unsigned int *value) | ||
429 | { | ||
430 | struct isst_if_io_regs io_regs; | ||
431 | const char *pathname = "/dev/isst_interface"; | ||
432 | int cmd; | ||
433 | int fd; | ||
434 | |||
435 | debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); | ||
436 | |||
437 | fd = open(pathname, O_RDWR); | ||
438 | if (fd < 0) | ||
439 | err(-1, "%s open failed", pathname); | ||
440 | |||
441 | io_regs.req_count = 1; | ||
442 | io_regs.io_reg[0].logical_cpu = cpu; | ||
443 | io_regs.io_reg[0].reg = reg; | ||
444 | cmd = ISST_IF_IO_CMD; | ||
445 | if (write) { | ||
446 | io_regs.io_reg[0].read_write = 1; | ||
447 | io_regs.io_reg[0].value = *value; | ||
448 | } else { | ||
449 | io_regs.io_reg[0].read_write = 0; | ||
450 | } | ||
451 | |||
452 | if (ioctl(fd, cmd, &io_regs) == -1) { | ||
453 | perror("ISST_IF_IO_CMD"); | ||
454 | fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", | ||
455 | cpu, reg, write); | ||
456 | } else { | ||
457 | if (!write) | ||
458 | *value = io_regs.io_reg[0].value; | ||
459 | |||
460 | debug_printf( | ||
461 | "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", | ||
462 | cpu, reg, write, *value); | ||
463 | } | ||
464 | |||
465 | close(fd); | ||
466 | |||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | int isst_send_mbox_command(unsigned int cpu, unsigned char command, | ||
471 | unsigned char sub_command, unsigned int parameter, | ||
472 | unsigned int req_data, unsigned int *resp) | ||
473 | { | ||
474 | const char *pathname = "/dev/isst_interface"; | ||
475 | int fd; | ||
476 | struct isst_if_mbox_cmds mbox_cmds = { 0 }; | ||
477 | |||
478 | debug_printf( | ||
479 | "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", | ||
480 | cpu, command, sub_command, parameter, req_data); | ||
481 | |||
482 | if (isst_platform_info.mmio_supported && command == CONFIG_CLOS) { | ||
483 | unsigned int value; | ||
484 | int write = 0; | ||
485 | int clos_id, core_id, ret = 0; | ||
486 | |||
487 | debug_printf("CLOS %d\n", cpu); | ||
488 | |||
489 | if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { | ||
490 | value = req_data; | ||
491 | write = 1; | ||
492 | } | ||
493 | |||
494 | switch (sub_command) { | ||
495 | case CLOS_PQR_ASSOC: | ||
496 | core_id = parameter & 0xff; | ||
497 | ret = isst_send_mmio_command( | ||
498 | cpu, PQR_ASSOC_OFFSET + core_id * 4, write, | ||
499 | &value); | ||
500 | if (!ret && !write) | ||
501 | *resp = value; | ||
502 | break; | ||
503 | case CLOS_PM_CLOS: | ||
504 | clos_id = parameter & 0x03; | ||
505 | ret = isst_send_mmio_command( | ||
506 | cpu, PM_CLOS_OFFSET + clos_id * 4, write, | ||
507 | &value); | ||
508 | if (!ret && !write) | ||
509 | *resp = value; | ||
510 | break; | ||
511 | case CLOS_PM_QOS_CONFIG: | ||
512 | ret = isst_send_mmio_command(cpu, PM_QOS_CONFIG_OFFSET, | ||
513 | write, &value); | ||
514 | if (!ret && !write) | ||
515 | *resp = value; | ||
516 | break; | ||
517 | case CLOS_STATUS: | ||
518 | break; | ||
519 | default: | ||
520 | break; | ||
521 | } | ||
522 | return ret; | ||
523 | } | ||
524 | |||
525 | mbox_cmds.cmd_count = 1; | ||
526 | mbox_cmds.mbox_cmd[0].logical_cpu = cpu; | ||
527 | mbox_cmds.mbox_cmd[0].command = command; | ||
528 | mbox_cmds.mbox_cmd[0].sub_command = sub_command; | ||
529 | mbox_cmds.mbox_cmd[0].parameter = parameter; | ||
530 | mbox_cmds.mbox_cmd[0].req_data = req_data; | ||
531 | |||
532 | fd = open(pathname, O_RDWR); | ||
533 | if (fd < 0) | ||
534 | err(-1, "%s open failed", pathname); | ||
535 | |||
536 | if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { | ||
537 | perror("ISST_IF_MBOX_COMMAND"); | ||
538 | fprintf(outf, | ||
539 | "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", | ||
540 | cpu, command, sub_command, parameter, req_data); | ||
541 | } else { | ||
542 | *resp = mbox_cmds.mbox_cmd[0].resp_data; | ||
543 | debug_printf( | ||
544 | "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", | ||
545 | cpu, command, sub_command, parameter, req_data, *resp); | ||
546 | } | ||
547 | |||
548 | close(fd); | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, | ||
554 | unsigned long long *req_resp) | ||
555 | { | ||
556 | struct isst_if_msr_cmds msr_cmds; | ||
557 | const char *pathname = "/dev/isst_interface"; | ||
558 | int fd; | ||
559 | |||
560 | fd = open(pathname, O_RDWR); | ||
561 | if (fd < 0) | ||
562 | err(-1, "%s open failed", pathname); | ||
563 | |||
564 | msr_cmds.cmd_count = 1; | ||
565 | msr_cmds.msr_cmd[0].logical_cpu = cpu; | ||
566 | msr_cmds.msr_cmd[0].msr = msr; | ||
567 | msr_cmds.msr_cmd[0].read_write = write; | ||
568 | if (write) | ||
569 | msr_cmds.msr_cmd[0].data = *req_resp; | ||
570 | |||
571 | if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) { | ||
572 | perror("ISST_IF_MSR_COMMAD"); | ||
573 | fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n", | ||
574 | cpu, msr, write); | ||
575 | } else { | ||
576 | if (!write) | ||
577 | *req_resp = msr_cmds.msr_cmd[0].data; | ||
578 | |||
579 | debug_printf( | ||
580 | "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n", | ||
581 | cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data); | ||
582 | } | ||
583 | |||
584 | close(fd); | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int isst_fill_platform_info(void) | ||
590 | { | ||
591 | const char *pathname = "/dev/isst_interface"; | ||
592 | int fd; | ||
593 | |||
594 | fd = open(pathname, O_RDWR); | ||
595 | if (fd < 0) | ||
596 | err(-1, "%s open failed", pathname); | ||
597 | |||
598 | if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &isst_platform_info) == -1) { | ||
599 | perror("ISST_IF_GET_PLATFORM_INFO"); | ||
600 | close(fd); | ||
601 | return -1; | ||
602 | } | ||
603 | |||
604 | close(fd); | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static void isst_print_platform_information(void) | ||
610 | { | ||
611 | struct isst_if_platform_info platform_info; | ||
612 | const char *pathname = "/dev/isst_interface"; | ||
613 | int fd; | ||
614 | |||
615 | fd = open(pathname, O_RDWR); | ||
616 | if (fd < 0) | ||
617 | err(-1, "%s open failed", pathname); | ||
618 | |||
619 | if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &platform_info) == -1) { | ||
620 | perror("ISST_IF_GET_PLATFORM_INFO"); | ||
621 | } else { | ||
622 | fprintf(outf, "Platform: API version : %d\n", | ||
623 | platform_info.api_version); | ||
624 | fprintf(outf, "Platform: Driver version : %d\n", | ||
625 | platform_info.driver_version); | ||
626 | fprintf(outf, "Platform: mbox supported : %d\n", | ||
627 | platform_info.mbox_supported); | ||
628 | fprintf(outf, "Platform: mmio supported : %d\n", | ||
629 | platform_info.mmio_supported); | ||
630 | } | ||
631 | |||
632 | close(fd); | ||
633 | |||
634 | exit(0); | ||
635 | } | ||
636 | |||
637 | static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
638 | void *arg4) | ||
639 | { | ||
640 | int (*fn_ptr)(int cpu, void *arg); | ||
641 | int ret; | ||
642 | |||
643 | fn_ptr = arg1; | ||
644 | ret = fn_ptr(cpu, arg2); | ||
645 | if (ret) | ||
646 | perror("get_tdp_*"); | ||
647 | else | ||
648 | isst_display_result(cpu, outf, "perf-profile", (char *)arg3, | ||
649 | *(unsigned int *)arg4); | ||
650 | } | ||
651 | |||
652 | #define _get_tdp_level(desc, suffix, object, help) \ | ||
653 | static void get_tdp_##object(void) \ | ||
654 | { \ | ||
655 | struct isst_pkg_ctdp ctdp; \ | ||
656 | \ | ||
657 | if (cmd_help) { \ | ||
658 | fprintf(stderr, \ | ||
659 | "Print %s [No command arguments are required]\n", \ | ||
660 | help); \ | ||
661 | exit(0); \ | ||
662 | } \ | ||
663 | isst_ctdp_display_information_start(outf); \ | ||
664 | if (max_target_cpus) \ | ||
665 | for_each_online_target_cpu_in_set( \ | ||
666 | exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix, \ | ||
667 | &ctdp, desc, &ctdp.object); \ | ||
668 | else \ | ||
669 | for_each_online_package_in_set(exec_on_get_ctdp_cpu, \ | ||
670 | isst_get_ctdp_##suffix, \ | ||
671 | &ctdp, desc, \ | ||
672 | &ctdp.object); \ | ||
673 | isst_ctdp_display_information_end(outf); \ | ||
674 | } | ||
675 | |||
676 | _get_tdp_level("get-config-levels", levels, levels, "TDP levels"); | ||
677 | _get_tdp_level("get-config-version", levels, version, "TDP version"); | ||
678 | _get_tdp_level("get-config-enabled", levels, enabled, "TDP enable status"); | ||
679 | _get_tdp_level("get-config-current_level", levels, current_level, | ||
680 | "Current TDP Level"); | ||
681 | _get_tdp_level("get-lock-status", levels, locked, "TDP lock status"); | ||
682 | |||
683 | static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, | ||
684 | void *arg3, void *arg4) | ||
685 | { | ||
686 | struct isst_pkg_ctdp pkg_dev; | ||
687 | int ret; | ||
688 | |||
689 | memset(&pkg_dev, 0, sizeof(pkg_dev)); | ||
690 | ret = isst_get_process_ctdp(cpu, tdp_level, &pkg_dev); | ||
691 | if (ret) { | ||
692 | perror("isst_get_process_ctdp"); | ||
693 | } else { | ||
694 | isst_ctdp_display_information(cpu, outf, tdp_level, &pkg_dev); | ||
695 | isst_get_process_ctdp_complete(cpu, &pkg_dev); | ||
696 | } | ||
697 | } | ||
698 | |||
699 | static void dump_isst_config(void) | ||
700 | { | ||
701 | if (cmd_help) { | ||
702 | fprintf(stderr, | ||
703 | "Print Intel(R) Speed Select Technology Performance profile configuration\n"); | ||
704 | fprintf(stderr, | ||
705 | "including base frequency and turbo frequency configurations\n"); | ||
706 | fprintf(stderr, "Optional: -l|--level : Specify tdp level\n"); | ||
707 | fprintf(stderr, | ||
708 | "\tIf no arguments, dump information for all TDP levels\n"); | ||
709 | exit(0); | ||
710 | } | ||
711 | |||
712 | isst_ctdp_display_information_start(outf); | ||
713 | |||
714 | if (max_target_cpus) | ||
715 | for_each_online_target_cpu_in_set(dump_isst_config_for_cpu, | ||
716 | NULL, NULL, NULL, NULL); | ||
717 | else | ||
718 | for_each_online_package_in_set(dump_isst_config_for_cpu, NULL, | ||
719 | NULL, NULL, NULL); | ||
720 | |||
721 | isst_ctdp_display_information_end(outf); | ||
722 | } | ||
723 | |||
724 | static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
725 | void *arg4) | ||
726 | { | ||
727 | int ret; | ||
728 | |||
729 | ret = isst_set_tdp_level(cpu, tdp_level); | ||
730 | if (ret) | ||
731 | perror("set_tdp_level_for_cpu"); | ||
732 | else | ||
733 | isst_display_result(cpu, outf, "perf-profile", "set_tdp_level", | ||
734 | ret); | ||
735 | } | ||
736 | |||
737 | static void set_tdp_level(void) | ||
738 | { | ||
739 | if (cmd_help) { | ||
740 | fprintf(stderr, "Set Config TDP level\n"); | ||
741 | fprintf(stderr, | ||
742 | "\t Arguments: -l|--level : Specify tdp level\n"); | ||
743 | exit(0); | ||
744 | } | ||
745 | |||
746 | if (tdp_level == 0xff) { | ||
747 | fprintf(outf, "Invalid command: specify tdp_level\n"); | ||
748 | exit(1); | ||
749 | } | ||
750 | isst_ctdp_display_information_start(outf); | ||
751 | if (max_target_cpus) | ||
752 | for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL, | ||
753 | NULL, NULL, NULL); | ||
754 | else | ||
755 | for_each_online_package_in_set(set_tdp_level_for_cpu, NULL, | ||
756 | NULL, NULL, NULL); | ||
757 | isst_ctdp_display_information_end(outf); | ||
758 | } | ||
759 | |||
760 | static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
761 | void *arg4) | ||
762 | { | ||
763 | struct isst_pbf_info pbf_info; | ||
764 | int ret; | ||
765 | |||
766 | ret = isst_get_pbf_info(cpu, tdp_level, &pbf_info); | ||
767 | if (ret) { | ||
768 | perror("isst_get_pbf_info"); | ||
769 | } else { | ||
770 | isst_pbf_display_information(cpu, outf, tdp_level, &pbf_info); | ||
771 | isst_get_pbf_info_complete(&pbf_info); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static void dump_pbf_config(void) | ||
776 | { | ||
777 | if (cmd_help) { | ||
778 | fprintf(stderr, | ||
779 | "Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n"); | ||
780 | fprintf(stderr, | ||
781 | "\tArguments: -l|--level : Specify tdp level\n"); | ||
782 | exit(0); | ||
783 | } | ||
784 | |||
785 | if (tdp_level == 0xff) { | ||
786 | fprintf(outf, "Invalid command: specify tdp_level\n"); | ||
787 | exit(1); | ||
788 | } | ||
789 | |||
790 | isst_ctdp_display_information_start(outf); | ||
791 | if (max_target_cpus) | ||
792 | for_each_online_target_cpu_in_set(dump_pbf_config_for_cpu, NULL, | ||
793 | NULL, NULL, NULL); | ||
794 | else | ||
795 | for_each_online_package_in_set(dump_pbf_config_for_cpu, NULL, | ||
796 | NULL, NULL, NULL); | ||
797 | isst_ctdp_display_information_end(outf); | ||
798 | } | ||
799 | |||
800 | static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
801 | void *arg4) | ||
802 | { | ||
803 | int ret; | ||
804 | int status = *(int *)arg4; | ||
805 | |||
806 | ret = isst_set_pbf_fact_status(cpu, 1, status); | ||
807 | if (ret) { | ||
808 | perror("isst_set_pbf"); | ||
809 | } else { | ||
810 | if (status) | ||
811 | isst_display_result(cpu, outf, "base-freq", "enable", | ||
812 | ret); | ||
813 | else | ||
814 | isst_display_result(cpu, outf, "base-freq", "disable", | ||
815 | ret); | ||
816 | } | ||
817 | } | ||
818 | |||
819 | static void set_pbf_enable(void) | ||
820 | { | ||
821 | int status = 1; | ||
822 | |||
823 | if (cmd_help) { | ||
824 | fprintf(stderr, | ||
825 | "Enable Intel Speed Select Technology base frequency feature [No command arguments are required]\n"); | ||
826 | exit(0); | ||
827 | } | ||
828 | |||
829 | isst_ctdp_display_information_start(outf); | ||
830 | if (max_target_cpus) | ||
831 | for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, | ||
832 | NULL, &status); | ||
833 | else | ||
834 | for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, | ||
835 | NULL, &status); | ||
836 | isst_ctdp_display_information_end(outf); | ||
837 | } | ||
838 | |||
839 | static void set_pbf_disable(void) | ||
840 | { | ||
841 | int status = 0; | ||
842 | |||
843 | if (cmd_help) { | ||
844 | fprintf(stderr, | ||
845 | "Disable Intel Speed Select Technology base frequency feature [No command arguments are required]\n"); | ||
846 | exit(0); | ||
847 | } | ||
848 | |||
849 | isst_ctdp_display_information_start(outf); | ||
850 | if (max_target_cpus) | ||
851 | for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, | ||
852 | NULL, &status); | ||
853 | else | ||
854 | for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, | ||
855 | NULL, &status); | ||
856 | isst_ctdp_display_information_end(outf); | ||
857 | } | ||
858 | |||
859 | static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2, | ||
860 | void *arg3, void *arg4) | ||
861 | { | ||
862 | struct isst_fact_info fact_info; | ||
863 | int ret; | ||
864 | |||
865 | ret = isst_get_fact_info(cpu, tdp_level, &fact_info); | ||
866 | if (ret) | ||
867 | perror("isst_get_fact_bucket_info"); | ||
868 | else | ||
869 | isst_fact_display_information(cpu, outf, tdp_level, fact_bucket, | ||
870 | fact_avx, &fact_info); | ||
871 | } | ||
872 | |||
873 | static void dump_fact_config(void) | ||
874 | { | ||
875 | if (cmd_help) { | ||
876 | fprintf(stderr, | ||
877 | "Print complete Intel Speed Select Technology turbo frequency configuration for a TDP level. Other arguments are optional.\n"); | ||
878 | fprintf(stderr, | ||
879 | "\tArguments: -l|--level : Specify tdp level\n"); | ||
880 | fprintf(stderr, | ||
881 | "\tArguments: -b|--bucket : Bucket index to dump\n"); | ||
882 | fprintf(stderr, | ||
883 | "\tArguments: -r|--trl-type : Specify trl type: sse|avx2|avx512\n"); | ||
884 | exit(0); | ||
885 | } | ||
886 | |||
887 | if (tdp_level == 0xff) { | ||
888 | fprintf(outf, "Invalid command: specify tdp_level\n"); | ||
889 | exit(1); | ||
890 | } | ||
891 | |||
892 | isst_ctdp_display_information_start(outf); | ||
893 | if (max_target_cpus) | ||
894 | for_each_online_target_cpu_in_set(dump_fact_config_for_cpu, | ||
895 | NULL, NULL, NULL, NULL); | ||
896 | else | ||
897 | for_each_online_package_in_set(dump_fact_config_for_cpu, NULL, | ||
898 | NULL, NULL, NULL); | ||
899 | isst_ctdp_display_information_end(outf); | ||
900 | } | ||
901 | |||
902 | static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
903 | void *arg4) | ||
904 | { | ||
905 | int ret; | ||
906 | int status = *(int *)arg4; | ||
907 | |||
908 | ret = isst_set_pbf_fact_status(cpu, 0, status); | ||
909 | if (ret) | ||
910 | perror("isst_set_fact"); | ||
911 | else { | ||
912 | if (status) { | ||
913 | struct isst_pkg_ctdp pkg_dev; | ||
914 | |||
915 | ret = isst_get_ctdp_levels(cpu, &pkg_dev); | ||
916 | if (ret) { | ||
917 | isst_display_result(cpu, outf, "turbo-freq", | ||
918 | "enable", ret); | ||
919 | return; | ||
920 | } | ||
921 | ret = isst_set_trl(cpu, fact_trl); | ||
922 | isst_display_result(cpu, outf, "turbo-freq", "enable", | ||
923 | ret); | ||
924 | } else { | ||
925 | /* Since we modified TRL during Fact enable, restore it */ | ||
926 | isst_set_trl_from_current_tdp(cpu, fact_trl); | ||
927 | isst_display_result(cpu, outf, "turbo-freq", "disable", | ||
928 | ret); | ||
929 | } | ||
930 | } | ||
931 | } | ||
932 | |||
933 | static void set_fact_enable(void) | ||
934 | { | ||
935 | int status = 1; | ||
936 | |||
937 | if (cmd_help) { | ||
938 | fprintf(stderr, | ||
939 | "Enable Intel Speed Select Technology Turbo frequency feature\n"); | ||
940 | fprintf(stderr, | ||
941 | "Optional: -t|--trl : Specify turbo ratio limit\n"); | ||
942 | exit(0); | ||
943 | } | ||
944 | |||
945 | isst_ctdp_display_information_start(outf); | ||
946 | if (max_target_cpus) | ||
947 | for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, | ||
948 | NULL, &status); | ||
949 | else | ||
950 | for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, | ||
951 | NULL, &status); | ||
952 | isst_ctdp_display_information_end(outf); | ||
953 | } | ||
954 | |||
955 | static void set_fact_disable(void) | ||
956 | { | ||
957 | int status = 0; | ||
958 | |||
959 | if (cmd_help) { | ||
960 | fprintf(stderr, | ||
961 | "Disable Intel Speed Select Technology turbo frequency feature\n"); | ||
962 | fprintf(stderr, | ||
963 | "Optional: -t|--trl : Specify turbo ratio limit\n"); | ||
964 | exit(0); | ||
965 | } | ||
966 | |||
967 | isst_ctdp_display_information_start(outf); | ||
968 | if (max_target_cpus) | ||
969 | for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, | ||
970 | NULL, &status); | ||
971 | else | ||
972 | for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, | ||
973 | NULL, &status); | ||
974 | isst_ctdp_display_information_end(outf); | ||
975 | } | ||
976 | |||
977 | static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, | ||
978 | void *arg4) | ||
979 | { | ||
980 | int ret; | ||
981 | int status = *(int *)arg4; | ||
982 | |||
983 | ret = isst_pm_qos_config(cpu, status, clos_priority_type); | ||
984 | if (ret) { | ||
985 | perror("isst_pm_qos_config"); | ||
986 | } else { | ||
987 | if (status) | ||
988 | isst_display_result(cpu, outf, "core-power", "enable", | ||
989 | ret); | ||
990 | else | ||
991 | isst_display_result(cpu, outf, "core-power", "disable", | ||
992 | ret); | ||
993 | } | ||
994 | } | ||
995 | |||
996 | static void set_clos_enable(void) | ||
997 | { | ||
998 | int status = 1; | ||
999 | |||
1000 | if (cmd_help) { | ||
1001 | fprintf(stderr, "Enable core-power for a package/die\n"); | ||
1002 | fprintf(stderr, | ||
1003 | "\tClos Enable: Specify priority type with [--priority|-p]\n"); | ||
1004 | fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); | ||
1005 | exit(0); | ||
1006 | } | ||
1007 | |||
1008 | if (cpufreq_sysfs_present()) { | ||
1009 | fprintf(stderr, | ||
1010 | "cpufreq subsystem and core-power enable will interfere with each other!\n"); | ||
1011 | } | ||
1012 | |||
1013 | isst_ctdp_display_information_start(outf); | ||
1014 | if (max_target_cpus) | ||
1015 | for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, | ||
1016 | NULL, NULL, &status); | ||
1017 | else | ||
1018 | for_each_online_package_in_set(enable_clos_qos_config, NULL, | ||
1019 | NULL, NULL, &status); | ||
1020 | isst_ctdp_display_information_end(outf); | ||
1021 | } | ||
1022 | |||
1023 | static void set_clos_disable(void) | ||
1024 | { | ||
1025 | int status = 0; | ||
1026 | |||
1027 | if (cmd_help) { | ||
1028 | fprintf(stderr, | ||
1029 | "Disable core-power: [No command arguments are required]\n"); | ||
1030 | exit(0); | ||
1031 | } | ||
1032 | |||
1033 | isst_ctdp_display_information_start(outf); | ||
1034 | if (max_target_cpus) | ||
1035 | for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, | ||
1036 | NULL, NULL, &status); | ||
1037 | else | ||
1038 | for_each_online_package_in_set(enable_clos_qos_config, NULL, | ||
1039 | NULL, NULL, &status); | ||
1040 | isst_ctdp_display_information_end(outf); | ||
1041 | } | ||
1042 | |||
1043 | static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2, | ||
1044 | void *arg3, void *arg4) | ||
1045 | { | ||
1046 | struct isst_clos_config clos_config; | ||
1047 | int ret; | ||
1048 | |||
1049 | ret = isst_pm_get_clos(cpu, current_clos, &clos_config); | ||
1050 | if (ret) | ||
1051 | perror("isst_pm_get_clos"); | ||
1052 | else | ||
1053 | isst_clos_display_information(cpu, outf, current_clos, | ||
1054 | &clos_config); | ||
1055 | } | ||
1056 | |||
1057 | static void dump_clos_config(void) | ||
1058 | { | ||
1059 | if (cmd_help) { | ||
1060 | fprintf(stderr, | ||
1061 | "Print Intel Speed Select Technology core power configuration\n"); | ||
1062 | fprintf(stderr, | ||
1063 | "\tArguments: [-c | --clos]: Specify clos id\n"); | ||
1064 | exit(0); | ||
1065 | } | ||
1066 | if (current_clos < 0 || current_clos > 3) { | ||
1067 | fprintf(stderr, "Invalid clos id\n"); | ||
1068 | exit(0); | ||
1069 | } | ||
1070 | |||
1071 | isst_ctdp_display_information_start(outf); | ||
1072 | if (max_target_cpus) | ||
1073 | for_each_online_target_cpu_in_set(dump_clos_config_for_cpu, | ||
1074 | NULL, NULL, NULL, NULL); | ||
1075 | else | ||
1076 | for_each_online_package_in_set(dump_clos_config_for_cpu, NULL, | ||
1077 | NULL, NULL, NULL); | ||
1078 | isst_ctdp_display_information_end(outf); | ||
1079 | } | ||
1080 | |||
1081 | static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
1082 | void *arg4) | ||
1083 | { | ||
1084 | struct isst_clos_config clos_config; | ||
1085 | int ret; | ||
1086 | |||
1087 | clos_config.pkg_id = get_physical_package_id(cpu); | ||
1088 | clos_config.die_id = get_physical_die_id(cpu); | ||
1089 | |||
1090 | clos_config.epp = clos_epp; | ||
1091 | clos_config.clos_prop_prio = clos_prop_prio; | ||
1092 | clos_config.clos_min = clos_min; | ||
1093 | clos_config.clos_max = clos_max; | ||
1094 | clos_config.clos_desired = clos_desired; | ||
1095 | ret = isst_set_clos(cpu, current_clos, &clos_config); | ||
1096 | if (ret) | ||
1097 | perror("isst_set_clos"); | ||
1098 | else | ||
1099 | isst_display_result(cpu, outf, "core-power", "config", ret); | ||
1100 | } | ||
1101 | |||
1102 | static void set_clos_config(void) | ||
1103 | { | ||
1104 | if (cmd_help) { | ||
1105 | fprintf(stderr, | ||
1106 | "Set core-power configuration for one of the four clos ids\n"); | ||
1107 | fprintf(stderr, | ||
1108 | "\tSpecify targeted clos id with [--clos|-c]\n"); | ||
1109 | fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n"); | ||
1110 | fprintf(stderr, | ||
1111 | "\tSpecify clos Proportional Priority [--weight|-w]\n"); | ||
1112 | fprintf(stderr, "\tSpecify clos min with [--min|-n]\n"); | ||
1113 | fprintf(stderr, "\tSpecify clos max with [--max|-m]\n"); | ||
1114 | fprintf(stderr, "\tSpecify clos desired with [--desired|-d]\n"); | ||
1115 | exit(0); | ||
1116 | } | ||
1117 | |||
1118 | if (current_clos < 0 || current_clos > 3) { | ||
1119 | fprintf(stderr, "Invalid clos id\n"); | ||
1120 | exit(0); | ||
1121 | } | ||
1122 | if (clos_epp < 0 || clos_epp > 0x0F) { | ||
1123 | fprintf(stderr, "clos epp is not specified, default: 0\n"); | ||
1124 | clos_epp = 0; | ||
1125 | } | ||
1126 | if (clos_prop_prio < 0 || clos_prop_prio > 0x0F) { | ||
1127 | fprintf(stderr, | ||
1128 | "clos frequency weight is not specified, default: 0\n"); | ||
1129 | clos_prop_prio = 0; | ||
1130 | } | ||
1131 | if (clos_min < 0) { | ||
1132 | fprintf(stderr, "clos min is not specified, default: 0\n"); | ||
1133 | clos_min = 0; | ||
1134 | } | ||
1135 | if (clos_max < 0) { | ||
1136 | fprintf(stderr, "clos max is not specified, default: 0xff\n"); | ||
1137 | clos_max = 0xff; | ||
1138 | } | ||
1139 | if (clos_desired < 0) { | ||
1140 | fprintf(stderr, "clos desired is not specified, default: 0\n"); | ||
1141 | clos_desired = 0x00; | ||
1142 | } | ||
1143 | |||
1144 | isst_ctdp_display_information_start(outf); | ||
1145 | if (max_target_cpus) | ||
1146 | for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL, | ||
1147 | NULL, NULL, NULL); | ||
1148 | else | ||
1149 | for_each_online_package_in_set(set_clos_config_for_cpu, NULL, | ||
1150 | NULL, NULL, NULL); | ||
1151 | isst_ctdp_display_information_end(outf); | ||
1152 | } | ||
1153 | |||
1154 | static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
1155 | void *arg4) | ||
1156 | { | ||
1157 | int ret; | ||
1158 | |||
1159 | ret = isst_clos_associate(cpu, current_clos); | ||
1160 | if (ret) | ||
1161 | perror("isst_clos_associate"); | ||
1162 | else | ||
1163 | isst_display_result(cpu, outf, "core-power", "assoc", ret); | ||
1164 | } | ||
1165 | |||
1166 | static void set_clos_assoc(void) | ||
1167 | { | ||
1168 | if (cmd_help) { | ||
1169 | fprintf(stderr, "Associate a clos id to a CPU\n"); | ||
1170 | fprintf(stderr, | ||
1171 | "\tSpecify targeted clos id with [--clos|-c]\n"); | ||
1172 | exit(0); | ||
1173 | } | ||
1174 | |||
1175 | if (current_clos < 0 || current_clos > 3) { | ||
1176 | fprintf(stderr, "Invalid clos id\n"); | ||
1177 | exit(0); | ||
1178 | } | ||
1179 | if (max_target_cpus) | ||
1180 | for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL, | ||
1181 | NULL, NULL, NULL); | ||
1182 | else { | ||
1183 | fprintf(stderr, | ||
1184 | "Invalid target cpu. Specify with [-c|--cpu]\n"); | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, | ||
1189 | void *arg4) | ||
1190 | { | ||
1191 | int clos, ret; | ||
1192 | |||
1193 | ret = isst_clos_get_assoc_status(cpu, &clos); | ||
1194 | if (ret) | ||
1195 | perror("isst_clos_get_assoc_status"); | ||
1196 | else | ||
1197 | isst_display_result(cpu, outf, "core-power", "get-assoc", clos); | ||
1198 | } | ||
1199 | |||
1200 | static void get_clos_assoc(void) | ||
1201 | { | ||
1202 | if (cmd_help) { | ||
1203 | fprintf(stderr, "Get associate clos id to a CPU\n"); | ||
1204 | fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n"); | ||
1205 | exit(0); | ||
1206 | } | ||
1207 | if (max_target_cpus) | ||
1208 | for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL, | ||
1209 | NULL, NULL, NULL); | ||
1210 | else { | ||
1211 | fprintf(stderr, | ||
1212 | "Invalid target cpu. Specify with [-c|--cpu]\n"); | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | static struct process_cmd_struct isst_cmds[] = { | ||
1217 | { "perf-profile", "get-lock-status", get_tdp_locked }, | ||
1218 | { "perf-profile", "get-config-levels", get_tdp_levels }, | ||
1219 | { "perf-profile", "get-config-version", get_tdp_version }, | ||
1220 | { "perf-profile", "get-config-enabled", get_tdp_enabled }, | ||
1221 | { "perf-profile", "get-config-current-level", get_tdp_current_level }, | ||
1222 | { "perf-profile", "set-config-level", set_tdp_level }, | ||
1223 | { "perf-profile", "info", dump_isst_config }, | ||
1224 | { "base-freq", "info", dump_pbf_config }, | ||
1225 | { "base-freq", "enable", set_pbf_enable }, | ||
1226 | { "base-freq", "disable", set_pbf_disable }, | ||
1227 | { "turbo-freq", "info", dump_fact_config }, | ||
1228 | { "turbo-freq", "enable", set_fact_enable }, | ||
1229 | { "turbo-freq", "disable", set_fact_disable }, | ||
1230 | { "core-power", "info", dump_clos_config }, | ||
1231 | { "core-power", "enable", set_clos_enable }, | ||
1232 | { "core-power", "disable", set_clos_disable }, | ||
1233 | { "core-power", "config", set_clos_config }, | ||
1234 | { "core-power", "assoc", set_clos_assoc }, | ||
1235 | { "core-power", "get-assoc", get_clos_assoc }, | ||
1236 | { NULL, NULL, NULL } | ||
1237 | }; | ||
1238 | |||
1239 | /* | ||
1240 | * parse cpuset with following syntax | ||
1241 | * 1,2,4..6,8-10 and set bits in cpu_subset | ||
1242 | */ | ||
1243 | void parse_cpu_command(char *optarg) | ||
1244 | { | ||
1245 | unsigned int start, end; | ||
1246 | char *next; | ||
1247 | |||
1248 | next = optarg; | ||
1249 | |||
1250 | while (next && *next) { | ||
1251 | if (*next == '-') /* no negative cpu numbers */ | ||
1252 | goto error; | ||
1253 | |||
1254 | start = strtoul(next, &next, 10); | ||
1255 | |||
1256 | if (max_target_cpus < MAX_CPUS_IN_ONE_REQ) | ||
1257 | target_cpus[max_target_cpus++] = start; | ||
1258 | |||
1259 | if (*next == '\0') | ||
1260 | break; | ||
1261 | |||
1262 | if (*next == ',') { | ||
1263 | next += 1; | ||
1264 | continue; | ||
1265 | } | ||
1266 | |||
1267 | if (*next == '-') { | ||
1268 | next += 1; /* start range */ | ||
1269 | } else if (*next == '.') { | ||
1270 | next += 1; | ||
1271 | if (*next == '.') | ||
1272 | next += 1; /* start range */ | ||
1273 | else | ||
1274 | goto error; | ||
1275 | } | ||
1276 | |||
1277 | end = strtoul(next, &next, 10); | ||
1278 | if (end <= start) | ||
1279 | goto error; | ||
1280 | |||
1281 | while (++start <= end) { | ||
1282 | if (max_target_cpus < MAX_CPUS_IN_ONE_REQ) | ||
1283 | target_cpus[max_target_cpus++] = start; | ||
1284 | } | ||
1285 | |||
1286 | if (*next == ',') | ||
1287 | next += 1; | ||
1288 | else if (*next != '\0') | ||
1289 | goto error; | ||
1290 | } | ||
1291 | |||
1292 | #ifdef DEBUG | ||
1293 | { | ||
1294 | int i; | ||
1295 | |||
1296 | for (i = 0; i < max_target_cpus; ++i) | ||
1297 | printf("cpu [%d] in arg\n", target_cpus[i]); | ||
1298 | } | ||
1299 | #endif | ||
1300 | return; | ||
1301 | |||
1302 | error: | ||
1303 | fprintf(stderr, "\"--cpu %s\" malformed\n", optarg); | ||
1304 | exit(-1); | ||
1305 | } | ||
1306 | |||
1307 | static void parse_cmd_args(int argc, int start, char **argv) | ||
1308 | { | ||
1309 | int opt; | ||
1310 | int option_index; | ||
1311 | |||
1312 | static struct option long_options[] = { | ||
1313 | { "bucket", required_argument, 0, 'b' }, | ||
1314 | { "level", required_argument, 0, 'l' }, | ||
1315 | { "trl-type", required_argument, 0, 'r' }, | ||
1316 | { "trl", required_argument, 0, 't' }, | ||
1317 | { "help", no_argument, 0, 'h' }, | ||
1318 | { "clos", required_argument, 0, 'c' }, | ||
1319 | { "desired", required_argument, 0, 'd' }, | ||
1320 | { "epp", required_argument, 0, 'e' }, | ||
1321 | { "min", required_argument, 0, 'n' }, | ||
1322 | { "max", required_argument, 0, 'm' }, | ||
1323 | { "priority", required_argument, 0, 'p' }, | ||
1324 | { "weight", required_argument, 0, 'w' }, | ||
1325 | { 0, 0, 0, 0 } | ||
1326 | }; | ||
1327 | |||
1328 | option_index = start; | ||
1329 | |||
1330 | optind = start + 1; | ||
1331 | while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:h", | ||
1332 | long_options, &option_index)) != -1) { | ||
1333 | switch (opt) { | ||
1334 | case 'b': | ||
1335 | fact_bucket = atoi(optarg); | ||
1336 | break; | ||
1337 | case 'h': | ||
1338 | cmd_help = 1; | ||
1339 | break; | ||
1340 | case 'l': | ||
1341 | tdp_level = atoi(optarg); | ||
1342 | break; | ||
1343 | case 't': | ||
1344 | sscanf(optarg, "0x%llx", &fact_trl); | ||
1345 | break; | ||
1346 | case 'r': | ||
1347 | if (!strncmp(optarg, "sse", 3)) { | ||
1348 | fact_avx = 0x01; | ||
1349 | } else if (!strncmp(optarg, "avx2", 4)) { | ||
1350 | fact_avx = 0x02; | ||
1351 | } else if (!strncmp(optarg, "avx512", 4)) { | ||
1352 | fact_avx = 0x04; | ||
1353 | } else { | ||
1354 | fprintf(outf, "Invalid sse,avx options\n"); | ||
1355 | exit(1); | ||
1356 | } | ||
1357 | break; | ||
1358 | /* CLOS related */ | ||
1359 | case 'c': | ||
1360 | current_clos = atoi(optarg); | ||
1361 | printf("clos %d\n", current_clos); | ||
1362 | break; | ||
1363 | case 'd': | ||
1364 | clos_desired = atoi(optarg); | ||
1365 | break; | ||
1366 | case 'e': | ||
1367 | clos_epp = atoi(optarg); | ||
1368 | break; | ||
1369 | case 'n': | ||
1370 | clos_min = atoi(optarg); | ||
1371 | break; | ||
1372 | case 'm': | ||
1373 | clos_max = atoi(optarg); | ||
1374 | break; | ||
1375 | case 'p': | ||
1376 | clos_priority_type = atoi(optarg); | ||
1377 | break; | ||
1378 | case 'w': | ||
1379 | clos_prop_prio = atoi(optarg); | ||
1380 | break; | ||
1381 | default: | ||
1382 | printf("no match\n"); | ||
1383 | } | ||
1384 | } | ||
1385 | } | ||
1386 | |||
1387 | static void isst_help(void) | ||
1388 | { | ||
1389 | printf("perf-profile:\tAn architectural mechanism that allows multiple optimized \n\ | ||
1390 | performance profiles per system via static and/or dynamic\n\ | ||
1391 | adjustment of core count, workload, Tjmax, and\n\ | ||
1392 | TDP, etc.\n"); | ||
1393 | printf("\nCommands : For feature=perf-profile\n"); | ||
1394 | printf("\tinfo\n"); | ||
1395 | printf("\tget-lock-status\n"); | ||
1396 | printf("\tget-config-levels\n"); | ||
1397 | printf("\tget-config-version\n"); | ||
1398 | printf("\tget-config-enabled\n"); | ||
1399 | printf("\tget-config-current-level\n"); | ||
1400 | printf("\tset-config-level\n"); | ||
1401 | } | ||
1402 | |||
1403 | static void pbf_help(void) | ||
1404 | { | ||
1405 | printf("base-freq:\tEnables users to increase guaranteed base frequency\n\ | ||
1406 | on certain cores (high priority cores) in exchange for lower\n\ | ||
1407 | base frequency on remaining cores (low priority cores).\n"); | ||
1408 | printf("\tcommand : info\n"); | ||
1409 | printf("\tcommand : enable\n"); | ||
1410 | printf("\tcommand : disable\n"); | ||
1411 | } | ||
1412 | |||
1413 | static void fact_help(void) | ||
1414 | { | ||
1415 | printf("turbo-freq:\tEnables the ability to set different turbo ratio\n\ | ||
1416 | limits to cores based on priority.\n"); | ||
1417 | printf("\nCommand: For feature=turbo-freq\n"); | ||
1418 | printf("\tcommand : info\n"); | ||
1419 | printf("\tcommand : enable\n"); | ||
1420 | printf("\tcommand : disable\n"); | ||
1421 | } | ||
1422 | |||
1423 | static void core_power_help(void) | ||
1424 | { | ||
1425 | printf("core-power:\tInterface that allows user to define per core/tile\n\ | ||
1426 | priority.\n"); | ||
1427 | printf("\nCommands : For feature=core-power\n"); | ||
1428 | printf("\tinfo\n"); | ||
1429 | printf("\tenable\n"); | ||
1430 | printf("\tdisable\n"); | ||
1431 | printf("\tconfig\n"); | ||
1432 | printf("\tassoc\n"); | ||
1433 | printf("\tget-assoc\n"); | ||
1434 | } | ||
1435 | |||
1436 | struct process_cmd_help_struct { | ||
1437 | char *feature; | ||
1438 | void (*process_fn)(void); | ||
1439 | }; | ||
1440 | |||
1441 | static struct process_cmd_help_struct isst_help_cmds[] = { | ||
1442 | { "perf-profile", isst_help }, | ||
1443 | { "base-freq", pbf_help }, | ||
1444 | { "turbo-freq", fact_help }, | ||
1445 | { "core-power", core_power_help }, | ||
1446 | { NULL, NULL } | ||
1447 | }; | ||
1448 | |||
1449 | void process_command(int argc, char **argv) | ||
1450 | { | ||
1451 | int i = 0, matched = 0; | ||
1452 | char *feature = argv[optind]; | ||
1453 | char *cmd = argv[optind + 1]; | ||
1454 | |||
1455 | if (!feature || !cmd) | ||
1456 | return; | ||
1457 | |||
1458 | debug_printf("feature name [%s] command [%s]\n", feature, cmd); | ||
1459 | if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) { | ||
1460 | while (isst_help_cmds[i].feature) { | ||
1461 | if (!strcmp(isst_help_cmds[i].feature, feature)) { | ||
1462 | isst_help_cmds[i].process_fn(); | ||
1463 | exit(0); | ||
1464 | } | ||
1465 | ++i; | ||
1466 | } | ||
1467 | } | ||
1468 | |||
1469 | create_cpu_map(); | ||
1470 | |||
1471 | i = 0; | ||
1472 | while (isst_cmds[i].feature) { | ||
1473 | if (!strcmp(isst_cmds[i].feature, feature) && | ||
1474 | !strcmp(isst_cmds[i].command, cmd)) { | ||
1475 | parse_cmd_args(argc, optind + 1, argv); | ||
1476 | isst_cmds[i].process_fn(); | ||
1477 | matched = 1; | ||
1478 | break; | ||
1479 | } | ||
1480 | ++i; | ||
1481 | } | ||
1482 | |||
1483 | if (!matched) | ||
1484 | fprintf(stderr, "Invalid command\n"); | ||
1485 | } | ||
1486 | |||
1487 | static void usage(void) | ||
1488 | { | ||
1489 | printf("Intel(R) Speed Select Technology\n"); | ||
1490 | printf("\nUsage:\n"); | ||
1491 | printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n"); | ||
1492 | printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features,\n"); | ||
1493 | printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power]\n"); | ||
1494 | printf("\nFor help on each feature, use --h|--help\n"); | ||
1495 | printf("\tFor example: intel-speed-select perf-profile -h\n"); | ||
1496 | |||
1497 | printf("\nFor additional help on each command for a feature, use --h|--help\n"); | ||
1498 | printf("\tFor example: intel-speed-select perf-profile get-lock-status -h\n"); | ||
1499 | printf("\t\t This will print help for the command \"get-lock-status\" for the feature \"perf-profile\"\n"); | ||
1500 | |||
1501 | printf("\nOPTIONS\n"); | ||
1502 | printf("\t[-c|--cpu] : logical cpu number\n"); | ||
1503 | printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n"); | ||
1504 | printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n"); | ||
1505 | printf("\t[-d|--debug] : Debug mode\n"); | ||
1506 | printf("\t[-h|--help] : Print help\n"); | ||
1507 | printf("\t[-i|--info] : Print platform information\n"); | ||
1508 | printf("\t[-o|--out] : Output file\n"); | ||
1509 | printf("\t\t\tDefault : stderr\n"); | ||
1510 | printf("\t[-f|--format] : output format [json|text]. Default: text\n"); | ||
1511 | printf("\t[-v|--version] : Print version\n"); | ||
1512 | |||
1513 | printf("\nResult format\n"); | ||
1514 | printf("\tResult display uses a common format for each command:\n"); | ||
1515 | printf("\tResults are formatted in text/JSON with\n"); | ||
1516 | printf("\t\tPackage, Die, CPU, and command specific results.\n"); | ||
1517 | printf("\t\t\tFor Set commands, status is 0 for success and rest for failures\n"); | ||
1518 | exit(1); | ||
1519 | } | ||
1520 | |||
1521 | static void print_version(void) | ||
1522 | { | ||
1523 | fprintf(outf, "Version %s\n", version_str); | ||
1524 | fprintf(outf, "Build date %s time %s\n", __DATE__, __TIME__); | ||
1525 | exit(0); | ||
1526 | } | ||
1527 | |||
1528 | static void cmdline(int argc, char **argv) | ||
1529 | { | ||
1530 | int opt; | ||
1531 | int option_index = 0; | ||
1532 | |||
1533 | static struct option long_options[] = { | ||
1534 | { "cpu", required_argument, 0, 'c' }, | ||
1535 | { "debug", no_argument, 0, 'd' }, | ||
1536 | { "format", required_argument, 0, 'f' }, | ||
1537 | { "help", no_argument, 0, 'h' }, | ||
1538 | { "info", no_argument, 0, 'i' }, | ||
1539 | { "out", required_argument, 0, 'o' }, | ||
1540 | { "version", no_argument, 0, 'v' }, | ||
1541 | { 0, 0, 0, 0 } | ||
1542 | }; | ||
1543 | |||
1544 | progname = argv[0]; | ||
1545 | while ((opt = getopt_long_only(argc, argv, "+c:df:hio:v", long_options, | ||
1546 | &option_index)) != -1) { | ||
1547 | switch (opt) { | ||
1548 | case 'c': | ||
1549 | parse_cpu_command(optarg); | ||
1550 | break; | ||
1551 | case 'd': | ||
1552 | debug_flag = 1; | ||
1553 | printf("Debug Mode ON\n"); | ||
1554 | break; | ||
1555 | case 'f': | ||
1556 | if (!strncmp(optarg, "json", 4)) | ||
1557 | out_format_json = 1; | ||
1558 | break; | ||
1559 | case 'h': | ||
1560 | usage(); | ||
1561 | break; | ||
1562 | case 'i': | ||
1563 | isst_print_platform_information(); | ||
1564 | break; | ||
1565 | case 'o': | ||
1566 | if (outf) | ||
1567 | fclose(outf); | ||
1568 | outf = fopen_or_exit(optarg, "w"); | ||
1569 | break; | ||
1570 | case 'v': | ||
1571 | print_version(); | ||
1572 | break; | ||
1573 | default: | ||
1574 | usage(); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | if (geteuid() != 0) { | ||
1579 | fprintf(stderr, "Must run as root\n"); | ||
1580 | exit(0); | ||
1581 | } | ||
1582 | |||
1583 | if (optind > (argc - 2)) { | ||
1584 | fprintf(stderr, "Feature name and|or command not specified\n"); | ||
1585 | exit(0); | ||
1586 | } | ||
1587 | update_cpu_model(); | ||
1588 | printf("Intel(R) Speed Select Technology\n"); | ||
1589 | printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model); | ||
1590 | set_max_cpu_num(); | ||
1591 | set_cpu_present_cpu_mask(); | ||
1592 | set_cpu_target_cpu_mask(); | ||
1593 | isst_fill_platform_info(); | ||
1594 | if (isst_platform_info.api_version > supported_api_ver) { | ||
1595 | printf("Incompatible API versions; Upgrade of tool is required\n"); | ||
1596 | exit(0); | ||
1597 | } | ||
1598 | |||
1599 | process_command(argc, argv); | ||
1600 | } | ||
1601 | |||
1602 | int main(int argc, char **argv) | ||
1603 | { | ||
1604 | outf = stderr; | ||
1605 | cmdline(argc, argv); | ||
1606 | return 0; | ||
1607 | } | ||
diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c new file mode 100644 index 000000000000..8de4ac39a008 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst-core.c | |||
@@ -0,0 +1,721 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Intel Speed Select -- Enumerate and control features | ||
4 | * Copyright (c) 2019 Intel Corporation. | ||
5 | */ | ||
6 | |||
7 | #include "isst.h" | ||
8 | |||
9 | int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev) | ||
10 | { | ||
11 | unsigned int resp; | ||
12 | int ret; | ||
13 | |||
14 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
15 | CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); | ||
16 | if (ret) | ||
17 | return ret; | ||
18 | |||
19 | debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp); | ||
20 | |||
21 | pkg_dev->version = resp & 0xff; | ||
22 | pkg_dev->levels = (resp >> 8) & 0xff; | ||
23 | pkg_dev->current_level = (resp >> 16) & 0xff; | ||
24 | pkg_dev->locked = !!(resp & BIT(24)); | ||
25 | pkg_dev->enabled = !!(resp & BIT(31)); | ||
26 | |||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | int isst_get_ctdp_control(int cpu, int config_index, | ||
31 | struct isst_pkg_ctdp_level_info *ctdp_level) | ||
32 | { | ||
33 | unsigned int resp; | ||
34 | int ret; | ||
35 | |||
36 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
37 | CONFIG_TDP_GET_TDP_CONTROL, 0, | ||
38 | config_index, &resp); | ||
39 | if (ret) | ||
40 | return ret; | ||
41 | |||
42 | ctdp_level->fact_support = resp & BIT(0); | ||
43 | ctdp_level->pbf_support = !!(resp & BIT(1)); | ||
44 | ctdp_level->fact_enabled = !!(resp & BIT(16)); | ||
45 | ctdp_level->pbf_enabled = !!(resp & BIT(17)); | ||
46 | |||
47 | debug_printf( | ||
48 | "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", | ||
49 | cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support, | ||
50 | ctdp_level->fact_enabled, ctdp_level->pbf_enabled); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | int isst_get_tdp_info(int cpu, int config_index, | ||
56 | struct isst_pkg_ctdp_level_info *ctdp_level) | ||
57 | { | ||
58 | unsigned int resp; | ||
59 | int ret; | ||
60 | |||
61 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, | ||
62 | 0, config_index, &resp); | ||
63 | if (ret) | ||
64 | return ret; | ||
65 | |||
66 | ctdp_level->pkg_tdp = resp & GENMASK(14, 0); | ||
67 | ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16; | ||
68 | |||
69 | debug_printf( | ||
70 | "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n", | ||
71 | cpu, config_index, resp, ctdp_level->tdp_ratio, | ||
72 | ctdp_level->pkg_tdp); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | int isst_get_pwr_info(int cpu, int config_index, | ||
77 | struct isst_pkg_ctdp_level_info *ctdp_level) | ||
78 | { | ||
79 | unsigned int resp; | ||
80 | int ret; | ||
81 | |||
82 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, | ||
83 | 0, config_index, &resp); | ||
84 | if (ret) | ||
85 | return ret; | ||
86 | |||
87 | ctdp_level->pkg_max_power = resp & GENMASK(14, 0); | ||
88 | ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; | ||
89 | |||
90 | debug_printf( | ||
91 | "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", | ||
92 | cpu, config_index, resp, ctdp_level->pkg_max_power, | ||
93 | ctdp_level->pkg_min_power); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | int isst_get_tjmax_info(int cpu, int config_index, | ||
99 | struct isst_pkg_ctdp_level_info *ctdp_level) | ||
100 | { | ||
101 | unsigned int resp; | ||
102 | int ret; | ||
103 | |||
104 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, | ||
105 | 0, config_index, &resp); | ||
106 | if (ret) | ||
107 | return ret; | ||
108 | |||
109 | ctdp_level->t_proc_hot = resp & GENMASK(7, 0); | ||
110 | |||
111 | debug_printf( | ||
112 | "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n", | ||
113 | cpu, config_index, resp, ctdp_level->t_proc_hot); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | int isst_get_coremask_info(int cpu, int config_index, | ||
119 | struct isst_pkg_ctdp_level_info *ctdp_level) | ||
120 | { | ||
121 | unsigned int resp; | ||
122 | int i, ret; | ||
123 | |||
124 | ctdp_level->cpu_count = 0; | ||
125 | for (i = 0; i < 2; ++i) { | ||
126 | unsigned long long mask; | ||
127 | int cpu_count = 0; | ||
128 | |||
129 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
130 | CONFIG_TDP_GET_CORE_MASK, 0, | ||
131 | (i << 8) | config_index, &resp); | ||
132 | if (ret) | ||
133 | return ret; | ||
134 | |||
135 | debug_printf( | ||
136 | "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n", | ||
137 | cpu, config_index, i, resp); | ||
138 | |||
139 | mask = (unsigned long long)resp << (32 * i); | ||
140 | set_cpu_mask_from_punit_coremask(cpu, mask, | ||
141 | ctdp_level->core_cpumask_size, | ||
142 | ctdp_level->core_cpumask, | ||
143 | &cpu_count); | ||
144 | ctdp_level->cpu_count += cpu_count; | ||
145 | debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", cpu, | ||
146 | config_index, i, ctdp_level->cpu_count); | ||
147 | } | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) | ||
153 | { | ||
154 | unsigned int req, resp; | ||
155 | int ret; | ||
156 | |||
157 | req = level | (avx_level << 16); | ||
158 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
159 | CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, | ||
160 | &resp); | ||
161 | if (ret) | ||
162 | return ret; | ||
163 | |||
164 | debug_printf( | ||
165 | "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n", | ||
166 | cpu, req, resp); | ||
167 | |||
168 | trl[0] = resp & GENMASK(7, 0); | ||
169 | trl[1] = (resp & GENMASK(15, 8)) >> 8; | ||
170 | trl[2] = (resp & GENMASK(23, 16)) >> 16; | ||
171 | trl[3] = (resp & GENMASK(31, 24)) >> 24; | ||
172 | |||
173 | req = level | BIT(8) | (avx_level << 16); | ||
174 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
175 | CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, | ||
176 | &resp); | ||
177 | if (ret) | ||
178 | return ret; | ||
179 | |||
180 | debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", cpu, | ||
181 | req, resp); | ||
182 | |||
183 | trl[4] = resp & GENMASK(7, 0); | ||
184 | trl[5] = (resp & GENMASK(15, 8)) >> 8; | ||
185 | trl[6] = (resp & GENMASK(23, 16)) >> 16; | ||
186 | trl[7] = (resp & GENMASK(31, 24)) >> 24; | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | int isst_set_tdp_level_msr(int cpu, int tdp_level) | ||
192 | { | ||
193 | int ret; | ||
194 | |||
195 | debug_printf("cpu: tdp_level via MSR %d\n", cpu, tdp_level); | ||
196 | |||
197 | if (isst_get_config_tdp_lock_status(cpu)) { | ||
198 | debug_printf("cpu: tdp_locked %d\n", cpu); | ||
199 | return -1; | ||
200 | } | ||
201 | |||
202 | if (tdp_level > 2) | ||
203 | return -1; /* invalid value */ | ||
204 | |||
205 | ret = isst_send_msr_command(cpu, 0x64b, 1, | ||
206 | (unsigned long long *)&tdp_level); | ||
207 | if (ret) | ||
208 | return ret; | ||
209 | |||
210 | debug_printf("cpu: tdp_level via MSR successful %d\n", cpu, tdp_level); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | int isst_set_tdp_level(int cpu, int tdp_level) | ||
216 | { | ||
217 | unsigned int resp; | ||
218 | int ret; | ||
219 | |||
220 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, | ||
221 | tdp_level, &resp); | ||
222 | if (ret) | ||
223 | return isst_set_tdp_level_msr(cpu, tdp_level); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) | ||
229 | { | ||
230 | unsigned int req, resp; | ||
231 | int i, ret; | ||
232 | |||
233 | pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); | ||
234 | |||
235 | for (i = 0; i < 2; ++i) { | ||
236 | unsigned long long mask; | ||
237 | int count; | ||
238 | |||
239 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
240 | CONFIG_TDP_PBF_GET_CORE_MASK_INFO, | ||
241 | 0, (i << 8) | level, &resp); | ||
242 | if (ret) | ||
243 | return ret; | ||
244 | |||
245 | debug_printf( | ||
246 | "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", | ||
247 | cpu, resp); | ||
248 | |||
249 | mask = (unsigned long long)resp << (32 * i); | ||
250 | set_cpu_mask_from_punit_coremask(cpu, mask, | ||
251 | pbf_info->core_cpumask_size, | ||
252 | pbf_info->core_cpumask, | ||
253 | &count); | ||
254 | } | ||
255 | |||
256 | req = level; | ||
257 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
258 | CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, | ||
259 | &resp); | ||
260 | if (ret) | ||
261 | return ret; | ||
262 | |||
263 | debug_printf("cpu:%d CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO resp:%x\n", cpu, | ||
264 | resp); | ||
265 | |||
266 | pbf_info->p1_low = resp & 0xff; | ||
267 | pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; | ||
268 | |||
269 | req = level; | ||
270 | ret = isst_send_mbox_command( | ||
271 | cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); | ||
272 | if (ret) | ||
273 | return ret; | ||
274 | |||
275 | debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TDP_INFO resp:%x\n", cpu, resp); | ||
276 | |||
277 | pbf_info->tdp = resp & 0xffff; | ||
278 | |||
279 | req = level; | ||
280 | ret = isst_send_mbox_command( | ||
281 | cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); | ||
282 | if (ret) | ||
283 | return ret; | ||
284 | |||
285 | debug_printf("cpu:%d CONFIG_TDP_PBF_GET_TJ_MAX_INFO resp:%x\n", cpu, | ||
286 | resp); | ||
287 | pbf_info->t_control = (resp >> 8) & 0xff; | ||
288 | pbf_info->t_prochot = resp & 0xff; | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info) | ||
294 | { | ||
295 | free_cpu_set(pbf_info->core_cpumask); | ||
296 | } | ||
297 | |||
298 | int isst_set_pbf_fact_status(int cpu, int pbf, int enable) | ||
299 | { | ||
300 | struct isst_pkg_ctdp pkg_dev; | ||
301 | struct isst_pkg_ctdp_level_info ctdp_level; | ||
302 | int current_level; | ||
303 | unsigned int req = 0, resp; | ||
304 | int ret; | ||
305 | |||
306 | ret = isst_get_ctdp_levels(cpu, &pkg_dev); | ||
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
310 | current_level = pkg_dev.current_level; | ||
311 | |||
312 | ret = isst_get_ctdp_control(cpu, current_level, &ctdp_level); | ||
313 | if (ret) | ||
314 | return ret; | ||
315 | |||
316 | if (pbf) { | ||
317 | if (ctdp_level.fact_enabled) | ||
318 | req = BIT(16); | ||
319 | |||
320 | if (enable) | ||
321 | req |= BIT(17); | ||
322 | else | ||
323 | req &= ~BIT(17); | ||
324 | } else { | ||
325 | if (ctdp_level.pbf_enabled) | ||
326 | req = BIT(17); | ||
327 | |||
328 | if (enable) | ||
329 | req |= BIT(16); | ||
330 | else | ||
331 | req &= ~BIT(16); | ||
332 | } | ||
333 | |||
334 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
335 | CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | |||
339 | debug_printf("cpu:%d CONFIG_TDP_SET_TDP_CONTROL pbf/fact:%d req:%x\n", | ||
340 | cpu, pbf, req); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | int isst_get_fact_bucket_info(int cpu, int level, | ||
346 | struct isst_fact_bucket_info *bucket_info) | ||
347 | { | ||
348 | unsigned int resp; | ||
349 | int i, k, ret; | ||
350 | |||
351 | for (i = 0; i < 2; ++i) { | ||
352 | int j; | ||
353 | |||
354 | ret = isst_send_mbox_command( | ||
355 | cpu, CONFIG_TDP, | ||
356 | CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, | ||
357 | (i << 8) | level, &resp); | ||
358 | if (ret) | ||
359 | return ret; | ||
360 | |||
361 | debug_printf( | ||
362 | "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES index:%d level:%d resp:%x\n", | ||
363 | cpu, i, level, resp); | ||
364 | |||
365 | for (j = 0; j < 4; ++j) { | ||
366 | bucket_info[j + (i * 4)].high_priority_cores_count = | ||
367 | (resp >> (j * 8)) & 0xff; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | for (k = 0; k < 3; ++k) { | ||
372 | for (i = 0; i < 2; ++i) { | ||
373 | int j; | ||
374 | |||
375 | ret = isst_send_mbox_command( | ||
376 | cpu, CONFIG_TDP, | ||
377 | CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, | ||
378 | (k << 16) | (i << 8) | level, &resp); | ||
379 | if (ret) | ||
380 | return ret; | ||
381 | |||
382 | debug_printf( | ||
383 | "cpu:%d CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS index:%d level:%d avx:%d resp:%x\n", | ||
384 | cpu, i, level, k, resp); | ||
385 | |||
386 | for (j = 0; j < 4; ++j) { | ||
387 | switch (k) { | ||
388 | case 0: | ||
389 | bucket_info[j + (i * 4)].sse_trl = | ||
390 | (resp >> (j * 8)) & 0xff; | ||
391 | break; | ||
392 | case 1: | ||
393 | bucket_info[j + (i * 4)].avx_trl = | ||
394 | (resp >> (j * 8)) & 0xff; | ||
395 | break; | ||
396 | case 2: | ||
397 | bucket_info[j + (i * 4)].avx512_trl = | ||
398 | (resp >> (j * 8)) & 0xff; | ||
399 | break; | ||
400 | default: | ||
401 | break; | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | } | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | int isst_get_fact_info(int cpu, int level, struct isst_fact_info *fact_info) | ||
411 | { | ||
412 | unsigned int resp; | ||
413 | int ret; | ||
414 | |||
415 | ret = isst_send_mbox_command(cpu, CONFIG_TDP, | ||
416 | CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, | ||
417 | level, &resp); | ||
418 | if (ret) | ||
419 | return ret; | ||
420 | |||
421 | debug_printf("cpu:%d CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO resp:%x\n", | ||
422 | cpu, resp); | ||
423 | |||
424 | fact_info->lp_clipping_ratio_license_sse = resp & 0xff; | ||
425 | fact_info->lp_clipping_ratio_license_avx2 = (resp >> 8) & 0xff; | ||
426 | fact_info->lp_clipping_ratio_license_avx512 = (resp >> 16) & 0xff; | ||
427 | |||
428 | ret = isst_get_fact_bucket_info(cpu, level, fact_info->bucket_info); | ||
429 | |||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | int isst_set_trl(int cpu, unsigned long long trl) | ||
434 | { | ||
435 | int ret; | ||
436 | |||
437 | if (!trl) | ||
438 | trl = 0xFFFFFFFFFFFFFFFFULL; | ||
439 | |||
440 | ret = isst_send_msr_command(cpu, 0x1AD, 1, &trl); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl) | ||
448 | { | ||
449 | unsigned long long msr_trl; | ||
450 | int ret; | ||
451 | |||
452 | if (trl) { | ||
453 | msr_trl = trl; | ||
454 | } else { | ||
455 | struct isst_pkg_ctdp pkg_dev; | ||
456 | int trl[8]; | ||
457 | int i; | ||
458 | |||
459 | ret = isst_get_ctdp_levels(cpu, &pkg_dev); | ||
460 | if (ret) | ||
461 | return ret; | ||
462 | |||
463 | ret = isst_get_get_trl(cpu, pkg_dev.current_level, 0, trl); | ||
464 | if (ret) | ||
465 | return ret; | ||
466 | |||
467 | msr_trl = 0; | ||
468 | for (i = 0; i < 8; ++i) { | ||
469 | unsigned long long _trl = trl[i]; | ||
470 | |||
471 | msr_trl |= (_trl << (i * 8)); | ||
472 | } | ||
473 | } | ||
474 | ret = isst_send_msr_command(cpu, 0x1AD, 1, &msr_trl); | ||
475 | if (ret) | ||
476 | return ret; | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | /* Return 1 if locked */ | ||
482 | int isst_get_config_tdp_lock_status(int cpu) | ||
483 | { | ||
484 | unsigned long long tdp_control = 0; | ||
485 | int ret; | ||
486 | |||
487 | ret = isst_send_msr_command(cpu, 0x64b, 0, &tdp_control); | ||
488 | if (ret) | ||
489 | return ret; | ||
490 | |||
491 | ret = !!(tdp_control & BIT(31)); | ||
492 | |||
493 | return ret; | ||
494 | } | ||
495 | |||
496 | void isst_get_process_ctdp_complete(int cpu, struct isst_pkg_ctdp *pkg_dev) | ||
497 | { | ||
498 | int i; | ||
499 | |||
500 | if (!pkg_dev->processed) | ||
501 | return; | ||
502 | |||
503 | for (i = 0; i < pkg_dev->levels; ++i) { | ||
504 | struct isst_pkg_ctdp_level_info *ctdp_level; | ||
505 | |||
506 | ctdp_level = &pkg_dev->ctdp_level[i]; | ||
507 | if (ctdp_level->pbf_support) | ||
508 | free_cpu_set(ctdp_level->pbf_info.core_cpumask); | ||
509 | free_cpu_set(ctdp_level->core_cpumask); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) | ||
514 | { | ||
515 | int i, ret; | ||
516 | |||
517 | if (pkg_dev->processed) | ||
518 | return 0; | ||
519 | |||
520 | ret = isst_get_ctdp_levels(cpu, pkg_dev); | ||
521 | if (ret) | ||
522 | return ret; | ||
523 | |||
524 | debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n", | ||
525 | cpu, pkg_dev->enabled, pkg_dev->current_level, | ||
526 | pkg_dev->levels); | ||
527 | |||
528 | for (i = 0; i <= pkg_dev->levels; ++i) { | ||
529 | struct isst_pkg_ctdp_level_info *ctdp_level; | ||
530 | |||
531 | if (tdp_level != 0xff && i != tdp_level) | ||
532 | continue; | ||
533 | |||
534 | debug_printf("cpu:%d Get Information for TDP level:%d\n", cpu, | ||
535 | i); | ||
536 | ctdp_level = &pkg_dev->ctdp_level[i]; | ||
537 | |||
538 | ctdp_level->processed = 1; | ||
539 | ctdp_level->level = i; | ||
540 | ctdp_level->control_cpu = cpu; | ||
541 | ctdp_level->pkg_id = get_physical_package_id(cpu); | ||
542 | ctdp_level->die_id = get_physical_die_id(cpu); | ||
543 | |||
544 | ret = isst_get_ctdp_control(cpu, i, ctdp_level); | ||
545 | if (ret) | ||
546 | return ret; | ||
547 | |||
548 | ret = isst_get_tdp_info(cpu, i, ctdp_level); | ||
549 | if (ret) | ||
550 | return ret; | ||
551 | |||
552 | ret = isst_get_pwr_info(cpu, i, ctdp_level); | ||
553 | if (ret) | ||
554 | return ret; | ||
555 | |||
556 | ret = isst_get_tjmax_info(cpu, i, ctdp_level); | ||
557 | if (ret) | ||
558 | return ret; | ||
559 | |||
560 | ctdp_level->core_cpumask_size = | ||
561 | alloc_cpu_set(&ctdp_level->core_cpumask); | ||
562 | ret = isst_get_coremask_info(cpu, i, ctdp_level); | ||
563 | if (ret) | ||
564 | return ret; | ||
565 | |||
566 | ret = isst_get_get_trl(cpu, i, 0, | ||
567 | ctdp_level->trl_sse_active_cores); | ||
568 | if (ret) | ||
569 | return ret; | ||
570 | |||
571 | ret = isst_get_get_trl(cpu, i, 1, | ||
572 | ctdp_level->trl_avx_active_cores); | ||
573 | if (ret) | ||
574 | return ret; | ||
575 | |||
576 | ret = isst_get_get_trl(cpu, i, 2, | ||
577 | ctdp_level->trl_avx_512_active_cores); | ||
578 | if (ret) | ||
579 | return ret; | ||
580 | |||
581 | if (ctdp_level->pbf_support) { | ||
582 | ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); | ||
583 | if (!ret) | ||
584 | ctdp_level->pbf_found = 1; | ||
585 | } | ||
586 | |||
587 | if (ctdp_level->fact_support) { | ||
588 | ret = isst_get_fact_info(cpu, i, | ||
589 | &ctdp_level->fact_info); | ||
590 | if (ret) | ||
591 | return ret; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | pkg_dev->processed = 1; | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) | ||
601 | { | ||
602 | unsigned int req, resp; | ||
603 | int ret; | ||
604 | |||
605 | ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, | ||
606 | &resp); | ||
607 | if (ret) | ||
608 | return ret; | ||
609 | |||
610 | debug_printf("cpu:%d CLOS_PM_QOS_CONFIG resp:%x\n", cpu, resp); | ||
611 | |||
612 | req = resp; | ||
613 | |||
614 | if (enable_clos) | ||
615 | req = req | BIT(1); | ||
616 | else | ||
617 | req = req & ~BIT(1); | ||
618 | |||
619 | if (priority_type) | ||
620 | req = req | BIT(2); | ||
621 | else | ||
622 | req = req & ~BIT(2); | ||
623 | |||
624 | ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, | ||
625 | BIT(MBOX_CMD_WRITE_BIT), req, &resp); | ||
626 | if (ret) | ||
627 | return ret; | ||
628 | |||
629 | debug_printf("cpu:%d CLOS_PM_QOS_CONFIG priority type:%d req:%x\n", cpu, | ||
630 | priority_type, req); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | int isst_pm_get_clos(int cpu, int clos, struct isst_clos_config *clos_config) | ||
636 | { | ||
637 | unsigned int resp; | ||
638 | int ret; | ||
639 | |||
640 | ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, | ||
641 | &resp); | ||
642 | if (ret) | ||
643 | return ret; | ||
644 | |||
645 | clos_config->pkg_id = get_physical_package_id(cpu); | ||
646 | clos_config->die_id = get_physical_die_id(cpu); | ||
647 | |||
648 | clos_config->epp = resp & 0x0f; | ||
649 | clos_config->clos_prop_prio = (resp >> 4) & 0x0f; | ||
650 | clos_config->clos_min = (resp >> 8) & 0xff; | ||
651 | clos_config->clos_max = (resp >> 16) & 0xff; | ||
652 | clos_config->clos_desired = (resp >> 24) & 0xff; | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | int isst_set_clos(int cpu, int clos, struct isst_clos_config *clos_config) | ||
658 | { | ||
659 | unsigned int req, resp; | ||
660 | unsigned int param; | ||
661 | int ret; | ||
662 | |||
663 | req = clos_config->epp & 0x0f; | ||
664 | req |= (clos_config->clos_prop_prio & 0x0f) << 4; | ||
665 | req |= (clos_config->clos_min & 0xff) << 8; | ||
666 | req |= (clos_config->clos_max & 0xff) << 16; | ||
667 | req |= (clos_config->clos_desired & 0xff) << 24; | ||
668 | |||
669 | param = BIT(MBOX_CMD_WRITE_BIT) | clos; | ||
670 | |||
671 | ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, | ||
672 | &resp); | ||
673 | if (ret) | ||
674 | return ret; | ||
675 | |||
676 | debug_printf("cpu:%d CLOS_PM_CLOS param:%x req:%x\n", cpu, param, req); | ||
677 | |||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | int isst_clos_get_assoc_status(int cpu, int *clos_id) | ||
682 | { | ||
683 | unsigned int resp; | ||
684 | unsigned int param; | ||
685 | int core_id, ret; | ||
686 | |||
687 | core_id = find_phy_core_num(cpu); | ||
688 | param = core_id; | ||
689 | |||
690 | ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, | ||
691 | &resp); | ||
692 | if (ret) | ||
693 | return ret; | ||
694 | |||
695 | debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x resp:%x\n", cpu, param, | ||
696 | resp); | ||
697 | *clos_id = (resp >> 16) & 0x03; | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | int isst_clos_associate(int cpu, int clos_id) | ||
703 | { | ||
704 | unsigned int req, resp; | ||
705 | unsigned int param; | ||
706 | int core_id, ret; | ||
707 | |||
708 | req = (clos_id & 0x03) << 16; | ||
709 | core_id = find_phy_core_num(cpu); | ||
710 | param = BIT(MBOX_CMD_WRITE_BIT) | core_id; | ||
711 | |||
712 | ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, | ||
713 | req, &resp); | ||
714 | if (ret) | ||
715 | return ret; | ||
716 | |||
717 | debug_printf("cpu:%d CLOS_PQR_ASSOC param:%x req:%x\n", cpu, param, | ||
718 | req); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c new file mode 100644 index 000000000000..f368b8323742 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst-display.c | |||
@@ -0,0 +1,479 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Intel dynamic_speed_select -- Enumerate and control features | ||
4 | * Copyright (c) 2019 Intel Corporation. | ||
5 | */ | ||
6 | |||
7 | #include "isst.h" | ||
8 | |||
9 | #define DISP_FREQ_MULTIPLIER 100000 | ||
10 | |||
11 | static void printcpumask(int str_len, char *str, int mask_size, | ||
12 | cpu_set_t *cpu_mask) | ||
13 | { | ||
14 | int i, max_cpus = get_topo_max_cpus(); | ||
15 | unsigned int *mask; | ||
16 | int size, index, curr_index; | ||
17 | |||
18 | size = max_cpus / (sizeof(unsigned int) * 8); | ||
19 | if (max_cpus % (sizeof(unsigned int) * 8)) | ||
20 | size++; | ||
21 | |||
22 | mask = calloc(size, sizeof(unsigned int)); | ||
23 | if (!mask) | ||
24 | return; | ||
25 | |||
26 | for (i = 0; i < max_cpus; ++i) { | ||
27 | int mask_index, bit_index; | ||
28 | |||
29 | if (!CPU_ISSET_S(i, mask_size, cpu_mask)) | ||
30 | continue; | ||
31 | |||
32 | mask_index = i / (sizeof(unsigned int) * 8); | ||
33 | bit_index = i % (sizeof(unsigned int) * 8); | ||
34 | mask[mask_index] |= BIT(bit_index); | ||
35 | } | ||
36 | |||
37 | curr_index = 0; | ||
38 | for (i = size - 1; i >= 0; --i) { | ||
39 | index = snprintf(&str[curr_index], str_len - curr_index, "%08x", | ||
40 | mask[i]); | ||
41 | curr_index += index; | ||
42 | if (i) { | ||
43 | strncat(&str[curr_index], ",", str_len - curr_index); | ||
44 | curr_index++; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | free(mask); | ||
49 | } | ||
50 | |||
51 | static void format_and_print_txt(FILE *outf, int level, char *header, | ||
52 | char *value) | ||
53 | { | ||
54 | char *spaces = " "; | ||
55 | static char delimiters[256]; | ||
56 | int i, j = 0; | ||
57 | |||
58 | if (!level) | ||
59 | return; | ||
60 | |||
61 | if (level == 1) { | ||
62 | strcpy(delimiters, " "); | ||
63 | } else { | ||
64 | for (i = 0; i < level - 1; ++i) | ||
65 | j += snprintf(&delimiters[j], sizeof(delimiters) - j, | ||
66 | "%s", spaces); | ||
67 | } | ||
68 | |||
69 | if (header && value) { | ||
70 | fprintf(outf, "%s", delimiters); | ||
71 | fprintf(outf, "%s:%s\n", header, value); | ||
72 | } else if (header) { | ||
73 | fprintf(outf, "%s", delimiters); | ||
74 | fprintf(outf, "%s\n", header); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static int last_level; | ||
79 | static void format_and_print(FILE *outf, int level, char *header, char *value) | ||
80 | { | ||
81 | char *spaces = " "; | ||
82 | static char delimiters[256]; | ||
83 | int i; | ||
84 | |||
85 | if (!out_format_is_json()) { | ||
86 | format_and_print_txt(outf, level, header, value); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | if (level == 0) { | ||
91 | if (header) | ||
92 | fprintf(outf, "{"); | ||
93 | else | ||
94 | fprintf(outf, "\n}\n"); | ||
95 | |||
96 | } else { | ||
97 | int j = 0; | ||
98 | |||
99 | for (i = 0; i < level; ++i) | ||
100 | j += snprintf(&delimiters[j], sizeof(delimiters) - j, | ||
101 | "%s", spaces); | ||
102 | |||
103 | if (last_level == level) | ||
104 | fprintf(outf, ",\n"); | ||
105 | |||
106 | if (value) { | ||
107 | if (last_level != level) | ||
108 | fprintf(outf, "\n"); | ||
109 | |||
110 | fprintf(outf, "%s\"%s\": ", delimiters, header); | ||
111 | fprintf(outf, "\"%s\"", value); | ||
112 | } else { | ||
113 | for (i = last_level - 1; i >= level; --i) { | ||
114 | int k = 0; | ||
115 | |||
116 | for (j = i; j > 0; --j) | ||
117 | k += snprintf(&delimiters[k], | ||
118 | sizeof(delimiters) - k, | ||
119 | "%s", spaces); | ||
120 | if (i == level && header) | ||
121 | fprintf(outf, "\n%s},", delimiters); | ||
122 | else | ||
123 | fprintf(outf, "\n%s}", delimiters); | ||
124 | } | ||
125 | if (abs(last_level - level) < 3) | ||
126 | fprintf(outf, "\n"); | ||
127 | if (header) | ||
128 | fprintf(outf, "%s\"%s\": {", delimiters, | ||
129 | header); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | last_level = level; | ||
134 | } | ||
135 | |||
136 | static void print_packag_info(int cpu, FILE *outf) | ||
137 | { | ||
138 | char header[256]; | ||
139 | |||
140 | snprintf(header, sizeof(header), "package-%d", | ||
141 | get_physical_package_id(cpu)); | ||
142 | format_and_print(outf, 1, header, NULL); | ||
143 | snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu)); | ||
144 | format_and_print(outf, 2, header, NULL); | ||
145 | snprintf(header, sizeof(header), "cpu-%d", cpu); | ||
146 | format_and_print(outf, 3, header, NULL); | ||
147 | } | ||
148 | |||
149 | static void _isst_pbf_display_information(int cpu, FILE *outf, int level, | ||
150 | struct isst_pbf_info *pbf_info, | ||
151 | int disp_level) | ||
152 | { | ||
153 | char header[256]; | ||
154 | char value[256]; | ||
155 | |||
156 | snprintf(header, sizeof(header), "speed-select-base-freq"); | ||
157 | format_and_print(outf, disp_level, header, NULL); | ||
158 | |||
159 | snprintf(header, sizeof(header), "high-priority-base-frequency(KHz)"); | ||
160 | snprintf(value, sizeof(value), "%d", | ||
161 | pbf_info->p1_high * DISP_FREQ_MULTIPLIER); | ||
162 | format_and_print(outf, disp_level + 1, header, value); | ||
163 | |||
164 | snprintf(header, sizeof(header), "high-priority-cpu-mask"); | ||
165 | printcpumask(sizeof(value), value, pbf_info->core_cpumask_size, | ||
166 | pbf_info->core_cpumask); | ||
167 | format_and_print(outf, disp_level + 1, header, value); | ||
168 | |||
169 | snprintf(header, sizeof(header), "low-priority-base-frequency(KHz)"); | ||
170 | snprintf(value, sizeof(value), "%d", | ||
171 | pbf_info->p1_low * DISP_FREQ_MULTIPLIER); | ||
172 | format_and_print(outf, disp_level + 1, header, value); | ||
173 | |||
174 | snprintf(header, sizeof(header), "tjunction-temperature(C)"); | ||
175 | snprintf(value, sizeof(value), "%d", pbf_info->t_prochot); | ||
176 | format_and_print(outf, disp_level + 1, header, value); | ||
177 | |||
178 | snprintf(header, sizeof(header), "thermal-design-power(W)"); | ||
179 | snprintf(value, sizeof(value), "%d", pbf_info->tdp); | ||
180 | format_and_print(outf, disp_level + 1, header, value); | ||
181 | } | ||
182 | |||
183 | static void _isst_fact_display_information(int cpu, FILE *outf, int level, | ||
184 | int fact_bucket, int fact_avx, | ||
185 | struct isst_fact_info *fact_info, | ||
186 | int base_level) | ||
187 | { | ||
188 | struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info; | ||
189 | char header[256]; | ||
190 | char value[256]; | ||
191 | int j; | ||
192 | |||
193 | snprintf(header, sizeof(header), "speed-select-turbo-freq"); | ||
194 | format_and_print(outf, base_level, header, NULL); | ||
195 | for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) { | ||
196 | if (fact_bucket != 0xff && fact_bucket != j) | ||
197 | continue; | ||
198 | |||
199 | if (!bucket_info[j].high_priority_cores_count) | ||
200 | break; | ||
201 | |||
202 | snprintf(header, sizeof(header), "bucket-%d", j); | ||
203 | format_and_print(outf, base_level + 1, header, NULL); | ||
204 | |||
205 | snprintf(header, sizeof(header), "high-priority-cores-count"); | ||
206 | snprintf(value, sizeof(value), "%d", | ||
207 | bucket_info[j].high_priority_cores_count); | ||
208 | format_and_print(outf, base_level + 2, header, value); | ||
209 | |||
210 | if (fact_avx & 0x01) { | ||
211 | snprintf(header, sizeof(header), | ||
212 | "high-priority-max-frequency(KHz)"); | ||
213 | snprintf(value, sizeof(value), "%d", | ||
214 | bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER); | ||
215 | format_and_print(outf, base_level + 2, header, value); | ||
216 | } | ||
217 | |||
218 | if (fact_avx & 0x02) { | ||
219 | snprintf(header, sizeof(header), | ||
220 | "high-priority-max-avx2-frequency(KHz)"); | ||
221 | snprintf(value, sizeof(value), "%d", | ||
222 | bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER); | ||
223 | format_and_print(outf, base_level + 2, header, value); | ||
224 | } | ||
225 | |||
226 | if (fact_avx & 0x04) { | ||
227 | snprintf(header, sizeof(header), | ||
228 | "high-priority-max-avx512-frequency(KHz)"); | ||
229 | snprintf(value, sizeof(value), "%d", | ||
230 | bucket_info[j].avx512_trl * | ||
231 | DISP_FREQ_MULTIPLIER); | ||
232 | format_and_print(outf, base_level + 2, header, value); | ||
233 | } | ||
234 | } | ||
235 | snprintf(header, sizeof(header), | ||
236 | "speed-select-turbo-freq-clip-frequencies"); | ||
237 | format_and_print(outf, base_level + 1, header, NULL); | ||
238 | snprintf(header, sizeof(header), "low-priority-max-frequency(KHz)"); | ||
239 | snprintf(value, sizeof(value), "%d", | ||
240 | fact_info->lp_clipping_ratio_license_sse * | ||
241 | DISP_FREQ_MULTIPLIER); | ||
242 | format_and_print(outf, base_level + 2, header, value); | ||
243 | snprintf(header, sizeof(header), | ||
244 | "low-priority-max-avx2-frequency(KHz)"); | ||
245 | snprintf(value, sizeof(value), "%d", | ||
246 | fact_info->lp_clipping_ratio_license_avx2 * | ||
247 | DISP_FREQ_MULTIPLIER); | ||
248 | format_and_print(outf, base_level + 2, header, value); | ||
249 | snprintf(header, sizeof(header), | ||
250 | "low-priority-max-avx512-frequency(KHz)"); | ||
251 | snprintf(value, sizeof(value), "%d", | ||
252 | fact_info->lp_clipping_ratio_license_avx512 * | ||
253 | DISP_FREQ_MULTIPLIER); | ||
254 | format_and_print(outf, base_level + 2, header, value); | ||
255 | } | ||
256 | |||
257 | void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, | ||
258 | struct isst_pkg_ctdp *pkg_dev) | ||
259 | { | ||
260 | char header[256]; | ||
261 | char value[256]; | ||
262 | int i, base_level = 1; | ||
263 | |||
264 | print_packag_info(cpu, outf); | ||
265 | |||
266 | for (i = 0; i <= pkg_dev->levels; ++i) { | ||
267 | struct isst_pkg_ctdp_level_info *ctdp_level; | ||
268 | int j; | ||
269 | |||
270 | ctdp_level = &pkg_dev->ctdp_level[i]; | ||
271 | if (!ctdp_level->processed) | ||
272 | continue; | ||
273 | |||
274 | snprintf(header, sizeof(header), "perf-profile-level-%d", | ||
275 | ctdp_level->level); | ||
276 | format_and_print(outf, base_level + 3, header, NULL); | ||
277 | |||
278 | snprintf(header, sizeof(header), "cpu-count"); | ||
279 | j = get_cpu_count(get_physical_die_id(cpu), | ||
280 | get_physical_die_id(cpu)); | ||
281 | snprintf(value, sizeof(value), "%d", j); | ||
282 | format_and_print(outf, base_level + 4, header, value); | ||
283 | |||
284 | snprintf(header, sizeof(header), "enable-cpu-mask"); | ||
285 | printcpumask(sizeof(value), value, | ||
286 | ctdp_level->core_cpumask_size, | ||
287 | ctdp_level->core_cpumask); | ||
288 | format_and_print(outf, base_level + 4, header, value); | ||
289 | |||
290 | snprintf(header, sizeof(header), "thermal-design-power-ratio"); | ||
291 | snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio); | ||
292 | format_and_print(outf, base_level + 4, header, value); | ||
293 | |||
294 | snprintf(header, sizeof(header), "base-frequency(KHz)"); | ||
295 | snprintf(value, sizeof(value), "%d", | ||
296 | ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER); | ||
297 | format_and_print(outf, base_level + 4, header, value); | ||
298 | |||
299 | snprintf(header, sizeof(header), | ||
300 | "speed-select-turbo-freq-support"); | ||
301 | snprintf(value, sizeof(value), "%d", ctdp_level->fact_support); | ||
302 | format_and_print(outf, base_level + 4, header, value); | ||
303 | |||
304 | snprintf(header, sizeof(header), | ||
305 | "speed-select-base-freq-support"); | ||
306 | snprintf(value, sizeof(value), "%d", ctdp_level->pbf_support); | ||
307 | format_and_print(outf, base_level + 4, header, value); | ||
308 | |||
309 | snprintf(header, sizeof(header), | ||
310 | "speed-select-base-freq-enabled"); | ||
311 | snprintf(value, sizeof(value), "%d", ctdp_level->pbf_enabled); | ||
312 | format_and_print(outf, base_level + 4, header, value); | ||
313 | |||
314 | snprintf(header, sizeof(header), | ||
315 | "speed-select-turbo-freq-enabled"); | ||
316 | snprintf(value, sizeof(value), "%d", ctdp_level->fact_enabled); | ||
317 | format_and_print(outf, base_level + 4, header, value); | ||
318 | |||
319 | snprintf(header, sizeof(header), "thermal-design-power(W)"); | ||
320 | snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); | ||
321 | format_and_print(outf, base_level + 4, header, value); | ||
322 | |||
323 | snprintf(header, sizeof(header), "tjunction-max(C)"); | ||
324 | snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot); | ||
325 | format_and_print(outf, base_level + 4, header, value); | ||
326 | |||
327 | snprintf(header, sizeof(header), "turbo-ratio-limits-sse"); | ||
328 | format_and_print(outf, base_level + 4, header, NULL); | ||
329 | for (j = 0; j < 8; ++j) { | ||
330 | snprintf(header, sizeof(header), "bucket-%d", j); | ||
331 | format_and_print(outf, base_level + 5, header, NULL); | ||
332 | |||
333 | snprintf(header, sizeof(header), "core-count"); | ||
334 | snprintf(value, sizeof(value), "%d", j); | ||
335 | format_and_print(outf, base_level + 6, header, value); | ||
336 | |||
337 | snprintf(header, sizeof(header), "turbo-ratio"); | ||
338 | snprintf(value, sizeof(value), "%d", | ||
339 | ctdp_level->trl_sse_active_cores[j]); | ||
340 | format_and_print(outf, base_level + 6, header, value); | ||
341 | } | ||
342 | snprintf(header, sizeof(header), "turbo-ratio-limits-avx"); | ||
343 | format_and_print(outf, base_level + 4, header, NULL); | ||
344 | for (j = 0; j < 8; ++j) { | ||
345 | snprintf(header, sizeof(header), "bucket-%d", j); | ||
346 | format_and_print(outf, base_level + 5, header, NULL); | ||
347 | |||
348 | snprintf(header, sizeof(header), "core-count"); | ||
349 | snprintf(value, sizeof(value), "%d", j); | ||
350 | format_and_print(outf, base_level + 6, header, value); | ||
351 | |||
352 | snprintf(header, sizeof(header), "turbo-ratio"); | ||
353 | snprintf(value, sizeof(value), "%d", | ||
354 | ctdp_level->trl_avx_active_cores[j]); | ||
355 | format_and_print(outf, base_level + 6, header, value); | ||
356 | } | ||
357 | |||
358 | snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); | ||
359 | format_and_print(outf, base_level + 4, header, NULL); | ||
360 | for (j = 0; j < 8; ++j) { | ||
361 | snprintf(header, sizeof(header), "bucket-%d", j); | ||
362 | format_and_print(outf, base_level + 5, header, NULL); | ||
363 | |||
364 | snprintf(header, sizeof(header), "core-count"); | ||
365 | snprintf(value, sizeof(value), "%d", j); | ||
366 | format_and_print(outf, base_level + 6, header, value); | ||
367 | |||
368 | snprintf(header, sizeof(header), "turbo-ratio"); | ||
369 | snprintf(value, sizeof(value), "%d", | ||
370 | ctdp_level->trl_avx_512_active_cores[j]); | ||
371 | format_and_print(outf, base_level + 6, header, value); | ||
372 | } | ||
373 | if (ctdp_level->pbf_support) | ||
374 | _isst_pbf_display_information(cpu, outf, i, | ||
375 | &ctdp_level->pbf_info, | ||
376 | base_level + 4); | ||
377 | if (ctdp_level->fact_support) | ||
378 | _isst_fact_display_information(cpu, outf, i, 0xff, 0xff, | ||
379 | &ctdp_level->fact_info, | ||
380 | base_level + 4); | ||
381 | } | ||
382 | |||
383 | format_and_print(outf, 1, NULL, NULL); | ||
384 | } | ||
385 | |||
386 | void isst_ctdp_display_information_start(FILE *outf) | ||
387 | { | ||
388 | last_level = 0; | ||
389 | format_and_print(outf, 0, "start", NULL); | ||
390 | } | ||
391 | |||
392 | void isst_ctdp_display_information_end(FILE *outf) | ||
393 | { | ||
394 | format_and_print(outf, 0, NULL, NULL); | ||
395 | } | ||
396 | |||
397 | void isst_pbf_display_information(int cpu, FILE *outf, int level, | ||
398 | struct isst_pbf_info *pbf_info) | ||
399 | { | ||
400 | print_packag_info(cpu, outf); | ||
401 | _isst_pbf_display_information(cpu, outf, level, pbf_info, 4); | ||
402 | format_and_print(outf, 1, NULL, NULL); | ||
403 | } | ||
404 | |||
405 | void isst_fact_display_information(int cpu, FILE *outf, int level, | ||
406 | int fact_bucket, int fact_avx, | ||
407 | struct isst_fact_info *fact_info) | ||
408 | { | ||
409 | print_packag_info(cpu, outf); | ||
410 | _isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx, | ||
411 | fact_info, 4); | ||
412 | format_and_print(outf, 1, NULL, NULL); | ||
413 | } | ||
414 | |||
415 | void isst_clos_display_information(int cpu, FILE *outf, int clos, | ||
416 | struct isst_clos_config *clos_config) | ||
417 | { | ||
418 | char header[256]; | ||
419 | char value[256]; | ||
420 | |||
421 | snprintf(header, sizeof(header), "package-%d", | ||
422 | get_physical_package_id(cpu)); | ||
423 | format_and_print(outf, 1, header, NULL); | ||
424 | snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu)); | ||
425 | format_and_print(outf, 2, header, NULL); | ||
426 | snprintf(header, sizeof(header), "cpu-%d", cpu); | ||
427 | format_and_print(outf, 3, header, NULL); | ||
428 | |||
429 | snprintf(header, sizeof(header), "core-power"); | ||
430 | format_and_print(outf, 4, header, NULL); | ||
431 | |||
432 | snprintf(header, sizeof(header), "clos"); | ||
433 | snprintf(value, sizeof(value), "%d", clos); | ||
434 | format_and_print(outf, 5, header, value); | ||
435 | |||
436 | snprintf(header, sizeof(header), "epp"); | ||
437 | snprintf(value, sizeof(value), "%d", clos_config->epp); | ||
438 | format_and_print(outf, 5, header, value); | ||
439 | |||
440 | snprintf(header, sizeof(header), "clos-proportional-priority"); | ||
441 | snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio); | ||
442 | format_and_print(outf, 5, header, value); | ||
443 | |||
444 | snprintf(header, sizeof(header), "clos-min"); | ||
445 | snprintf(value, sizeof(value), "%d", clos_config->clos_min); | ||
446 | format_and_print(outf, 5, header, value); | ||
447 | |||
448 | snprintf(header, sizeof(header), "clos-max"); | ||
449 | snprintf(value, sizeof(value), "%d", clos_config->clos_max); | ||
450 | format_and_print(outf, 5, header, value); | ||
451 | |||
452 | snprintf(header, sizeof(header), "clos-desired"); | ||
453 | snprintf(value, sizeof(value), "%d", clos_config->clos_desired); | ||
454 | format_and_print(outf, 5, header, value); | ||
455 | |||
456 | format_and_print(outf, 1, NULL, NULL); | ||
457 | } | ||
458 | |||
459 | void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, | ||
460 | int result) | ||
461 | { | ||
462 | char header[256]; | ||
463 | char value[256]; | ||
464 | |||
465 | snprintf(header, sizeof(header), "package-%d", | ||
466 | get_physical_package_id(cpu)); | ||
467 | format_and_print(outf, 1, header, NULL); | ||
468 | snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu)); | ||
469 | format_and_print(outf, 2, header, NULL); | ||
470 | snprintf(header, sizeof(header), "cpu-%d", cpu); | ||
471 | format_and_print(outf, 3, header, NULL); | ||
472 | snprintf(header, sizeof(header), "%s", feature); | ||
473 | format_and_print(outf, 4, header, NULL); | ||
474 | snprintf(header, sizeof(header), "%s", cmd); | ||
475 | snprintf(value, sizeof(value), "%d", result); | ||
476 | format_and_print(outf, 5, header, value); | ||
477 | |||
478 | format_and_print(outf, 1, NULL, NULL); | ||
479 | } | ||
diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h new file mode 100644 index 000000000000..221881761609 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst.h | |||
@@ -0,0 +1,231 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Intel Speed Select -- Enumerate and control features | ||
4 | * Copyright (c) 2019 Intel Corporation. | ||
5 | */ | ||
6 | |||
7 | #ifndef _ISST_H_ | ||
8 | #define _ISST_H_ | ||
9 | |||
10 | #include <stdio.h> | ||
11 | #include <unistd.h> | ||
12 | #include <sys/types.h> | ||
13 | #include <sched.h> | ||
14 | #include <sys/stat.h> | ||
15 | #include <sys/resource.h> | ||
16 | #include <getopt.h> | ||
17 | #include <err.h> | ||
18 | #include <fcntl.h> | ||
19 | #include <signal.h> | ||
20 | #include <sys/time.h> | ||
21 | #include <limits.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <cpuid.h> | ||
25 | #include <dirent.h> | ||
26 | #include <errno.h> | ||
27 | |||
28 | #include <stdarg.h> | ||
29 | #include <sys/ioctl.h> | ||
30 | |||
31 | #define BIT(x) (1 << (x)) | ||
32 | #define GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (sizeof(long) * 8 - 1 - (h)))) | ||
33 | #define GENMASK_ULL(h, l) \ | ||
34 | (((~0ULL) << (l)) & (~0ULL >> (sizeof(long long) * 8 - 1 - (h)))) | ||
35 | |||
36 | #define CONFIG_TDP 0x7f | ||
37 | #define CONFIG_TDP_GET_LEVELS_INFO 0x00 | ||
38 | #define CONFIG_TDP_GET_TDP_CONTROL 0x01 | ||
39 | #define CONFIG_TDP_SET_TDP_CONTROL 0x02 | ||
40 | #define CONFIG_TDP_GET_TDP_INFO 0x03 | ||
41 | #define CONFIG_TDP_GET_PWR_INFO 0x04 | ||
42 | #define CONFIG_TDP_GET_TJMAX_INFO 0x05 | ||
43 | #define CONFIG_TDP_GET_CORE_MASK 0x06 | ||
44 | #define CONFIG_TDP_GET_TURBO_LIMIT_RATIOS 0x07 | ||
45 | #define CONFIG_TDP_SET_LEVEL 0x08 | ||
46 | #define CONFIG_TDP_GET_UNCORE_P0_P1_INFO 0X09 | ||
47 | #define CONFIG_TDP_GET_P1_INFO 0x0a | ||
48 | #define CONFIG_TDP_GET_MEM_FREQ 0x0b | ||
49 | |||
50 | #define CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES 0x10 | ||
51 | #define CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS 0x11 | ||
52 | #define CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO 0x12 | ||
53 | |||
54 | #define CONFIG_TDP_PBF_GET_CORE_MASK_INFO 0x20 | ||
55 | #define CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO 0x21 | ||
56 | #define CONFIG_TDP_PBF_GET_TJ_MAX_INFO 0x22 | ||
57 | #define CONFIG_TDP_PBF_GET_TDP_INFO 0X23 | ||
58 | |||
59 | #define CONFIG_CLOS 0xd0 | ||
60 | #define CLOS_PQR_ASSOC 0x00 | ||
61 | #define CLOS_PM_CLOS 0x01 | ||
62 | #define CLOS_PM_QOS_CONFIG 0x02 | ||
63 | #define CLOS_STATUS 0x03 | ||
64 | |||
65 | #define MBOX_CMD_WRITE_BIT 0x08 | ||
66 | |||
67 | #define PM_QOS_INFO_OFFSET 0x00 | ||
68 | #define PM_QOS_CONFIG_OFFSET 0x04 | ||
69 | #define PM_CLOS_OFFSET 0x08 | ||
70 | #define PQR_ASSOC_OFFSET 0x20 | ||
71 | |||
72 | struct isst_clos_config { | ||
73 | int pkg_id; | ||
74 | int die_id; | ||
75 | unsigned char epp; | ||
76 | unsigned char clos_prop_prio; | ||
77 | unsigned char clos_min; | ||
78 | unsigned char clos_max; | ||
79 | unsigned char clos_desired; | ||
80 | }; | ||
81 | |||
82 | struct isst_fact_bucket_info { | ||
83 | int high_priority_cores_count; | ||
84 | int sse_trl; | ||
85 | int avx_trl; | ||
86 | int avx512_trl; | ||
87 | }; | ||
88 | |||
89 | struct isst_pbf_info { | ||
90 | int pbf_acticated; | ||
91 | int pbf_available; | ||
92 | size_t core_cpumask_size; | ||
93 | cpu_set_t *core_cpumask; | ||
94 | int p1_high; | ||
95 | int p1_low; | ||
96 | int t_control; | ||
97 | int t_prochot; | ||
98 | int tdp; | ||
99 | }; | ||
100 | |||
101 | #define ISST_TRL_MAX_ACTIVE_CORES 8 | ||
102 | #define ISST_FACT_MAX_BUCKETS 8 | ||
103 | struct isst_fact_info { | ||
104 | int lp_clipping_ratio_license_sse; | ||
105 | int lp_clipping_ratio_license_avx2; | ||
106 | int lp_clipping_ratio_license_avx512; | ||
107 | struct isst_fact_bucket_info bucket_info[ISST_FACT_MAX_BUCKETS]; | ||
108 | }; | ||
109 | |||
110 | struct isst_pkg_ctdp_level_info { | ||
111 | int processed; | ||
112 | int control_cpu; | ||
113 | int pkg_id; | ||
114 | int die_id; | ||
115 | int level; | ||
116 | int fact_support; | ||
117 | int pbf_support; | ||
118 | int fact_enabled; | ||
119 | int pbf_enabled; | ||
120 | int tdp_ratio; | ||
121 | int active; | ||
122 | int tdp_control; | ||
123 | int pkg_tdp; | ||
124 | int pkg_min_power; | ||
125 | int pkg_max_power; | ||
126 | int fact; | ||
127 | int t_proc_hot; | ||
128 | int uncore_p0; | ||
129 | int uncore_p1; | ||
130 | int sse_p1; | ||
131 | int avx2_p1; | ||
132 | int avx512_p1; | ||
133 | int mem_freq; | ||
134 | size_t core_cpumask_size; | ||
135 | cpu_set_t *core_cpumask; | ||
136 | int cpu_count; | ||
137 | int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; | ||
138 | int trl_avx_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; | ||
139 | int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES]; | ||
140 | int kobj_bucket_index; | ||
141 | int active_bucket; | ||
142 | int fact_max_index; | ||
143 | int fact_max_config; | ||
144 | int pbf_found; | ||
145 | int pbf_active; | ||
146 | struct isst_pbf_info pbf_info; | ||
147 | struct isst_fact_info fact_info; | ||
148 | }; | ||
149 | |||
150 | #define ISST_MAX_TDP_LEVELS (4 + 1) /* +1 for base config */ | ||
151 | struct isst_pkg_ctdp { | ||
152 | int locked; | ||
153 | int version; | ||
154 | int processed; | ||
155 | int levels; | ||
156 | int current_level; | ||
157 | int enabled; | ||
158 | struct isst_pkg_ctdp_level_info ctdp_level[ISST_MAX_TDP_LEVELS]; | ||
159 | }; | ||
160 | |||
161 | extern int get_topo_max_cpus(void); | ||
162 | extern int get_cpu_count(int pkg_id, int die_id); | ||
163 | |||
164 | /* Common interfaces */ | ||
165 | extern void debug_printf(const char *format, ...); | ||
166 | extern int out_format_is_json(void); | ||
167 | extern int get_physical_package_id(int cpu); | ||
168 | extern int get_physical_die_id(int cpu); | ||
169 | extern size_t alloc_cpu_set(cpu_set_t **cpu_set); | ||
170 | extern void free_cpu_set(cpu_set_t *cpu_set); | ||
171 | extern int find_logical_cpu(int pkg_id, int die_id, int phy_cpu); | ||
172 | extern int find_phy_cpu_num(int logical_cpu); | ||
173 | extern int find_phy_core_num(int logical_cpu); | ||
174 | extern void set_cpu_mask_from_punit_coremask(int cpu, | ||
175 | unsigned long long core_mask, | ||
176 | size_t core_cpumask_size, | ||
177 | cpu_set_t *core_cpumask, | ||
178 | int *cpu_cnt); | ||
179 | |||
180 | extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, | ||
181 | unsigned char sub_command, | ||
182 | unsigned int write, | ||
183 | unsigned int req_data, unsigned int *resp); | ||
184 | |||
185 | extern int isst_send_msr_command(unsigned int cpu, unsigned int command, | ||
186 | int write, unsigned long long *req_resp); | ||
187 | |||
188 | extern int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev); | ||
189 | extern int isst_get_process_ctdp(int cpu, int tdp_level, | ||
190 | struct isst_pkg_ctdp *pkg_dev); | ||
191 | extern void isst_get_process_ctdp_complete(int cpu, | ||
192 | struct isst_pkg_ctdp *pkg_dev); | ||
193 | extern void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, | ||
194 | struct isst_pkg_ctdp *pkg_dev); | ||
195 | extern void isst_ctdp_display_information_start(FILE *outf); | ||
196 | extern void isst_ctdp_display_information_end(FILE *outf); | ||
197 | extern void isst_pbf_display_information(int cpu, FILE *outf, int level, | ||
198 | struct isst_pbf_info *info); | ||
199 | extern int isst_set_tdp_level(int cpu, int tdp_level); | ||
200 | extern int isst_set_tdp_level_msr(int cpu, int tdp_level); | ||
201 | extern int isst_set_pbf_fact_status(int cpu, int pbf, int enable); | ||
202 | extern int isst_get_pbf_info(int cpu, int level, | ||
203 | struct isst_pbf_info *pbf_info); | ||
204 | extern void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info); | ||
205 | extern int isst_get_fact_info(int cpu, int level, | ||
206 | struct isst_fact_info *fact_info); | ||
207 | extern int isst_get_fact_bucket_info(int cpu, int level, | ||
208 | struct isst_fact_bucket_info *bucket_info); | ||
209 | extern void isst_fact_display_information(int cpu, FILE *outf, int level, | ||
210 | int fact_bucket, int fact_avx, | ||
211 | struct isst_fact_info *fact_info); | ||
212 | extern int isst_set_trl(int cpu, unsigned long long trl); | ||
213 | extern int isst_set_trl_from_current_tdp(int cpu, unsigned long long trl); | ||
214 | extern int isst_get_config_tdp_lock_status(int cpu); | ||
215 | |||
216 | extern int isst_pm_qos_config(int cpu, int enable_clos, int priority_type); | ||
217 | extern int isst_pm_get_clos(int cpu, int clos, | ||
218 | struct isst_clos_config *clos_config); | ||
219 | extern int isst_set_clos(int cpu, int clos, | ||
220 | struct isst_clos_config *clos_config); | ||
221 | extern int isst_clos_associate(int cpu, int clos); | ||
222 | extern int isst_clos_get_assoc_status(int cpu, int *clos_id); | ||
223 | extern void isst_clos_display_information(int cpu, FILE *outf, int clos, | ||
224 | struct isst_clos_config *clos_config); | ||
225 | |||
226 | extern int isst_read_reg(unsigned short reg, unsigned int *val); | ||
227 | extern int isst_write_reg(int reg, unsigned int val); | ||
228 | |||
229 | extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, | ||
230 | int result); | ||
231 | #endif | ||
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c index 076df22e4bda..cd040b5abffe 100644 --- a/tools/testing/nvdimm/test/iomap.c +++ b/tools/testing/nvdimm/test/iomap.c | |||
@@ -100,25 +100,60 @@ static void nfit_test_kill(void *_pgmap) | |||
100 | { | 100 | { |
101 | struct dev_pagemap *pgmap = _pgmap; | 101 | struct dev_pagemap *pgmap = _pgmap; |
102 | 102 | ||
103 | WARN_ON(!pgmap || !pgmap->ref || !pgmap->kill || !pgmap->cleanup); | 103 | WARN_ON(!pgmap || !pgmap->ref); |
104 | pgmap->kill(pgmap->ref); | 104 | |
105 | pgmap->cleanup(pgmap->ref); | 105 | if (pgmap->ops && pgmap->ops->kill) |
106 | pgmap->ops->kill(pgmap); | ||
107 | else | ||
108 | percpu_ref_kill(pgmap->ref); | ||
109 | |||
110 | if (pgmap->ops && pgmap->ops->cleanup) { | ||
111 | pgmap->ops->cleanup(pgmap); | ||
112 | } else { | ||
113 | wait_for_completion(&pgmap->done); | ||
114 | percpu_ref_exit(pgmap->ref); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | static void dev_pagemap_percpu_release(struct percpu_ref *ref) | ||
119 | { | ||
120 | struct dev_pagemap *pgmap = | ||
121 | container_of(ref, struct dev_pagemap, internal_ref); | ||
122 | |||
123 | complete(&pgmap->done); | ||
106 | } | 124 | } |
107 | 125 | ||
108 | void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) | 126 | void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) |
109 | { | 127 | { |
128 | int error; | ||
110 | resource_size_t offset = pgmap->res.start; | 129 | resource_size_t offset = pgmap->res.start; |
111 | struct nfit_test_resource *nfit_res = get_nfit_res(offset); | 130 | struct nfit_test_resource *nfit_res = get_nfit_res(offset); |
112 | 131 | ||
113 | if (nfit_res) { | 132 | if (!nfit_res) |
114 | int rc; | 133 | return devm_memremap_pages(dev, pgmap); |
115 | 134 | ||
116 | rc = devm_add_action_or_reset(dev, nfit_test_kill, pgmap); | 135 | pgmap->dev = dev; |
117 | if (rc) | 136 | if (!pgmap->ref) { |
118 | return ERR_PTR(rc); | 137 | if (pgmap->ops && (pgmap->ops->kill || pgmap->ops->cleanup)) |
119 | return nfit_res->buf + offset - nfit_res->res.start; | 138 | return ERR_PTR(-EINVAL); |
139 | |||
140 | init_completion(&pgmap->done); | ||
141 | error = percpu_ref_init(&pgmap->internal_ref, | ||
142 | dev_pagemap_percpu_release, 0, GFP_KERNEL); | ||
143 | if (error) | ||
144 | return ERR_PTR(error); | ||
145 | pgmap->ref = &pgmap->internal_ref; | ||
146 | } else { | ||
147 | if (!pgmap->ops || !pgmap->ops->kill || !pgmap->ops->cleanup) { | ||
148 | WARN(1, "Missing reference count teardown definition\n"); | ||
149 | return ERR_PTR(-EINVAL); | ||
150 | } | ||
120 | } | 151 | } |
121 | return devm_memremap_pages(dev, pgmap); | 152 | |
153 | error = devm_add_action_or_reset(dev, nfit_test_kill, pgmap); | ||
154 | if (error) | ||
155 | return ERR_PTR(error); | ||
156 | return nfit_res->buf + offset - nfit_res->res.start; | ||
122 | } | 157 | } |
123 | EXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages); | 158 | EXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages); |
124 | 159 | ||
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 2620406a53ec..11c9c62c3362 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile | |||
@@ -1,4 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | include ../../../../scripts/Kbuild.include | ||
3 | include ../../../scripts/Makefile.arch | ||
2 | 4 | ||
3 | LIBDIR := ../../../lib | 5 | LIBDIR := ../../../lib |
4 | BPFDIR := $(LIBDIR)/bpf | 6 | BPFDIR := $(LIBDIR)/bpf |
@@ -81,13 +83,14 @@ all: $(TEST_CUSTOM_PROGS) | |||
81 | $(OUTPUT)/urandom_read: $(OUTPUT)/%: %.c | 83 | $(OUTPUT)/urandom_read: $(OUTPUT)/%: %.c |
82 | $(CC) -o $@ $< -Wl,--build-id | 84 | $(CC) -o $@ $< -Wl,--build-id |
83 | 85 | ||
84 | $(OUTPUT)/test_maps: map_tests/*.c | 86 | $(OUTPUT)/test_stub.o: test_stub.c |
87 | $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) -c -o $@ $< | ||
85 | 88 | ||
86 | BPFOBJ := $(OUTPUT)/libbpf.a | 89 | BPFOBJ := $(OUTPUT)/libbpf.a |
87 | 90 | ||
88 | $(TEST_GEN_PROGS): test_stub.o $(BPFOBJ) | 91 | $(TEST_GEN_PROGS): $(OUTPUT)/test_stub.o $(BPFOBJ) |
89 | 92 | ||
90 | $(TEST_GEN_PROGS_EXTENDED): test_stub.o $(OUTPUT)/libbpf.a | 93 | $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(OUTPUT)/libbpf.a |
91 | 94 | ||
92 | $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c | 95 | $(OUTPUT)/test_dev_cgroup: cgroup_helpers.c |
93 | $(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c | 96 | $(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c |
@@ -138,7 +141,8 @@ CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - </dev/null 2>&1 \ | |||
138 | 141 | ||
139 | CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \ | 142 | CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \ |
140 | $(CLANG_SYS_INCLUDES) \ | 143 | $(CLANG_SYS_INCLUDES) \ |
141 | -Wno-compare-distinct-pointer-types | 144 | -Wno-compare-distinct-pointer-types \ |
145 | -D__TARGET_ARCH_$(SRCARCH) | ||
142 | 146 | ||
143 | $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline | 147 | $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline |
144 | $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline | 148 | $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline |
@@ -172,6 +176,7 @@ endif | |||
172 | endif | 176 | endif |
173 | 177 | ||
174 | TEST_PROGS_CFLAGS := -I. -I$(OUTPUT) | 178 | TEST_PROGS_CFLAGS := -I. -I$(OUTPUT) |
179 | TEST_MAPS_CFLAGS := -I. -I$(OUTPUT) | ||
175 | TEST_VERIFIER_CFLAGS := -I. -I$(OUTPUT) -Iverifier | 180 | TEST_VERIFIER_CFLAGS := -I. -I$(OUTPUT) -Iverifier |
176 | 181 | ||
177 | ifneq ($(SUBREG_CODEGEN),) | 182 | ifneq ($(SUBREG_CODEGEN),) |
@@ -180,12 +185,12 @@ TEST_CUSTOM_PROGS += $(ALU32_BUILD_DIR)/test_progs_32 | |||
180 | $(ALU32_BUILD_DIR): | 185 | $(ALU32_BUILD_DIR): |
181 | mkdir -p $@ | 186 | mkdir -p $@ |
182 | 187 | ||
183 | $(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read | 188 | $(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read | $(ALU32_BUILD_DIR) |
184 | cp $< $@ | 189 | cp $< $@ |
185 | 190 | ||
186 | $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ | 191 | $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ |
187 | $(ALU32_BUILD_DIR) \ | 192 | $(ALU32_BUILD_DIR)/urandom_read \ |
188 | $(ALU32_BUILD_DIR)/urandom_read | 193 | | $(ALU32_BUILD_DIR) |
189 | $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ | 194 | $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ |
190 | -o $(ALU32_BUILD_DIR)/test_progs_32 \ | 195 | -o $(ALU32_BUILD_DIR)/test_progs_32 \ |
191 | test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \ | 196 | test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \ |
@@ -194,10 +199,10 @@ $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ | |||
194 | $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) | 199 | $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) |
195 | $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c | 200 | $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c |
196 | 201 | ||
197 | $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR) \ | 202 | $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \ |
198 | $(ALU32_BUILD_DIR)/test_progs_32 | 203 | | $(ALU32_BUILD_DIR) |
199 | $(CLANG) $(CLANG_FLAGS) \ | 204 | ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ |
200 | -O2 -target bpf -emit-llvm -c $< -o - | \ | 205 | echo "clang failed") | \ |
201 | $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ | 206 | $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ |
202 | -filetype=obj -o $@ | 207 | -filetype=obj -o $@ |
203 | ifeq ($(DWARF2BTF),y) | 208 | ifeq ($(DWARF2BTF),y) |
@@ -208,32 +213,30 @@ endif | |||
208 | # Have one program compiled without "-target bpf" to test whether libbpf loads | 213 | # Have one program compiled without "-target bpf" to test whether libbpf loads |
209 | # it successfully | 214 | # it successfully |
210 | $(OUTPUT)/test_xdp.o: progs/test_xdp.c | 215 | $(OUTPUT)/test_xdp.o: progs/test_xdp.c |
211 | $(CLANG) $(CLANG_FLAGS) \ | 216 | ($(CLANG) $(CLANG_FLAGS) -O2 -emit-llvm -c $< -o - || \ |
212 | -O2 -emit-llvm -c $< -o - | \ | 217 | echo "clang failed") | \ |
213 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ | 218 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ |
214 | ifeq ($(DWARF2BTF),y) | 219 | ifeq ($(DWARF2BTF),y) |
215 | $(BTF_PAHOLE) -J $@ | 220 | $(BTF_PAHOLE) -J $@ |
216 | endif | 221 | endif |
217 | 222 | ||
218 | $(OUTPUT)/%.o: progs/%.c | 223 | $(OUTPUT)/%.o: progs/%.c |
219 | $(CLANG) $(CLANG_FLAGS) \ | 224 | ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ |
220 | -O2 -target bpf -emit-llvm -c $< -o - | \ | 225 | echo "clang failed") | \ |
221 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ | 226 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ |
222 | ifeq ($(DWARF2BTF),y) | 227 | ifeq ($(DWARF2BTF),y) |
223 | $(BTF_PAHOLE) -J $@ | 228 | $(BTF_PAHOLE) -J $@ |
224 | endif | 229 | endif |
225 | 230 | ||
226 | PROG_TESTS_H := $(OUTPUT)/prog_tests/tests.h | ||
227 | test_progs.c: $(PROG_TESTS_H) | ||
228 | $(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS) | ||
229 | $(OUTPUT)/test_progs: prog_tests/*.c | ||
230 | |||
231 | PROG_TESTS_DIR = $(OUTPUT)/prog_tests | 231 | PROG_TESTS_DIR = $(OUTPUT)/prog_tests |
232 | $(PROG_TESTS_DIR): | 232 | $(PROG_TESTS_DIR): |
233 | mkdir -p $@ | 233 | mkdir -p $@ |
234 | 234 | PROG_TESTS_H := $(PROG_TESTS_DIR)/tests.h | |
235 | PROG_TESTS_FILES := $(wildcard prog_tests/*.c) | 235 | PROG_TESTS_FILES := $(wildcard prog_tests/*.c) |
236 | $(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES) | 236 | test_progs.c: $(PROG_TESTS_H) |
237 | $(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS) | ||
238 | $(OUTPUT)/test_progs: test_progs.c $(PROG_TESTS_H) $(PROG_TESTS_FILES) | ||
239 | $(PROG_TESTS_H): $(PROG_TESTS_FILES) | $(PROG_TESTS_DIR) | ||
237 | $(shell ( cd prog_tests/; \ | 240 | $(shell ( cd prog_tests/; \ |
238 | echo '/* Generated header, do not edit */'; \ | 241 | echo '/* Generated header, do not edit */'; \ |
239 | echo '#ifdef DECLARE'; \ | 242 | echo '#ifdef DECLARE'; \ |
@@ -246,15 +249,15 @@ $(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES) | |||
246 | echo '#endif' \ | 249 | echo '#endif' \ |
247 | ) > $(PROG_TESTS_H)) | 250 | ) > $(PROG_TESTS_H)) |
248 | 251 | ||
249 | TEST_MAPS_CFLAGS := -I. -I$(OUTPUT) | ||
250 | MAP_TESTS_DIR = $(OUTPUT)/map_tests | 252 | MAP_TESTS_DIR = $(OUTPUT)/map_tests |
251 | $(MAP_TESTS_DIR): | 253 | $(MAP_TESTS_DIR): |
252 | mkdir -p $@ | 254 | mkdir -p $@ |
253 | MAP_TESTS_H := $(MAP_TESTS_DIR)/tests.h | 255 | MAP_TESTS_H := $(MAP_TESTS_DIR)/tests.h |
256 | MAP_TESTS_FILES := $(wildcard map_tests/*.c) | ||
254 | test_maps.c: $(MAP_TESTS_H) | 257 | test_maps.c: $(MAP_TESTS_H) |
255 | $(OUTPUT)/test_maps: CFLAGS += $(TEST_MAPS_CFLAGS) | 258 | $(OUTPUT)/test_maps: CFLAGS += $(TEST_MAPS_CFLAGS) |
256 | MAP_TESTS_FILES := $(wildcard map_tests/*.c) | 259 | $(OUTPUT)/test_maps: test_maps.c $(MAP_TESTS_H) $(MAP_TESTS_FILES) |
257 | $(MAP_TESTS_H): $(MAP_TESTS_DIR) $(MAP_TESTS_FILES) | 260 | $(MAP_TESTS_H): $(MAP_TESTS_FILES) | $(MAP_TESTS_DIR) |
258 | $(shell ( cd map_tests/; \ | 261 | $(shell ( cd map_tests/; \ |
259 | echo '/* Generated header, do not edit */'; \ | 262 | echo '/* Generated header, do not edit */'; \ |
260 | echo '#ifdef DECLARE'; \ | 263 | echo '#ifdef DECLARE'; \ |
@@ -267,16 +270,15 @@ $(MAP_TESTS_H): $(MAP_TESTS_DIR) $(MAP_TESTS_FILES) | |||
267 | echo '#endif' \ | 270 | echo '#endif' \ |
268 | ) > $(MAP_TESTS_H)) | 271 | ) > $(MAP_TESTS_H)) |
269 | 272 | ||
270 | VERIFIER_TESTS_H := $(OUTPUT)/verifier/tests.h | ||
271 | test_verifier.c: $(VERIFIER_TESTS_H) | ||
272 | $(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS) | ||
273 | |||
274 | VERIFIER_TESTS_DIR = $(OUTPUT)/verifier | 273 | VERIFIER_TESTS_DIR = $(OUTPUT)/verifier |
275 | $(VERIFIER_TESTS_DIR): | 274 | $(VERIFIER_TESTS_DIR): |
276 | mkdir -p $@ | 275 | mkdir -p $@ |
277 | 276 | VERIFIER_TESTS_H := $(VERIFIER_TESTS_DIR)/tests.h | |
278 | VERIFIER_TEST_FILES := $(wildcard verifier/*.c) | 277 | VERIFIER_TEST_FILES := $(wildcard verifier/*.c) |
279 | $(OUTPUT)/verifier/tests.h: $(VERIFIER_TESTS_DIR) $(VERIFIER_TEST_FILES) | 278 | test_verifier.c: $(VERIFIER_TESTS_H) |
279 | $(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS) | ||
280 | $(OUTPUT)/test_verifier: test_verifier.c $(VERIFIER_TESTS_H) | ||
281 | $(VERIFIER_TESTS_H): $(VERIFIER_TEST_FILES) | $(VERIFIER_TESTS_DIR) | ||
280 | $(shell ( cd verifier/; \ | 282 | $(shell ( cd verifier/; \ |
281 | echo '/* Generated header, do not edit */'; \ | 283 | echo '/* Generated header, do not edit */'; \ |
282 | echo '#ifdef FILL_ARRAY'; \ | 284 | echo '#ifdef FILL_ARRAY'; \ |
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 5a3d92c8bec8..f804f210244e 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
@@ -315,8 +315,8 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode, | |||
315 | #if defined(__TARGET_ARCH_x86) | 315 | #if defined(__TARGET_ARCH_x86) |
316 | #define bpf_target_x86 | 316 | #define bpf_target_x86 |
317 | #define bpf_target_defined | 317 | #define bpf_target_defined |
318 | #elif defined(__TARGET_ARCH_s930x) | 318 | #elif defined(__TARGET_ARCH_s390) |
319 | #define bpf_target_s930x | 319 | #define bpf_target_s390 |
320 | #define bpf_target_defined | 320 | #define bpf_target_defined |
321 | #elif defined(__TARGET_ARCH_arm) | 321 | #elif defined(__TARGET_ARCH_arm) |
322 | #define bpf_target_arm | 322 | #define bpf_target_arm |
@@ -341,8 +341,8 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode, | |||
341 | #ifndef bpf_target_defined | 341 | #ifndef bpf_target_defined |
342 | #if defined(__x86_64__) | 342 | #if defined(__x86_64__) |
343 | #define bpf_target_x86 | 343 | #define bpf_target_x86 |
344 | #elif defined(__s390x__) | 344 | #elif defined(__s390__) |
345 | #define bpf_target_s930x | 345 | #define bpf_target_s390 |
346 | #elif defined(__arm__) | 346 | #elif defined(__arm__) |
347 | #define bpf_target_arm | 347 | #define bpf_target_arm |
348 | #elif defined(__aarch64__) | 348 | #elif defined(__aarch64__) |
@@ -358,6 +358,7 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode, | |||
358 | 358 | ||
359 | #if defined(bpf_target_x86) | 359 | #if defined(bpf_target_x86) |
360 | 360 | ||
361 | #ifdef __KERNEL__ | ||
361 | #define PT_REGS_PARM1(x) ((x)->di) | 362 | #define PT_REGS_PARM1(x) ((x)->di) |
362 | #define PT_REGS_PARM2(x) ((x)->si) | 363 | #define PT_REGS_PARM2(x) ((x)->si) |
363 | #define PT_REGS_PARM3(x) ((x)->dx) | 364 | #define PT_REGS_PARM3(x) ((x)->dx) |
@@ -368,19 +369,49 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode, | |||
368 | #define PT_REGS_RC(x) ((x)->ax) | 369 | #define PT_REGS_RC(x) ((x)->ax) |
369 | #define PT_REGS_SP(x) ((x)->sp) | 370 | #define PT_REGS_SP(x) ((x)->sp) |
370 | #define PT_REGS_IP(x) ((x)->ip) | 371 | #define PT_REGS_IP(x) ((x)->ip) |
372 | #else | ||
373 | #ifdef __i386__ | ||
374 | /* i386 kernel is built with -mregparm=3 */ | ||
375 | #define PT_REGS_PARM1(x) ((x)->eax) | ||
376 | #define PT_REGS_PARM2(x) ((x)->edx) | ||
377 | #define PT_REGS_PARM3(x) ((x)->ecx) | ||
378 | #define PT_REGS_PARM4(x) 0 | ||
379 | #define PT_REGS_PARM5(x) 0 | ||
380 | #define PT_REGS_RET(x) ((x)->esp) | ||
381 | #define PT_REGS_FP(x) ((x)->ebp) | ||
382 | #define PT_REGS_RC(x) ((x)->eax) | ||
383 | #define PT_REGS_SP(x) ((x)->esp) | ||
384 | #define PT_REGS_IP(x) ((x)->eip) | ||
385 | #else | ||
386 | #define PT_REGS_PARM1(x) ((x)->rdi) | ||
387 | #define PT_REGS_PARM2(x) ((x)->rsi) | ||
388 | #define PT_REGS_PARM3(x) ((x)->rdx) | ||
389 | #define PT_REGS_PARM4(x) ((x)->rcx) | ||
390 | #define PT_REGS_PARM5(x) ((x)->r8) | ||
391 | #define PT_REGS_RET(x) ((x)->rsp) | ||
392 | #define PT_REGS_FP(x) ((x)->rbp) | ||
393 | #define PT_REGS_RC(x) ((x)->rax) | ||
394 | #define PT_REGS_SP(x) ((x)->rsp) | ||
395 | #define PT_REGS_IP(x) ((x)->rip) | ||
396 | #endif | ||
397 | #endif | ||
371 | 398 | ||
372 | #elif defined(bpf_target_s390x) | 399 | #elif defined(bpf_target_s390) |
373 | 400 | ||
374 | #define PT_REGS_PARM1(x) ((x)->gprs[2]) | 401 | /* s390 provides user_pt_regs instead of struct pt_regs to userspace */ |
375 | #define PT_REGS_PARM2(x) ((x)->gprs[3]) | 402 | struct pt_regs; |
376 | #define PT_REGS_PARM3(x) ((x)->gprs[4]) | 403 | #define PT_REGS_S390 const volatile user_pt_regs |
377 | #define PT_REGS_PARM4(x) ((x)->gprs[5]) | 404 | #define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2]) |
378 | #define PT_REGS_PARM5(x) ((x)->gprs[6]) | 405 | #define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3]) |
379 | #define PT_REGS_RET(x) ((x)->gprs[14]) | 406 | #define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4]) |
380 | #define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */ | 407 | #define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5]) |
381 | #define PT_REGS_RC(x) ((x)->gprs[2]) | 408 | #define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6]) |
382 | #define PT_REGS_SP(x) ((x)->gprs[15]) | 409 | #define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14]) |
383 | #define PT_REGS_IP(x) ((x)->psw.addr) | 410 | /* Works only with CONFIG_FRAME_POINTER */ |
411 | #define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11]) | ||
412 | #define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2]) | ||
413 | #define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15]) | ||
414 | #define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr) | ||
384 | 415 | ||
385 | #elif defined(bpf_target_arm) | 416 | #elif defined(bpf_target_arm) |
386 | 417 | ||
@@ -397,16 +428,20 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode, | |||
397 | 428 | ||
398 | #elif defined(bpf_target_arm64) | 429 | #elif defined(bpf_target_arm64) |
399 | 430 | ||
400 | #define PT_REGS_PARM1(x) ((x)->regs[0]) | 431 | /* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */ |
401 | #define PT_REGS_PARM2(x) ((x)->regs[1]) | 432 | struct pt_regs; |
402 | #define PT_REGS_PARM3(x) ((x)->regs[2]) | 433 | #define PT_REGS_ARM64 const volatile struct user_pt_regs |
403 | #define PT_REGS_PARM4(x) ((x)->regs[3]) | 434 | #define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0]) |
404 | #define PT_REGS_PARM5(x) ((x)->regs[4]) | 435 | #define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1]) |
405 | #define PT_REGS_RET(x) ((x)->regs[30]) | 436 | #define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2]) |
406 | #define PT_REGS_FP(x) ((x)->regs[29]) /* Works only with CONFIG_FRAME_POINTER */ | 437 | #define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3]) |
407 | #define PT_REGS_RC(x) ((x)->regs[0]) | 438 | #define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4]) |
408 | #define PT_REGS_SP(x) ((x)->sp) | 439 | #define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30]) |
409 | #define PT_REGS_IP(x) ((x)->pc) | 440 | /* Works only with CONFIG_FRAME_POINTER */ |
441 | #define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29]) | ||
442 | #define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0]) | ||
443 | #define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp) | ||
444 | #define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc) | ||
410 | 445 | ||
411 | #elif defined(bpf_target_mips) | 446 | #elif defined(bpf_target_mips) |
412 | 447 | ||
@@ -452,10 +487,10 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode, | |||
452 | 487 | ||
453 | #endif | 488 | #endif |
454 | 489 | ||
455 | #ifdef bpf_target_powerpc | 490 | #if defined(bpf_target_powerpc) |
456 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) | 491 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) |
457 | #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP | 492 | #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP |
458 | #elif bpf_target_sparc | 493 | #elif defined(bpf_target_sparc) |
459 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); }) | 494 | #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); }) |
460 | #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP | 495 | #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP |
461 | #else | 496 | #else |
diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c index a4686395522c..5ecc267d98b0 100644 --- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c +++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c | |||
@@ -21,12 +21,6 @@ ssize_t get_base_addr() { | |||
21 | return -EINVAL; | 21 | return -EINVAL; |
22 | } | 22 | } |
23 | 23 | ||
24 | #ifdef __x86_64__ | ||
25 | #define SYS_KPROBE_NAME "__x64_sys_nanosleep" | ||
26 | #else | ||
27 | #define SYS_KPROBE_NAME "sys_nanosleep" | ||
28 | #endif | ||
29 | |||
30 | void test_attach_probe(void) | 24 | void test_attach_probe(void) |
31 | { | 25 | { |
32 | const char *kprobe_name = "kprobe/sys_nanosleep"; | 26 | const char *kprobe_name = "kprobe/sys_nanosleep"; |
@@ -84,7 +78,7 @@ void test_attach_probe(void) | |||
84 | 78 | ||
85 | kprobe_link = bpf_program__attach_kprobe(kprobe_prog, | 79 | kprobe_link = bpf_program__attach_kprobe(kprobe_prog, |
86 | false /* retprobe */, | 80 | false /* retprobe */, |
87 | SYS_KPROBE_NAME); | 81 | SYS_NANOSLEEP_KPROBE_NAME); |
88 | if (CHECK(IS_ERR(kprobe_link), "attach_kprobe", | 82 | if (CHECK(IS_ERR(kprobe_link), "attach_kprobe", |
89 | "err %ld\n", PTR_ERR(kprobe_link))) { | 83 | "err %ld\n", PTR_ERR(kprobe_link))) { |
90 | kprobe_link = NULL; | 84 | kprobe_link = NULL; |
@@ -92,7 +86,7 @@ void test_attach_probe(void) | |||
92 | } | 86 | } |
93 | kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog, | 87 | kretprobe_link = bpf_program__attach_kprobe(kretprobe_prog, |
94 | true /* retprobe */, | 88 | true /* retprobe */, |
95 | SYS_KPROBE_NAME); | 89 | SYS_NANOSLEEP_KPROBE_NAME); |
96 | if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe", | 90 | if (CHECK(IS_ERR(kretprobe_link), "attach_kretprobe", |
97 | "err %ld\n", PTR_ERR(kretprobe_link))) { | 91 | "err %ld\n", PTR_ERR(kretprobe_link))) { |
98 | kretprobe_link = NULL; | 92 | kretprobe_link = NULL; |
diff --git a/tools/testing/selftests/bpf/prog_tests/perf_buffer.c b/tools/testing/selftests/bpf/prog_tests/perf_buffer.c index 3f1ef95865ff..3003fddc0613 100644 --- a/tools/testing/selftests/bpf/prog_tests/perf_buffer.c +++ b/tools/testing/selftests/bpf/prog_tests/perf_buffer.c | |||
@@ -5,12 +5,6 @@ | |||
5 | #include <sys/socket.h> | 5 | #include <sys/socket.h> |
6 | #include <test_progs.h> | 6 | #include <test_progs.h> |
7 | 7 | ||
8 | #ifdef __x86_64__ | ||
9 | #define SYS_KPROBE_NAME "__x64_sys_nanosleep" | ||
10 | #else | ||
11 | #define SYS_KPROBE_NAME "sys_nanosleep" | ||
12 | #endif | ||
13 | |||
14 | static void on_sample(void *ctx, int cpu, void *data, __u32 size) | 8 | static void on_sample(void *ctx, int cpu, void *data, __u32 size) |
15 | { | 9 | { |
16 | int cpu_data = *(int *)data, duration = 0; | 10 | int cpu_data = *(int *)data, duration = 0; |
@@ -56,7 +50,7 @@ void test_perf_buffer(void) | |||
56 | 50 | ||
57 | /* attach kprobe */ | 51 | /* attach kprobe */ |
58 | link = bpf_program__attach_kprobe(prog, false /* retprobe */, | 52 | link = bpf_program__attach_kprobe(prog, false /* retprobe */, |
59 | SYS_KPROBE_NAME); | 53 | SYS_NANOSLEEP_KPROBE_NAME); |
60 | if (CHECK(IS_ERR(link), "attach_kprobe", "err %ld\n", PTR_ERR(link))) | 54 | if (CHECK(IS_ERR(link), "attach_kprobe", "err %ld\n", PTR_ERR(link))) |
61 | goto out_close; | 55 | goto out_close; |
62 | 56 | ||
diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c index 67cea1686305..54218ee3c004 100644 --- a/tools/testing/selftests/bpf/prog_tests/send_signal.c +++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c | |||
@@ -173,6 +173,18 @@ static int test_send_signal_tracepoint(void) | |||
173 | return test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint"); | 173 | return test_send_signal_common(&attr, BPF_PROG_TYPE_TRACEPOINT, "tracepoint"); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int test_send_signal_perf(void) | ||
177 | { | ||
178 | struct perf_event_attr attr = { | ||
179 | .sample_period = 1, | ||
180 | .type = PERF_TYPE_SOFTWARE, | ||
181 | .config = PERF_COUNT_SW_CPU_CLOCK, | ||
182 | }; | ||
183 | |||
184 | return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, | ||
185 | "perf_sw_event"); | ||
186 | } | ||
187 | |||
176 | static int test_send_signal_nmi(void) | 188 | static int test_send_signal_nmi(void) |
177 | { | 189 | { |
178 | struct perf_event_attr attr = { | 190 | struct perf_event_attr attr = { |
@@ -181,8 +193,26 @@ static int test_send_signal_nmi(void) | |||
181 | .type = PERF_TYPE_HARDWARE, | 193 | .type = PERF_TYPE_HARDWARE, |
182 | .config = PERF_COUNT_HW_CPU_CYCLES, | 194 | .config = PERF_COUNT_HW_CPU_CYCLES, |
183 | }; | 195 | }; |
196 | int pmu_fd; | ||
197 | |||
198 | /* Some setups (e.g. virtual machines) might run with hardware | ||
199 | * perf events disabled. If this is the case, skip this test. | ||
200 | */ | ||
201 | pmu_fd = syscall(__NR_perf_event_open, &attr, 0 /* pid */, | ||
202 | -1 /* cpu */, -1 /* group_fd */, 0 /* flags */); | ||
203 | if (pmu_fd == -1) { | ||
204 | if (errno == ENOENT) { | ||
205 | printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", | ||
206 | __func__); | ||
207 | return 0; | ||
208 | } | ||
209 | /* Let the test fail with a more informative message */ | ||
210 | } else { | ||
211 | close(pmu_fd); | ||
212 | } | ||
184 | 213 | ||
185 | return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, "perf_event"); | 214 | return test_send_signal_common(&attr, BPF_PROG_TYPE_PERF_EVENT, |
215 | "perf_hw_event"); | ||
186 | } | 216 | } |
187 | 217 | ||
188 | void test_send_signal(void) | 218 | void test_send_signal(void) |
@@ -190,6 +220,7 @@ void test_send_signal(void) | |||
190 | int ret = 0; | 220 | int ret = 0; |
191 | 221 | ||
192 | ret |= test_send_signal_tracepoint(); | 222 | ret |= test_send_signal_tracepoint(); |
223 | ret |= test_send_signal_perf(); | ||
193 | ret |= test_send_signal_nmi(); | 224 | ret |= test_send_signal_nmi(); |
194 | if (!ret) | 225 | if (!ret) |
195 | printf("test_send_signal:OK\n"); | 226 | printf("test_send_signal:OK\n"); |
diff --git a/tools/testing/selftests/bpf/progs/loop1.c b/tools/testing/selftests/bpf/progs/loop1.c index dea395af9ea9..7cdb7f878310 100644 --- a/tools/testing/selftests/bpf/progs/loop1.c +++ b/tools/testing/selftests/bpf/progs/loop1.c | |||
@@ -18,7 +18,7 @@ int nested_loops(volatile struct pt_regs* ctx) | |||
18 | for (j = 0; j < 300; j++) | 18 | for (j = 0; j < 300; j++) |
19 | for (i = 0; i < j; i++) { | 19 | for (i = 0; i < j; i++) { |
20 | if (j & 1) | 20 | if (j & 1) |
21 | m = ctx->rax; | 21 | m = PT_REGS_RC(ctx); |
22 | else | 22 | else |
23 | m = j; | 23 | m = j; |
24 | sum += i * m; | 24 | sum += i * m; |
diff --git a/tools/testing/selftests/bpf/progs/loop2.c b/tools/testing/selftests/bpf/progs/loop2.c index 0637bd8e8bcf..9b2f808a2863 100644 --- a/tools/testing/selftests/bpf/progs/loop2.c +++ b/tools/testing/selftests/bpf/progs/loop2.c | |||
@@ -16,7 +16,7 @@ int while_true(volatile struct pt_regs* ctx) | |||
16 | int i = 0; | 16 | int i = 0; |
17 | 17 | ||
18 | while (true) { | 18 | while (true) { |
19 | if (ctx->rax & 1) | 19 | if (PT_REGS_RC(ctx) & 1) |
20 | i += 3; | 20 | i += 3; |
21 | else | 21 | else |
22 | i += 7; | 22 | i += 7; |
diff --git a/tools/testing/selftests/bpf/progs/loop3.c b/tools/testing/selftests/bpf/progs/loop3.c index 30a0f6cba080..d727657d51e2 100644 --- a/tools/testing/selftests/bpf/progs/loop3.c +++ b/tools/testing/selftests/bpf/progs/loop3.c | |||
@@ -16,7 +16,7 @@ int while_true(volatile struct pt_regs* ctx) | |||
16 | __u64 i = 0, sum = 0; | 16 | __u64 i = 0, sum = 0; |
17 | do { | 17 | do { |
18 | i++; | 18 | i++; |
19 | sum += ctx->rax; | 19 | sum += PT_REGS_RC(ctx); |
20 | } while (i < 0x100000000ULL); | 20 | } while (i < 0x100000000ULL); |
21 | return sum; | 21 | return sum; |
22 | } | 22 | } |
diff --git a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c index d06b47a09097..33254b771384 100644 --- a/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c +++ b/tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c | |||
@@ -47,11 +47,12 @@ struct { | |||
47 | * issue and avoid complicated C programming massaging. | 47 | * issue and avoid complicated C programming massaging. |
48 | * This is an acceptable workaround since there is one entry here. | 48 | * This is an acceptable workaround since there is one entry here. |
49 | */ | 49 | */ |
50 | typedef __u64 raw_stack_trace_t[2 * MAX_STACK_RAWTP]; | ||
50 | struct { | 51 | struct { |
51 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | 52 | __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); |
52 | __uint(max_entries, 1); | 53 | __uint(max_entries, 1); |
53 | __type(key, __u32); | 54 | __type(key, __u32); |
54 | __u64 (*value)[2 * MAX_STACK_RAWTP]; | 55 | __type(value, raw_stack_trace_t); |
55 | } rawdata_map SEC(".maps"); | 56 | } rawdata_map SEC(".maps"); |
56 | 57 | ||
57 | SEC("tracepoint/raw_syscalls/sys_enter") | 58 | SEC("tracepoint/raw_syscalls/sys_enter") |
diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c b/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c index bbfc8337b6f0..f5638e26865d 100644 --- a/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c +++ b/tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c | |||
@@ -36,8 +36,7 @@ struct { | |||
36 | __uint(type, BPF_MAP_TYPE_ARRAY); | 36 | __uint(type, BPF_MAP_TYPE_ARRAY); |
37 | __uint(max_entries, 128); | 37 | __uint(max_entries, 128); |
38 | __type(key, __u32); | 38 | __type(key, __u32); |
39 | /* there seems to be a bug in kernel not handling typedef properly */ | 39 | __type(value, stack_trace_t); |
40 | struct bpf_stack_build_id (*value)[PERF_MAX_STACK_DEPTH]; | ||
41 | } stack_amap SEC(".maps"); | 40 | } stack_amap SEC(".maps"); |
42 | 41 | ||
43 | /* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */ | 42 | /* taken from /sys/kernel/debug/tracing/events/random/urandom_read/format */ |
diff --git a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c index 803c15dc109d..fa0be3e10a10 100644 --- a/tools/testing/selftests/bpf/progs/test_stacktrace_map.c +++ b/tools/testing/selftests/bpf/progs/test_stacktrace_map.c | |||
@@ -35,7 +35,7 @@ struct { | |||
35 | __uint(type, BPF_MAP_TYPE_ARRAY); | 35 | __uint(type, BPF_MAP_TYPE_ARRAY); |
36 | __uint(max_entries, 16384); | 36 | __uint(max_entries, 16384); |
37 | __type(key, __u32); | 37 | __type(key, __u32); |
38 | __u64 (*value)[PERF_MAX_STACK_DEPTH]; | 38 | __type(value, stack_trace_t); |
39 | } stack_amap SEC(".maps"); | 39 | } stack_amap SEC(".maps"); |
40 | 40 | ||
41 | /* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */ | 41 | /* taken from /sys/kernel/debug/tracing/events/sched/sched_switch/format */ |
diff --git a/tools/testing/selftests/bpf/progs/test_xdp_noinline.c b/tools/testing/selftests/bpf/progs/test_xdp_noinline.c index dad8a7e33eaa..e88d7b9d65ab 100644 --- a/tools/testing/selftests/bpf/progs/test_xdp_noinline.c +++ b/tools/testing/selftests/bpf/progs/test_xdp_noinline.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/tcp.h> | 14 | #include <linux/tcp.h> |
15 | #include <linux/udp.h> | 15 | #include <linux/udp.h> |
16 | #include "bpf_helpers.h" | 16 | #include "bpf_helpers.h" |
17 | #include "bpf_endian.h" | ||
17 | 18 | ||
18 | static __u32 rol32(__u32 word, unsigned int shift) | 19 | static __u32 rol32(__u32 word, unsigned int shift) |
19 | { | 20 | { |
@@ -305,7 +306,7 @@ bool encap_v6(struct xdp_md *xdp, struct ctl_value *cval, | |||
305 | ip6h->nexthdr = IPPROTO_IPV6; | 306 | ip6h->nexthdr = IPPROTO_IPV6; |
306 | ip_suffix = pckt->flow.srcv6[3] ^ pckt->flow.port16[0]; | 307 | ip_suffix = pckt->flow.srcv6[3] ^ pckt->flow.port16[0]; |
307 | ip6h->payload_len = | 308 | ip6h->payload_len = |
308 | __builtin_bswap16(pkt_bytes + sizeof(struct ipv6hdr)); | 309 | bpf_htons(pkt_bytes + sizeof(struct ipv6hdr)); |
309 | ip6h->hop_limit = 4; | 310 | ip6h->hop_limit = 4; |
310 | 311 | ||
311 | ip6h->saddr.in6_u.u6_addr32[0] = 1; | 312 | ip6h->saddr.in6_u.u6_addr32[0] = 1; |
@@ -322,7 +323,7 @@ bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval, | |||
322 | struct real_definition *dst, __u32 pkt_bytes) | 323 | struct real_definition *dst, __u32 pkt_bytes) |
323 | { | 324 | { |
324 | 325 | ||
325 | __u32 ip_suffix = __builtin_bswap16(pckt->flow.port16[0]); | 326 | __u32 ip_suffix = bpf_ntohs(pckt->flow.port16[0]); |
326 | struct eth_hdr *new_eth; | 327 | struct eth_hdr *new_eth; |
327 | struct eth_hdr *old_eth; | 328 | struct eth_hdr *old_eth; |
328 | __u16 *next_iph_u16; | 329 | __u16 *next_iph_u16; |
@@ -352,7 +353,7 @@ bool encap_v4(struct xdp_md *xdp, struct ctl_value *cval, | |||
352 | iph->protocol = IPPROTO_IPIP; | 353 | iph->protocol = IPPROTO_IPIP; |
353 | iph->check = 0; | 354 | iph->check = 0; |
354 | iph->tos = 1; | 355 | iph->tos = 1; |
355 | iph->tot_len = __builtin_bswap16(pkt_bytes + sizeof(struct iphdr)); | 356 | iph->tot_len = bpf_htons(pkt_bytes + sizeof(struct iphdr)); |
356 | /* don't update iph->daddr, since it will overwrite old eth_proto | 357 | /* don't update iph->daddr, since it will overwrite old eth_proto |
357 | * and multiple iterations of bpf_prog_run() will fail | 358 | * and multiple iterations of bpf_prog_run() will fail |
358 | */ | 359 | */ |
@@ -639,7 +640,7 @@ static int process_l3_headers_v6(struct packet_description *pckt, | |||
639 | iph_len = sizeof(struct ipv6hdr); | 640 | iph_len = sizeof(struct ipv6hdr); |
640 | *protocol = ip6h->nexthdr; | 641 | *protocol = ip6h->nexthdr; |
641 | pckt->flow.proto = *protocol; | 642 | pckt->flow.proto = *protocol; |
642 | *pkt_bytes = __builtin_bswap16(ip6h->payload_len); | 643 | *pkt_bytes = bpf_ntohs(ip6h->payload_len); |
643 | off += iph_len; | 644 | off += iph_len; |
644 | if (*protocol == 45) { | 645 | if (*protocol == 45) { |
645 | return XDP_DROP; | 646 | return XDP_DROP; |
@@ -671,7 +672,7 @@ static int process_l3_headers_v4(struct packet_description *pckt, | |||
671 | return XDP_DROP; | 672 | return XDP_DROP; |
672 | *protocol = iph->protocol; | 673 | *protocol = iph->protocol; |
673 | pckt->flow.proto = *protocol; | 674 | pckt->flow.proto = *protocol; |
674 | *pkt_bytes = __builtin_bswap16(iph->tot_len); | 675 | *pkt_bytes = bpf_ntohs(iph->tot_len); |
675 | off += 20; | 676 | off += 20; |
676 | if (iph->frag_off & 65343) | 677 | if (iph->frag_off & 65343) |
677 | return XDP_DROP; | 678 | return XDP_DROP; |
@@ -808,10 +809,10 @@ int balancer_ingress(struct xdp_md *ctx) | |||
808 | nh_off = sizeof(struct eth_hdr); | 809 | nh_off = sizeof(struct eth_hdr); |
809 | if (data + nh_off > data_end) | 810 | if (data + nh_off > data_end) |
810 | return XDP_DROP; | 811 | return XDP_DROP; |
811 | eth_proto = eth->eth_proto; | 812 | eth_proto = bpf_ntohs(eth->eth_proto); |
812 | if (eth_proto == 8) | 813 | if (eth_proto == ETH_P_IP) |
813 | return process_packet(data, nh_off, data_end, 0, ctx); | 814 | return process_packet(data, nh_off, data_end, 0, ctx); |
814 | else if (eth_proto == 56710) | 815 | else if (eth_proto == ETH_P_IPV6) |
815 | return process_packet(data, nh_off, data_end, 1, ctx); | 816 | return process_packet(data, nh_off, data_end, 1, ctx); |
816 | else | 817 | else |
817 | return XDP_DROP; | 818 | return XDP_DROP; |
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c index 8351cb5f4a20..3d617e806054 100644 --- a/tools/testing/selftests/bpf/test_btf.c +++ b/tools/testing/selftests/bpf/test_btf.c | |||
@@ -3417,6 +3417,94 @@ static struct btf_raw_test raw_tests[] = { | |||
3417 | .value_type_id = 1, | 3417 | .value_type_id = 1, |
3418 | .max_entries = 4, | 3418 | .max_entries = 4, |
3419 | }, | 3419 | }, |
3420 | /* | ||
3421 | * typedef int arr_t[16]; | ||
3422 | * struct s { | ||
3423 | * arr_t *a; | ||
3424 | * }; | ||
3425 | */ | ||
3426 | { | ||
3427 | .descr = "struct->ptr->typedef->array->int size resolution", | ||
3428 | .raw_types = { | ||
3429 | BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */ | ||
3430 | BTF_MEMBER_ENC(NAME_TBD, 2, 0), | ||
3431 | BTF_PTR_ENC(3), /* [2] */ | ||
3432 | BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ | ||
3433 | BTF_TYPE_ARRAY_ENC(5, 5, 16), /* [4] */ | ||
3434 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [5] */ | ||
3435 | BTF_END_RAW, | ||
3436 | }, | ||
3437 | BTF_STR_SEC("\0s\0a\0arr_t"), | ||
3438 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
3439 | .map_name = "ptr_mod_chain_size_resolve_map", | ||
3440 | .key_size = sizeof(int), | ||
3441 | .value_size = sizeof(int) * 16, | ||
3442 | .key_type_id = 5 /* int */, | ||
3443 | .value_type_id = 3 /* arr_t */, | ||
3444 | .max_entries = 4, | ||
3445 | }, | ||
3446 | /* | ||
3447 | * typedef int arr_t[16][8][4]; | ||
3448 | * struct s { | ||
3449 | * arr_t *a; | ||
3450 | * }; | ||
3451 | */ | ||
3452 | { | ||
3453 | .descr = "struct->ptr->typedef->multi-array->int size resolution", | ||
3454 | .raw_types = { | ||
3455 | BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */ | ||
3456 | BTF_MEMBER_ENC(NAME_TBD, 2, 0), | ||
3457 | BTF_PTR_ENC(3), /* [2] */ | ||
3458 | BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ | ||
3459 | BTF_TYPE_ARRAY_ENC(5, 7, 16), /* [4] */ | ||
3460 | BTF_TYPE_ARRAY_ENC(6, 7, 8), /* [5] */ | ||
3461 | BTF_TYPE_ARRAY_ENC(7, 7, 4), /* [6] */ | ||
3462 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [7] */ | ||
3463 | BTF_END_RAW, | ||
3464 | }, | ||
3465 | BTF_STR_SEC("\0s\0a\0arr_t"), | ||
3466 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
3467 | .map_name = "multi_arr_size_resolve_map", | ||
3468 | .key_size = sizeof(int), | ||
3469 | .value_size = sizeof(int) * 16 * 8 * 4, | ||
3470 | .key_type_id = 7 /* int */, | ||
3471 | .value_type_id = 3 /* arr_t */, | ||
3472 | .max_entries = 4, | ||
3473 | }, | ||
3474 | /* | ||
3475 | * typedef int int_t; | ||
3476 | * typedef int_t arr3_t[4]; | ||
3477 | * typedef arr3_t arr2_t[8]; | ||
3478 | * typedef arr2_t arr1_t[16]; | ||
3479 | * struct s { | ||
3480 | * arr1_t *a; | ||
3481 | * }; | ||
3482 | */ | ||
3483 | { | ||
3484 | .descr = "typedef/multi-arr mix size resolution", | ||
3485 | .raw_types = { | ||
3486 | BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */ | ||
3487 | BTF_MEMBER_ENC(NAME_TBD, 2, 0), | ||
3488 | BTF_PTR_ENC(3), /* [2] */ | ||
3489 | BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ | ||
3490 | BTF_TYPE_ARRAY_ENC(5, 10, 16), /* [4] */ | ||
3491 | BTF_TYPEDEF_ENC(NAME_TBD, 6), /* [5] */ | ||
3492 | BTF_TYPE_ARRAY_ENC(7, 10, 8), /* [6] */ | ||
3493 | BTF_TYPEDEF_ENC(NAME_TBD, 8), /* [7] */ | ||
3494 | BTF_TYPE_ARRAY_ENC(9, 10, 4), /* [8] */ | ||
3495 | BTF_TYPEDEF_ENC(NAME_TBD, 10), /* [9] */ | ||
3496 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [10] */ | ||
3497 | BTF_END_RAW, | ||
3498 | }, | ||
3499 | BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"), | ||
3500 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
3501 | .map_name = "typedef_arra_mix_size_resolve_map", | ||
3502 | .key_size = sizeof(int), | ||
3503 | .value_size = sizeof(int) * 16 * 8 * 4, | ||
3504 | .key_type_id = 10 /* int */, | ||
3505 | .value_type_id = 3 /* arr_t */, | ||
3506 | .max_entries = 4, | ||
3507 | }, | ||
3420 | 3508 | ||
3421 | }; /* struct btf_raw_test raw_tests[] */ | 3509 | }; /* struct btf_raw_test raw_tests[] */ |
3422 | 3510 | ||
diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h index f095e1d4c657..49e0f7d85643 100644 --- a/tools/testing/selftests/bpf/test_progs.h +++ b/tools/testing/selftests/bpf/test_progs.h | |||
@@ -92,3 +92,11 @@ int compare_map_keys(int map1_fd, int map2_fd); | |||
92 | int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); | 92 | int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len); |
93 | int extract_build_id(char *build_id, size_t size); | 93 | int extract_build_id(char *build_id, size_t size); |
94 | void *spin_lock_thread(void *arg); | 94 | void *spin_lock_thread(void *arg); |
95 | |||
96 | #ifdef __x86_64__ | ||
97 | #define SYS_NANOSLEEP_KPROBE_NAME "__x64_sys_nanosleep" | ||
98 | #elif defined(__s390x__) | ||
99 | #define SYS_NANOSLEEP_KPROBE_NAME "__s390x_sys_nanosleep" | ||
100 | #else | ||
101 | #define SYS_NANOSLEEP_KPROBE_NAME "sys_nanosleep" | ||
102 | #endif | ||
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index b0773291012a..84135d5f4b35 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c | |||
@@ -86,7 +86,7 @@ struct bpf_test { | |||
86 | int fixup_sk_storage_map[MAX_FIXUPS]; | 86 | int fixup_sk_storage_map[MAX_FIXUPS]; |
87 | const char *errstr; | 87 | const char *errstr; |
88 | const char *errstr_unpriv; | 88 | const char *errstr_unpriv; |
89 | uint32_t retval, retval_unpriv, insn_processed; | 89 | uint32_t insn_processed; |
90 | int prog_len; | 90 | int prog_len; |
91 | enum { | 91 | enum { |
92 | UNDEF, | 92 | UNDEF, |
@@ -95,16 +95,20 @@ struct bpf_test { | |||
95 | } result, result_unpriv; | 95 | } result, result_unpriv; |
96 | enum bpf_prog_type prog_type; | 96 | enum bpf_prog_type prog_type; |
97 | uint8_t flags; | 97 | uint8_t flags; |
98 | __u8 data[TEST_DATA_LEN]; | ||
99 | void (*fill_helper)(struct bpf_test *self); | 98 | void (*fill_helper)(struct bpf_test *self); |
100 | uint8_t runs; | 99 | uint8_t runs; |
101 | struct { | 100 | #define bpf_testdata_struct_t \ |
102 | uint32_t retval, retval_unpriv; | 101 | struct { \ |
103 | union { | 102 | uint32_t retval, retval_unpriv; \ |
104 | __u8 data[TEST_DATA_LEN]; | 103 | union { \ |
105 | __u64 data64[TEST_DATA_LEN / 8]; | 104 | __u8 data[TEST_DATA_LEN]; \ |
106 | }; | 105 | __u64 data64[TEST_DATA_LEN / 8]; \ |
107 | } retvals[MAX_TEST_RUNS]; | 106 | }; \ |
107 | } | ||
108 | union { | ||
109 | bpf_testdata_struct_t; | ||
110 | bpf_testdata_struct_t retvals[MAX_TEST_RUNS]; | ||
111 | }; | ||
108 | enum bpf_attach_type expected_attach_type; | 112 | enum bpf_attach_type expected_attach_type; |
109 | }; | 113 | }; |
110 | 114 | ||
@@ -949,17 +953,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv, | |||
949 | uint32_t expected_val; | 953 | uint32_t expected_val; |
950 | int i; | 954 | int i; |
951 | 955 | ||
952 | if (!test->runs) { | 956 | if (!test->runs) |
953 | expected_val = unpriv && test->retval_unpriv ? | 957 | test->runs = 1; |
954 | test->retval_unpriv : test->retval; | ||
955 | |||
956 | err = do_prog_test_run(fd_prog, unpriv, expected_val, | ||
957 | test->data, sizeof(test->data)); | ||
958 | if (err) | ||
959 | run_errs++; | ||
960 | else | ||
961 | run_successes++; | ||
962 | } | ||
963 | 958 | ||
964 | for (i = 0; i < test->runs; i++) { | 959 | for (i = 0; i < test->runs; i++) { |
965 | if (unpriv && test->retvals[i].retval_unpriv) | 960 | if (unpriv && test->retvals[i].retval_unpriv) |
diff --git a/tools/testing/selftests/bpf/verifier/array_access.c b/tools/testing/selftests/bpf/verifier/array_access.c index bcb83196e459..f3c33e128709 100644 --- a/tools/testing/selftests/bpf/verifier/array_access.c +++ b/tools/testing/selftests/bpf/verifier/array_access.c | |||
@@ -226,7 +226,7 @@ | |||
226 | BPF_LD_MAP_FD(BPF_REG_1, 0), | 226 | BPF_LD_MAP_FD(BPF_REG_1, 0), |
227 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), | 227 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
228 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), | 228 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), |
229 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0), | 229 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0), |
230 | BPF_EXIT_INSN(), | 230 | BPF_EXIT_INSN(), |
231 | }, | 231 | }, |
232 | .fixup_map_array_ro = { 3 }, | 232 | .fixup_map_array_ro = { 3 }, |
diff --git a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c index c3de1a2c9dc5..a53d99cebd9f 100644 --- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c | |||
@@ -183,7 +183,7 @@ | |||
183 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | 183 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), |
184 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | 184 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), |
185 | BPF_EXIT_INSN(), | 185 | BPF_EXIT_INSN(), |
186 | BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), | 186 | BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), |
187 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), | 187 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), |
188 | BPF_MOV64_IMM(BPF_REG_2, 0), | 188 | BPF_MOV64_IMM(BPF_REG_2, 0), |
189 | BPF_MOV64_IMM(BPF_REG_3, 0x100000), | 189 | BPF_MOV64_IMM(BPF_REG_3, 0x100000), |
diff --git a/tools/testing/selftests/bpf/verifier/wide_access.c b/tools/testing/selftests/bpf/verifier/wide_access.c new file mode 100644 index 000000000000..ccade9312d21 --- /dev/null +++ b/tools/testing/selftests/bpf/verifier/wide_access.c | |||
@@ -0,0 +1,73 @@ | |||
1 | #define BPF_SOCK_ADDR_STORE(field, off, res, err) \ | ||
2 | { \ | ||
3 | "wide store to bpf_sock_addr." #field "[" #off "]", \ | ||
4 | .insns = { \ | ||
5 | BPF_MOV64_IMM(BPF_REG_0, 1), \ | ||
6 | BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \ | ||
7 | offsetof(struct bpf_sock_addr, field[off])), \ | ||
8 | BPF_EXIT_INSN(), \ | ||
9 | }, \ | ||
10 | .result = res, \ | ||
11 | .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ | ||
12 | .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ | ||
13 | .errstr = err, \ | ||
14 | } | ||
15 | |||
16 | /* user_ip6[0] is u64 aligned */ | ||
17 | BPF_SOCK_ADDR_STORE(user_ip6, 0, ACCEPT, | ||
18 | NULL), | ||
19 | BPF_SOCK_ADDR_STORE(user_ip6, 1, REJECT, | ||
20 | "invalid bpf_context access off=12 size=8"), | ||
21 | BPF_SOCK_ADDR_STORE(user_ip6, 2, ACCEPT, | ||
22 | NULL), | ||
23 | BPF_SOCK_ADDR_STORE(user_ip6, 3, REJECT, | ||
24 | "invalid bpf_context access off=20 size=8"), | ||
25 | |||
26 | /* msg_src_ip6[0] is _not_ u64 aligned */ | ||
27 | BPF_SOCK_ADDR_STORE(msg_src_ip6, 0, REJECT, | ||
28 | "invalid bpf_context access off=44 size=8"), | ||
29 | BPF_SOCK_ADDR_STORE(msg_src_ip6, 1, ACCEPT, | ||
30 | NULL), | ||
31 | BPF_SOCK_ADDR_STORE(msg_src_ip6, 2, REJECT, | ||
32 | "invalid bpf_context access off=52 size=8"), | ||
33 | BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT, | ||
34 | "invalid bpf_context access off=56 size=8"), | ||
35 | |||
36 | #undef BPF_SOCK_ADDR_STORE | ||
37 | |||
38 | #define BPF_SOCK_ADDR_LOAD(field, off, res, err) \ | ||
39 | { \ | ||
40 | "wide load from bpf_sock_addr." #field "[" #off "]", \ | ||
41 | .insns = { \ | ||
42 | BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, \ | ||
43 | offsetof(struct bpf_sock_addr, field[off])), \ | ||
44 | BPF_MOV64_IMM(BPF_REG_0, 1), \ | ||
45 | BPF_EXIT_INSN(), \ | ||
46 | }, \ | ||
47 | .result = res, \ | ||
48 | .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ | ||
49 | .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ | ||
50 | .errstr = err, \ | ||
51 | } | ||
52 | |||
53 | /* user_ip6[0] is u64 aligned */ | ||
54 | BPF_SOCK_ADDR_LOAD(user_ip6, 0, ACCEPT, | ||
55 | NULL), | ||
56 | BPF_SOCK_ADDR_LOAD(user_ip6, 1, REJECT, | ||
57 | "invalid bpf_context access off=12 size=8"), | ||
58 | BPF_SOCK_ADDR_LOAD(user_ip6, 2, ACCEPT, | ||
59 | NULL), | ||
60 | BPF_SOCK_ADDR_LOAD(user_ip6, 3, REJECT, | ||
61 | "invalid bpf_context access off=20 size=8"), | ||
62 | |||
63 | /* msg_src_ip6[0] is _not_ u64 aligned */ | ||
64 | BPF_SOCK_ADDR_LOAD(msg_src_ip6, 0, REJECT, | ||
65 | "invalid bpf_context access off=44 size=8"), | ||
66 | BPF_SOCK_ADDR_LOAD(msg_src_ip6, 1, ACCEPT, | ||
67 | NULL), | ||
68 | BPF_SOCK_ADDR_LOAD(msg_src_ip6, 2, REJECT, | ||
69 | "invalid bpf_context access off=52 size=8"), | ||
70 | BPF_SOCK_ADDR_LOAD(msg_src_ip6, 3, REJECT, | ||
71 | "invalid bpf_context access off=56 size=8"), | ||
72 | |||
73 | #undef BPF_SOCK_ADDR_LOAD | ||
diff --git a/tools/testing/selftests/bpf/verifier/wide_store.c b/tools/testing/selftests/bpf/verifier/wide_store.c deleted file mode 100644 index 8fe99602ded4..000000000000 --- a/tools/testing/selftests/bpf/verifier/wide_store.c +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | #define BPF_SOCK_ADDR(field, off, res, err) \ | ||
2 | { \ | ||
3 | "wide store to bpf_sock_addr." #field "[" #off "]", \ | ||
4 | .insns = { \ | ||
5 | BPF_MOV64_IMM(BPF_REG_0, 1), \ | ||
6 | BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \ | ||
7 | offsetof(struct bpf_sock_addr, field[off])), \ | ||
8 | BPF_EXIT_INSN(), \ | ||
9 | }, \ | ||
10 | .result = res, \ | ||
11 | .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ | ||
12 | .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ | ||
13 | .errstr = err, \ | ||
14 | } | ||
15 | |||
16 | /* user_ip6[0] is u64 aligned */ | ||
17 | BPF_SOCK_ADDR(user_ip6, 0, ACCEPT, | ||
18 | NULL), | ||
19 | BPF_SOCK_ADDR(user_ip6, 1, REJECT, | ||
20 | "invalid bpf_context access off=12 size=8"), | ||
21 | BPF_SOCK_ADDR(user_ip6, 2, ACCEPT, | ||
22 | NULL), | ||
23 | BPF_SOCK_ADDR(user_ip6, 3, REJECT, | ||
24 | "invalid bpf_context access off=20 size=8"), | ||
25 | |||
26 | /* msg_src_ip6[0] is _not_ u64 aligned */ | ||
27 | BPF_SOCK_ADDR(msg_src_ip6, 0, REJECT, | ||
28 | "invalid bpf_context access off=44 size=8"), | ||
29 | BPF_SOCK_ADDR(msg_src_ip6, 1, ACCEPT, | ||
30 | NULL), | ||
31 | BPF_SOCK_ADDR(msg_src_ip6, 2, REJECT, | ||
32 | "invalid bpf_context access off=52 size=8"), | ||
33 | BPF_SOCK_ADDR(msg_src_ip6, 3, REJECT, | ||
34 | "invalid bpf_context access off=56 size=8"), | ||
35 | |||
36 | #undef BPF_SOCK_ADDR | ||
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest index 6d5e9e87c4b7..063ecb290a5a 100755 --- a/tools/testing/selftests/ftrace/ftracetest +++ b/tools/testing/selftests/ftrace/ftracetest | |||
@@ -23,9 +23,15 @@ echo " If <dir> is -, all logs output in console only" | |||
23 | exit $1 | 23 | exit $1 |
24 | } | 24 | } |
25 | 25 | ||
26 | # default error | ||
27 | err_ret=1 | ||
28 | |||
29 | # kselftest skip code is 4 | ||
30 | err_skip=4 | ||
31 | |||
26 | errexit() { # message | 32 | errexit() { # message |
27 | echo "Error: $1" 1>&2 | 33 | echo "Error: $1" 1>&2 |
28 | exit 1 | 34 | exit $err_ret |
29 | } | 35 | } |
30 | 36 | ||
31 | # Ensuring user privilege | 37 | # Ensuring user privilege |
@@ -116,11 +122,31 @@ parse_opts() { # opts | |||
116 | } | 122 | } |
117 | 123 | ||
118 | # Parameters | 124 | # Parameters |
119 | DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1` | 125 | TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1` |
120 | if [ -z "$DEBUGFS_DIR" ]; then | 126 | if [ -z "$TRACING_DIR" ]; then |
121 | TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1` | 127 | DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1` |
122 | else | 128 | if [ -z "$DEBUGFS_DIR" ]; then |
123 | TRACING_DIR=$DEBUGFS_DIR/tracing | 129 | # If tracefs exists, then so does /sys/kernel/tracing |
130 | if [ -d "/sys/kernel/tracing" ]; then | ||
131 | mount -t tracefs nodev /sys/kernel/tracing || | ||
132 | errexit "Failed to mount /sys/kernel/tracing" | ||
133 | TRACING_DIR="/sys/kernel/tracing" | ||
134 | # If debugfs exists, then so does /sys/kernel/debug | ||
135 | elif [ -d "/sys/kernel/debug" ]; then | ||
136 | mount -t debugfs nodev /sys/kernel/debug || | ||
137 | errexit "Failed to mount /sys/kernel/debug" | ||
138 | TRACING_DIR="/sys/kernel/debug/tracing" | ||
139 | else | ||
140 | err_ret=$err_skip | ||
141 | errexit "debugfs and tracefs are not configured in this kernel" | ||
142 | fi | ||
143 | else | ||
144 | TRACING_DIR="$DEBUGFS_DIR/tracing" | ||
145 | fi | ||
146 | fi | ||
147 | if [ ! -d "$TRACING_DIR" ]; then | ||
148 | err_ret=$err_skip | ||
149 | errexit "ftrace is not configured in this kernel" | ||
124 | fi | 150 | fi |
125 | 151 | ||
126 | TOP_DIR=`absdir $0` | 152 | TOP_DIR=`absdir $0` |
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions index 779ec11f61bd..1d96c5f7e402 100644 --- a/tools/testing/selftests/ftrace/test.d/functions +++ b/tools/testing/selftests/ftrace/test.d/functions | |||
@@ -91,8 +91,8 @@ initialize_ftrace() { # Reset ftrace to initial-state | |||
91 | reset_events_filter | 91 | reset_events_filter |
92 | reset_ftrace_filter | 92 | reset_ftrace_filter |
93 | disable_events | 93 | disable_events |
94 | echo > set_event_pid # event tracer is always on | 94 | [ -f set_event_pid ] && echo > set_event_pid |
95 | echo > set_ftrace_pid | 95 | [ -f set_ftrace_pid ] && echo > set_ftrace_pid |
96 | [ -f set_ftrace_filter ] && echo | tee set_ftrace_* | 96 | [ -f set_ftrace_filter ] && echo | tee set_ftrace_* |
97 | [ -f set_graph_function ] && echo | tee set_graph_* | 97 | [ -f set_graph_function ] && echo | tee set_graph_* |
98 | [ -f stack_trace_filter ] && echo > stack_trace_filter | 98 | [ -f stack_trace_filter ] && echo > stack_trace_filter |
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc new file mode 100644 index 000000000000..0f60087583d8 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc | |||
@@ -0,0 +1,32 @@ | |||
1 | #!/bin/sh | ||
2 | # SPDX-License-Identifier: GPL-2.0 | ||
3 | # description: Kprobe event user-memory access | ||
4 | |||
5 | [ -f kprobe_events ] || exit_unsupported # this is configurable | ||
6 | |||
7 | grep -q '\$arg<N>' README || exit_unresolved # depends on arch | ||
8 | grep -A10 "fetcharg:" README | grep -q 'ustring' || exit_unsupported | ||
9 | grep -A10 "fetcharg:" README | grep -q '\[u\]<offset>' || exit_unsupported | ||
10 | |||
11 | :;: "user-memory access syntax and ustring working on user memory";: | ||
12 | echo 'p:myevent do_sys_open path=+0($arg2):ustring path2=+u0($arg2):string' \ | ||
13 | > kprobe_events | ||
14 | |||
15 | grep myevent kprobe_events | \ | ||
16 | grep -q 'path=+0($arg2):ustring path2=+u0($arg2):string' | ||
17 | echo 1 > events/kprobes/myevent/enable | ||
18 | echo > /dev/null | ||
19 | echo 0 > events/kprobes/myevent/enable | ||
20 | |||
21 | grep myevent trace | grep -q 'path="/dev/null" path2="/dev/null"' | ||
22 | |||
23 | :;: "user-memory access syntax and ustring not working with kernel memory";: | ||
24 | echo 'p:myevent vfs_symlink path=+0($arg3):ustring path2=+u0($arg3):string' \ | ||
25 | > kprobe_events | ||
26 | echo 1 > events/kprobes/myevent/enable | ||
27 | ln -s foo $TMPDIR/bar | ||
28 | echo 0 > events/kprobes/myevent/enable | ||
29 | |||
30 | grep myevent trace | grep -q 'path=(fault) path2=(fault)' | ||
31 | |||
32 | exit 0 | ||
diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index 9457aaeae092..4465fc2dae14 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh | |||
@@ -9,12 +9,13 @@ ret=0 | |||
9 | ksft_skip=4 | 9 | ksft_skip=4 |
10 | 10 | ||
11 | # all tests in this script. Can be overridden with -t option | 11 | # all tests in this script. Can be overridden with -t option |
12 | TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw" | 12 | TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter" |
13 | 13 | ||
14 | VERBOSE=0 | 14 | VERBOSE=0 |
15 | PAUSE_ON_FAIL=no | 15 | PAUSE_ON_FAIL=no |
16 | PAUSE=no | 16 | PAUSE=no |
17 | IP="ip -netns ns1" | 17 | IP="ip -netns ns1" |
18 | NS_EXEC="ip netns exec ns1" | ||
18 | 19 | ||
19 | log_test() | 20 | log_test() |
20 | { | 21 | { |
@@ -433,6 +434,37 @@ fib_carrier_test() | |||
433 | fib_carrier_unicast_test | 434 | fib_carrier_unicast_test |
434 | } | 435 | } |
435 | 436 | ||
437 | fib_rp_filter_test() | ||
438 | { | ||
439 | echo | ||
440 | echo "IPv4 rp_filter tests" | ||
441 | |||
442 | setup | ||
443 | |||
444 | set -e | ||
445 | $IP link set dev lo address 52:54:00:6a:c7:5e | ||
446 | $IP link set dummy0 address 52:54:00:6a:c7:5e | ||
447 | $IP link add dummy1 type dummy | ||
448 | $IP link set dummy1 address 52:54:00:6a:c7:5e | ||
449 | $IP link set dev dummy1 up | ||
450 | $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1 | ||
451 | $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1 | ||
452 | $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1 | ||
453 | |||
454 | $NS_EXEC tc qd add dev dummy1 parent root handle 1: fq_codel | ||
455 | $NS_EXEC tc filter add dev dummy1 parent 1: protocol arp basic action mirred egress redirect dev lo | ||
456 | $NS_EXEC tc filter add dev dummy1 parent 1: protocol ip basic action mirred egress redirect dev lo | ||
457 | set +e | ||
458 | |||
459 | run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 198.51.100.1" | ||
460 | log_test $? 0 "rp_filter passes local packets" | ||
461 | |||
462 | run_cmd "ip netns exec ns1 ping -I dummy1 -w1 -c1 127.0.0.1" | ||
463 | log_test $? 0 "rp_filter passes loopback packets" | ||
464 | |||
465 | cleanup | ||
466 | } | ||
467 | |||
436 | ################################################################################ | 468 | ################################################################################ |
437 | # Tests on nexthop spec | 469 | # Tests on nexthop spec |
438 | 470 | ||
@@ -1557,6 +1589,7 @@ do | |||
1557 | fib_unreg_test|unregister) fib_unreg_test;; | 1589 | fib_unreg_test|unregister) fib_unreg_test;; |
1558 | fib_down_test|down) fib_down_test;; | 1590 | fib_down_test|down) fib_down_test;; |
1559 | fib_carrier_test|carrier) fib_carrier_test;; | 1591 | fib_carrier_test|carrier) fib_carrier_test;; |
1592 | fib_rp_filter_test|rp_filter) fib_rp_filter_test;; | ||
1560 | fib_nexthop_test|nexthop) fib_nexthop_test;; | 1593 | fib_nexthop_test|nexthop) fib_nexthop_test;; |
1561 | ipv6_route_test|ipv6_rt) ipv6_route_test;; | 1594 | ipv6_route_test|ipv6_rt) ipv6_route_test;; |
1562 | ipv4_route_test|ipv4_rt) ipv4_route_test;; | 1595 | ipv4_route_test|ipv4_rt) ipv4_route_test;; |
diff --git a/tools/testing/selftests/ntb/ntb_test.sh b/tools/testing/selftests/ntb/ntb_test.sh index 8a20e03d4cb7..9c60337317c6 100755 --- a/tools/testing/selftests/ntb/ntb_test.sh +++ b/tools/testing/selftests/ntb/ntb_test.sh | |||
@@ -78,10 +78,10 @@ set -e | |||
78 | 78 | ||
79 | function _modprobe() | 79 | function _modprobe() |
80 | { | 80 | { |
81 | modprobe "$@" | 81 | modprobe "$@" || return 1 |
82 | 82 | ||
83 | if [[ "$REMOTE_HOST" != "" ]]; then | 83 | if [[ "$REMOTE_HOST" != "" ]]; then |
84 | ssh "$REMOTE_HOST" modprobe "$@" | 84 | ssh "$REMOTE_HOST" modprobe "$@" || return 1 |
85 | fi | 85 | fi |
86 | } | 86 | } |
87 | 87 | ||
@@ -442,6 +442,30 @@ function pingpong_test() | |||
442 | echo " Passed" | 442 | echo " Passed" |
443 | } | 443 | } |
444 | 444 | ||
445 | function msi_test() | ||
446 | { | ||
447 | LOC=$1 | ||
448 | REM=$2 | ||
449 | |||
450 | write_file 1 $LOC/ready | ||
451 | |||
452 | echo "Running MSI interrupt tests on: $(subdirname $LOC) / $(subdirname $REM)" | ||
453 | |||
454 | CNT=$(read_file "$LOC/count") | ||
455 | for ((i = 0; i < $CNT; i++)); do | ||
456 | START=$(read_file $REM/../irq${i}_occurrences) | ||
457 | write_file $i $LOC/trigger | ||
458 | END=$(read_file $REM/../irq${i}_occurrences) | ||
459 | |||
460 | if [[ $(($END - $START)) != 1 ]]; then | ||
461 | echo "MSI did not trigger the interrupt on the remote side!" >&2 | ||
462 | exit 1 | ||
463 | fi | ||
464 | done | ||
465 | |||
466 | echo " Passed" | ||
467 | } | ||
468 | |||
445 | function perf_test() | 469 | function perf_test() |
446 | { | 470 | { |
447 | USE_DMA=$1 | 471 | USE_DMA=$1 |
@@ -520,6 +544,29 @@ function ntb_pingpong_tests() | |||
520 | _modprobe -r ntb_pingpong | 544 | _modprobe -r ntb_pingpong |
521 | } | 545 | } |
522 | 546 | ||
547 | function ntb_msi_tests() | ||
548 | { | ||
549 | LOCAL_MSI="$DEBUGFS/ntb_msi_test/$LOCAL_DEV" | ||
550 | REMOTE_MSI="$REMOTE_HOST:$DEBUGFS/ntb_msi_test/$REMOTE_DEV" | ||
551 | |||
552 | echo "Starting ntb_msi_test tests..." | ||
553 | |||
554 | if ! _modprobe ntb_msi_test 2> /dev/null; then | ||
555 | echo " Not doing MSI tests seeing the module is not available." | ||
556 | return | ||
557 | fi | ||
558 | |||
559 | port_test $LOCAL_MSI $REMOTE_MSI | ||
560 | |||
561 | LOCAL_PEER="$LOCAL_MSI/peer$LOCAL_PIDX" | ||
562 | REMOTE_PEER="$REMOTE_MSI/peer$REMOTE_PIDX" | ||
563 | |||
564 | msi_test $LOCAL_PEER $REMOTE_PEER | ||
565 | msi_test $REMOTE_PEER $LOCAL_PEER | ||
566 | |||
567 | _modprobe -r ntb_msi_test | ||
568 | } | ||
569 | |||
523 | function ntb_perf_tests() | 570 | function ntb_perf_tests() |
524 | { | 571 | { |
525 | LOCAL_PERF="$DEBUGFS/ntb_perf/$LOCAL_DEV" | 572 | LOCAL_PERF="$DEBUGFS/ntb_perf/$LOCAL_DEV" |
@@ -541,6 +588,7 @@ function cleanup() | |||
541 | _modprobe -r ntb_perf 2> /dev/null | 588 | _modprobe -r ntb_perf 2> /dev/null |
542 | _modprobe -r ntb_pingpong 2> /dev/null | 589 | _modprobe -r ntb_pingpong 2> /dev/null |
543 | _modprobe -r ntb_transport 2> /dev/null | 590 | _modprobe -r ntb_transport 2> /dev/null |
591 | _modprobe -r ntb_msi_test 2> /dev/null | ||
544 | set -e | 592 | set -e |
545 | } | 593 | } |
546 | 594 | ||
@@ -577,5 +625,7 @@ ntb_tool_tests | |||
577 | echo | 625 | echo |
578 | ntb_pingpong_tests | 626 | ntb_pingpong_tests |
579 | echo | 627 | echo |
628 | ntb_msi_tests | ||
629 | echo | ||
580 | ntb_perf_tests | 630 | ntb_perf_tests |
581 | echo | 631 | echo |
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore index d503b8764a8e..7101ffd08d66 100644 --- a/tools/testing/selftests/powerpc/mm/.gitignore +++ b/tools/testing/selftests/powerpc/mm/.gitignore | |||
@@ -4,4 +4,4 @@ tempfile | |||
4 | prot_sao | 4 | prot_sao |
5 | segv_errors | 5 | segv_errors |
6 | wild_bctr | 6 | wild_bctr |
7 | large_vm_fork_separation \ No newline at end of file | 7 | large_vm_fork_separation |
diff --git a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h index d2c0a911f55e..2b488b78c4f2 100644 --- a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h +++ b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _PPC_ASM_H | 2 | #ifndef _PPC_ASM_H |
3 | #define __PPC_ASM_H | 3 | #define _PPC_ASM_H |
4 | #include <ppc-asm.h> | 4 | #include <ppc-asm.h> |
5 | 5 | ||
6 | #ifndef r1 | 6 | #ifndef r1 |
diff --git a/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c b/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c index 147c6dc4eb0b..c1e788a6df47 100644 --- a/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c +++ b/tools/testing/selftests/powerpc/tm/tm-vmxcopy.c | |||
@@ -79,7 +79,7 @@ int test_vmxcopy() | |||
79 | 79 | ||
80 | "5:;" | 80 | "5:;" |
81 | "stxvd2x 40,0,%[vecoutptr];" | 81 | "stxvd2x 40,0,%[vecoutptr];" |
82 | : [res]"=r"(aborted) | 82 | : [res]"=&r"(aborted) |
83 | : [vecinptr]"r"(&vecin), | 83 | : [vecinptr]"r"(&vecin), |
84 | [vecoutptr]"r"(&vecout), | 84 | [vecoutptr]"r"(&vecout), |
85 | [map]"r"(a) | 85 | [map]"r"(a) |
diff --git a/tools/testing/selftests/powerpc/vphn/Makefile b/tools/testing/selftests/powerpc/vphn/Makefile index 18b885da01bd..cf65cbf33085 100644 --- a/tools/testing/selftests/powerpc/vphn/Makefile +++ b/tools/testing/selftests/powerpc/vphn/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
2 | TEST_GEN_PROGS := test-vphn | 2 | TEST_GEN_PROGS := test-vphn |
3 | 3 | ||
4 | CFLAGS += -m64 | 4 | CFLAGS += -m64 -I$(CURDIR) |
5 | 5 | ||
6 | top_srcdir = ../../../../.. | 6 | top_srcdir = ../../../../.. |
7 | include ../../lib.mk | 7 | include ../../lib.mk |
diff --git a/tools/testing/selftests/powerpc/vphn/asm/lppaca.h b/tools/testing/selftests/powerpc/vphn/asm/lppaca.h new file mode 120000 index 000000000000..942b1d00999c --- /dev/null +++ b/tools/testing/selftests/powerpc/vphn/asm/lppaca.h | |||
@@ -0,0 +1 @@ | |||
../../../../../../arch/powerpc/include/asm/lppaca.h \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/vphn/vphn.c b/tools/testing/selftests/powerpc/vphn/vphn.c index 1d1f5f2be3b2..5b5fbddccabd 120000 --- a/tools/testing/selftests/powerpc/vphn/vphn.c +++ b/tools/testing/selftests/powerpc/vphn/vphn.c | |||
@@ -1 +1 @@ | |||
../../../../../arch/powerpc/mm/book3s64/vphn.c \ No newline at end of file | ../../../../../arch/powerpc/platforms/pseries/vphn.c \ No newline at end of file | ||
diff --git a/tools/testing/selftests/powerpc/vphn/vphn.h b/tools/testing/selftests/powerpc/vphn/vphn.h deleted file mode 120000 index 45fe160f8288..000000000000 --- a/tools/testing/selftests/powerpc/vphn/vphn.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | ../../../../../arch/powerpc/mm/book3s64/vphn.h \ No newline at end of file | ||
diff --git a/tools/testing/selftests/proc/.gitignore b/tools/testing/selftests/proc/.gitignore index 444ad39d3700..66fab4c58ed4 100644 --- a/tools/testing/selftests/proc/.gitignore +++ b/tools/testing/selftests/proc/.gitignore | |||
@@ -12,4 +12,5 @@ | |||
12 | /read | 12 | /read |
13 | /self | 13 | /self |
14 | /setns-dcache | 14 | /setns-dcache |
15 | /setns-sysvipc | ||
15 | /thread-self | 16 | /thread-self |
diff --git a/tools/testing/selftests/proc/Makefile b/tools/testing/selftests/proc/Makefile index 9f09fcd09ea3..a8ed0f684829 100644 --- a/tools/testing/selftests/proc/Makefile +++ b/tools/testing/selftests/proc/Makefile | |||
@@ -17,6 +17,7 @@ TEST_GEN_PROGS += proc-uptime-002 | |||
17 | TEST_GEN_PROGS += read | 17 | TEST_GEN_PROGS += read |
18 | TEST_GEN_PROGS += self | 18 | TEST_GEN_PROGS += self |
19 | TEST_GEN_PROGS += setns-dcache | 19 | TEST_GEN_PROGS += setns-dcache |
20 | TEST_GEN_PROGS += setns-sysvipc | ||
20 | TEST_GEN_PROGS += thread-self | 21 | TEST_GEN_PROGS += thread-self |
21 | 22 | ||
22 | include ../lib.mk | 23 | include ../lib.mk |
diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index 853aa164a401..18a3bde8bc96 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c | |||
@@ -215,6 +215,11 @@ static const char str_vsyscall[] = | |||
215 | "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; | 215 | "ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n"; |
216 | 216 | ||
217 | #ifdef __x86_64__ | 217 | #ifdef __x86_64__ |
218 | static void sigaction_SIGSEGV(int _, siginfo_t *__, void *___) | ||
219 | { | ||
220 | _exit(1); | ||
221 | } | ||
222 | |||
218 | /* | 223 | /* |
219 | * vsyscall page can't be unmapped, probe it with memory load. | 224 | * vsyscall page can't be unmapped, probe it with memory load. |
220 | */ | 225 | */ |
@@ -231,11 +236,19 @@ static void vsyscall(void) | |||
231 | if (pid == 0) { | 236 | if (pid == 0) { |
232 | struct rlimit rlim = {0, 0}; | 237 | struct rlimit rlim = {0, 0}; |
233 | (void)setrlimit(RLIMIT_CORE, &rlim); | 238 | (void)setrlimit(RLIMIT_CORE, &rlim); |
239 | |||
240 | /* Hide "segfault at ffffffffff600000" messages. */ | ||
241 | struct sigaction act; | ||
242 | memset(&act, 0, sizeof(struct sigaction)); | ||
243 | act.sa_flags = SA_SIGINFO; | ||
244 | act.sa_sigaction = sigaction_SIGSEGV; | ||
245 | (void)sigaction(SIGSEGV, &act, NULL); | ||
246 | |||
234 | *(volatile int *)0xffffffffff600000UL; | 247 | *(volatile int *)0xffffffffff600000UL; |
235 | exit(0); | 248 | exit(0); |
236 | } | 249 | } |
237 | wait(&wstatus); | 250 | waitpid(pid, &wstatus, 0); |
238 | if (WIFEXITED(wstatus)) { | 251 | if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) { |
239 | g_vsyscall = true; | 252 | g_vsyscall = true; |
240 | } | 253 | } |
241 | } | 254 | } |
diff --git a/tools/testing/selftests/proc/setns-sysvipc.c b/tools/testing/selftests/proc/setns-sysvipc.c new file mode 100644 index 000000000000..903890c5e587 --- /dev/null +++ b/tools/testing/selftests/proc/setns-sysvipc.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Copyright © 2019 Alexey Dobriyan <adobriyan@gmail.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | /* | ||
17 | * Test that setns(CLONE_NEWIPC) points to new /proc/sysvipc content even | ||
18 | * if old one is in dcache. | ||
19 | */ | ||
20 | #undef NDEBUG | ||
21 | #include <assert.h> | ||
22 | #include <errno.h> | ||
23 | #include <stdio.h> | ||
24 | #include <sched.h> | ||
25 | #include <signal.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <string.h> | ||
28 | #include <unistd.h> | ||
29 | #include <sys/types.h> | ||
30 | #include <sys/stat.h> | ||
31 | #include <fcntl.h> | ||
32 | #include <sys/ipc.h> | ||
33 | #include <sys/shm.h> | ||
34 | |||
35 | static pid_t pid = -1; | ||
36 | |||
37 | static void f(void) | ||
38 | { | ||
39 | if (pid > 0) { | ||
40 | kill(pid, SIGTERM); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | int main(void) | ||
45 | { | ||
46 | int fd[2]; | ||
47 | char _ = 0; | ||
48 | int nsfd; | ||
49 | |||
50 | atexit(f); | ||
51 | |||
52 | /* Check for priviledges and syscall availability straight away. */ | ||
53 | if (unshare(CLONE_NEWIPC) == -1) { | ||
54 | if (errno == ENOSYS || errno == EPERM) { | ||
55 | return 4; | ||
56 | } | ||
57 | return 1; | ||
58 | } | ||
59 | /* Distinguisher between two otherwise empty IPC namespaces. */ | ||
60 | if (shmget(IPC_PRIVATE, 1, IPC_CREAT) == -1) { | ||
61 | return 1; | ||
62 | } | ||
63 | |||
64 | if (pipe(fd) == -1) { | ||
65 | return 1; | ||
66 | } | ||
67 | |||
68 | pid = fork(); | ||
69 | if (pid == -1) { | ||
70 | return 1; | ||
71 | } | ||
72 | |||
73 | if (pid == 0) { | ||
74 | if (unshare(CLONE_NEWIPC) == -1) { | ||
75 | return 1; | ||
76 | } | ||
77 | |||
78 | if (write(fd[1], &_, 1) != 1) { | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | pause(); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | if (read(fd[0], &_, 1) != 1) { | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | { | ||
92 | char buf[64]; | ||
93 | snprintf(buf, sizeof(buf), "/proc/%u/ns/ipc", pid); | ||
94 | nsfd = open(buf, O_RDONLY); | ||
95 | if (nsfd == -1) { | ||
96 | return 1; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* Reliably pin dentry into dcache. */ | ||
101 | (void)open("/proc/sysvipc/shm", O_RDONLY); | ||
102 | |||
103 | if (setns(nsfd, CLONE_NEWIPC) == -1) { | ||
104 | return 1; | ||
105 | } | ||
106 | |||
107 | kill(pid, SIGTERM); | ||
108 | pid = 0; | ||
109 | |||
110 | { | ||
111 | char buf[4096]; | ||
112 | ssize_t rv; | ||
113 | int fd; | ||
114 | |||
115 | fd = open("/proc/sysvipc/shm", O_RDONLY); | ||
116 | if (fd == -1) { | ||
117 | return 1; | ||
118 | } | ||
119 | |||
120 | #define S32 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n" | ||
121 | #define S64 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n" | ||
122 | rv = read(fd, buf, sizeof(buf)); | ||
123 | if (rv == strlen(S32)) { | ||
124 | assert(memcmp(buf, S32, strlen(S32)) == 0); | ||
125 | } else if (rv == strlen(S64)) { | ||
126 | assert(memcmp(buf, S64, strlen(S64)) == 0); | ||
127 | } else { | ||
128 | assert(0); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
diff --git a/tools/testing/selftests/ptrace/.gitignore b/tools/testing/selftests/ptrace/.gitignore index b3e59d41fd82..cfcc49a7def7 100644 --- a/tools/testing/selftests/ptrace/.gitignore +++ b/tools/testing/selftests/ptrace/.gitignore | |||
@@ -1 +1,2 @@ | |||
1 | get_syscall_info | ||
1 | peeksiginfo | 2 | peeksiginfo |
diff --git a/tools/testing/selftests/ptrace/Makefile b/tools/testing/selftests/ptrace/Makefile index cb21c76a18ca..c0b7f89f0930 100644 --- a/tools/testing/selftests/ptrace/Makefile +++ b/tools/testing/selftests/ptrace/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
2 | CFLAGS += -iquote../../../../include/uapi -Wall | 2 | CFLAGS += -iquote../../../../include/uapi -Wall |
3 | 3 | ||
4 | TEST_GEN_PROGS := peeksiginfo | 4 | TEST_GEN_PROGS := get_syscall_info peeksiginfo |
5 | 5 | ||
6 | include ../lib.mk | 6 | include ../lib.mk |
diff --git a/tools/testing/selftests/ptrace/get_syscall_info.c b/tools/testing/selftests/ptrace/get_syscall_info.c new file mode 100644 index 000000000000..5bcd1c7b5be6 --- /dev/null +++ b/tools/testing/selftests/ptrace/get_syscall_info.c | |||
@@ -0,0 +1,271 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Copyright (c) 2018 Dmitry V. Levin <ldv@altlinux.org> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Check whether PTRACE_GET_SYSCALL_INFO semantics implemented in the kernel | ||
7 | * matches userspace expectations. | ||
8 | */ | ||
9 | |||
10 | #include "../kselftest_harness.h" | ||
11 | #include <err.h> | ||
12 | #include <signal.h> | ||
13 | #include <asm/unistd.h> | ||
14 | #include "linux/ptrace.h" | ||
15 | |||
16 | static int | ||
17 | kill_tracee(pid_t pid) | ||
18 | { | ||
19 | if (!pid) | ||
20 | return 0; | ||
21 | |||
22 | int saved_errno = errno; | ||
23 | |||
24 | int rc = kill(pid, SIGKILL); | ||
25 | |||
26 | errno = saved_errno; | ||
27 | return rc; | ||
28 | } | ||
29 | |||
30 | static long | ||
31 | sys_ptrace(int request, pid_t pid, unsigned long addr, unsigned long data) | ||
32 | { | ||
33 | return syscall(__NR_ptrace, request, pid, addr, data); | ||
34 | } | ||
35 | |||
36 | #define LOG_KILL_TRACEE(fmt, ...) \ | ||
37 | do { \ | ||
38 | kill_tracee(pid); \ | ||
39 | TH_LOG("wait #%d: " fmt, \ | ||
40 | ptrace_stop, ##__VA_ARGS__); \ | ||
41 | } while (0) | ||
42 | |||
43 | TEST(get_syscall_info) | ||
44 | { | ||
45 | static const unsigned long args[][7] = { | ||
46 | /* a sequence of architecture-agnostic syscalls */ | ||
47 | { | ||
48 | __NR_chdir, | ||
49 | (unsigned long) "", | ||
50 | 0xbad1fed1, | ||
51 | 0xbad2fed2, | ||
52 | 0xbad3fed3, | ||
53 | 0xbad4fed4, | ||
54 | 0xbad5fed5 | ||
55 | }, | ||
56 | { | ||
57 | __NR_gettid, | ||
58 | 0xcaf0bea0, | ||
59 | 0xcaf1bea1, | ||
60 | 0xcaf2bea2, | ||
61 | 0xcaf3bea3, | ||
62 | 0xcaf4bea4, | ||
63 | 0xcaf5bea5 | ||
64 | }, | ||
65 | { | ||
66 | __NR_exit_group, | ||
67 | 0, | ||
68 | 0xfac1c0d1, | ||
69 | 0xfac2c0d2, | ||
70 | 0xfac3c0d3, | ||
71 | 0xfac4c0d4, | ||
72 | 0xfac5c0d5 | ||
73 | } | ||
74 | }; | ||
75 | const unsigned long *exp_args; | ||
76 | |||
77 | pid_t pid = fork(); | ||
78 | |||
79 | ASSERT_LE(0, pid) { | ||
80 | TH_LOG("fork: %m"); | ||
81 | } | ||
82 | |||
83 | if (pid == 0) { | ||
84 | /* get the pid before PTRACE_TRACEME */ | ||
85 | pid = getpid(); | ||
86 | ASSERT_EQ(0, sys_ptrace(PTRACE_TRACEME, 0, 0, 0)) { | ||
87 | TH_LOG("PTRACE_TRACEME: %m"); | ||
88 | } | ||
89 | ASSERT_EQ(0, kill(pid, SIGSTOP)) { | ||
90 | /* cannot happen */ | ||
91 | TH_LOG("kill SIGSTOP: %m"); | ||
92 | } | ||
93 | for (unsigned int i = 0; i < ARRAY_SIZE(args); ++i) { | ||
94 | syscall(args[i][0], | ||
95 | args[i][1], args[i][2], args[i][3], | ||
96 | args[i][4], args[i][5], args[i][6]); | ||
97 | } | ||
98 | /* unreachable */ | ||
99 | _exit(1); | ||
100 | } | ||
101 | |||
102 | const struct { | ||
103 | unsigned int is_error; | ||
104 | int rval; | ||
105 | } *exp_param, exit_param[] = { | ||
106 | { 1, -ENOENT }, /* chdir */ | ||
107 | { 0, pid } /* gettid */ | ||
108 | }; | ||
109 | |||
110 | unsigned int ptrace_stop; | ||
111 | |||
112 | for (ptrace_stop = 0; ; ++ptrace_stop) { | ||
113 | struct ptrace_syscall_info info = { | ||
114 | .op = 0xff /* invalid PTRACE_SYSCALL_INFO_* op */ | ||
115 | }; | ||
116 | const size_t size = sizeof(info); | ||
117 | const int expected_none_size = | ||
118 | (void *) &info.entry - (void *) &info; | ||
119 | const int expected_entry_size = | ||
120 | (void *) &info.entry.args[6] - (void *) &info; | ||
121 | const int expected_exit_size = | ||
122 | (void *) (&info.exit.is_error + 1) - | ||
123 | (void *) &info; | ||
124 | int status; | ||
125 | long rc; | ||
126 | |||
127 | ASSERT_EQ(pid, wait(&status)) { | ||
128 | /* cannot happen */ | ||
129 | LOG_KILL_TRACEE("wait: %m"); | ||
130 | } | ||
131 | if (WIFEXITED(status)) { | ||
132 | pid = 0; /* the tracee is no more */ | ||
133 | ASSERT_EQ(0, WEXITSTATUS(status)); | ||
134 | break; | ||
135 | } | ||
136 | ASSERT_FALSE(WIFSIGNALED(status)) { | ||
137 | pid = 0; /* the tracee is no more */ | ||
138 | LOG_KILL_TRACEE("unexpected signal %u", | ||
139 | WTERMSIG(status)); | ||
140 | } | ||
141 | ASSERT_TRUE(WIFSTOPPED(status)) { | ||
142 | /* cannot happen */ | ||
143 | LOG_KILL_TRACEE("unexpected wait status %#x", status); | ||
144 | } | ||
145 | |||
146 | switch (WSTOPSIG(status)) { | ||
147 | case SIGSTOP: | ||
148 | ASSERT_EQ(0, ptrace_stop) { | ||
149 | LOG_KILL_TRACEE("unexpected signal stop"); | ||
150 | } | ||
151 | ASSERT_EQ(0, sys_ptrace(PTRACE_SETOPTIONS, pid, 0, | ||
152 | PTRACE_O_TRACESYSGOOD)) { | ||
153 | LOG_KILL_TRACEE("PTRACE_SETOPTIONS: %m"); | ||
154 | } | ||
155 | ASSERT_LT(0, (rc = sys_ptrace(PTRACE_GET_SYSCALL_INFO, | ||
156 | pid, size, | ||
157 | (unsigned long) &info))) { | ||
158 | LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m"); | ||
159 | } | ||
160 | ASSERT_EQ(expected_none_size, rc) { | ||
161 | LOG_KILL_TRACEE("signal stop mismatch"); | ||
162 | } | ||
163 | ASSERT_EQ(PTRACE_SYSCALL_INFO_NONE, info.op) { | ||
164 | LOG_KILL_TRACEE("signal stop mismatch"); | ||
165 | } | ||
166 | ASSERT_TRUE(info.arch) { | ||
167 | LOG_KILL_TRACEE("signal stop mismatch"); | ||
168 | } | ||
169 | ASSERT_TRUE(info.instruction_pointer) { | ||
170 | LOG_KILL_TRACEE("signal stop mismatch"); | ||
171 | } | ||
172 | ASSERT_TRUE(info.stack_pointer) { | ||
173 | LOG_KILL_TRACEE("signal stop mismatch"); | ||
174 | } | ||
175 | break; | ||
176 | |||
177 | case SIGTRAP | 0x80: | ||
178 | ASSERT_LT(0, (rc = sys_ptrace(PTRACE_GET_SYSCALL_INFO, | ||
179 | pid, size, | ||
180 | (unsigned long) &info))) { | ||
181 | LOG_KILL_TRACEE("PTRACE_GET_SYSCALL_INFO: %m"); | ||
182 | } | ||
183 | switch (ptrace_stop) { | ||
184 | case 1: /* entering chdir */ | ||
185 | case 3: /* entering gettid */ | ||
186 | case 5: /* entering exit_group */ | ||
187 | exp_args = args[ptrace_stop / 2]; | ||
188 | ASSERT_EQ(expected_entry_size, rc) { | ||
189 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
190 | } | ||
191 | ASSERT_EQ(PTRACE_SYSCALL_INFO_ENTRY, info.op) { | ||
192 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
193 | } | ||
194 | ASSERT_TRUE(info.arch) { | ||
195 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
196 | } | ||
197 | ASSERT_TRUE(info.instruction_pointer) { | ||
198 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
199 | } | ||
200 | ASSERT_TRUE(info.stack_pointer) { | ||
201 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
202 | } | ||
203 | ASSERT_EQ(exp_args[0], info.entry.nr) { | ||
204 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
205 | } | ||
206 | ASSERT_EQ(exp_args[1], info.entry.args[0]) { | ||
207 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
208 | } | ||
209 | ASSERT_EQ(exp_args[2], info.entry.args[1]) { | ||
210 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
211 | } | ||
212 | ASSERT_EQ(exp_args[3], info.entry.args[2]) { | ||
213 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
214 | } | ||
215 | ASSERT_EQ(exp_args[4], info.entry.args[3]) { | ||
216 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
217 | } | ||
218 | ASSERT_EQ(exp_args[5], info.entry.args[4]) { | ||
219 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
220 | } | ||
221 | ASSERT_EQ(exp_args[6], info.entry.args[5]) { | ||
222 | LOG_KILL_TRACEE("entry stop mismatch"); | ||
223 | } | ||
224 | break; | ||
225 | case 2: /* exiting chdir */ | ||
226 | case 4: /* exiting gettid */ | ||
227 | exp_param = &exit_param[ptrace_stop / 2 - 1]; | ||
228 | ASSERT_EQ(expected_exit_size, rc) { | ||
229 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
230 | } | ||
231 | ASSERT_EQ(PTRACE_SYSCALL_INFO_EXIT, info.op) { | ||
232 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
233 | } | ||
234 | ASSERT_TRUE(info.arch) { | ||
235 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
236 | } | ||
237 | ASSERT_TRUE(info.instruction_pointer) { | ||
238 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
239 | } | ||
240 | ASSERT_TRUE(info.stack_pointer) { | ||
241 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
242 | } | ||
243 | ASSERT_EQ(exp_param->is_error, | ||
244 | info.exit.is_error) { | ||
245 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
246 | } | ||
247 | ASSERT_EQ(exp_param->rval, info.exit.rval) { | ||
248 | LOG_KILL_TRACEE("exit stop mismatch"); | ||
249 | } | ||
250 | break; | ||
251 | default: | ||
252 | LOG_KILL_TRACEE("unexpected syscall stop"); | ||
253 | abort(); | ||
254 | } | ||
255 | break; | ||
256 | |||
257 | default: | ||
258 | LOG_KILL_TRACEE("unexpected stop signal %#x", | ||
259 | WSTOPSIG(status)); | ||
260 | abort(); | ||
261 | } | ||
262 | |||
263 | ASSERT_EQ(0, sys_ptrace(PTRACE_SYSCALL, pid, 0, 0)) { | ||
264 | LOG_KILL_TRACEE("PTRACE_SYSCALL: %m"); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | ASSERT_EQ(ARRAY_SIZE(args) * 2, ptrace_stop); | ||
269 | } | ||
270 | |||
271 | TEST_HARNESS_MAIN | ||
diff --git a/tools/testing/selftests/safesetid/safesetid-test.c b/tools/testing/selftests/safesetid/safesetid-test.c index 892c8e8b1b8b..8f40c6ecdad1 100644 --- a/tools/testing/selftests/safesetid/safesetid-test.c +++ b/tools/testing/selftests/safesetid/safesetid-test.c | |||
@@ -142,23 +142,19 @@ static void ensure_securityfs_mounted(void) | |||
142 | 142 | ||
143 | static void write_policies(void) | 143 | static void write_policies(void) |
144 | { | 144 | { |
145 | static char *policy_str = | ||
146 | "1:2\n" | ||
147 | "1:3\n" | ||
148 | "2:2\n" | ||
149 | "3:3\n"; | ||
145 | ssize_t written; | 150 | ssize_t written; |
146 | int fd; | 151 | int fd; |
147 | 152 | ||
148 | fd = open(add_whitelist_policy_file, O_WRONLY); | 153 | fd = open(add_whitelist_policy_file, O_WRONLY); |
149 | if (fd < 0) | 154 | if (fd < 0) |
150 | die("cant open add_whitelist_policy file\n"); | 155 | die("cant open add_whitelist_policy file\n"); |
151 | written = write(fd, "1:2", strlen("1:2")); | 156 | written = write(fd, policy_str, strlen(policy_str)); |
152 | if (written != strlen("1:2")) { | 157 | if (written != strlen(policy_str)) { |
153 | if (written >= 0) { | ||
154 | die("short write to %s\n", add_whitelist_policy_file); | ||
155 | } else { | ||
156 | die("write to %s failed: %s\n", | ||
157 | add_whitelist_policy_file, strerror(errno)); | ||
158 | } | ||
159 | } | ||
160 | written = write(fd, "1:3", strlen("1:3")); | ||
161 | if (written != strlen("1:3")) { | ||
162 | if (written >= 0) { | 158 | if (written >= 0) { |
163 | die("short write to %s\n", add_whitelist_policy_file); | 159 | die("short write to %s\n", add_whitelist_policy_file); |
164 | } else { | 160 | } else { |
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index dc66fe852768..6ef7f16c4cf5 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c | |||
@@ -1775,13 +1775,18 @@ void tracer_ptrace(struct __test_metadata *_metadata, pid_t tracee, | |||
1775 | unsigned long msg; | 1775 | unsigned long msg; |
1776 | static bool entry; | 1776 | static bool entry; |
1777 | 1777 | ||
1778 | /* Make sure we got an empty message. */ | 1778 | /* |
1779 | * The traditional way to tell PTRACE_SYSCALL entry/exit | ||
1780 | * is by counting. | ||
1781 | */ | ||
1782 | entry = !entry; | ||
1783 | |||
1784 | /* Make sure we got an appropriate message. */ | ||
1779 | ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg); | 1785 | ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg); |
1780 | EXPECT_EQ(0, ret); | 1786 | EXPECT_EQ(0, ret); |
1781 | EXPECT_EQ(0, msg); | 1787 | EXPECT_EQ(entry ? PTRACE_EVENTMSG_SYSCALL_ENTRY |
1788 | : PTRACE_EVENTMSG_SYSCALL_EXIT, msg); | ||
1782 | 1789 | ||
1783 | /* The only way to tell PTRACE_SYSCALL entry/exit is by counting. */ | ||
1784 | entry = !entry; | ||
1785 | if (!entry) | 1790 | if (!entry) |
1786 | return; | 1791 | return; |
1787 | 1792 | ||
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 45e7e89928a5..bf5ebf59c2d4 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json | |||
@@ -70,6 +70,123 @@ | |||
70 | "teardown": [] | 70 | "teardown": [] |
71 | }, | 71 | }, |
72 | { | 72 | { |
73 | "id": "d4cd", | ||
74 | "name": "Add skbedit action with valid mark and mask", | ||
75 | "category": [ | ||
76 | "actions", | ||
77 | "skbedit" | ||
78 | ], | ||
79 | "setup": [ | ||
80 | [ | ||
81 | "$TC actions flush action skbedit", | ||
82 | 0, | ||
83 | 1, | ||
84 | 255 | ||
85 | ] | ||
86 | ], | ||
87 | "cmdUnderTest": "$TC actions add action skbedit mark 1/0xaabb", | ||
88 | "expExitCode": "0", | ||
89 | "verifyCmd": "$TC actions list action skbedit", | ||
90 | "matchPattern": "action order [0-9]*: skbedit mark 1/0xaabb", | ||
91 | "matchCount": "1", | ||
92 | "teardown": [ | ||
93 | "$TC actions flush action skbedit" | ||
94 | ] | ||
95 | }, | ||
96 | { | ||
97 | "id": "baa7", | ||
98 | "name": "Add skbedit action with valid mark and 32-bit maximum mask", | ||
99 | "category": [ | ||
100 | "actions", | ||
101 | "skbedit" | ||
102 | ], | ||
103 | "setup": [ | ||
104 | [ | ||
105 | "$TC actions flush action skbedit", | ||
106 | 0, | ||
107 | 1, | ||
108 | 255 | ||
109 | ] | ||
110 | ], | ||
111 | "cmdUnderTest": "$TC actions add action skbedit mark 1/0xffffffff", | ||
112 | "expExitCode": "0", | ||
113 | "verifyCmd": "$TC actions list action skbedit", | ||
114 | "matchPattern": "action order [0-9]*: skbedit mark 1/0xffffffff", | ||
115 | "matchCount": "1", | ||
116 | "teardown": [ | ||
117 | "$TC actions flush action skbedit" | ||
118 | ] | ||
119 | }, | ||
120 | { | ||
121 | "id": "62a5", | ||
122 | "name": "Add skbedit action with valid mark and mask exceeding 32-bit maximum", | ||
123 | "category": [ | ||
124 | "actions", | ||
125 | "skbedit" | ||
126 | ], | ||
127 | "setup": [ | ||
128 | [ | ||
129 | "$TC actions flush action skbedit", | ||
130 | 0, | ||
131 | 1, | ||
132 | 255 | ||
133 | ] | ||
134 | ], | ||
135 | "cmdUnderTest": "$TC actions add action skbedit mark 1/0xaabbccddeeff112233", | ||
136 | "expExitCode": "255", | ||
137 | "verifyCmd": "$TC actions list action skbedit", | ||
138 | "matchPattern": "action order [0-9]*: skbedit mark 1/0xaabbccddeeff112233", | ||
139 | "matchCount": "0", | ||
140 | "teardown": [] | ||
141 | }, | ||
142 | { | ||
143 | "id": "bc15", | ||
144 | "name": "Add skbedit action with valid mark and mask with invalid format", | ||
145 | "category": [ | ||
146 | "actions", | ||
147 | "skbedit" | ||
148 | ], | ||
149 | "setup": [ | ||
150 | [ | ||
151 | "$TC actions flush action skbedit", | ||
152 | 0, | ||
153 | 1, | ||
154 | 255 | ||
155 | ] | ||
156 | ], | ||
157 | "cmdUnderTest": "$TC actions add action skbedit mark 1/-1234", | ||
158 | "expExitCode": "255", | ||
159 | "verifyCmd": "$TC actions list action skbedit", | ||
160 | "matchPattern": "action order [0-9]*: skbedit mark 1/-1234", | ||
161 | "matchCount": "0", | ||
162 | "teardown": [] | ||
163 | }, | ||
164 | { | ||
165 | "id": "57c2", | ||
166 | "name": "Replace skbedit action with new mask", | ||
167 | "category": [ | ||
168 | "actions", | ||
169 | "skbedit" | ||
170 | ], | ||
171 | "setup": [ | ||
172 | [ | ||
173 | "$TC actions flush action skbedit", | ||
174 | 0, | ||
175 | 1, | ||
176 | 255 | ||
177 | ], | ||
178 | "$TC actions add action skbedit mark 1/0x11223344 index 1" | ||
179 | ], | ||
180 | "cmdUnderTest": "$TC actions replace action skbedit mark 1/0xaabb index 1", | ||
181 | "expExitCode": "0", | ||
182 | "verifyCmd": "$TC actions list action skbedit", | ||
183 | "matchPattern": "action order [0-9]*: skbedit mark 1/0xaabb", | ||
184 | "matchCount": "1", | ||
185 | "teardown": [ | ||
186 | "$TC actions flush action skbedit" | ||
187 | ] | ||
188 | }, | ||
189 | { | ||
73 | "id": "081d", | 190 | "id": "081d", |
74 | "name": "Add skbedit action with priority", | 191 | "name": "Add skbedit action with priority", |
75 | "category": [ | 192 | "category": [ |
diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c index 5ab4c60c100e..15a329da59fa 100644 --- a/tools/testing/selftests/x86/fsgsbase.c +++ b/tools/testing/selftests/x86/fsgsbase.c | |||
@@ -489,25 +489,11 @@ static void test_ptrace_write_gsbase(void) | |||
489 | * selector value is changed or not by the GSBASE write in | 489 | * selector value is changed or not by the GSBASE write in |
490 | * a ptracer. | 490 | * a ptracer. |
491 | */ | 491 | */ |
492 | if (gs != *shared_scratch) { | 492 | if (gs == 0 && base == 0xFF) { |
493 | nerrs++; | 493 | printf("[OK]\tGS was reset as expected\n"); |
494 | printf("[FAIL]\tGS changed to %lx\n", gs); | ||
495 | |||
496 | /* | ||
497 | * On older kernels, poking a nonzero value into the | ||
498 | * base would zero the selector. On newer kernels, | ||
499 | * this behavior has changed -- poking the base | ||
500 | * changes only the base and, if FSGSBASE is not | ||
501 | * available, this may have no effect. | ||
502 | */ | ||
503 | if (gs == 0) | ||
504 | printf("\tNote: this is expected behavior on older kernels.\n"); | ||
505 | } else if (have_fsgsbase && (base != 0xFF)) { | ||
506 | nerrs++; | ||
507 | printf("[FAIL]\tGSBASE changed to %lx\n", base); | ||
508 | } else { | 494 | } else { |
509 | printf("[OK]\tGS remained 0x%hx%s", *shared_scratch, have_fsgsbase ? " and GSBASE changed to 0xFF" : ""); | 495 | nerrs++; |
510 | printf("\n"); | 496 | printf("[FAIL]\tGS=0x%lx, GSBASE=0x%lx (should be 0, 0xFF)\n", gs, base); |
511 | } | 497 | } |
512 | } | 498 | } |
513 | 499 | ||
diff --git a/tools/testing/selftests/zram/README b/tools/testing/selftests/zram/README index 7972cc512408..110b34834a6f 100644 --- a/tools/testing/selftests/zram/README +++ b/tools/testing/selftests/zram/README | |||
@@ -37,4 +37,4 @@ Commands required for testing: | |||
37 | - mkfs/ mkfs.ext4 | 37 | - mkfs/ mkfs.ext4 |
38 | 38 | ||
39 | For more information please refer: | 39 | For more information please refer: |
40 | kernel-source-tree/Documentation/blockdev/zram.txt | 40 | kernel-source-tree/Documentation/admin-guide/blockdev/zram.rst |