diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 14:39:09 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-14 14:39:09 -0500 |
commit | 747a9b0a08ae300b99b8aa7861bd3609f3b3e782 (patch) | |
tree | c76ce3e65c4066120dc2918b8db1bc4100bdf272 /tools | |
parent | 32250e4a5fa0b618044afa59fba01093a4bcb14a (diff) | |
parent | c36608843adf4674c462e49f63b64b2987d0ba0b (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"Tooling fixes, the biggest patch is one that decouples the kernel's
list.h from tooling list.h"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
perf tools: Fallback to srcdir/Documentation/tips.txt
perf ui/tui: Print helpline message as is
perf tools: Set and pass DOCDIR to builtin-report.c
perf tools: Add file_only config option to strlist
perf tools: Add more usage tips
perf record: Add --buildid-all option
tools subcmd: Add missing NORETURN define for parse-options.h
tools: Fix formatting of the "make -C tools" help message
tools: Make list.h self-sufficient
perf tools: Fix mmap2 event allocation in synthesize code
perf stat: Fix recort_usage typo
perf test: Reset err after using it hold errcode in hist testcases
perf test: Fix false TEST_OK result for 'perf test hist'
tools build: Add BPF feature check to test-all
perf bpf: Fix build breakage due to libbpf
tools: Move Makefile.arch from perf/config to tools/scripts
perf tools: Fix PowerPC native building
perf tools: Fix phony build target for build-test
perf tools: Add -lutil in python lib list for broken python-config
perf tools: Add missing sources to perf's MANIFEST
...
Diffstat (limited to 'tools')
28 files changed, 918 insertions, 66 deletions
diff --git a/tools/Makefile b/tools/Makefile index 1dc6900468ed..6339f6ac3ccb 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -8,24 +8,24 @@ include scripts/Makefile.include | |||
8 | help: | 8 | help: |
9 | @echo 'Possible targets:' | 9 | @echo 'Possible targets:' |
10 | @echo '' | 10 | @echo '' |
11 | @echo ' acpi - ACPI tools' | 11 | @echo ' acpi - ACPI tools' |
12 | @echo ' cgroup - cgroup tools' | 12 | @echo ' cgroup - cgroup tools' |
13 | @echo ' cpupower - a tool for all things x86 CPU power' | 13 | @echo ' cpupower - a tool for all things x86 CPU power' |
14 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' | 14 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' |
15 | @echo ' hv - tools used when in Hyper-V clients' | 15 | @echo ' freefall - laptop accelerometer program for disk protection' |
16 | @echo ' iio - IIO tools' | 16 | @echo ' hv - tools used when in Hyper-V clients' |
17 | @echo ' lguest - a minimal 32-bit x86 hypervisor' | 17 | @echo ' iio - IIO tools' |
18 | @echo ' perf - Linux performance measurement and analysis tool' | 18 | @echo ' lguest - a minimal 32-bit x86 hypervisor' |
19 | @echo ' selftests - various kernel selftests' | 19 | @echo ' net - misc networking tools' |
20 | @echo ' spi - spi tools' | 20 | @echo ' perf - Linux performance measurement and analysis tool' |
21 | @echo ' turbostat - Intel CPU idle stats and freq reporting tool' | 21 | @echo ' selftests - various kernel selftests' |
22 | @echo ' usb - USB testing tools' | 22 | @echo ' spi - spi tools' |
23 | @echo ' virtio - vhost test module' | 23 | @echo ' tmon - thermal monitoring and tuning tool' |
24 | @echo ' net - misc networking tools' | 24 | @echo ' turbostat - Intel CPU idle stats and freq reporting tool' |
25 | @echo ' vm - misc vm tools' | 25 | @echo ' usb - USB testing tools' |
26 | @echo ' virtio - vhost test module' | ||
27 | @echo ' vm - misc vm tools' | ||
26 | @echo ' x86_energy_perf_policy - Intel energy policy tool' | 28 | @echo ' x86_energy_perf_policy - Intel energy policy tool' |
27 | @echo ' tmon - thermal monitoring and tuning tool' | ||
28 | @echo ' freefall - laptop accelerometer program for disk protection' | ||
29 | @echo '' | 29 | @echo '' |
30 | @echo 'You can do:' | 30 | @echo 'You can do:' |
31 | @echo ' $$ make -C tools/ <tool>_install' | 31 | @echo ' $$ make -C tools/ <tool>_install' |
@@ -128,6 +128,12 @@ liblockdep_clean: | |||
128 | libapi_clean: | 128 | libapi_clean: |
129 | $(call descend,lib/api,clean) | 129 | $(call descend,lib/api,clean) |
130 | 130 | ||
131 | libbpf_clean: | ||
132 | $(call descend,lib/bpf,clean) | ||
133 | |||
134 | libsubcmd_clean: | ||
135 | $(call descend,lib/subcmd,clean) | ||
136 | |||
131 | perf_clean: | 137 | perf_clean: |
132 | $(call descend,$(@:_clean=),clean) | 138 | $(call descend,$(@:_clean=),clean) |
133 | 139 | ||
@@ -143,9 +149,12 @@ tmon_clean: | |||
143 | freefall_clean: | 149 | freefall_clean: |
144 | $(call descend,laptop/freefall,clean) | 150 | $(call descend,laptop/freefall,clean) |
145 | 151 | ||
152 | build_clean: | ||
153 | $(call descend,build,clean) | ||
154 | |||
146 | clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ | 155 | clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ |
147 | perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ | 156 | perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ |
148 | vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ | 157 | vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ |
149 | freefall_clean | 158 | freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean |
150 | 159 | ||
151 | .PHONY: FORCE | 160 | .PHONY: FORCE |
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index 33cf6f20bd4e..81025cade45f 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c | |||
@@ -125,6 +125,10 @@ | |||
125 | # include "test-get_cpuid.c" | 125 | # include "test-get_cpuid.c" |
126 | #undef main | 126 | #undef main |
127 | 127 | ||
128 | #define main main_test_bpf | ||
129 | # include "test-bpf.c" | ||
130 | #undef main | ||
131 | |||
128 | int main(int argc, char *argv[]) | 132 | int main(int argc, char *argv[]) |
129 | { | 133 | { |
130 | main_test_libpython(); | 134 | main_test_libpython(); |
@@ -153,6 +157,7 @@ int main(int argc, char *argv[]) | |||
153 | main_test_pthread_attr_setaffinity_np(); | 157 | main_test_pthread_attr_setaffinity_np(); |
154 | main_test_lzma(); | 158 | main_test_lzma(); |
155 | main_test_get_cpuid(); | 159 | main_test_get_cpuid(); |
160 | main_test_bpf(); | ||
156 | 161 | ||
157 | return 0; | 162 | return 0; |
158 | } | 163 | } |
diff --git a/tools/build/feature/test-bpf.c b/tools/build/feature/test-bpf.c index 062bac811af9..b389026839b9 100644 --- a/tools/build/feature/test-bpf.c +++ b/tools/build/feature/test-bpf.c | |||
@@ -1,9 +1,23 @@ | |||
1 | #include <asm/unistd.h> | ||
1 | #include <linux/bpf.h> | 2 | #include <linux/bpf.h> |
3 | #include <unistd.h> | ||
4 | |||
5 | #ifndef __NR_bpf | ||
6 | # if defined(__i386__) | ||
7 | # define __NR_bpf 357 | ||
8 | # elif defined(__x86_64__) | ||
9 | # define __NR_bpf 321 | ||
10 | # elif defined(__aarch64__) | ||
11 | # define __NR_bpf 280 | ||
12 | # error __NR_bpf not defined. libbpf does not support your arch. | ||
13 | # endif | ||
14 | #endif | ||
2 | 15 | ||
3 | int main(void) | 16 | int main(void) |
4 | { | 17 | { |
5 | union bpf_attr attr; | 18 | union bpf_attr attr; |
6 | 19 | ||
20 | /* Check fields in attr */ | ||
7 | attr.prog_type = BPF_PROG_TYPE_KPROBE; | 21 | attr.prog_type = BPF_PROG_TYPE_KPROBE; |
8 | attr.insn_cnt = 0; | 22 | attr.insn_cnt = 0; |
9 | attr.insns = 0; | 23 | attr.insns = 0; |
@@ -14,5 +28,9 @@ int main(void) | |||
14 | attr.kern_version = 0; | 28 | attr.kern_version = 0; |
15 | 29 | ||
16 | attr = attr; | 30 | attr = attr; |
17 | return 0; | 31 | /* |
32 | * Test existence of __NR_bpf and BPF_PROG_LOAD. | ||
33 | * This call should fail if we run the testcase. | ||
34 | */ | ||
35 | return syscall(__NR_bpf, BPF_PROG_LOAD, attr, sizeof(attr)); | ||
18 | } | 36 | } |
diff --git a/tools/include/linux/list.h b/tools/include/linux/list.h index a017f1595676..1da423820ad4 100644 --- a/tools/include/linux/list.h +++ b/tools/include/linux/list.h | |||
@@ -1,11 +1,751 @@ | |||
1 | #include <linux/compiler.h> | 1 | #ifndef __TOOLS_LINUX_LIST_H |
2 | #include <linux/kernel.h> | 2 | #define __TOOLS_LINUX_LIST_H |
3 | |||
3 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/poison.h> | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/compiler.h> | ||
8 | |||
9 | /* | ||
10 | * Simple doubly linked list implementation. | ||
11 | * | ||
12 | * Some of the internal functions ("__xxx") are useful when | ||
13 | * manipulating whole lists rather than single entries, as | ||
14 | * sometimes we already know the next/prev entries and we can | ||
15 | * generate better code by using them directly rather than | ||
16 | * using the generic single-entry routines. | ||
17 | */ | ||
18 | |||
19 | #define LIST_HEAD_INIT(name) { &(name), &(name) } | ||
20 | |||
21 | #define LIST_HEAD(name) \ | ||
22 | struct list_head name = LIST_HEAD_INIT(name) | ||
23 | |||
24 | static inline void INIT_LIST_HEAD(struct list_head *list) | ||
25 | { | ||
26 | list->next = list; | ||
27 | list->prev = list; | ||
28 | } | ||
29 | |||
30 | /* | ||
31 | * Insert a new entry between two known consecutive entries. | ||
32 | * | ||
33 | * This is only for internal list manipulation where we know | ||
34 | * the prev/next entries already! | ||
35 | */ | ||
36 | #ifndef CONFIG_DEBUG_LIST | ||
37 | static inline void __list_add(struct list_head *new, | ||
38 | struct list_head *prev, | ||
39 | struct list_head *next) | ||
40 | { | ||
41 | next->prev = new; | ||
42 | new->next = next; | ||
43 | new->prev = prev; | ||
44 | prev->next = new; | ||
45 | } | ||
46 | #else | ||
47 | extern void __list_add(struct list_head *new, | ||
48 | struct list_head *prev, | ||
49 | struct list_head *next); | ||
50 | #endif | ||
51 | |||
52 | /** | ||
53 | * list_add - add a new entry | ||
54 | * @new: new entry to be added | ||
55 | * @head: list head to add it after | ||
56 | * | ||
57 | * Insert a new entry after the specified head. | ||
58 | * This is good for implementing stacks. | ||
59 | */ | ||
60 | static inline void list_add(struct list_head *new, struct list_head *head) | ||
61 | { | ||
62 | __list_add(new, head, head->next); | ||
63 | } | ||
64 | |||
65 | |||
66 | /** | ||
67 | * list_add_tail - add a new entry | ||
68 | * @new: new entry to be added | ||
69 | * @head: list head to add it before | ||
70 | * | ||
71 | * Insert a new entry before the specified head. | ||
72 | * This is useful for implementing queues. | ||
73 | */ | ||
74 | static inline void list_add_tail(struct list_head *new, struct list_head *head) | ||
75 | { | ||
76 | __list_add(new, head->prev, head); | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * Delete a list entry by making the prev/next entries | ||
81 | * point to each other. | ||
82 | * | ||
83 | * This is only for internal list manipulation where we know | ||
84 | * the prev/next entries already! | ||
85 | */ | ||
86 | static inline void __list_del(struct list_head * prev, struct list_head * next) | ||
87 | { | ||
88 | next->prev = prev; | ||
89 | WRITE_ONCE(prev->next, next); | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * list_del - deletes entry from list. | ||
94 | * @entry: the element to delete from the list. | ||
95 | * Note: list_empty() on entry does not return true after this, the entry is | ||
96 | * in an undefined state. | ||
97 | */ | ||
98 | #ifndef CONFIG_DEBUG_LIST | ||
99 | static inline void __list_del_entry(struct list_head *entry) | ||
100 | { | ||
101 | __list_del(entry->prev, entry->next); | ||
102 | } | ||
103 | |||
104 | static inline void list_del(struct list_head *entry) | ||
105 | { | ||
106 | __list_del(entry->prev, entry->next); | ||
107 | entry->next = LIST_POISON1; | ||
108 | entry->prev = LIST_POISON2; | ||
109 | } | ||
110 | #else | ||
111 | extern void __list_del_entry(struct list_head *entry); | ||
112 | extern void list_del(struct list_head *entry); | ||
113 | #endif | ||
114 | |||
115 | /** | ||
116 | * list_replace - replace old entry by new one | ||
117 | * @old : the element to be replaced | ||
118 | * @new : the new element to insert | ||
119 | * | ||
120 | * If @old was empty, it will be overwritten. | ||
121 | */ | ||
122 | static inline void list_replace(struct list_head *old, | ||
123 | struct list_head *new) | ||
124 | { | ||
125 | new->next = old->next; | ||
126 | new->next->prev = new; | ||
127 | new->prev = old->prev; | ||
128 | new->prev->next = new; | ||
129 | } | ||
130 | |||
131 | static inline void list_replace_init(struct list_head *old, | ||
132 | struct list_head *new) | ||
133 | { | ||
134 | list_replace(old, new); | ||
135 | INIT_LIST_HEAD(old); | ||
136 | } | ||
137 | |||
138 | /** | ||
139 | * list_del_init - deletes entry from list and reinitialize it. | ||
140 | * @entry: the element to delete from the list. | ||
141 | */ | ||
142 | static inline void list_del_init(struct list_head *entry) | ||
143 | { | ||
144 | __list_del_entry(entry); | ||
145 | INIT_LIST_HEAD(entry); | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * list_move - delete from one list and add as another's head | ||
150 | * @list: the entry to move | ||
151 | * @head: the head that will precede our entry | ||
152 | */ | ||
153 | static inline void list_move(struct list_head *list, struct list_head *head) | ||
154 | { | ||
155 | __list_del_entry(list); | ||
156 | list_add(list, head); | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * list_move_tail - delete from one list and add as another's tail | ||
161 | * @list: the entry to move | ||
162 | * @head: the head that will follow our entry | ||
163 | */ | ||
164 | static inline void list_move_tail(struct list_head *list, | ||
165 | struct list_head *head) | ||
166 | { | ||
167 | __list_del_entry(list); | ||
168 | list_add_tail(list, head); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * list_is_last - tests whether @list is the last entry in list @head | ||
173 | * @list: the entry to test | ||
174 | * @head: the head of the list | ||
175 | */ | ||
176 | static inline int list_is_last(const struct list_head *list, | ||
177 | const struct list_head *head) | ||
178 | { | ||
179 | return list->next == head; | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * list_empty - tests whether a list is empty | ||
184 | * @head: the list to test. | ||
185 | */ | ||
186 | static inline int list_empty(const struct list_head *head) | ||
187 | { | ||
188 | return head->next == head; | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * list_empty_careful - tests whether a list is empty and not being modified | ||
193 | * @head: the list to test | ||
194 | * | ||
195 | * Description: | ||
196 | * tests whether a list is empty _and_ checks that no other CPU might be | ||
197 | * in the process of modifying either member (next or prev) | ||
198 | * | ||
199 | * NOTE: using list_empty_careful() without synchronization | ||
200 | * can only be safe if the only activity that can happen | ||
201 | * to the list entry is list_del_init(). Eg. it cannot be used | ||
202 | * if another CPU could re-list_add() it. | ||
203 | */ | ||
204 | static inline int list_empty_careful(const struct list_head *head) | ||
205 | { | ||
206 | struct list_head *next = head->next; | ||
207 | return (next == head) && (next == head->prev); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * list_rotate_left - rotate the list to the left | ||
212 | * @head: the head of the list | ||
213 | */ | ||
214 | static inline void list_rotate_left(struct list_head *head) | ||
215 | { | ||
216 | struct list_head *first; | ||
217 | |||
218 | if (!list_empty(head)) { | ||
219 | first = head->next; | ||
220 | list_move_tail(first, head); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * list_is_singular - tests whether a list has just one entry. | ||
226 | * @head: the list to test. | ||
227 | */ | ||
228 | static inline int list_is_singular(const struct list_head *head) | ||
229 | { | ||
230 | return !list_empty(head) && (head->next == head->prev); | ||
231 | } | ||
232 | |||
233 | static inline void __list_cut_position(struct list_head *list, | ||
234 | struct list_head *head, struct list_head *entry) | ||
235 | { | ||
236 | struct list_head *new_first = entry->next; | ||
237 | list->next = head->next; | ||
238 | list->next->prev = list; | ||
239 | list->prev = entry; | ||
240 | entry->next = list; | ||
241 | head->next = new_first; | ||
242 | new_first->prev = head; | ||
243 | } | ||
244 | |||
245 | /** | ||
246 | * list_cut_position - cut a list into two | ||
247 | * @list: a new list to add all removed entries | ||
248 | * @head: a list with entries | ||
249 | * @entry: an entry within head, could be the head itself | ||
250 | * and if so we won't cut the list | ||
251 | * | ||
252 | * This helper moves the initial part of @head, up to and | ||
253 | * including @entry, from @head to @list. You should | ||
254 | * pass on @entry an element you know is on @head. @list | ||
255 | * should be an empty list or a list you do not care about | ||
256 | * losing its data. | ||
257 | * | ||
258 | */ | ||
259 | static inline void list_cut_position(struct list_head *list, | ||
260 | struct list_head *head, struct list_head *entry) | ||
261 | { | ||
262 | if (list_empty(head)) | ||
263 | return; | ||
264 | if (list_is_singular(head) && | ||
265 | (head->next != entry && head != entry)) | ||
266 | return; | ||
267 | if (entry == head) | ||
268 | INIT_LIST_HEAD(list); | ||
269 | else | ||
270 | __list_cut_position(list, head, entry); | ||
271 | } | ||
272 | |||
273 | static inline void __list_splice(const struct list_head *list, | ||
274 | struct list_head *prev, | ||
275 | struct list_head *next) | ||
276 | { | ||
277 | struct list_head *first = list->next; | ||
278 | struct list_head *last = list->prev; | ||
279 | |||
280 | first->prev = prev; | ||
281 | prev->next = first; | ||
282 | |||
283 | last->next = next; | ||
284 | next->prev = last; | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * list_splice - join two lists, this is designed for stacks | ||
289 | * @list: the new list to add. | ||
290 | * @head: the place to add it in the first list. | ||
291 | */ | ||
292 | static inline void list_splice(const struct list_head *list, | ||
293 | struct list_head *head) | ||
294 | { | ||
295 | if (!list_empty(list)) | ||
296 | __list_splice(list, head, head->next); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * list_splice_tail - join two lists, each list being a queue | ||
301 | * @list: the new list to add. | ||
302 | * @head: the place to add it in the first list. | ||
303 | */ | ||
304 | static inline void list_splice_tail(struct list_head *list, | ||
305 | struct list_head *head) | ||
306 | { | ||
307 | if (!list_empty(list)) | ||
308 | __list_splice(list, head->prev, head); | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * list_splice_init - join two lists and reinitialise the emptied list. | ||
313 | * @list: the new list to add. | ||
314 | * @head: the place to add it in the first list. | ||
315 | * | ||
316 | * The list at @list is reinitialised | ||
317 | */ | ||
318 | static inline void list_splice_init(struct list_head *list, | ||
319 | struct list_head *head) | ||
320 | { | ||
321 | if (!list_empty(list)) { | ||
322 | __list_splice(list, head, head->next); | ||
323 | INIT_LIST_HEAD(list); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /** | ||
328 | * list_splice_tail_init - join two lists and reinitialise the emptied list | ||
329 | * @list: the new list to add. | ||
330 | * @head: the place to add it in the first list. | ||
331 | * | ||
332 | * Each of the lists is a queue. | ||
333 | * The list at @list is reinitialised | ||
334 | */ | ||
335 | static inline void list_splice_tail_init(struct list_head *list, | ||
336 | struct list_head *head) | ||
337 | { | ||
338 | if (!list_empty(list)) { | ||
339 | __list_splice(list, head->prev, head); | ||
340 | INIT_LIST_HEAD(list); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | /** | ||
345 | * list_entry - get the struct for this entry | ||
346 | * @ptr: the &struct list_head pointer. | ||
347 | * @type: the type of the struct this is embedded in. | ||
348 | * @member: the name of the list_head within the struct. | ||
349 | */ | ||
350 | #define list_entry(ptr, type, member) \ | ||
351 | container_of(ptr, type, member) | ||
352 | |||
353 | /** | ||
354 | * list_first_entry - get the first element from a list | ||
355 | * @ptr: the list head to take the element from. | ||
356 | * @type: the type of the struct this is embedded in. | ||
357 | * @member: the name of the list_head within the struct. | ||
358 | * | ||
359 | * Note, that list is expected to be not empty. | ||
360 | */ | ||
361 | #define list_first_entry(ptr, type, member) \ | ||
362 | list_entry((ptr)->next, type, member) | ||
363 | |||
364 | /** | ||
365 | * list_last_entry - get the last element from a list | ||
366 | * @ptr: the list head to take the element from. | ||
367 | * @type: the type of the struct this is embedded in. | ||
368 | * @member: the name of the list_head within the struct. | ||
369 | * | ||
370 | * Note, that list is expected to be not empty. | ||
371 | */ | ||
372 | #define list_last_entry(ptr, type, member) \ | ||
373 | list_entry((ptr)->prev, type, member) | ||
374 | |||
375 | /** | ||
376 | * list_first_entry_or_null - get the first element from a list | ||
377 | * @ptr: the list head to take the element from. | ||
378 | * @type: the type of the struct this is embedded in. | ||
379 | * @member: the name of the list_head within the struct. | ||
380 | * | ||
381 | * Note that if the list is empty, it returns NULL. | ||
382 | */ | ||
383 | #define list_first_entry_or_null(ptr, type, member) \ | ||
384 | (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL) | ||
385 | |||
386 | /** | ||
387 | * list_next_entry - get the next element in list | ||
388 | * @pos: the type * to cursor | ||
389 | * @member: the name of the list_head within the struct. | ||
390 | */ | ||
391 | #define list_next_entry(pos, member) \ | ||
392 | list_entry((pos)->member.next, typeof(*(pos)), member) | ||
393 | |||
394 | /** | ||
395 | * list_prev_entry - get the prev element in list | ||
396 | * @pos: the type * to cursor | ||
397 | * @member: the name of the list_head within the struct. | ||
398 | */ | ||
399 | #define list_prev_entry(pos, member) \ | ||
400 | list_entry((pos)->member.prev, typeof(*(pos)), member) | ||
401 | |||
402 | /** | ||
403 | * list_for_each - iterate over a list | ||
404 | * @pos: the &struct list_head to use as a loop cursor. | ||
405 | * @head: the head for your list. | ||
406 | */ | ||
407 | #define list_for_each(pos, head) \ | ||
408 | for (pos = (head)->next; pos != (head); pos = pos->next) | ||
409 | |||
410 | /** | ||
411 | * list_for_each_prev - iterate over a list backwards | ||
412 | * @pos: the &struct list_head to use as a loop cursor. | ||
413 | * @head: the head for your list. | ||
414 | */ | ||
415 | #define list_for_each_prev(pos, head) \ | ||
416 | for (pos = (head)->prev; pos != (head); pos = pos->prev) | ||
417 | |||
418 | /** | ||
419 | * list_for_each_safe - iterate over a list safe against removal of list entry | ||
420 | * @pos: the &struct list_head to use as a loop cursor. | ||
421 | * @n: another &struct list_head to use as temporary storage | ||
422 | * @head: the head for your list. | ||
423 | */ | ||
424 | #define list_for_each_safe(pos, n, head) \ | ||
425 | for (pos = (head)->next, n = pos->next; pos != (head); \ | ||
426 | pos = n, n = pos->next) | ||
427 | |||
428 | /** | ||
429 | * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry | ||
430 | * @pos: the &struct list_head to use as a loop cursor. | ||
431 | * @n: another &struct list_head to use as temporary storage | ||
432 | * @head: the head for your list. | ||
433 | */ | ||
434 | #define list_for_each_prev_safe(pos, n, head) \ | ||
435 | for (pos = (head)->prev, n = pos->prev; \ | ||
436 | pos != (head); \ | ||
437 | pos = n, n = pos->prev) | ||
438 | |||
439 | /** | ||
440 | * list_for_each_entry - iterate over list of given type | ||
441 | * @pos: the type * to use as a loop cursor. | ||
442 | * @head: the head for your list. | ||
443 | * @member: the name of the list_head within the struct. | ||
444 | */ | ||
445 | #define list_for_each_entry(pos, head, member) \ | ||
446 | for (pos = list_first_entry(head, typeof(*pos), member); \ | ||
447 | &pos->member != (head); \ | ||
448 | pos = list_next_entry(pos, member)) | ||
449 | |||
450 | /** | ||
451 | * list_for_each_entry_reverse - iterate backwards over list of given type. | ||
452 | * @pos: the type * to use as a loop cursor. | ||
453 | * @head: the head for your list. | ||
454 | * @member: the name of the list_head within the struct. | ||
455 | */ | ||
456 | #define list_for_each_entry_reverse(pos, head, member) \ | ||
457 | for (pos = list_last_entry(head, typeof(*pos), member); \ | ||
458 | &pos->member != (head); \ | ||
459 | pos = list_prev_entry(pos, member)) | ||
460 | |||
461 | /** | ||
462 | * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() | ||
463 | * @pos: the type * to use as a start point | ||
464 | * @head: the head of the list | ||
465 | * @member: the name of the list_head within the struct. | ||
466 | * | ||
467 | * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). | ||
468 | */ | ||
469 | #define list_prepare_entry(pos, head, member) \ | ||
470 | ((pos) ? : list_entry(head, typeof(*pos), member)) | ||
471 | |||
472 | /** | ||
473 | * list_for_each_entry_continue - continue iteration over list of given type | ||
474 | * @pos: the type * to use as a loop cursor. | ||
475 | * @head: the head for your list. | ||
476 | * @member: the name of the list_head within the struct. | ||
477 | * | ||
478 | * Continue to iterate over list of given type, continuing after | ||
479 | * the current position. | ||
480 | */ | ||
481 | #define list_for_each_entry_continue(pos, head, member) \ | ||
482 | for (pos = list_next_entry(pos, member); \ | ||
483 | &pos->member != (head); \ | ||
484 | pos = list_next_entry(pos, member)) | ||
485 | |||
486 | /** | ||
487 | * list_for_each_entry_continue_reverse - iterate backwards from the given point | ||
488 | * @pos: the type * to use as a loop cursor. | ||
489 | * @head: the head for your list. | ||
490 | * @member: the name of the list_head within the struct. | ||
491 | * | ||
492 | * Start to iterate over list of given type backwards, continuing after | ||
493 | * the current position. | ||
494 | */ | ||
495 | #define list_for_each_entry_continue_reverse(pos, head, member) \ | ||
496 | for (pos = list_prev_entry(pos, member); \ | ||
497 | &pos->member != (head); \ | ||
498 | pos = list_prev_entry(pos, member)) | ||
499 | |||
500 | /** | ||
501 | * list_for_each_entry_from - iterate over list of given type from the current point | ||
502 | * @pos: the type * to use as a loop cursor. | ||
503 | * @head: the head for your list. | ||
504 | * @member: the name of the list_head within the struct. | ||
505 | * | ||
506 | * Iterate over list of given type, continuing from current position. | ||
507 | */ | ||
508 | #define list_for_each_entry_from(pos, head, member) \ | ||
509 | for (; &pos->member != (head); \ | ||
510 | pos = list_next_entry(pos, member)) | ||
511 | |||
512 | /** | ||
513 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry | ||
514 | * @pos: the type * to use as a loop cursor. | ||
515 | * @n: another type * to use as temporary storage | ||
516 | * @head: the head for your list. | ||
517 | * @member: the name of the list_head within the struct. | ||
518 | */ | ||
519 | #define list_for_each_entry_safe(pos, n, head, member) \ | ||
520 | for (pos = list_first_entry(head, typeof(*pos), member), \ | ||
521 | n = list_next_entry(pos, member); \ | ||
522 | &pos->member != (head); \ | ||
523 | pos = n, n = list_next_entry(n, member)) | ||
524 | |||
525 | /** | ||
526 | * list_for_each_entry_safe_continue - continue list iteration safe against removal | ||
527 | * @pos: the type * to use as a loop cursor. | ||
528 | * @n: another type * to use as temporary storage | ||
529 | * @head: the head for your list. | ||
530 | * @member: the name of the list_head within the struct. | ||
531 | * | ||
532 | * Iterate over list of given type, continuing after current point, | ||
533 | * safe against removal of list entry. | ||
534 | */ | ||
535 | #define list_for_each_entry_safe_continue(pos, n, head, member) \ | ||
536 | for (pos = list_next_entry(pos, member), \ | ||
537 | n = list_next_entry(pos, member); \ | ||
538 | &pos->member != (head); \ | ||
539 | pos = n, n = list_next_entry(n, member)) | ||
540 | |||
541 | /** | ||
542 | * list_for_each_entry_safe_from - iterate over list from current point safe against removal | ||
543 | * @pos: the type * to use as a loop cursor. | ||
544 | * @n: another type * to use as temporary storage | ||
545 | * @head: the head for your list. | ||
546 | * @member: the name of the list_head within the struct. | ||
547 | * | ||
548 | * Iterate over list of given type from current point, safe against | ||
549 | * removal of list entry. | ||
550 | */ | ||
551 | #define list_for_each_entry_safe_from(pos, n, head, member) \ | ||
552 | for (n = list_next_entry(pos, member); \ | ||
553 | &pos->member != (head); \ | ||
554 | pos = n, n = list_next_entry(n, member)) | ||
555 | |||
556 | /** | ||
557 | * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal | ||
558 | * @pos: the type * to use as a loop cursor. | ||
559 | * @n: another type * to use as temporary storage | ||
560 | * @head: the head for your list. | ||
561 | * @member: the name of the list_head within the struct. | ||
562 | * | ||
563 | * Iterate backwards over list of given type, safe against removal | ||
564 | * of list entry. | ||
565 | */ | ||
566 | #define list_for_each_entry_safe_reverse(pos, n, head, member) \ | ||
567 | for (pos = list_last_entry(head, typeof(*pos), member), \ | ||
568 | n = list_prev_entry(pos, member); \ | ||
569 | &pos->member != (head); \ | ||
570 | pos = n, n = list_prev_entry(n, member)) | ||
4 | 571 | ||
5 | #include "../../../include/linux/list.h" | 572 | /** |
573 | * list_safe_reset_next - reset a stale list_for_each_entry_safe loop | ||
574 | * @pos: the loop cursor used in the list_for_each_entry_safe loop | ||
575 | * @n: temporary storage used in list_for_each_entry_safe | ||
576 | * @member: the name of the list_head within the struct. | ||
577 | * | ||
578 | * list_safe_reset_next is not safe to use in general if the list may be | ||
579 | * modified concurrently (eg. the lock is dropped in the loop body). An | ||
580 | * exception to this is if the cursor element (pos) is pinned in the list, | ||
581 | * and list_safe_reset_next is called after re-taking the lock and before | ||
582 | * completing the current iteration of the loop body. | ||
583 | */ | ||
584 | #define list_safe_reset_next(pos, n, member) \ | ||
585 | n = list_next_entry(pos, member) | ||
586 | |||
587 | /* | ||
588 | * Double linked lists with a single pointer list head. | ||
589 | * Mostly useful for hash tables where the two pointer list head is | ||
590 | * too wasteful. | ||
591 | * You lose the ability to access the tail in O(1). | ||
592 | */ | ||
593 | |||
594 | #define HLIST_HEAD_INIT { .first = NULL } | ||
595 | #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } | ||
596 | #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) | ||
597 | static inline void INIT_HLIST_NODE(struct hlist_node *h) | ||
598 | { | ||
599 | h->next = NULL; | ||
600 | h->pprev = NULL; | ||
601 | } | ||
602 | |||
603 | static inline int hlist_unhashed(const struct hlist_node *h) | ||
604 | { | ||
605 | return !h->pprev; | ||
606 | } | ||
607 | |||
608 | static inline int hlist_empty(const struct hlist_head *h) | ||
609 | { | ||
610 | return !h->first; | ||
611 | } | ||
612 | |||
613 | static inline void __hlist_del(struct hlist_node *n) | ||
614 | { | ||
615 | struct hlist_node *next = n->next; | ||
616 | struct hlist_node **pprev = n->pprev; | ||
617 | |||
618 | WRITE_ONCE(*pprev, next); | ||
619 | if (next) | ||
620 | next->pprev = pprev; | ||
621 | } | ||
622 | |||
623 | static inline void hlist_del(struct hlist_node *n) | ||
624 | { | ||
625 | __hlist_del(n); | ||
626 | n->next = LIST_POISON1; | ||
627 | n->pprev = LIST_POISON2; | ||
628 | } | ||
629 | |||
630 | static inline void hlist_del_init(struct hlist_node *n) | ||
631 | { | ||
632 | if (!hlist_unhashed(n)) { | ||
633 | __hlist_del(n); | ||
634 | INIT_HLIST_NODE(n); | ||
635 | } | ||
636 | } | ||
637 | |||
638 | static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) | ||
639 | { | ||
640 | struct hlist_node *first = h->first; | ||
641 | n->next = first; | ||
642 | if (first) | ||
643 | first->pprev = &n->next; | ||
644 | h->first = n; | ||
645 | n->pprev = &h->first; | ||
646 | } | ||
647 | |||
648 | /* next must be != NULL */ | ||
649 | static inline void hlist_add_before(struct hlist_node *n, | ||
650 | struct hlist_node *next) | ||
651 | { | ||
652 | n->pprev = next->pprev; | ||
653 | n->next = next; | ||
654 | next->pprev = &n->next; | ||
655 | *(n->pprev) = n; | ||
656 | } | ||
657 | |||
658 | static inline void hlist_add_behind(struct hlist_node *n, | ||
659 | struct hlist_node *prev) | ||
660 | { | ||
661 | n->next = prev->next; | ||
662 | prev->next = n; | ||
663 | n->pprev = &prev->next; | ||
664 | |||
665 | if (n->next) | ||
666 | n->next->pprev = &n->next; | ||
667 | } | ||
668 | |||
669 | /* after that we'll appear to be on some hlist and hlist_del will work */ | ||
670 | static inline void hlist_add_fake(struct hlist_node *n) | ||
671 | { | ||
672 | n->pprev = &n->next; | ||
673 | } | ||
674 | |||
675 | static inline bool hlist_fake(struct hlist_node *h) | ||
676 | { | ||
677 | return h->pprev == &h->next; | ||
678 | } | ||
679 | |||
680 | /* | ||
681 | * Move a list from one list head to another. Fixup the pprev | ||
682 | * reference of the first entry if it exists. | ||
683 | */ | ||
684 | static inline void hlist_move_list(struct hlist_head *old, | ||
685 | struct hlist_head *new) | ||
686 | { | ||
687 | new->first = old->first; | ||
688 | if (new->first) | ||
689 | new->first->pprev = &new->first; | ||
690 | old->first = NULL; | ||
691 | } | ||
692 | |||
693 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) | ||
694 | |||
695 | #define hlist_for_each(pos, head) \ | ||
696 | for (pos = (head)->first; pos ; pos = pos->next) | ||
697 | |||
698 | #define hlist_for_each_safe(pos, n, head) \ | ||
699 | for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ | ||
700 | pos = n) | ||
701 | |||
702 | #define hlist_entry_safe(ptr, type, member) \ | ||
703 | ({ typeof(ptr) ____ptr = (ptr); \ | ||
704 | ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ | ||
705 | }) | ||
706 | |||
707 | /** | ||
708 | * hlist_for_each_entry - iterate over list of given type | ||
709 | * @pos: the type * to use as a loop cursor. | ||
710 | * @head: the head for your list. | ||
711 | * @member: the name of the hlist_node within the struct. | ||
712 | */ | ||
713 | #define hlist_for_each_entry(pos, head, member) \ | ||
714 | for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ | ||
715 | pos; \ | ||
716 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) | ||
717 | |||
718 | /** | ||
719 | * hlist_for_each_entry_continue - iterate over a hlist continuing after current point | ||
720 | * @pos: the type * to use as a loop cursor. | ||
721 | * @member: the name of the hlist_node within the struct. | ||
722 | */ | ||
723 | #define hlist_for_each_entry_continue(pos, member) \ | ||
724 | for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ | ||
725 | pos; \ | ||
726 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) | ||
727 | |||
728 | /** | ||
729 | * hlist_for_each_entry_from - iterate over a hlist continuing from current point | ||
730 | * @pos: the type * to use as a loop cursor. | ||
731 | * @member: the name of the hlist_node within the struct. | ||
732 | */ | ||
733 | #define hlist_for_each_entry_from(pos, member) \ | ||
734 | for (; pos; \ | ||
735 | pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) | ||
736 | |||
737 | /** | ||
738 | * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry | ||
739 | * @pos: the type * to use as a loop cursor. | ||
740 | * @n: another &struct hlist_node to use as temporary storage | ||
741 | * @head: the head for your list. | ||
742 | * @member: the name of the hlist_node within the struct. | ||
743 | */ | ||
744 | #define hlist_for_each_entry_safe(pos, n, head, member) \ | ||
745 | for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ | ||
746 | pos && ({ n = pos->member.next; 1; }); \ | ||
747 | pos = hlist_entry_safe(n, typeof(*pos), member)) | ||
6 | 748 | ||
7 | #ifndef TOOLS_LIST_H | ||
8 | #define TOOLS_LIST_H | ||
9 | /** | 749 | /** |
10 | * list_del_range - deletes range of entries from list. | 750 | * list_del_range - deletes range of entries from list. |
11 | * @begin: first element in the range to delete from the list. | 751 | * @begin: first element in the range to delete from the list. |
@@ -27,4 +767,5 @@ static inline void list_del_range(struct list_head *begin, | |||
27 | */ | 767 | */ |
28 | #define list_for_each_from(pos, head) \ | 768 | #define list_for_each_from(pos, head) \ |
29 | for (; pos != (head); pos = pos->next) | 769 | for (; pos != (head); pos = pos->next) |
30 | #endif | 770 | |
771 | #endif /* __TOOLS_LINUX_LIST_H */ | ||
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 919b71780710..fc1bc75ae56d 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile | |||
@@ -6,6 +6,12 @@ BPF_EXTRAVERSION = 1 | |||
6 | 6 | ||
7 | MAKEFLAGS += --no-print-directory | 7 | MAKEFLAGS += --no-print-directory |
8 | 8 | ||
9 | ifeq ($(srctree),) | ||
10 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | ||
11 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
12 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
13 | #$(info Determined 'srctree' to be $(srctree)) | ||
14 | endif | ||
9 | 15 | ||
10 | # Makefiles suck: This macro sets a default value of $(2) for the | 16 | # Makefiles suck: This macro sets a default value of $(2) for the |
11 | # variable named by $(1), unless the variable has been set by | 17 | # variable named by $(1), unless the variable has been set by |
@@ -31,7 +37,8 @@ INSTALL = install | |||
31 | DESTDIR ?= | 37 | DESTDIR ?= |
32 | DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' | 38 | DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' |
33 | 39 | ||
34 | LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1) | 40 | include $(srctree)/tools/scripts/Makefile.arch |
41 | |||
35 | ifeq ($(LP64), 1) | 42 | ifeq ($(LP64), 1) |
36 | libdir_relative = lib64 | 43 | libdir_relative = lib64 |
37 | else | 44 | else |
@@ -57,13 +64,6 @@ ifndef VERBOSE | |||
57 | VERBOSE = 0 | 64 | VERBOSE = 0 |
58 | endif | 65 | endif |
59 | 66 | ||
60 | ifeq ($(srctree),) | ||
61 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | ||
62 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
63 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
64 | #$(info Determined 'srctree' to be $(srctree)) | ||
65 | endif | ||
66 | |||
67 | FEATURE_USER = .libbpf | 67 | FEATURE_USER = .libbpf |
68 | FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf | 68 | FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf |
69 | FEATURE_DISPLAY = libelf bpf | 69 | FEATURE_DISPLAY = libelf bpf |
@@ -192,7 +192,7 @@ config-clean: | |||
192 | $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null | 192 | $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null |
193 | 193 | ||
194 | clean: | 194 | clean: |
195 | $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ | 195 | $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd \ |
196 | $(RM) LIBBPF-CFLAGS | 196 | $(RM) LIBBPF-CFLAGS |
197 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf | 197 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf |
198 | 198 | ||
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 5bdc6eab6852..1f91cc941b7c 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c | |||
@@ -14,8 +14,8 @@ | |||
14 | #include "bpf.h" | 14 | #include "bpf.h" |
15 | 15 | ||
16 | /* | 16 | /* |
17 | * When building perf, unistd.h is override. Define __NR_bpf is | 17 | * When building perf, unistd.h is overrided. __NR_bpf is |
18 | * required to be defined. | 18 | * required to be defined explicitly. |
19 | */ | 19 | */ |
20 | #ifndef __NR_bpf | 20 | #ifndef __NR_bpf |
21 | # if defined(__i386__) | 21 | # if defined(__i386__) |
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index 7e319afac78a..90d2baeb621a 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile | |||
@@ -149,7 +149,7 @@ install_lib: all_cmd | |||
149 | install: install_lib | 149 | install: install_lib |
150 | 150 | ||
151 | clean: | 151 | clean: |
152 | $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d | 152 | $(RM) *.o *~ $(TARGETS) *.a *liblockdep*.so* $(VERSION_FILES) .*.d .*.cmd |
153 | $(RM) tags TAGS | 153 | $(RM) tags TAGS |
154 | 154 | ||
155 | PHONY += force | 155 | PHONY += force |
diff --git a/tools/lib/subcmd/parse-options.h b/tools/lib/subcmd/parse-options.h index 13a2cc1d6140..d60cab2726da 100644 --- a/tools/lib/subcmd/parse-options.h +++ b/tools/lib/subcmd/parse-options.h | |||
@@ -4,6 +4,10 @@ | |||
4 | #include <stdbool.h> | 4 | #include <stdbool.h> |
5 | #include <stdint.h> | 5 | #include <stdint.h> |
6 | 6 | ||
7 | #ifndef NORETURN | ||
8 | #define NORETURN __attribute__((__noreturn__)) | ||
9 | #endif | ||
10 | |||
7 | enum parse_opt_type { | 11 | enum parse_opt_type { |
8 | /* special types */ | 12 | /* special types */ |
9 | OPTION_END, | 13 | OPTION_END, |
diff --git a/tools/perf/Build b/tools/perf/Build index 6b67e6f4179f..a43fae7f439a 100644 --- a/tools/perf/Build +++ b/tools/perf/Build | |||
@@ -42,6 +42,7 @@ CFLAGS_perf.o += -DPERF_HTML_PATH="BUILD_STR($(htmldir_SQ))" \ | |||
42 | -include $(OUTPUT)PERF-VERSION-FILE | 42 | -include $(OUTPUT)PERF-VERSION-FILE |
43 | CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" | 43 | CFLAGS_builtin-trace.o += -DSTRACE_GROUPS_DIR="BUILD_STR($(STRACE_GROUPS_DIR_SQ))" |
44 | CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))" | 44 | CFLAGS_builtin-report.o += -DTIPDIR="BUILD_STR($(tipdir_SQ))" |
45 | CFLAGS_builtin-report.o += -DDOCDIR="BUILD_STR($(srcdir_SQ)/Documentation)" | ||
45 | 46 | ||
46 | libperf-y += util/ | 47 | libperf-y += util/ |
47 | libperf-y += arch/ | 48 | libperf-y += arch/ |
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 3a1a32f5479f..fbceb631387c 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -338,6 +338,9 @@ Options passed to clang when compiling BPF scriptlets. | |||
338 | Specify vmlinux path which has debuginfo. | 338 | Specify vmlinux path which has debuginfo. |
339 | (enabled when BPF prologue is on) | 339 | (enabled when BPF prologue is on) |
340 | 340 | ||
341 | --buildid-all:: | ||
342 | Record build-id of all DSOs regardless whether it's actually hit or not. | ||
343 | |||
341 | SEE ALSO | 344 | SEE ALSO |
342 | -------- | 345 | -------- |
343 | linkperf:perf-stat[1], linkperf:perf-list[1] | 346 | linkperf:perf-stat[1], linkperf:perf-list[1] |
diff --git a/tools/perf/Documentation/tips.txt b/tools/perf/Documentation/tips.txt index a1c10e360db5..e0ce9573b79b 100644 --- a/tools/perf/Documentation/tips.txt +++ b/tools/perf/Documentation/tips.txt | |||
@@ -12,3 +12,18 @@ List events using substring match: perf list <keyword> | |||
12 | To see list of saved events and attributes: perf evlist -v | 12 | To see list of saved events and attributes: perf evlist -v |
13 | Use --symfs <dir> if your symbol files are in non-standard locations | 13 | Use --symfs <dir> if your symbol files are in non-standard locations |
14 | To see callchains in a more compact form: perf report -g folded | 14 | To see callchains in a more compact form: perf report -g folded |
15 | Show individual samples with: perf script | ||
16 | Limit to show entries above 5% only: perf report --percent-limit 5 | ||
17 | Profiling branch (mis)predictions with: perf record -b / perf report | ||
18 | Treat branches as callchains: perf report --branch-history | ||
19 | To count events in every 1000 msec: perf stat -I 1000 | ||
20 | Print event counts in CSV format with: perf stat -x, | ||
21 | If you have debuginfo enabled, try: perf report -s sym,srcline | ||
22 | For memory address profiling, try: perf mem record / perf mem report | ||
23 | For tracepoint events, try: perf report -s trace_fields | ||
24 | To record callchains for each sample: perf record -g | ||
25 | To record every process run by an user: perf record -u <user> | ||
26 | Skip collecing build-id when recording: perf record -B | ||
27 | To change sampling frequency to 100 Hz: perf record -F 100 | ||
28 | See assembly instructions with percentage: perf annotate <symbol> | ||
29 | If you prefer Intel style assembly, try: perf annotate -M intel | ||
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index ddf922f93aa1..2e1fa2357528 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -28,6 +28,7 @@ tools/lib/string.c | |||
28 | tools/lib/symbol/kallsyms.c | 28 | tools/lib/symbol/kallsyms.c |
29 | tools/lib/symbol/kallsyms.h | 29 | tools/lib/symbol/kallsyms.h |
30 | tools/lib/find_bit.c | 30 | tools/lib/find_bit.c |
31 | tools/lib/bitmap.c | ||
31 | tools/include/asm/atomic.h | 32 | tools/include/asm/atomic.h |
32 | tools/include/asm/barrier.h | 33 | tools/include/asm/barrier.h |
33 | tools/include/asm/bug.h | 34 | tools/include/asm/bug.h |
@@ -57,6 +58,7 @@ tools/include/linux/rbtree_augmented.h | |||
57 | tools/include/linux/string.h | 58 | tools/include/linux/string.h |
58 | tools/include/linux/types.h | 59 | tools/include/linux/types.h |
59 | tools/include/linux/err.h | 60 | tools/include/linux/err.h |
61 | tools/include/linux/bitmap.h | ||
60 | include/asm-generic/bitops/arch_hweight.h | 62 | include/asm-generic/bitops/arch_hweight.h |
61 | include/asm-generic/bitops/const_hweight.h | 63 | include/asm-generic/bitops/const_hweight.h |
62 | include/asm-generic/bitops/fls64.h | 64 | include/asm-generic/bitops/fls64.h |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dc4e0adf5c5b..319712a4e02b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -50,6 +50,7 @@ struct record { | |||
50 | int realtime_prio; | 50 | int realtime_prio; |
51 | bool no_buildid; | 51 | bool no_buildid; |
52 | bool no_buildid_cache; | 52 | bool no_buildid_cache; |
53 | bool buildid_all; | ||
53 | unsigned long long samples; | 54 | unsigned long long samples; |
54 | }; | 55 | }; |
55 | 56 | ||
@@ -362,6 +363,13 @@ static int process_buildids(struct record *rec) | |||
362 | */ | 363 | */ |
363 | symbol_conf.ignore_vmlinux_buildid = true; | 364 | symbol_conf.ignore_vmlinux_buildid = true; |
364 | 365 | ||
366 | /* | ||
367 | * If --buildid-all is given, it marks all DSO regardless of hits, | ||
368 | * so no need to process samples. | ||
369 | */ | ||
370 | if (rec->buildid_all) | ||
371 | rec->tool.sample = NULL; | ||
372 | |||
365 | return perf_session__process_events(session); | 373 | return perf_session__process_events(session); |
366 | } | 374 | } |
367 | 375 | ||
@@ -756,12 +764,8 @@ out_child: | |||
756 | 764 | ||
757 | if (!rec->no_buildid) { | 765 | if (!rec->no_buildid) { |
758 | process_buildids(rec); | 766 | process_buildids(rec); |
759 | /* | 767 | |
760 | * We take all buildids when the file contains | 768 | if (rec->buildid_all) |
761 | * AUX area tracing data because we do not decode the | ||
762 | * trace because it would take too long. | ||
763 | */ | ||
764 | if (rec->opts.full_auxtrace) | ||
765 | dsos__hit_all(rec->session); | 769 | dsos__hit_all(rec->session); |
766 | } | 770 | } |
767 | perf_session__write_header(rec->session, rec->evlist, fd, true); | 771 | perf_session__write_header(rec->session, rec->evlist, fd, true); |
@@ -1138,6 +1142,8 @@ struct option __record_options[] = { | |||
1138 | "options passed to clang when compiling BPF scriptlets"), | 1142 | "options passed to clang when compiling BPF scriptlets"), |
1139 | OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, | 1143 | OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, |
1140 | "file", "vmlinux pathname"), | 1144 | "file", "vmlinux pathname"), |
1145 | OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, | ||
1146 | "Record build-id of all DSOs regardless of hits"), | ||
1141 | OPT_END() | 1147 | OPT_END() |
1142 | }; | 1148 | }; |
1143 | 1149 | ||
@@ -1255,6 +1261,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1255 | if (err) | 1261 | if (err) |
1256 | goto out_symbol_exit; | 1262 | goto out_symbol_exit; |
1257 | 1263 | ||
1264 | /* | ||
1265 | * We take all buildids when the file contains | ||
1266 | * AUX area tracing data because we do not decode the | ||
1267 | * trace because it would take too long. | ||
1268 | */ | ||
1269 | if (rec->opts.full_auxtrace) | ||
1270 | rec->buildid_all = true; | ||
1271 | |||
1258 | if (record_opts__config(&rec->opts)) { | 1272 | if (record_opts__config(&rec->opts)) { |
1259 | err = -EINVAL; | 1273 | err = -EINVAL; |
1260 | goto out_symbol_exit; | 1274 | goto out_symbol_exit; |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d5a42ee12529..2bf537f190a0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "util/tool.h" | 28 | #include "util/tool.h" |
29 | 29 | ||
30 | #include <subcmd/parse-options.h> | 30 | #include <subcmd/parse-options.h> |
31 | #include <subcmd/exec-cmd.h> | ||
31 | #include "util/parse-events.h" | 32 | #include "util/parse-events.h" |
32 | 33 | ||
33 | #include "util/thread.h" | 34 | #include "util/thread.h" |
@@ -433,7 +434,14 @@ static int report__browse_hists(struct report *rep) | |||
433 | int ret; | 434 | int ret; |
434 | struct perf_session *session = rep->session; | 435 | struct perf_session *session = rep->session; |
435 | struct perf_evlist *evlist = session->evlist; | 436 | struct perf_evlist *evlist = session->evlist; |
436 | const char *help = perf_tip(TIPDIR); | 437 | const char *help = perf_tip(system_path(TIPDIR)); |
438 | |||
439 | if (help == NULL) { | ||
440 | /* fallback for people who don't install perf ;-) */ | ||
441 | help = perf_tip(DOCDIR); | ||
442 | if (help == NULL) | ||
443 | help = "Cannot load tips.txt file, please install perf!"; | ||
444 | } | ||
437 | 445 | ||
438 | switch (use_browser) { | 446 | switch (use_browser) { |
439 | case 1: | 447 | case 1: |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 7f568244662b..038e877081b6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -1588,7 +1588,7 @@ static int add_default_attributes(void) | |||
1588 | return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); | 1588 | return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); |
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | static const char * const recort_usage[] = { | 1591 | static const char * const stat_record_usage[] = { |
1592 | "perf stat record [<options>]", | 1592 | "perf stat record [<options>]", |
1593 | NULL, | 1593 | NULL, |
1594 | }; | 1594 | }; |
@@ -1611,7 +1611,7 @@ static int __cmd_record(int argc, const char **argv) | |||
1611 | struct perf_session *session; | 1611 | struct perf_session *session; |
1612 | struct perf_data_file *file = &perf_stat.file; | 1612 | struct perf_data_file *file = &perf_stat.file; |
1613 | 1613 | ||
1614 | argc = parse_options(argc, argv, stat_options, record_usage, | 1614 | argc = parse_options(argc, argv, stat_options, stat_record_usage, |
1615 | PARSE_OPT_STOP_AT_NON_OPTION); | 1615 | PARSE_OPT_STOP_AT_NON_OPTION); |
1616 | 1616 | ||
1617 | if (output_name) | 1617 | if (output_name) |
@@ -1745,7 +1745,7 @@ int process_cpu_map_event(struct perf_tool *tool __maybe_unused, | |||
1745 | return set_maps(st); | 1745 | return set_maps(st); |
1746 | } | 1746 | } |
1747 | 1747 | ||
1748 | static const char * const report_usage[] = { | 1748 | static const char * const stat_report_usage[] = { |
1749 | "perf stat report [<options>]", | 1749 | "perf stat report [<options>]", |
1750 | NULL, | 1750 | NULL, |
1751 | }; | 1751 | }; |
@@ -1779,7 +1779,7 @@ static int __cmd_report(int argc, const char **argv) | |||
1779 | struct stat st; | 1779 | struct stat st; |
1780 | int ret; | 1780 | int ret; |
1781 | 1781 | ||
1782 | argc = parse_options(argc, argv, options, report_usage, 0); | 1782 | argc = parse_options(argc, argv, options, stat_report_usage, 0); |
1783 | 1783 | ||
1784 | if (!input_name || !strlen(input_name)) { | 1784 | if (!input_name || !strlen(input_name)) { |
1785 | if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) | 1785 | if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 254d06e39bea..e5959c136a19 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -17,7 +17,7 @@ detected_var = $(shell echo "$(1)=$($(1))" >> $(OUTPUT).config-detected) | |||
17 | 17 | ||
18 | CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) | 18 | CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) |
19 | 19 | ||
20 | include $(src-perf)/config/Makefile.arch | 20 | include $(srctree)/tools/scripts/Makefile.arch |
21 | 21 | ||
22 | $(call detected_var,ARCH) | 22 | $(call detected_var,ARCH) |
23 | 23 | ||
@@ -493,7 +493,7 @@ else | |||
493 | 493 | ||
494 | PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) | 494 | PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) |
495 | PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) | 495 | PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) |
496 | PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) | 496 | PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil |
497 | PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) | 497 | PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) |
498 | FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) | 498 | FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) |
499 | 499 | ||
@@ -692,6 +692,7 @@ template_dir = share/perf-core/templates | |||
692 | STRACE_GROUPS_DIR = share/perf-core/strace/groups | 692 | STRACE_GROUPS_DIR = share/perf-core/strace/groups |
693 | htmldir = share/doc/perf-doc | 693 | htmldir = share/doc/perf-doc |
694 | tipdir = share/doc/perf-tip | 694 | tipdir = share/doc/perf-tip |
695 | srcdir = $(srctree)/tools/perf | ||
695 | ifeq ($(prefix),/usr) | 696 | ifeq ($(prefix),/usr) |
696 | sysconfdir = /etc | 697 | sysconfdir = /etc |
697 | ETC_PERFCONFIG = $(sysconfdir)/perfconfig | 698 | ETC_PERFCONFIG = $(sysconfdir)/perfconfig |
@@ -722,6 +723,7 @@ tipdir_SQ = $(subst ','\'',$(tipdir)) | |||
722 | prefix_SQ = $(subst ','\'',$(prefix)) | 723 | prefix_SQ = $(subst ','\'',$(prefix)) |
723 | sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) | 724 | sysconfdir_SQ = $(subst ','\'',$(sysconfdir)) |
724 | libdir_SQ = $(subst ','\'',$(libdir)) | 725 | libdir_SQ = $(subst ','\'',$(libdir)) |
726 | srcdir_SQ = $(subst ','\'',$(srcdir)) | ||
725 | 727 | ||
726 | ifneq ($(filter /%,$(firstword $(perfexecdir))),) | 728 | ifneq ($(filter /%,$(firstword $(perfexecdir))),) |
727 | perfexec_instdir = $(perfexecdir) | 729 | perfexec_instdir = $(perfexecdir) |
@@ -776,6 +778,7 @@ $(call detected_var,STRACE_GROUPS_DIR_SQ) | |||
776 | $(call detected_var,prefix_SQ) | 778 | $(call detected_var,prefix_SQ) |
777 | $(call detected_var,perfexecdir_SQ) | 779 | $(call detected_var,perfexecdir_SQ) |
778 | $(call detected_var,tipdir_SQ) | 780 | $(call detected_var,tipdir_SQ) |
781 | $(call detected_var,srcdir_SQ) | ||
779 | $(call detected_var,LIBDIR) | 782 | $(call detected_var,LIBDIR) |
780 | $(call detected_var,GTK_CFLAGS) | 783 | $(call detected_var,GTK_CFLAGS) |
781 | $(call detected_var,PERL_EMBED_CCOPTS) | 784 | $(call detected_var,PERL_EMBED_CCOPTS) |
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index bcfd081ee1d2..071a8b5f5232 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c | |||
@@ -87,11 +87,6 @@ struct machine *setup_fake_machine(struct machines *machines) | |||
87 | return NULL; | 87 | return NULL; |
88 | } | 88 | } |
89 | 89 | ||
90 | if (machine__create_kernel_maps(machine)) { | ||
91 | pr_debug("Cannot create kernel maps\n"); | ||
92 | return NULL; | ||
93 | } | ||
94 | |||
95 | for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { | 90 | for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { |
96 | struct thread *thread; | 91 | struct thread *thread; |
97 | 92 | ||
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index e36089212061..5e6a86e50fb9 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c | |||
@@ -706,6 +706,7 @@ int test__hists_cumulate(int subtest __maybe_unused) | |||
706 | err = parse_events(evlist, "cpu-clock", NULL); | 706 | err = parse_events(evlist, "cpu-clock", NULL); |
707 | if (err) | 707 | if (err) |
708 | goto out; | 708 | goto out; |
709 | err = TEST_FAIL; | ||
709 | 710 | ||
710 | machines__init(&machines); | 711 | machines__init(&machines); |
711 | 712 | ||
diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index 2a784befd9ce..351a42463444 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c | |||
@@ -120,6 +120,7 @@ int test__hists_filter(int subtest __maybe_unused) | |||
120 | err = parse_events(evlist, "task-clock", NULL); | 120 | err = parse_events(evlist, "task-clock", NULL); |
121 | if (err) | 121 | if (err) |
122 | goto out; | 122 | goto out; |
123 | err = TEST_FAIL; | ||
123 | 124 | ||
124 | /* default sort order (comm,dso,sym) will be used */ | 125 | /* default sort order (comm,dso,sym) will be used */ |
125 | if (setup_sorting(NULL) < 0) | 126 | if (setup_sorting(NULL) < 0) |
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index c764d69ac6ef..64b257d8d557 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c | |||
@@ -293,6 +293,7 @@ int test__hists_link(int subtest __maybe_unused) | |||
293 | if (err) | 293 | if (err) |
294 | goto out; | 294 | goto out; |
295 | 295 | ||
296 | err = TEST_FAIL; | ||
296 | /* default sort order (comm,dso,sym) will be used */ | 297 | /* default sort order (comm,dso,sym) will be used */ |
297 | if (setup_sorting(NULL) < 0) | 298 | if (setup_sorting(NULL) < 0) |
298 | goto out; | 299 | goto out; |
diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index ebe6cd485b5d..b231265148d8 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c | |||
@@ -597,6 +597,7 @@ int test__hists_output(int subtest __maybe_unused) | |||
597 | err = parse_events(evlist, "cpu-clock", NULL); | 597 | err = parse_events(evlist, "cpu-clock", NULL); |
598 | if (err) | 598 | if (err) |
599 | goto out; | 599 | goto out; |
600 | err = TEST_FAIL; | ||
600 | 601 | ||
601 | machines__init(&machines); | 602 | machines__init(&machines); |
602 | 603 | ||
diff --git a/tools/perf/tests/make b/tools/perf/tests/make index c1fbb8e884c0..df38decc48c3 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make | |||
@@ -1,3 +1,5 @@ | |||
1 | include ../scripts/Makefile.include | ||
2 | |||
1 | ifndef MK | 3 | ifndef MK |
2 | ifeq ($(MAKECMDGOALS),) | 4 | ifeq ($(MAKECMDGOALS),) |
3 | # no target specified, trigger the whole suite | 5 | # no target specified, trigger the whole suite |
@@ -12,7 +14,19 @@ endif | |||
12 | else | 14 | else |
13 | PERF := . | 15 | PERF := . |
14 | 16 | ||
15 | include config/Makefile.arch | 17 | # As per kernel Makefile, avoid funny character set dependencies |
18 | unexport LC_ALL | ||
19 | LC_COLLATE=C | ||
20 | LC_NUMERIC=C | ||
21 | export LC_COLLATE LC_NUMERIC | ||
22 | |||
23 | ifeq ($(srctree),) | ||
24 | srctree := $(patsubst %/,%,$(dir $(shell pwd))) | ||
25 | srctree := $(patsubst %/,%,$(dir $(srctree))) | ||
26 | #$(info Determined 'srctree' to be $(srctree)) | ||
27 | endif | ||
28 | |||
29 | include $(srctree)/tools/scripts/Makefile.arch | ||
16 | 30 | ||
17 | # FIXME looks like x86 is the only arch running tests ;-) | 31 | # FIXME looks like x86 is the only arch running tests ;-) |
18 | # we need some IS_(32/64) flag to make this generic | 32 | # we need some IS_(32/64) flag to make this generic |
@@ -280,5 +294,5 @@ all: $(run) $(run_O) tarpkg make_kernelsrc make_kernelsrc_tools | |||
280 | out: $(run_O) | 294 | out: $(run_O) |
281 | @echo OK | 295 | @echo OK |
282 | 296 | ||
283 | .PHONY: all $(run) $(run_O) tarpkg clean | 297 | .PHONY: all $(run) $(run_O) tarpkg clean make_kernelsrc make_kernelsrc_tools |
284 | endif # ifndef MK | 298 | endif # ifndef MK |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 901d481e6cea..08c09ad755d2 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -480,7 +480,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *help) | |||
480 | 480 | ||
481 | hists__browser_title(browser->hists, hbt, title, sizeof(title)); | 481 | hists__browser_title(browser->hists, hbt, title, sizeof(title)); |
482 | 482 | ||
483 | if (ui_browser__show(&browser->b, title, help) < 0) | 483 | if (ui_browser__show(&browser->b, title, "%s", help) < 0) |
484 | return -1; | 484 | return -1; |
485 | 485 | ||
486 | while (1) { | 486 | while (1) { |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index cd61bb1f3917..85155e91b61b 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -503,7 +503,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool, | |||
503 | if (comm_event == NULL) | 503 | if (comm_event == NULL) |
504 | goto out; | 504 | goto out; |
505 | 505 | ||
506 | mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); | 506 | mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); |
507 | if (mmap_event == NULL) | 507 | if (mmap_event == NULL) |
508 | goto out_free_comm; | 508 | goto out_free_comm; |
509 | 509 | ||
@@ -577,7 +577,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
577 | if (comm_event == NULL) | 577 | if (comm_event == NULL) |
578 | goto out; | 578 | goto out; |
579 | 579 | ||
580 | mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); | 580 | mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); |
581 | if (mmap_event == NULL) | 581 | if (mmap_event == NULL) |
582 | goto out_free_comm; | 582 | goto out_free_comm; |
583 | 583 | ||
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index bdf98f6f27bb..0d3dfcb919b4 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
@@ -126,6 +126,11 @@ static int strlist__parse_list_entry(struct strlist *slist, const char *s, | |||
126 | err = strlist__load(slist, subst); | 126 | err = strlist__load(slist, subst); |
127 | goto out; | 127 | goto out; |
128 | } | 128 | } |
129 | |||
130 | if (slist->file_only) { | ||
131 | err = -ENOENT; | ||
132 | goto out; | ||
133 | } | ||
129 | } | 134 | } |
130 | 135 | ||
131 | err = strlist__add(slist, s); | 136 | err = strlist__add(slist, s); |
@@ -157,11 +162,13 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf | |||
157 | 162 | ||
158 | if (slist != NULL) { | 163 | if (slist != NULL) { |
159 | bool dupstr = true; | 164 | bool dupstr = true; |
165 | bool file_only = false; | ||
160 | const char *dirname = NULL; | 166 | const char *dirname = NULL; |
161 | 167 | ||
162 | if (config) { | 168 | if (config) { |
163 | dupstr = !config->dont_dupstr; | 169 | dupstr = !config->dont_dupstr; |
164 | dirname = config->dirname; | 170 | dirname = config->dirname; |
171 | file_only = config->file_only; | ||
165 | } | 172 | } |
166 | 173 | ||
167 | rblist__init(&slist->rblist); | 174 | rblist__init(&slist->rblist); |
@@ -170,6 +177,7 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf | |||
170 | slist->rblist.node_delete = strlist__node_delete; | 177 | slist->rblist.node_delete = strlist__node_delete; |
171 | 178 | ||
172 | slist->dupstr = dupstr; | 179 | slist->dupstr = dupstr; |
180 | slist->file_only = file_only; | ||
173 | 181 | ||
174 | if (list && strlist__parse_list(slist, list, dirname) != 0) | 182 | if (list && strlist__parse_list(slist, list, dirname) != 0) |
175 | goto out_error; | 183 | goto out_error; |
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 297565aa7535..ca990029e243 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h | |||
@@ -13,11 +13,18 @@ struct str_node { | |||
13 | 13 | ||
14 | struct strlist { | 14 | struct strlist { |
15 | struct rblist rblist; | 15 | struct rblist rblist; |
16 | bool dupstr; | 16 | bool dupstr; |
17 | bool file_only; | ||
17 | }; | 18 | }; |
18 | 19 | ||
20 | /* | ||
21 | * @file_only: When dirname is present, only consider entries as filenames, | ||
22 | * that should not be added to the list if dirname/entry is not | ||
23 | * found | ||
24 | */ | ||
19 | struct strlist_config { | 25 | struct strlist_config { |
20 | bool dont_dupstr; | 26 | bool dont_dupstr; |
27 | bool file_only; | ||
21 | const char *dirname; | 28 | const char *dirname; |
22 | }; | 29 | }; |
23 | 30 | ||
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 88b8f8d21f58..ead9509835d2 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <unistd.h> | 17 | #include <unistd.h> |
18 | #include "callchain.h" | 18 | #include "callchain.h" |
19 | #include "strlist.h" | 19 | #include "strlist.h" |
20 | #include <subcmd/exec-cmd.h> | ||
21 | 20 | ||
22 | struct callchain_param callchain_param = { | 21 | struct callchain_param callchain_param = { |
23 | .mode = CHAIN_GRAPH_ABS, | 22 | .mode = CHAIN_GRAPH_ABS, |
@@ -672,14 +671,16 @@ const char *perf_tip(const char *dirpath) | |||
672 | struct str_node *node; | 671 | struct str_node *node; |
673 | char *tip = NULL; | 672 | char *tip = NULL; |
674 | struct strlist_config conf = { | 673 | struct strlist_config conf = { |
675 | .dirname = system_path(dirpath) , | 674 | .dirname = dirpath, |
675 | .file_only = true, | ||
676 | }; | 676 | }; |
677 | 677 | ||
678 | tips = strlist__new("tips.txt", &conf); | 678 | tips = strlist__new("tips.txt", &conf); |
679 | if (tips == NULL || strlist__nr_entries(tips) == 1) { | 679 | if (tips == NULL) |
680 | tip = (char *)"Cannot find tips.txt file"; | 680 | return errno == ENOENT ? NULL : "Tip: get more memory! ;-p"; |
681 | |||
682 | if (strlist__nr_entries(tips) == 0) | ||
681 | goto out; | 683 | goto out; |
682 | } | ||
683 | 684 | ||
684 | node = strlist__entry(tips, random() % strlist__nr_entries(tips)); | 685 | node = strlist__entry(tips, random() % strlist__nr_entries(tips)); |
685 | if (asprintf(&tip, "Tip: %s", node->s) < 0) | 686 | if (asprintf(&tip, "Tip: %s", node->s) < 0) |
diff --git a/tools/perf/config/Makefile.arch b/tools/scripts/Makefile.arch index e11fbd6fae78..e11fbd6fae78 100644 --- a/tools/perf/config/Makefile.arch +++ b/tools/scripts/Makefile.arch | |||