diff options
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 | |||
