Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes and cleanups from Ingo Molnar:
"A kernel fix plus mostly tooling fixes, but also some tooling
restructuring and cleanups"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (39 commits)
perf: Fix building warning on ARM 32
perf symbols: Fix use after free in filename__read_build_id
perf evlist: Use roundup_pow_of_two
tools: Adopt roundup_pow_of_two
perf tools: Make the mmap length autotuning more robust
tools: Adopt rounddown_pow_of_two and deps
tools: Adopt fls_long and deps
tools: Move bitops.h from tools/perf/util to tools/
tools: Introduce asm-generic/bitops.h
tools lib: Move asm-generic/bitops/find.h code to tools/include and tools/lib
tools: Whitespace prep patches for moving bitops.h
tools: Move code originally from asm-generic/atomic.h into tools/include/asm-generic/
tools: Move code originally from linux/log2.h to tools/include/linux/
tools: Move __ffs implementation to tools/include/asm-generic/bitops/__ffs.h
perf evlist: Do not use hard coded value for a mmap_pages default
perf trace: Let the perf_evlist__mmap autosize the number of pages to use
perf evlist: Improve the strerror_mmap method
perf evlist: Clarify sterror_mmap variable names
perf evlist: Fixup brown paper bag on "hint" for --mmap-pages cmdline arg
perf trace: Provide a better explanation when mmap fails
...

+951 -768
+19 -3
arch/x86/kernel/cpu/perf_event_intel_uncore.c
··· 276 276 return box; 277 277 } 278 278 279 + /* 280 + * Using uncore_pmu_event_init pmu event_init callback 281 + * as a detection point for uncore events. 282 + */ 283 + static int uncore_pmu_event_init(struct perf_event *event); 284 + 285 + static bool is_uncore_event(struct perf_event *event) 286 + { 287 + return event->pmu->event_init == uncore_pmu_event_init; 288 + } 289 + 279 290 static int 280 291 uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp) 281 292 { ··· 301 290 return -EINVAL; 302 291 303 292 n = box->n_events; 304 - box->event_list[n] = leader; 305 - n++; 293 + 294 + if (is_uncore_event(leader)) { 295 + box->event_list[n] = leader; 296 + n++; 297 + } 298 + 306 299 if (!dogrp) 307 300 return n; 308 301 309 302 list_for_each_entry(event, &leader->sibling_list, group_entry) { 310 - if (event->state <= PERF_EVENT_STATE_OFF) 303 + if (!is_uncore_event(event) || 304 + event->state <= PERF_EVENT_STATE_OFF) 311 305 continue; 312 306 313 307 if (n >= max_count)
+2 -2
kernel/events/core.c
··· 7477 7477 7478 7478 if (move_group) { 7479 7479 synchronize_rcu(); 7480 - perf_install_in_context(ctx, group_leader, event->cpu); 7480 + perf_install_in_context(ctx, group_leader, group_leader->cpu); 7481 7481 get_ctx(ctx); 7482 7482 list_for_each_entry(sibling, &group_leader->sibling_list, 7483 7483 group_entry) { 7484 - perf_install_in_context(ctx, sibling, event->cpu); 7484 + perf_install_in_context(ctx, sibling, sibling->cpu); 7485 7485 get_ctx(ctx); 7486 7486 } 7487 7487 }
+2 -2
scripts/kconfig/mconf.c
··· 330 330 list_for_each_entry(sp, &trail, entries) { 331 331 if (sp->text) { 332 332 if (pos) { 333 - pos->next = xcalloc(sizeof(*pos), 1); 333 + pos->next = xcalloc(1, sizeof(*pos)); 334 334 pos = pos->next; 335 335 } else { 336 - subtitles = pos = xcalloc(sizeof(*pos), 1); 336 + subtitles = pos = xcalloc(1, sizeof(*pos)); 337 337 } 338 338 pos->text = sp->text; 339 339 }
+27
tools/include/asm-generic/bitops.h
··· 1 + #ifndef __TOOLS_ASM_GENERIC_BITOPS_H 2 + #define __TOOLS_ASM_GENERIC_BITOPS_H 3 + 4 + /* 5 + * tools/ copied this from include/asm-generic/bitops.h, bit by bit as it needed 6 + * some functions. 7 + * 8 + * For the benefit of those who are trying to port Linux to another 9 + * architecture, here are some C-language equivalents. You should 10 + * recode these in the native assembly language, if at all possible. 11 + * 12 + * C language equivalents written by Theodore Ts'o, 9/26/92 13 + */ 14 + 15 + #include <asm-generic/bitops/__ffs.h> 16 + #include <asm-generic/bitops/fls.h> 17 + #include <asm-generic/bitops/__fls.h> 18 + #include <asm-generic/bitops/fls64.h> 19 + #include <asm-generic/bitops/find.h> 20 + 21 + #ifndef _TOOLS_LINUX_BITOPS_H_ 22 + #error only <linux/bitops.h> can be included directly 23 + #endif 24 + 25 + #include <asm-generic/bitops/atomic.h> 26 + 27 + #endif /* __TOOLS_ASM_GENERIC_BITOPS_H */
+43
tools/include/asm-generic/bitops/__ffs.h
··· 1 + #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ 2 + #define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ 3 + 4 + #include <asm/types.h> 5 + 6 + /** 7 + * __ffs - find first bit in word. 8 + * @word: The word to search 9 + * 10 + * Undefined if no bit exists, so code should check against 0 first. 11 + */ 12 + static __always_inline unsigned long __ffs(unsigned long word) 13 + { 14 + int num = 0; 15 + 16 + #if __BITS_PER_LONG == 64 17 + if ((word & 0xffffffff) == 0) { 18 + num += 32; 19 + word >>= 32; 20 + } 21 + #endif 22 + if ((word & 0xffff) == 0) { 23 + num += 16; 24 + word >>= 16; 25 + } 26 + if ((word & 0xff) == 0) { 27 + num += 8; 28 + word >>= 8; 29 + } 30 + if ((word & 0xf) == 0) { 31 + num += 4; 32 + word >>= 4; 33 + } 34 + if ((word & 0x3) == 0) { 35 + num += 2; 36 + word >>= 2; 37 + } 38 + if ((word & 0x1) == 0) 39 + num += 1; 40 + return num; 41 + } 42 + 43 + #endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ */
+1
tools/include/asm-generic/bitops/__fls.h
··· 1 + #include <../../../../include/asm-generic/bitops/__fls.h>
+22
tools/include/asm-generic/bitops/atomic.h
··· 1 + #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ 2 + #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ 3 + 4 + #include <asm/types.h> 5 + 6 + static inline void set_bit(int nr, unsigned long *addr) 7 + { 8 + addr[nr / __BITS_PER_LONG] |= 1UL << (nr % __BITS_PER_LONG); 9 + } 10 + 11 + static inline void clear_bit(int nr, unsigned long *addr) 12 + { 13 + addr[nr / __BITS_PER_LONG] &= ~(1UL << (nr % __BITS_PER_LONG)); 14 + } 15 + 16 + static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) 17 + { 18 + return ((1UL << (nr % __BITS_PER_LONG)) & 19 + (((unsigned long *)addr)[nr / __BITS_PER_LONG])) != 0; 20 + } 21 + 22 + #endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ */
+33
tools/include/asm-generic/bitops/find.h
··· 1 + #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ 2 + #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ 3 + 4 + #ifndef find_next_bit 5 + /** 6 + * find_next_bit - find the next set bit in a memory region 7 + * @addr: The address to base the search on 8 + * @offset: The bitnumber to start searching at 9 + * @size: The bitmap size in bits 10 + * 11 + * Returns the bit number for the next set bit 12 + * If no bits are set, returns @size. 13 + */ 14 + extern unsigned long find_next_bit(const unsigned long *addr, unsigned long 15 + size, unsigned long offset); 16 + #endif 17 + 18 + #ifndef find_first_bit 19 + 20 + /** 21 + * find_first_bit - find the first set bit in a memory region 22 + * @addr: The address to start the search at 23 + * @size: The maximum number of bits to search 24 + * 25 + * Returns the bit number of the first set bit. 26 + * If no bits are set, returns @size. 27 + */ 28 + extern unsigned long find_first_bit(const unsigned long *addr, 29 + unsigned long size); 30 + 31 + #endif /* find_first_bit */ 32 + 33 + #endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
+1
tools/include/asm-generic/bitops/fls.h
··· 1 + #include <../../../../include/asm-generic/bitops/fls.h>
+1
tools/include/asm-generic/bitops/fls64.h
··· 1 + #include <../../../../include/asm-generic/bitops/fls64.h>
+53
tools/include/linux/bitops.h
··· 1 + #ifndef _TOOLS_LINUX_BITOPS_H_ 2 + #define _TOOLS_LINUX_BITOPS_H_ 3 + 4 + #include <linux/kernel.h> 5 + #include <linux/compiler.h> 6 + #include <asm/hweight.h> 7 + 8 + #ifndef __WORDSIZE 9 + #define __WORDSIZE (__SIZEOF_LONG__ * 8) 10 + #endif 11 + 12 + #define BITS_PER_LONG __WORDSIZE 13 + 14 + #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 15 + #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 16 + #define BITS_PER_BYTE 8 17 + #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 18 + #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) 19 + #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) 20 + #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) 21 + 22 + /* 23 + * Include this here because some architectures need generic_ffs/fls in 24 + * scope 25 + * 26 + * XXX: this needs to be asm/bitops.h, when we get to per arch optimizations 27 + */ 28 + #include <asm-generic/bitops.h> 29 + 30 + #define for_each_set_bit(bit, addr, size) \ 31 + for ((bit) = find_first_bit((addr), (size)); \ 32 + (bit) < (size); \ 33 + (bit) = find_next_bit((addr), (size), (bit) + 1)) 34 + 35 + /* same as for_each_set_bit() but use bit as value to start with */ 36 + #define for_each_set_bit_from(bit, addr, size) \ 37 + for ((bit) = find_next_bit((addr), (size), (bit)); \ 38 + (bit) < (size); \ 39 + (bit) = find_next_bit((addr), (size), (bit) + 1)) 40 + 41 + static inline unsigned long hweight_long(unsigned long w) 42 + { 43 + return sizeof(w) == 4 ? hweight32(w) : hweight64(w); 44 + } 45 + 46 + static inline unsigned fls_long(unsigned long l) 47 + { 48 + if (sizeof(l) == 4) 49 + return fls(l); 50 + return fls64(l); 51 + } 52 + 53 + #endif
+185
tools/include/linux/log2.h
··· 1 + /* Integer base 2 logarithm calculation 2 + * 3 + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. 4 + * Written by David Howells (dhowells@redhat.com) 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 9 + * 2 of the License, or (at your option) any later version. 10 + */ 11 + 12 + #ifndef _TOOLS_LINUX_LOG2_H 13 + #define _TOOLS_LINUX_LOG2_H 14 + 15 + /* 16 + * deal with unrepresentable constant logarithms 17 + */ 18 + extern __attribute__((const, noreturn)) 19 + int ____ilog2_NaN(void); 20 + 21 + /* 22 + * non-constant log of base 2 calculators 23 + * - the arch may override these in asm/bitops.h if they can be implemented 24 + * more efficiently than using fls() and fls64() 25 + * - the arch is not required to handle n==0 if implementing the fallback 26 + */ 27 + static inline __attribute__((const)) 28 + int __ilog2_u32(u32 n) 29 + { 30 + return fls(n) - 1; 31 + } 32 + 33 + static inline __attribute__((const)) 34 + int __ilog2_u64(u64 n) 35 + { 36 + return fls64(n) - 1; 37 + } 38 + 39 + /* 40 + * Determine whether some value is a power of two, where zero is 41 + * *not* considered a power of two. 42 + */ 43 + 44 + static inline __attribute__((const)) 45 + bool is_power_of_2(unsigned long n) 46 + { 47 + return (n != 0 && ((n & (n - 1)) == 0)); 48 + } 49 + 50 + /* 51 + * round up to nearest power of two 52 + */ 53 + static inline __attribute__((const)) 54 + unsigned long __roundup_pow_of_two(unsigned long n) 55 + { 56 + return 1UL << fls_long(n - 1); 57 + } 58 + 59 + /* 60 + * round down to nearest power of two 61 + */ 62 + static inline __attribute__((const)) 63 + unsigned long __rounddown_pow_of_two(unsigned long n) 64 + { 65 + return 1UL << (fls_long(n) - 1); 66 + } 67 + 68 + /** 69 + * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value 70 + * @n - parameter 71 + * 72 + * constant-capable log of base 2 calculation 73 + * - this can be used to initialise global variables from constant data, hence 74 + * the massive ternary operator construction 75 + * 76 + * selects the appropriately-sized optimised version depending on sizeof(n) 77 + */ 78 + #define ilog2(n) \ 79 + ( \ 80 + __builtin_constant_p(n) ? ( \ 81 + (n) < 1 ? ____ilog2_NaN() : \ 82 + (n) & (1ULL << 63) ? 63 : \ 83 + (n) & (1ULL << 62) ? 62 : \ 84 + (n) & (1ULL << 61) ? 61 : \ 85 + (n) & (1ULL << 60) ? 60 : \ 86 + (n) & (1ULL << 59) ? 59 : \ 87 + (n) & (1ULL << 58) ? 58 : \ 88 + (n) & (1ULL << 57) ? 57 : \ 89 + (n) & (1ULL << 56) ? 56 : \ 90 + (n) & (1ULL << 55) ? 55 : \ 91 + (n) & (1ULL << 54) ? 54 : \ 92 + (n) & (1ULL << 53) ? 53 : \ 93 + (n) & (1ULL << 52) ? 52 : \ 94 + (n) & (1ULL << 51) ? 51 : \ 95 + (n) & (1ULL << 50) ? 50 : \ 96 + (n) & (1ULL << 49) ? 49 : \ 97 + (n) & (1ULL << 48) ? 48 : \ 98 + (n) & (1ULL << 47) ? 47 : \ 99 + (n) & (1ULL << 46) ? 46 : \ 100 + (n) & (1ULL << 45) ? 45 : \ 101 + (n) & (1ULL << 44) ? 44 : \ 102 + (n) & (1ULL << 43) ? 43 : \ 103 + (n) & (1ULL << 42) ? 42 : \ 104 + (n) & (1ULL << 41) ? 41 : \ 105 + (n) & (1ULL << 40) ? 40 : \ 106 + (n) & (1ULL << 39) ? 39 : \ 107 + (n) & (1ULL << 38) ? 38 : \ 108 + (n) & (1ULL << 37) ? 37 : \ 109 + (n) & (1ULL << 36) ? 36 : \ 110 + (n) & (1ULL << 35) ? 35 : \ 111 + (n) & (1ULL << 34) ? 34 : \ 112 + (n) & (1ULL << 33) ? 33 : \ 113 + (n) & (1ULL << 32) ? 32 : \ 114 + (n) & (1ULL << 31) ? 31 : \ 115 + (n) & (1ULL << 30) ? 30 : \ 116 + (n) & (1ULL << 29) ? 29 : \ 117 + (n) & (1ULL << 28) ? 28 : \ 118 + (n) & (1ULL << 27) ? 27 : \ 119 + (n) & (1ULL << 26) ? 26 : \ 120 + (n) & (1ULL << 25) ? 25 : \ 121 + (n) & (1ULL << 24) ? 24 : \ 122 + (n) & (1ULL << 23) ? 23 : \ 123 + (n) & (1ULL << 22) ? 22 : \ 124 + (n) & (1ULL << 21) ? 21 : \ 125 + (n) & (1ULL << 20) ? 20 : \ 126 + (n) & (1ULL << 19) ? 19 : \ 127 + (n) & (1ULL << 18) ? 18 : \ 128 + (n) & (1ULL << 17) ? 17 : \ 129 + (n) & (1ULL << 16) ? 16 : \ 130 + (n) & (1ULL << 15) ? 15 : \ 131 + (n) & (1ULL << 14) ? 14 : \ 132 + (n) & (1ULL << 13) ? 13 : \ 133 + (n) & (1ULL << 12) ? 12 : \ 134 + (n) & (1ULL << 11) ? 11 : \ 135 + (n) & (1ULL << 10) ? 10 : \ 136 + (n) & (1ULL << 9) ? 9 : \ 137 + (n) & (1ULL << 8) ? 8 : \ 138 + (n) & (1ULL << 7) ? 7 : \ 139 + (n) & (1ULL << 6) ? 6 : \ 140 + (n) & (1ULL << 5) ? 5 : \ 141 + (n) & (1ULL << 4) ? 4 : \ 142 + (n) & (1ULL << 3) ? 3 : \ 143 + (n) & (1ULL << 2) ? 2 : \ 144 + (n) & (1ULL << 1) ? 1 : \ 145 + (n) & (1ULL << 0) ? 0 : \ 146 + ____ilog2_NaN() \ 147 + ) : \ 148 + (sizeof(n) <= 4) ? \ 149 + __ilog2_u32(n) : \ 150 + __ilog2_u64(n) \ 151 + ) 152 + 153 + /** 154 + * roundup_pow_of_two - round the given value up to nearest power of two 155 + * @n - parameter 156 + * 157 + * round the given value up to the nearest power of two 158 + * - the result is undefined when n == 0 159 + * - this can be used to initialise global variables from constant data 160 + */ 161 + #define roundup_pow_of_two(n) \ 162 + ( \ 163 + __builtin_constant_p(n) ? ( \ 164 + (n == 1) ? 1 : \ 165 + (1UL << (ilog2((n) - 1) + 1)) \ 166 + ) : \ 167 + __roundup_pow_of_two(n) \ 168 + ) 169 + 170 + /** 171 + * rounddown_pow_of_two - round the given value down to nearest power of two 172 + * @n - parameter 173 + * 174 + * round the given value down to the nearest power of two 175 + * - the result is undefined when n == 0 176 + * - this can be used to initialise global variables from constant data 177 + */ 178 + #define rounddown_pow_of_two(n) \ 179 + ( \ 180 + __builtin_constant_p(n) ? ( \ 181 + (1UL << ilog2(n))) : \ 182 + __rounddown_pow_of_two(n) \ 183 + ) 184 + 185 + #endif /* _TOOLS_LINUX_LOG2_H */
+34
tools/lib/api/fs/fs.c
··· 7 7 #include <stdlib.h> 8 8 #include <string.h> 9 9 #include <sys/vfs.h> 10 + #include <sys/types.h> 11 + #include <sys/stat.h> 12 + #include <fcntl.h> 13 + #include <unistd.h> 10 14 11 15 #include "debugfs.h" 12 16 #include "fs.h" ··· 167 163 168 164 FS__MOUNTPOINT(sysfs, FS__SYSFS); 169 165 FS__MOUNTPOINT(procfs, FS__PROCFS); 166 + 167 + int filename__read_int(const char *filename, int *value) 168 + { 169 + char line[64]; 170 + int fd = open(filename, O_RDONLY), err = -1; 171 + 172 + if (fd < 0) 173 + return -1; 174 + 175 + if (read(fd, line, sizeof(line)) > 0) { 176 + *value = atoi(line); 177 + err = 0; 178 + } 179 + 180 + close(fd); 181 + return err; 182 + } 183 + 184 + int sysctl__read_int(const char *sysctl, int *value) 185 + { 186 + char path[PATH_MAX]; 187 + const char *procfs = procfs__mountpoint(); 188 + 189 + if (!procfs) 190 + return -1; 191 + 192 + snprintf(path, sizeof(path), "%s/sys/%s", procfs, sysctl); 193 + 194 + return filename__read_int(path, value); 195 + }
+3
tools/lib/api/fs/fs.h
··· 11 11 12 12 const char *sysfs__mountpoint(void); 13 13 const char *procfs__mountpoint(void); 14 + 15 + int filename__read_int(const char *filename, int *value); 16 + int sysctl__read_int(const char *sysctl, int *value); 14 17 #endif /* __API_FS__ */
+89
tools/lib/util/find_next_bit.c
··· 1 + /* find_next_bit.c: fallback find next bit implementation 2 + * 3 + * Copied from lib/find_next_bit.c to tools/lib/next_bit.c 4 + * 5 + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 6 + * Written by David Howells (dhowells@redhat.com) 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * as published by the Free Software Foundation; either version 11 + * 2 of the License, or (at your option) any later version. 12 + */ 13 + 14 + #include <linux/bitops.h> 15 + #include <asm/types.h> 16 + #include <asm/byteorder.h> 17 + 18 + #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) 19 + 20 + #ifndef find_next_bit 21 + /* 22 + * Find the next set bit in a memory region. 23 + */ 24 + unsigned long find_next_bit(const unsigned long *addr, unsigned long size, 25 + unsigned long offset) 26 + { 27 + const unsigned long *p = addr + BITOP_WORD(offset); 28 + unsigned long result = offset & ~(BITS_PER_LONG-1); 29 + unsigned long tmp; 30 + 31 + if (offset >= size) 32 + return size; 33 + size -= result; 34 + offset %= BITS_PER_LONG; 35 + if (offset) { 36 + tmp = *(p++); 37 + tmp &= (~0UL << offset); 38 + if (size < BITS_PER_LONG) 39 + goto found_first; 40 + if (tmp) 41 + goto found_middle; 42 + size -= BITS_PER_LONG; 43 + result += BITS_PER_LONG; 44 + } 45 + while (size & ~(BITS_PER_LONG-1)) { 46 + if ((tmp = *(p++))) 47 + goto found_middle; 48 + result += BITS_PER_LONG; 49 + size -= BITS_PER_LONG; 50 + } 51 + if (!size) 52 + return result; 53 + tmp = *p; 54 + 55 + found_first: 56 + tmp &= (~0UL >> (BITS_PER_LONG - size)); 57 + if (tmp == 0UL) /* Are any bits set? */ 58 + return result + size; /* Nope. */ 59 + found_middle: 60 + return result + __ffs(tmp); 61 + } 62 + #endif 63 + 64 + #ifndef find_first_bit 65 + /* 66 + * Find the first set bit in a memory region. 67 + */ 68 + unsigned long find_first_bit(const unsigned long *addr, unsigned long size) 69 + { 70 + const unsigned long *p = addr; 71 + unsigned long result = 0; 72 + unsigned long tmp; 73 + 74 + while (size & ~(BITS_PER_LONG-1)) { 75 + if ((tmp = *(p++))) 76 + goto found; 77 + result += BITS_PER_LONG; 78 + size -= BITS_PER_LONG; 79 + } 80 + if (!size) 81 + return result; 82 + 83 + tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); 84 + if (tmp == 0UL) /* Are any bits set? */ 85 + return result + size; /* Nope. */ 86 + found: 87 + return result + __ffs(tmp); 88 + } 89 + #endif
+4
tools/perf/Documentation/perf.txt
··· 18 18 --debug verbose # sets verbose = 1 19 19 --debug verbose=2 # sets verbose = 2 20 20 21 + --buildid-dir:: 22 + Setup buildid cache directory. It has higher priority than 23 + buildid.dir config file option. 24 + 21 25 DESCRIPTION 22 26 ----------- 23 27 Performance counters for Linux are a new kernel-based subsystem
+15 -1
tools/perf/MANIFEST
··· 4 4 tools/lib/api 5 5 tools/lib/symbol/kallsyms.c 6 6 tools/lib/symbol/kallsyms.h 7 + tools/lib/util/find_next_bit.c 7 8 tools/include/asm/bug.h 9 + tools/include/asm-generic/bitops/atomic.h 10 + tools/include/asm-generic/bitops/__ffs.h 11 + tools/include/asm-generic/bitops/__fls.h 12 + tools/include/asm-generic/bitops/find.h 13 + tools/include/asm-generic/bitops/fls64.h 14 + tools/include/asm-generic/bitops/fls.h 15 + tools/include/asm-generic/bitops.h 16 + tools/include/linux/bitops.h 8 17 tools/include/linux/compiler.h 9 - tools/include/linux/hash.h 10 18 tools/include/linux/export.h 19 + tools/include/linux/hash.h 20 + tools/include/linux/log2.h 11 21 tools/include/linux/types.h 22 + include/asm-generic/bitops/fls64.h 23 + include/asm-generic/bitops/__fls.h 24 + include/asm-generic/bitops/fls.h 12 25 include/linux/const.h 13 26 include/linux/perf_event.h 14 27 include/linux/rbtree.h 15 28 include/linux/list.h 16 29 include/linux/hash.h 17 30 include/linux/stringify.h 31 + lib/find_next_bit.c 18 32 lib/rbtree.c 19 33 include/linux/swab.h 20 34 arch/*/include/asm/unistd*.h
+13 -2
tools/perf/Makefile.perf
··· 231 231 LIB_H += ../include/linux/hash.h 232 232 LIB_H += ../../include/linux/stringify.h 233 233 LIB_H += util/include/linux/bitmap.h 234 - LIB_H += util/include/linux/bitops.h 234 + LIB_H += ../include/linux/bitops.h 235 + LIB_H += ../include/asm-generic/bitops/atomic.h 236 + LIB_H += ../include/asm-generic/bitops/find.h 237 + LIB_H += ../include/asm-generic/bitops/fls64.h 238 + LIB_H += ../include/asm-generic/bitops/fls.h 239 + LIB_H += ../include/asm-generic/bitops/__ffs.h 240 + LIB_H += ../include/asm-generic/bitops/__fls.h 241 + LIB_H += ../include/asm-generic/bitops.h 235 242 LIB_H += ../include/linux/compiler.h 243 + LIB_H += ../include/linux/log2.h 236 244 LIB_H += util/include/linux/const.h 237 245 LIB_H += util/include/linux/ctype.h 238 246 LIB_H += util/include/linux/kernel.h ··· 343 335 LIB_OBJS += $(OUTPUT)util/evlist.o 344 336 LIB_OBJS += $(OUTPUT)util/evsel.o 345 337 LIB_OBJS += $(OUTPUT)util/exec_cmd.o 338 + LIB_OBJS += $(OUTPUT)util/find_next_bit.o 346 339 LIB_OBJS += $(OUTPUT)util/help.o 347 340 LIB_OBJS += $(OUTPUT)util/kallsyms.o 348 341 LIB_OBJS += $(OUTPUT)util/levenshtein.o ··· 467 458 BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o 468 459 endif 469 460 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o 470 - BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o 471 461 BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o 472 462 BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o 473 463 BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o ··· 741 733 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $< 742 734 743 735 $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS 736 + $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 737 + 738 + $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS 744 739 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 745 740 746 741 $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
+256 -138
tools/perf/bench/mem-memcpy.c
··· 13 13 #include "../util/cloexec.h" 14 14 #include "bench.h" 15 15 #include "mem-memcpy-arch.h" 16 + #include "mem-memset-arch.h" 16 17 17 18 #include <stdio.h> 18 19 #include <stdlib.h> ··· 49 48 }; 50 49 51 50 typedef void *(*memcpy_t)(void *, const void *, size_t); 51 + typedef void *(*memset_t)(void *, int, size_t); 52 52 53 53 struct routine { 54 54 const char *name; 55 55 const char *desc; 56 - memcpy_t fn; 56 + union { 57 + memcpy_t memcpy; 58 + memset_t memset; 59 + } fn; 57 60 }; 58 61 59 - struct routine routines[] = { 60 - { "default", 61 - "Default memcpy() provided by glibc", 62 - memcpy }, 62 + struct routine memcpy_routines[] = { 63 + { .name = "default", 64 + .desc = "Default memcpy() provided by glibc", 65 + .fn.memcpy = memcpy }, 63 66 #ifdef HAVE_ARCH_X86_64_SUPPORT 64 67 65 - #define MEMCPY_FN(fn, name, desc) { name, desc, fn }, 68 + #define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, 66 69 #include "mem-memcpy-x86-64-asm-def.h" 67 70 #undef MEMCPY_FN 68 71 ··· 74 69 75 70 { NULL, 76 71 NULL, 77 - NULL } 72 + {NULL} } 78 73 }; 79 74 80 75 static const char * const bench_mem_memcpy_usage[] = { ··· 115 110 (double)ts->tv_usec / (double)1000000; 116 111 } 117 112 118 - static void alloc_mem(void **dst, void **src, size_t length) 113 + #define pf (no_prefault ? 0 : 1) 114 + 115 + #define print_bps(x) do { \ 116 + if (x < K) \ 117 + printf(" %14lf B/Sec", x); \ 118 + else if (x < K * K) \ 119 + printf(" %14lfd KB/Sec", x / K); \ 120 + else if (x < K * K * K) \ 121 + printf(" %14lf MB/Sec", x / K / K); \ 122 + else \ 123 + printf(" %14lf GB/Sec", x / K / K / K); \ 124 + } while (0) 125 + 126 + struct bench_mem_info { 127 + const struct routine *routines; 128 + u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault); 129 + double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault); 130 + const char *const *usage; 131 + }; 132 + 133 + static int bench_mem_common(int argc, const char **argv, 134 + const char *prefix __maybe_unused, 135 + struct bench_mem_info *info) 136 + { 137 + int i; 138 + size_t len; 139 + double totallen; 140 + double result_bps[2]; 141 + u64 result_cycle[2]; 142 + 143 + argc = parse_options(argc, argv, options, 144 + info->usage, 0); 145 + 146 + if (no_prefault && only_prefault) { 147 + fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); 148 + return 1; 149 + } 150 + 151 + if (use_cycle) 152 + init_cycle(); 153 + 154 + len = (size_t)perf_atoll((char *)length_str); 155 + totallen = (double)len * iterations; 156 + 157 + result_cycle[0] = result_cycle[1] = 0ULL; 158 + result_bps[0] = result_bps[1] = 0.0; 159 + 160 + if ((s64)len <= 0) { 161 + fprintf(stderr, "Invalid length:%s\n", length_str); 162 + return 1; 163 + } 164 + 165 + /* same to without specifying either of prefault and no-prefault */ 166 + if (only_prefault && no_prefault) 167 + only_prefault = no_prefault = false; 168 + 169 + for (i = 0; info->routines[i].name; i++) { 170 + if (!strcmp(info->routines[i].name, routine)) 171 + break; 172 + } 173 + if (!info->routines[i].name) { 174 + printf("Unknown routine:%s\n", routine); 175 + printf("Available routines...\n"); 176 + for (i = 0; info->routines[i].name; i++) { 177 + printf("\t%s ... %s\n", 178 + info->routines[i].name, info->routines[i].desc); 179 + } 180 + return 1; 181 + } 182 + 183 + if (bench_format == BENCH_FORMAT_DEFAULT) 184 + printf("# Copying %s Bytes ...\n\n", length_str); 185 + 186 + if (!only_prefault && !no_prefault) { 187 + /* show both of results */ 188 + if (use_cycle) { 189 + result_cycle[0] = 190 + info->do_cycle(&info->routines[i], len, false); 191 + result_cycle[1] = 192 + info->do_cycle(&info->routines[i], len, true); 193 + } else { 194 + result_bps[0] = 195 + info->do_gettimeofday(&info->routines[i], 196 + len, false); 197 + result_bps[1] = 198 + info->do_gettimeofday(&info->routines[i], 199 + len, true); 200 + } 201 + } else { 202 + if (use_cycle) { 203 + result_cycle[pf] = 204 + info->do_cycle(&info->routines[i], 205 + len, only_prefault); 206 + } else { 207 + result_bps[pf] = 208 + info->do_gettimeofday(&info->routines[i], 209 + len, only_prefault); 210 + } 211 + } 212 + 213 + switch (bench_format) { 214 + case BENCH_FORMAT_DEFAULT: 215 + if (!only_prefault && !no_prefault) { 216 + if (use_cycle) { 217 + printf(" %14lf Cycle/Byte\n", 218 + (double)result_cycle[0] 219 + / totallen); 220 + printf(" %14lf Cycle/Byte (with prefault)\n", 221 + (double)result_cycle[1] 222 + / totallen); 223 + } else { 224 + print_bps(result_bps[0]); 225 + printf("\n"); 226 + print_bps(result_bps[1]); 227 + printf(" (with prefault)\n"); 228 + } 229 + } else { 230 + if (use_cycle) { 231 + printf(" %14lf Cycle/Byte", 232 + (double)result_cycle[pf] 233 + / totallen); 234 + } else 235 + print_bps(result_bps[pf]); 236 + 237 + printf("%s\n", only_prefault ? " (with prefault)" : ""); 238 + } 239 + break; 240 + case BENCH_FORMAT_SIMPLE: 241 + if (!only_prefault && !no_prefault) { 242 + if (use_cycle) { 243 + printf("%lf %lf\n", 244 + (double)result_cycle[0] / totallen, 245 + (double)result_cycle[1] / totallen); 246 + } else { 247 + printf("%lf %lf\n", 248 + result_bps[0], result_bps[1]); 249 + } 250 + } else { 251 + if (use_cycle) { 252 + printf("%lf\n", (double)result_cycle[pf] 253 + / totallen); 254 + } else 255 + printf("%lf\n", result_bps[pf]); 256 + } 257 + break; 258 + default: 259 + /* reaching this means there's some disaster: */ 260 + die("unknown format: %d\n", bench_format); 261 + break; 262 + } 263 + 264 + return 0; 265 + } 266 + 267 + static void memcpy_alloc_mem(void **dst, void **src, size_t length) 119 268 { 120 269 *dst = zalloc(length); 121 270 if (!*dst) ··· 282 123 memset(*src, 0, length); 283 124 } 284 125 285 - static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault) 126 + static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault) 286 127 { 287 128 u64 cycle_start = 0ULL, cycle_end = 0ULL; 288 129 void *src = NULL, *dst = NULL; 130 + memcpy_t fn = r->fn.memcpy; 289 131 int i; 290 132 291 - alloc_mem(&src, &dst, len); 133 + memcpy_alloc_mem(&src, &dst, len); 292 134 293 135 if (prefault) 294 136 fn(dst, src, len); ··· 304 144 return cycle_end - cycle_start; 305 145 } 306 146 307 - static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) 147 + static double do_memcpy_gettimeofday(const struct routine *r, size_t len, 148 + bool prefault) 308 149 { 309 150 struct timeval tv_start, tv_end, tv_diff; 151 + memcpy_t fn = r->fn.memcpy; 310 152 void *src = NULL, *dst = NULL; 311 153 int i; 312 154 313 - alloc_mem(&src, &dst, len); 155 + memcpy_alloc_mem(&src, &dst, len); 314 156 315 157 if (prefault) 316 158 fn(dst, src, len); ··· 326 164 327 165 free(src); 328 166 free(dst); 329 - return (double)((double)len / timeval2double(&tv_diff)); 167 + return (double)(((double)len * iterations) / timeval2double(&tv_diff)); 330 168 } 331 - 332 - #define pf (no_prefault ? 0 : 1) 333 - 334 - #define print_bps(x) do { \ 335 - if (x < K) \ 336 - printf(" %14lf B/Sec", x); \ 337 - else if (x < K * K) \ 338 - printf(" %14lfd KB/Sec", x / K); \ 339 - else if (x < K * K * K) \ 340 - printf(" %14lf MB/Sec", x / K / K); \ 341 - else \ 342 - printf(" %14lf GB/Sec", x / K / K / K); \ 343 - } while (0) 344 169 345 170 int bench_mem_memcpy(int argc, const char **argv, 346 171 const char *prefix __maybe_unused) 347 172 { 173 + struct bench_mem_info info = { 174 + .routines = memcpy_routines, 175 + .do_cycle = do_memcpy_cycle, 176 + .do_gettimeofday = do_memcpy_gettimeofday, 177 + .usage = bench_mem_memcpy_usage, 178 + }; 179 + 180 + return bench_mem_common(argc, argv, prefix, &info); 181 + } 182 + 183 + static void memset_alloc_mem(void **dst, size_t length) 184 + { 185 + *dst = zalloc(length); 186 + if (!*dst) 187 + die("memory allocation failed - maybe length is too large?\n"); 188 + } 189 + 190 + static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault) 191 + { 192 + u64 cycle_start = 0ULL, cycle_end = 0ULL; 193 + memset_t fn = r->fn.memset; 194 + void *dst = NULL; 348 195 int i; 349 - size_t len; 350 - double result_bps[2]; 351 - u64 result_cycle[2]; 352 196 353 - argc = parse_options(argc, argv, options, 354 - bench_mem_memcpy_usage, 0); 197 + memset_alloc_mem(&dst, len); 355 198 356 - if (no_prefault && only_prefault) { 357 - fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); 358 - return 1; 359 - } 199 + if (prefault) 200 + fn(dst, -1, len); 360 201 361 - if (use_cycle) 362 - init_cycle(); 202 + cycle_start = get_cycle(); 203 + for (i = 0; i < iterations; ++i) 204 + fn(dst, i, len); 205 + cycle_end = get_cycle(); 363 206 364 - len = (size_t)perf_atoll((char *)length_str); 207 + free(dst); 208 + return cycle_end - cycle_start; 209 + } 365 210 366 - result_cycle[0] = result_cycle[1] = 0ULL; 367 - result_bps[0] = result_bps[1] = 0.0; 211 + static double do_memset_gettimeofday(const struct routine *r, size_t len, 212 + bool prefault) 213 + { 214 + struct timeval tv_start, tv_end, tv_diff; 215 + memset_t fn = r->fn.memset; 216 + void *dst = NULL; 217 + int i; 368 218 369 - if ((s64)len <= 0) { 370 - fprintf(stderr, "Invalid length:%s\n", length_str); 371 - return 1; 372 - } 219 + memset_alloc_mem(&dst, len); 373 220 374 - /* same to without specifying either of prefault and no-prefault */ 375 - if (only_prefault && no_prefault) 376 - only_prefault = no_prefault = false; 221 + if (prefault) 222 + fn(dst, -1, len); 377 223 378 - for (i = 0; routines[i].name; i++) { 379 - if (!strcmp(routines[i].name, routine)) 380 - break; 381 - } 382 - if (!routines[i].name) { 383 - printf("Unknown routine:%s\n", routine); 384 - printf("Available routines...\n"); 385 - for (i = 0; routines[i].name; i++) { 386 - printf("\t%s ... %s\n", 387 - routines[i].name, routines[i].desc); 388 - } 389 - return 1; 390 - } 224 + BUG_ON(gettimeofday(&tv_start, NULL)); 225 + for (i = 0; i < iterations; ++i) 226 + fn(dst, i, len); 227 + BUG_ON(gettimeofday(&tv_end, NULL)); 391 228 392 - if (bench_format == BENCH_FORMAT_DEFAULT) 393 - printf("# Copying %s Bytes ...\n\n", length_str); 229 + timersub(&tv_end, &tv_start, &tv_diff); 394 230 395 - if (!only_prefault && !no_prefault) { 396 - /* show both of results */ 397 - if (use_cycle) { 398 - result_cycle[0] = 399 - do_memcpy_cycle(routines[i].fn, len, false); 400 - result_cycle[1] = 401 - do_memcpy_cycle(routines[i].fn, len, true); 402 - } else { 403 - result_bps[0] = 404 - do_memcpy_gettimeofday(routines[i].fn, 405 - len, false); 406 - result_bps[1] = 407 - do_memcpy_gettimeofday(routines[i].fn, 408 - len, true); 409 - } 410 - } else { 411 - if (use_cycle) { 412 - result_cycle[pf] = 413 - do_memcpy_cycle(routines[i].fn, 414 - len, only_prefault); 415 - } else { 416 - result_bps[pf] = 417 - do_memcpy_gettimeofday(routines[i].fn, 418 - len, only_prefault); 419 - } 420 - } 231 + free(dst); 232 + return (double)(((double)len * iterations) / timeval2double(&tv_diff)); 233 + } 421 234 422 - switch (bench_format) { 423 - case BENCH_FORMAT_DEFAULT: 424 - if (!only_prefault && !no_prefault) { 425 - if (use_cycle) { 426 - printf(" %14lf Cycle/Byte\n", 427 - (double)result_cycle[0] 428 - / (double)len); 429 - printf(" %14lf Cycle/Byte (with prefault)\n", 430 - (double)result_cycle[1] 431 - / (double)len); 432 - } else { 433 - print_bps(result_bps[0]); 434 - printf("\n"); 435 - print_bps(result_bps[1]); 436 - printf(" (with prefault)\n"); 437 - } 438 - } else { 439 - if (use_cycle) { 440 - printf(" %14lf Cycle/Byte", 441 - (double)result_cycle[pf] 442 - / (double)len); 443 - } else 444 - print_bps(result_bps[pf]); 235 + static const char * const bench_mem_memset_usage[] = { 236 + "perf bench mem memset <options>", 237 + NULL 238 + }; 445 239 446 - printf("%s\n", only_prefault ? " (with prefault)" : ""); 447 - } 448 - break; 449 - case BENCH_FORMAT_SIMPLE: 450 - if (!only_prefault && !no_prefault) { 451 - if (use_cycle) { 452 - printf("%lf %lf\n", 453 - (double)result_cycle[0] / (double)len, 454 - (double)result_cycle[1] / (double)len); 455 - } else { 456 - printf("%lf %lf\n", 457 - result_bps[0], result_bps[1]); 458 - } 459 - } else { 460 - if (use_cycle) { 461 - printf("%lf\n", (double)result_cycle[pf] 462 - / (double)len); 463 - } else 464 - printf("%lf\n", result_bps[pf]); 465 - } 466 - break; 467 - default: 468 - /* reaching this means there's some disaster: */ 469 - die("unknown format: %d\n", bench_format); 470 - break; 471 - } 240 + static const struct routine memset_routines[] = { 241 + { .name ="default", 242 + .desc = "Default memset() provided by glibc", 243 + .fn.memset = memset }, 244 + #ifdef HAVE_ARCH_X86_64_SUPPORT 472 245 473 - return 0; 246 + #define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, 247 + #include "mem-memset-x86-64-asm-def.h" 248 + #undef MEMSET_FN 249 + 250 + #endif 251 + 252 + { .name = NULL, 253 + .desc = NULL, 254 + .fn.memset = NULL } 255 + }; 256 + 257 + int bench_mem_memset(int argc, const char **argv, 258 + const char *prefix __maybe_unused) 259 + { 260 + struct bench_mem_info info = { 261 + .routines = memset_routines, 262 + .do_cycle = do_memset_cycle, 263 + .do_gettimeofday = do_memset_gettimeofday, 264 + .usage = bench_mem_memset_usage, 265 + }; 266 + 267 + return bench_mem_common(argc, argv, prefix, &info); 474 268 }
-304
tools/perf/bench/mem-memset.c
··· 1 - /* 2 - * mem-memset.c 3 - * 4 - * memset: Simple memory set in various ways 5 - * 6 - * Trivial clone of mem-memcpy.c. 7 - */ 8 - 9 - #include "../perf.h" 10 - #include "../util/util.h" 11 - #include "../util/parse-options.h" 12 - #include "../util/header.h" 13 - #include "../util/cloexec.h" 14 - #include "bench.h" 15 - #include "mem-memset-arch.h" 16 - 17 - #include <stdio.h> 18 - #include <stdlib.h> 19 - #include <string.h> 20 - #include <sys/time.h> 21 - #include <errno.h> 22 - 23 - #define K 1024 24 - 25 - static const char *length_str = "1MB"; 26 - static const char *routine = "default"; 27 - static int iterations = 1; 28 - static bool use_cycle; 29 - static int cycle_fd; 30 - static bool only_prefault; 31 - static bool no_prefault; 32 - 33 - static const struct option options[] = { 34 - OPT_STRING('l', "length", &length_str, "1MB", 35 - "Specify length of memory to set. " 36 - "Available units: B, KB, MB, GB and TB (upper and lower)"), 37 - OPT_STRING('r', "routine", &routine, "default", 38 - "Specify routine to set"), 39 - OPT_INTEGER('i', "iterations", &iterations, 40 - "repeat memset() invocation this number of times"), 41 - OPT_BOOLEAN('c', "cycle", &use_cycle, 42 - "Use cycles event instead of gettimeofday() for measuring"), 43 - OPT_BOOLEAN('o', "only-prefault", &only_prefault, 44 - "Show only the result with page faults before memset()"), 45 - OPT_BOOLEAN('n', "no-prefault", &no_prefault, 46 - "Show only the result without page faults before memset()"), 47 - OPT_END() 48 - }; 49 - 50 - typedef void *(*memset_t)(void *, int, size_t); 51 - 52 - struct routine { 53 - const char *name; 54 - const char *desc; 55 - memset_t fn; 56 - }; 57 - 58 - static const struct routine routines[] = { 59 - { "default", 60 - "Default memset() provided by glibc", 61 - memset }, 62 - #ifdef HAVE_ARCH_X86_64_SUPPORT 63 - 64 - #define MEMSET_FN(fn, name, desc) { name, desc, fn }, 65 - #include "mem-memset-x86-64-asm-def.h" 66 - #undef MEMSET_FN 67 - 68 - #endif 69 - 70 - { NULL, 71 - NULL, 72 - NULL } 73 - }; 74 - 75 - static const char * const bench_mem_memset_usage[] = { 76 - "perf bench mem memset <options>", 77 - NULL 78 - }; 79 - 80 - static struct perf_event_attr cycle_attr = { 81 - .type = PERF_TYPE_HARDWARE, 82 - .config = PERF_COUNT_HW_CPU_CYCLES 83 - }; 84 - 85 - static void init_cycle(void) 86 - { 87 - cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 88 - perf_event_open_cloexec_flag()); 89 - 90 - if (cycle_fd < 0 && errno == ENOSYS) 91 - die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 92 - else 93 - BUG_ON(cycle_fd < 0); 94 - } 95 - 96 - static u64 get_cycle(void) 97 - { 98 - int ret; 99 - u64 clk; 100 - 101 - ret = read(cycle_fd, &clk, sizeof(u64)); 102 - BUG_ON(ret != sizeof(u64)); 103 - 104 - return clk; 105 - } 106 - 107 - static double timeval2double(struct timeval *ts) 108 - { 109 - return (double)ts->tv_sec + 110 - (double)ts->tv_usec / (double)1000000; 111 - } 112 - 113 - static void alloc_mem(void **dst, size_t length) 114 - { 115 - *dst = zalloc(length); 116 - if (!*dst) 117 - die("memory allocation failed - maybe length is too large?\n"); 118 - } 119 - 120 - static u64 do_memset_cycle(memset_t fn, size_t len, bool prefault) 121 - { 122 - u64 cycle_start = 0ULL, cycle_end = 0ULL; 123 - void *dst = NULL; 124 - int i; 125 - 126 - alloc_mem(&dst, len); 127 - 128 - if (prefault) 129 - fn(dst, -1, len); 130 - 131 - cycle_start = get_cycle(); 132 - for (i = 0; i < iterations; ++i) 133 - fn(dst, i, len); 134 - cycle_end = get_cycle(); 135 - 136 - free(dst); 137 - return cycle_end - cycle_start; 138 - } 139 - 140 - static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault) 141 - { 142 - struct timeval tv_start, tv_end, tv_diff; 143 - void *dst = NULL; 144 - int i; 145 - 146 - alloc_mem(&dst, len); 147 - 148 - if (prefault) 149 - fn(dst, -1, len); 150 - 151 - BUG_ON(gettimeofday(&tv_start, NULL)); 152 - for (i = 0; i < iterations; ++i) 153 - fn(dst, i, len); 154 - BUG_ON(gettimeofday(&tv_end, NULL)); 155 - 156 - timersub(&tv_end, &tv_start, &tv_diff); 157 - 158 - free(dst); 159 - return (double)((double)len / timeval2double(&tv_diff)); 160 - } 161 - 162 - #define pf (no_prefault ? 0 : 1) 163 - 164 - #define print_bps(x) do { \ 165 - if (x < K) \ 166 - printf(" %14lf B/Sec", x); \ 167 - else if (x < K * K) \ 168 - printf(" %14lfd KB/Sec", x / K); \ 169 - else if (x < K * K * K) \ 170 - printf(" %14lf MB/Sec", x / K / K); \ 171 - else \ 172 - printf(" %14lf GB/Sec", x / K / K / K); \ 173 - } while (0) 174 - 175 - int bench_mem_memset(int argc, const char **argv, 176 - const char *prefix __maybe_unused) 177 - { 178 - int i; 179 - size_t len; 180 - double result_bps[2]; 181 - u64 result_cycle[2]; 182 - 183 - argc = parse_options(argc, argv, options, 184 - bench_mem_memset_usage, 0); 185 - 186 - if (no_prefault && only_prefault) { 187 - fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); 188 - return 1; 189 - } 190 - 191 - if (use_cycle) 192 - init_cycle(); 193 - 194 - len = (size_t)perf_atoll((char *)length_str); 195 - 196 - result_cycle[0] = result_cycle[1] = 0ULL; 197 - result_bps[0] = result_bps[1] = 0.0; 198 - 199 - if ((s64)len <= 0) { 200 - fprintf(stderr, "Invalid length:%s\n", length_str); 201 - return 1; 202 - } 203 - 204 - /* same to without specifying either of prefault and no-prefault */ 205 - if (only_prefault && no_prefault) 206 - only_prefault = no_prefault = false; 207 - 208 - for (i = 0; routines[i].name; i++) { 209 - if (!strcmp(routines[i].name, routine)) 210 - break; 211 - } 212 - if (!routines[i].name) { 213 - printf("Unknown routine:%s\n", routine); 214 - printf("Available routines...\n"); 215 - for (i = 0; routines[i].name; i++) { 216 - printf("\t%s ... %s\n", 217 - routines[i].name, routines[i].desc); 218 - } 219 - return 1; 220 - } 221 - 222 - if (bench_format == BENCH_FORMAT_DEFAULT) 223 - printf("# Copying %s Bytes ...\n\n", length_str); 224 - 225 - if (!only_prefault && !no_prefault) { 226 - /* show both of results */ 227 - if (use_cycle) { 228 - result_cycle[0] = 229 - do_memset_cycle(routines[i].fn, len, false); 230 - result_cycle[1] = 231 - do_memset_cycle(routines[i].fn, len, true); 232 - } else { 233 - result_bps[0] = 234 - do_memset_gettimeofday(routines[i].fn, 235 - len, false); 236 - result_bps[1] = 237 - do_memset_gettimeofday(routines[i].fn, 238 - len, true); 239 - } 240 - } else { 241 - if (use_cycle) { 242 - result_cycle[pf] = 243 - do_memset_cycle(routines[i].fn, 244 - len, only_prefault); 245 - } else { 246 - result_bps[pf] = 247 - do_memset_gettimeofday(routines[i].fn, 248 - len, only_prefault); 249 - } 250 - } 251 - 252 - switch (bench_format) { 253 - case BENCH_FORMAT_DEFAULT: 254 - if (!only_prefault && !no_prefault) { 255 - if (use_cycle) { 256 - printf(" %14lf Cycle/Byte\n", 257 - (double)result_cycle[0] 258 - / (double)len); 259 - printf(" %14lf Cycle/Byte (with prefault)\n ", 260 - (double)result_cycle[1] 261 - / (double)len); 262 - } else { 263 - print_bps(result_bps[0]); 264 - printf("\n"); 265 - print_bps(result_bps[1]); 266 - printf(" (with prefault)\n"); 267 - } 268 - } else { 269 - if (use_cycle) { 270 - printf(" %14lf Cycle/Byte", 271 - (double)result_cycle[pf] 272 - / (double)len); 273 - } else 274 - print_bps(result_bps[pf]); 275 - 276 - printf("%s\n", only_prefault ? " (with prefault)" : ""); 277 - } 278 - break; 279 - case BENCH_FORMAT_SIMPLE: 280 - if (!only_prefault && !no_prefault) { 281 - if (use_cycle) { 282 - printf("%lf %lf\n", 283 - (double)result_cycle[0] / (double)len, 284 - (double)result_cycle[1] / (double)len); 285 - } else { 286 - printf("%lf %lf\n", 287 - result_bps[0], result_bps[1]); 288 - } 289 - } else { 290 - if (use_cycle) { 291 - printf("%lf\n", (double)result_cycle[pf] 292 - / (double)len); 293 - } else 294 - printf("%lf\n", result_bps[pf]); 295 - } 296 - break; 297 - default: 298 - /* reaching this means there's some disaster: */ 299 - die("unknown format: %d\n", bench_format); 300 - break; 301 - } 302 - 303 - return 0; 304 - }
+5 -8
tools/perf/builtin-buildid-cache.c
··· 285 285 struct str_node *pos; 286 286 int ret = 0; 287 287 bool force = false; 288 - char debugdir[PATH_MAX]; 289 288 char const *add_name_list_str = NULL, 290 289 *remove_name_list_str = NULL, 291 290 *missing_filename = NULL, 292 291 *update_name_list_str = NULL, 293 - *kcore_filename; 292 + *kcore_filename = NULL; 294 293 char sbuf[STRERR_BUFSIZE]; 295 294 296 295 struct perf_data_file file = { ··· 334 335 335 336 setup_pager(); 336 337 337 - snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); 338 - 339 338 if (add_name_list_str) { 340 339 list = strlist__new(true, add_name_list_str); 341 340 if (list) { 342 341 strlist__for_each(pos, list) 343 - if (build_id_cache__add_file(pos->s, debugdir)) { 342 + if (build_id_cache__add_file(pos->s, buildid_dir)) { 344 343 if (errno == EEXIST) { 345 344 pr_debug("%s already in the cache\n", 346 345 pos->s); ··· 356 359 list = strlist__new(true, remove_name_list_str); 357 360 if (list) { 358 361 strlist__for_each(pos, list) 359 - if (build_id_cache__remove_file(pos->s, debugdir)) { 362 + if (build_id_cache__remove_file(pos->s, buildid_dir)) { 360 363 if (errno == ENOENT) { 361 364 pr_debug("%s wasn't in the cache\n", 362 365 pos->s); ··· 377 380 list = strlist__new(true, update_name_list_str); 378 381 if (list) { 379 382 strlist__for_each(pos, list) 380 - if (build_id_cache__update_file(pos->s, debugdir)) { 383 + if (build_id_cache__update_file(pos->s, buildid_dir)) { 381 384 if (errno == ENOENT) { 382 385 pr_debug("%s wasn't in the cache\n", 383 386 pos->s); ··· 392 395 } 393 396 394 397 if (kcore_filename && 395 - build_id_cache__add_kcore(kcore_filename, debugdir, force)) 398 + build_id_cache__add_kcore(kcore_filename, buildid_dir, force)) 396 399 pr_warning("Couldn't add %s\n", kcore_filename); 397 400 398 401 out:
+2 -1
tools/perf/builtin-kvm.c
··· 1293 1293 OPT_UINTEGER('d', "display", &kvm->display_time, 1294 1294 "time in seconds between display updates"), 1295 1295 OPT_STRING(0, "event", &kvm->report_event, "report event", 1296 - "event for reporting: vmexit, mmio, ioport"), 1296 + "event for reporting: " 1297 + "vmexit, mmio (x86 only), ioport (x86 only)"), 1297 1298 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, 1298 1299 "vcpu id to report"), 1299 1300 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
+7 -7
tools/perf/builtin-trace.c
··· 2045 2045 unsigned long before; 2046 2046 const bool forks = argc > 0; 2047 2047 bool draining = false; 2048 - char sbuf[STRERR_BUFSIZE]; 2049 2048 2050 2049 trace->live = true; 2051 2050 ··· 2105 2106 goto out_error_open; 2106 2107 2107 2108 err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); 2108 - if (err < 0) { 2109 - fprintf(trace->output, "Couldn't mmap the events: %s\n", 2110 - strerror_r(errno, sbuf, sizeof(sbuf))); 2111 - goto out_delete_evlist; 2112 - } 2109 + if (err < 0) 2110 + goto out_error_mmap; 2113 2111 2114 2112 perf_evlist__enable(evlist); 2115 2113 ··· 2204 2208 2205 2209 out_error_tp: 2206 2210 perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); 2211 + goto out_error; 2212 + 2213 + out_error_mmap: 2214 + perf_evlist__strerror_mmap(evlist, errno, errbuf, sizeof(errbuf)); 2207 2215 goto out_error; 2208 2216 2209 2217 out_error_open: ··· 2485 2485 .user_freq = UINT_MAX, 2486 2486 .user_interval = ULLONG_MAX, 2487 2487 .no_buffering = true, 2488 - .mmap_pages = 1024, 2488 + .mmap_pages = UINT_MAX, 2489 2489 }, 2490 2490 .output = stdout, 2491 2491 .show_comm = true,
+12 -2
tools/perf/perf.c
··· 200 200 *envchanged = 1; 201 201 (*argv)++; 202 202 (*argc)--; 203 + } else if (!strcmp(cmd, "--buildid-dir")) { 204 + if (*argc < 2) { 205 + fprintf(stderr, "No directory given for --buildid-dir.\n"); 206 + usage(perf_usage_string); 207 + } 208 + set_buildid_dir((*argv)[1]); 209 + if (envchanged) 210 + *envchanged = 1; 211 + (*argv)++; 212 + (*argc)--; 203 213 } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { 204 214 perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); 205 215 fprintf(stderr, "dir: %s\n", debugfs_mountpoint); ··· 509 499 } 510 500 if (!prefixcmp(cmd, "trace")) { 511 501 #ifdef HAVE_LIBAUDIT_SUPPORT 512 - set_buildid_dir(); 502 + set_buildid_dir(NULL); 513 503 setup_path(); 514 504 argv[0] = "trace"; 515 505 return cmd_trace(argc, argv, NULL); ··· 524 514 argc--; 525 515 handle_options(&argv, &argc, NULL); 526 516 commit_pager_choice(); 527 - set_buildid_dir(); 517 + set_buildid_dir(NULL); 528 518 529 519 if (argc > 0) { 530 520 if (!prefixcmp(argv[0], "--"))
+1 -1
tools/perf/tests/attr/base-record
··· 5 5 flags=0|8 6 6 cpu=* 7 7 type=0|1 8 - size=96 8 + size=104 9 9 config=0 10 10 sample_period=4000 11 11 sample_type=263
+1 -1
tools/perf/tests/attr/base-stat
··· 5 5 flags=0|8 6 6 cpu=* 7 7 type=0 8 - size=96 8 + size=104 9 9 config=0 10 10 sample_period=0 11 11 sample_type=0
+1 -1
tools/perf/ui/browsers/hists.c
··· 1252 1252 1253 1253 nr_samples = convert_unit(nr_samples, &unit); 1254 1254 printed = scnprintf(bf, size, 1255 - "Samples: %lu%c of event '%s', Event count (approx.): %lu", 1255 + "Samples: %lu%c of event '%s', Event count (approx.): %" PRIu64, 1256 1256 nr_samples, unit, ev_name, nr_events); 1257 1257 1258 1258
+2 -2
tools/perf/ui/hist.c
··· 162 162 return ret; 163 163 164 164 nr_members = evsel->nr_members; 165 - fields_a = calloc(sizeof(*fields_a), nr_members); 166 - fields_b = calloc(sizeof(*fields_b), nr_members); 165 + fields_a = calloc(nr_members, sizeof(*fields_a)); 166 + fields_b = calloc(nr_members, sizeof(*fields_b)); 167 167 168 168 if (!fields_a || !fields_b) 169 169 goto out;
+3 -6
tools/perf/util/build-id.c
··· 410 410 { 411 411 struct rb_node *nd; 412 412 int ret; 413 - char debugdir[PATH_MAX]; 414 413 415 414 if (no_buildid_cache) 416 415 return 0; 417 416 418 - snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); 419 - 420 - if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) 417 + if (mkdir(buildid_dir, 0755) != 0 && errno != EEXIST) 421 418 return -1; 422 419 423 - ret = machine__cache_build_ids(&session->machines.host, debugdir); 420 + ret = machine__cache_build_ids(&session->machines.host, buildid_dir); 424 421 425 422 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { 426 423 struct machine *pos = rb_entry(nd, struct machine, rb_node); 427 - ret |= machine__cache_build_ids(pos, debugdir); 424 + ret |= machine__cache_build_ids(pos, buildid_dir); 428 425 } 429 426 return ret ? -1 : 0; 430 427 }
+1 -1
tools/perf/util/callchain.c
··· 77 77 ret = 0; 78 78 } else 79 79 pr_err("callchain: No more arguments " 80 - "needed for -g fp\n"); 80 + "needed for --call-graph fp\n"); 81 81 break; 82 82 83 83 #ifdef HAVE_DWARF_UNWIND_SUPPORT
+6 -4
tools/perf/util/config.c
··· 522 522 const char *v; 523 523 524 524 /* same dir for all commands */ 525 - if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) { 525 + if (!strcmp(var, "buildid.dir")) { 526 526 v = perf_config_dirname(var, value); 527 527 if (!v) 528 528 return -1; ··· 539 539 perf_config(buildid_dir_command_config, &c); 540 540 } 541 541 542 - void set_buildid_dir(void) 542 + void set_buildid_dir(const char *dir) 543 543 { 544 - buildid_dir[0] = '\0'; 544 + if (dir) 545 + scnprintf(buildid_dir, MAXPATHLEN-1, "%s", dir); 545 546 546 547 /* try config file */ 547 - check_buildid_dir_config(); 548 + if (buildid_dir[0] == '\0') 549 + check_buildid_dir_config(); 548 550 549 551 /* default to $HOME/.debug */ 550 552 if (buildid_dir[0] == '\0') {
+52 -5
tools/perf/util/evlist.c
··· 8 8 */ 9 9 #include "util.h" 10 10 #include <api/fs/debugfs.h> 11 + #include <api/fs/fs.h> 11 12 #include <poll.h> 12 13 #include "cpumap.h" 13 14 #include "thread_map.h" ··· 25 24 26 25 #include <linux/bitops.h> 27 26 #include <linux/hash.h> 27 + #include <linux/log2.h> 28 28 29 29 static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); 30 30 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); ··· 894 892 895 893 static size_t perf_evlist__mmap_size(unsigned long pages) 896 894 { 897 - /* 512 kiB: default amount of unprivileged mlocked memory */ 898 - if (pages == UINT_MAX) 899 - pages = (512 * 1024) / page_size; 900 - else if (!is_power_of_2(pages)) 895 + if (pages == UINT_MAX) { 896 + int max; 897 + 898 + if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { 899 + /* 900 + * Pick a once upon a time good value, i.e. things look 901 + * strange since we can't read a sysctl value, but lets not 902 + * die yet... 903 + */ 904 + max = 512; 905 + } else { 906 + max -= (page_size / 1024); 907 + } 908 + 909 + pages = (max * 1024) / page_size; 910 + if (!is_power_of_2(pages)) 911 + pages = rounddown_pow_of_two(pages); 912 + } else if (!is_power_of_2(pages)) 901 913 return 0; 902 914 903 915 return (pages + 1) * page_size; ··· 948 932 /* leave number of pages at 0 */ 949 933 } else if (!is_power_of_2(pages)) { 950 934 /* round pages up to next power of 2 */ 951 - pages = next_pow2_l(pages); 935 + pages = roundup_pow_of_two(pages); 952 936 if (!pages) 953 937 return -EINVAL; 954 938 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", ··· 1490 1474 printed += scnprintf(buf + printed, size - printed, 1491 1475 "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n" 1492 1476 "Hint:\tThe current value is %d.", value); 1477 + break; 1478 + default: 1479 + scnprintf(buf, size, "%s", emsg); 1480 + break; 1481 + } 1482 + 1483 + return 0; 1484 + } 1485 + 1486 + int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) 1487 + { 1488 + char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); 1489 + int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; 1490 + 1491 + switch (err) { 1492 + case EPERM: 1493 + sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); 1494 + printed += scnprintf(buf + printed, size - printed, 1495 + "Error:\t%s.\n" 1496 + "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" 1497 + "Hint:\tTried using %zd kB.\n", 1498 + emsg, pages_max_per_user, pages_attempted); 1499 + 1500 + if (pages_attempted >= pages_max_per_user) { 1501 + printed += scnprintf(buf + printed, size - printed, 1502 + "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", 1503 + pages_max_per_user + pages_attempted); 1504 + } 1505 + 1506 + printed += scnprintf(buf + printed, size - printed, 1507 + "Hint:\tTry using a smaller -m/--mmap-pages value."); 1493 1508 break; 1494 1509 default: 1495 1510 scnprintf(buf, size, "%s", emsg);
+1
tools/perf/util/evlist.h
··· 185 185 186 186 int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); 187 187 int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); 188 + int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); 188 189 189 190 static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) 190 191 {
-162
tools/perf/util/include/linux/bitops.h
··· 1 - #ifndef _PERF_LINUX_BITOPS_H_ 2 - #define _PERF_LINUX_BITOPS_H_ 3 - 4 - #include <linux/kernel.h> 5 - #include <linux/compiler.h> 6 - #include <asm/hweight.h> 7 - 8 - #ifndef __WORDSIZE 9 - #define __WORDSIZE (__SIZEOF_LONG__ * 8) 10 - #endif 11 - 12 - #define BITS_PER_LONG __WORDSIZE 13 - #define BITS_PER_BYTE 8 14 - #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 15 - #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) 16 - #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) 17 - #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) 18 - #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 19 - #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 20 - 21 - #define for_each_set_bit(bit, addr, size) \ 22 - for ((bit) = find_first_bit((addr), (size)); \ 23 - (bit) < (size); \ 24 - (bit) = find_next_bit((addr), (size), (bit) + 1)) 25 - 26 - /* same as for_each_set_bit() but use bit as value to start with */ 27 - #define for_each_set_bit_from(bit, addr, size) \ 28 - for ((bit) = find_next_bit((addr), (size), (bit)); \ 29 - (bit) < (size); \ 30 - (bit) = find_next_bit((addr), (size), (bit) + 1)) 31 - 32 - static inline void set_bit(int nr, unsigned long *addr) 33 - { 34 - addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); 35 - } 36 - 37 - static inline void clear_bit(int nr, unsigned long *addr) 38 - { 39 - addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG)); 40 - } 41 - 42 - static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) 43 - { 44 - return ((1UL << (nr % BITS_PER_LONG)) & 45 - (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; 46 - } 47 - 48 - static inline unsigned long hweight_long(unsigned long w) 49 - { 50 - return sizeof(w) == 4 ? hweight32(w) : hweight64(w); 51 - } 52 - 53 - #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) 54 - 55 - /** 56 - * __ffs - find first bit in word. 57 - * @word: The word to search 58 - * 59 - * Undefined if no bit exists, so code should check against 0 first. 60 - */ 61 - static __always_inline unsigned long __ffs(unsigned long word) 62 - { 63 - int num = 0; 64 - 65 - #if BITS_PER_LONG == 64 66 - if ((word & 0xffffffff) == 0) { 67 - num += 32; 68 - word >>= 32; 69 - } 70 - #endif 71 - if ((word & 0xffff) == 0) { 72 - num += 16; 73 - word >>= 16; 74 - } 75 - if ((word & 0xff) == 0) { 76 - num += 8; 77 - word >>= 8; 78 - } 79 - if ((word & 0xf) == 0) { 80 - num += 4; 81 - word >>= 4; 82 - } 83 - if ((word & 0x3) == 0) { 84 - num += 2; 85 - word >>= 2; 86 - } 87 - if ((word & 0x1) == 0) 88 - num += 1; 89 - return num; 90 - } 91 - 92 - typedef const unsigned long __attribute__((__may_alias__)) long_alias_t; 93 - 94 - /* 95 - * Find the first set bit in a memory region. 96 - */ 97 - static inline unsigned long 98 - find_first_bit(const unsigned long *addr, unsigned long size) 99 - { 100 - long_alias_t *p = (long_alias_t *) addr; 101 - unsigned long result = 0; 102 - unsigned long tmp; 103 - 104 - while (size & ~(BITS_PER_LONG-1)) { 105 - if ((tmp = *(p++))) 106 - goto found; 107 - result += BITS_PER_LONG; 108 - size -= BITS_PER_LONG; 109 - } 110 - if (!size) 111 - return result; 112 - 113 - tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); 114 - if (tmp == 0UL) /* Are any bits set? */ 115 - return result + size; /* Nope. */ 116 - found: 117 - return result + __ffs(tmp); 118 - } 119 - 120 - /* 121 - * Find the next set bit in a memory region. 122 - */ 123 - static inline unsigned long 124 - find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) 125 - { 126 - const unsigned long *p = addr + BITOP_WORD(offset); 127 - unsigned long result = offset & ~(BITS_PER_LONG-1); 128 - unsigned long tmp; 129 - 130 - if (offset >= size) 131 - return size; 132 - size -= result; 133 - offset %= BITS_PER_LONG; 134 - if (offset) { 135 - tmp = *(p++); 136 - tmp &= (~0UL << offset); 137 - if (size < BITS_PER_LONG) 138 - goto found_first; 139 - if (tmp) 140 - goto found_middle; 141 - size -= BITS_PER_LONG; 142 - result += BITS_PER_LONG; 143 - } 144 - while (size & ~(BITS_PER_LONG-1)) { 145 - if ((tmp = *(p++))) 146 - goto found_middle; 147 - result += BITS_PER_LONG; 148 - size -= BITS_PER_LONG; 149 - } 150 - if (!size) 151 - return result; 152 - tmp = *p; 153 - 154 - found_first: 155 - tmp &= (~0UL >> (BITS_PER_LONG - size)); 156 - if (tmp == 0UL) /* Are any bits set? */ 157 - return result + size; /* Nope. */ 158 - found_middle: 159 - return result + __ffs(tmp); 160 - } 161 - 162 - #endif
+35 -37
tools/perf/util/machine.c
··· 1385 1385 static int add_callchain_ip(struct thread *thread, 1386 1386 struct symbol **parent, 1387 1387 struct addr_location *root_al, 1388 - int cpumode, 1388 + bool branch_history, 1389 1389 u64 ip) 1390 1390 { 1391 1391 struct addr_location al; 1392 1392 1393 1393 al.filtered = 0; 1394 1394 al.sym = NULL; 1395 - if (cpumode == -1) 1395 + if (branch_history) 1396 1396 thread__find_cpumode_addr_location(thread, MAP__FUNCTION, 1397 1397 ip, &al); 1398 - else 1398 + else { 1399 + u8 cpumode = PERF_RECORD_MISC_USER; 1400 + 1401 + if (ip >= PERF_CONTEXT_MAX) { 1402 + switch (ip) { 1403 + case PERF_CONTEXT_HV: 1404 + cpumode = PERF_RECORD_MISC_HYPERVISOR; 1405 + break; 1406 + case PERF_CONTEXT_KERNEL: 1407 + cpumode = PERF_RECORD_MISC_KERNEL; 1408 + break; 1409 + case PERF_CONTEXT_USER: 1410 + cpumode = PERF_RECORD_MISC_USER; 1411 + break; 1412 + default: 1413 + pr_debug("invalid callchain context: " 1414 + "%"PRId64"\n", (s64) ip); 1415 + /* 1416 + * It seems the callchain is corrupted. 1417 + * Discard all. 1418 + */ 1419 + callchain_cursor_reset(&callchain_cursor); 1420 + return 1; 1421 + } 1422 + return 0; 1423 + } 1399 1424 thread__find_addr_location(thread, cpumode, MAP__FUNCTION, 1400 1425 ip, &al); 1426 + } 1427 + 1401 1428 if (al.sym != NULL) { 1402 1429 if (sort__has_parent && !*parent && 1403 1430 symbol__match_regex(al.sym, &parent_regex)) ··· 1507 1480 struct addr_location *root_al, 1508 1481 int max_stack) 1509 1482 { 1510 - u8 cpumode = PERF_RECORD_MISC_USER; 1511 1483 int chain_nr = min(max_stack, (int)chain->nr); 1512 - int i; 1513 - int j; 1514 - int err; 1484 + int i, j, err; 1515 1485 int skip_idx = -1; 1516 1486 int first_call = 0; 1517 1487 ··· 1566 1542 1567 1543 for (i = 0; i < nr; i++) { 1568 1544 err = add_callchain_ip(thread, parent, root_al, 1569 - -1, be[i].to); 1545 + true, be[i].to); 1570 1546 if (!err) 1571 1547 err = add_callchain_ip(thread, parent, root_al, 1572 - -1, be[i].from); 1548 + true, be[i].from); 1573 1549 if (err == -EINVAL) 1574 1550 break; 1575 1551 if (err) ··· 1598 1574 #endif 1599 1575 ip = chain->ips[j]; 1600 1576 1601 - if (ip >= PERF_CONTEXT_MAX) { 1602 - switch (ip) { 1603 - case PERF_CONTEXT_HV: 1604 - cpumode = PERF_RECORD_MISC_HYPERVISOR; 1605 - break; 1606 - case PERF_CONTEXT_KERNEL: 1607 - cpumode = PERF_RECORD_MISC_KERNEL; 1608 - break; 1609 - case PERF_CONTEXT_USER: 1610 - cpumode = PERF_RECORD_MISC_USER; 1611 - break; 1612 - default: 1613 - pr_debug("invalid callchain context: " 1614 - "%"PRId64"\n", (s64) ip); 1615 - /* 1616 - * It seems the callchain is corrupted. 1617 - * Discard all. 1618 - */ 1619 - callchain_cursor_reset(&callchain_cursor); 1620 - return 0; 1621 - } 1622 - continue; 1623 - } 1577 + err = add_callchain_ip(thread, parent, root_al, false, ip); 1624 1578 1625 - err = add_callchain_ip(thread, parent, root_al, 1626 - cpumode, ip); 1627 - if (err == -EINVAL) 1628 - break; 1629 1579 if (err) 1630 - return err; 1580 + return (err < 0) ? err : 0; 1631 1581 } 1632 1582 1633 1583 return 0;
+1 -10
tools/perf/util/record.c
··· 137 137 138 138 static int get_max_rate(unsigned int *rate) 139 139 { 140 - char path[PATH_MAX]; 141 - const char *procfs = procfs__mountpoint(); 142 - 143 - if (!procfs) 144 - return -1; 145 - 146 - snprintf(path, PATH_MAX, 147 - "%s/sys/kernel/perf_event_max_sample_rate", procfs); 148 - 149 - return filename__read_int(path, (int *) rate); 140 + return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate); 150 141 } 151 142 152 143 static int record_opts__config_freq(struct record_opts *opts)
+6 -6
tools/perf/util/srcline.c
··· 20 20 21 21 struct a2l_data { 22 22 const char *input; 23 - unsigned long addr; 23 + u64 addr; 24 24 25 25 bool found; 26 26 const char *filename; ··· 147 147 free(a2l); 148 148 } 149 149 150 - static int addr2line(const char *dso_name, unsigned long addr, 150 + static int addr2line(const char *dso_name, u64 addr, 151 151 char **file, unsigned int *line, struct dso *dso) 152 152 { 153 153 int ret = 0; ··· 193 193 194 194 #else /* HAVE_LIBBFD_SUPPORT */ 195 195 196 - static int addr2line(const char *dso_name, unsigned long addr, 196 + static int addr2line(const char *dso_name, u64 addr, 197 197 char **file, unsigned int *line_nr, 198 198 struct dso *dso __maybe_unused) 199 199 { ··· 252 252 */ 253 253 #define A2L_FAIL_LIMIT 123 254 254 255 - char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, 255 + char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 256 256 bool show_sym) 257 257 { 258 258 char *file = NULL; ··· 293 293 dso__free_a2l(dso); 294 294 } 295 295 if (sym) { 296 - if (asprintf(&srcline, "%s+%ld", show_sym ? sym->name : "", 296 + if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", 297 297 addr - sym->start) < 0) 298 298 return SRCLINE_UNKNOWN; 299 - } else if (asprintf(&srcline, "%s[%lx]", dso->short_name, addr) < 0) 299 + } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0) 300 300 return SRCLINE_UNKNOWN; 301 301 return srcline; 302 302 }
+6 -2
tools/perf/util/symbol-minimal.c
··· 129 129 130 130 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { 131 131 void *tmp; 132 + long offset; 132 133 133 134 if (need_swap) { 134 135 phdr->p_type = bswap_32(phdr->p_type); ··· 141 140 continue; 142 141 143 142 buf_size = phdr->p_filesz; 143 + offset = phdr->p_offset; 144 144 tmp = realloc(buf, buf_size); 145 145 if (tmp == NULL) 146 146 goto out_free; 147 147 148 148 buf = tmp; 149 - fseek(fp, phdr->p_offset, SEEK_SET); 149 + fseek(fp, offset, SEEK_SET); 150 150 if (fread(buf, buf_size, 1, fp) != 1) 151 151 goto out_free; 152 152 ··· 180 178 181 179 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { 182 180 void *tmp; 181 + long offset; 183 182 184 183 if (need_swap) { 185 184 phdr->p_type = bswap_32(phdr->p_type); ··· 192 189 continue; 193 190 194 191 buf_size = phdr->p_filesz; 192 + offset = phdr->p_offset; 195 193 tmp = realloc(buf, buf_size); 196 194 if (tmp == NULL) 197 195 goto out_free; 198 196 199 197 buf = tmp; 200 - fseek(fp, phdr->p_offset, SEEK_SET); 198 + fseek(fp, offset, SEEK_SET); 201 199 if (fread(buf, buf_size, 1, fp) != 1) 202 200 goto out_free; 203 201
+1 -25
tools/perf/util/util.c
··· 442 442 return (unsigned long) -1; 443 443 } 444 444 445 - int filename__read_int(const char *filename, int *value) 446 - { 447 - char line[64]; 448 - int fd = open(filename, O_RDONLY), err = -1; 449 - 450 - if (fd < 0) 451 - return -1; 452 - 453 - if (read(fd, line, sizeof(line)) > 0) { 454 - *value = atoi(line); 455 - err = 0; 456 - } 457 - 458 - close(fd); 459 - return err; 460 - } 461 - 462 445 int filename__read_str(const char *filename, char **buf, size_t *sizep) 463 446 { 464 447 size_t size = 0, alloc_size = 0; ··· 506 523 507 524 int perf_event_paranoid(void) 508 525 { 509 - char path[PATH_MAX]; 510 - const char *procfs = procfs__mountpoint(); 511 526 int value; 512 527 513 - if (!procfs) 514 - return INT_MAX; 515 - 516 - scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs); 517 - 518 - if (filename__read_int(path, &value)) 528 + if (sysctl__read_int("kernel/perf_event_paranoid", &value)) 519 529 return INT_MAX; 520 530 521 531 return value;
+2 -32
tools/perf/util/util.h
··· 153 153 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 154 154 155 155 extern int prefixcmp(const char *str, const char *prefix); 156 - extern void set_buildid_dir(void); 156 + extern void set_buildid_dir(const char *dir); 157 157 158 158 static inline const char *skip_prefix(const char *str, const char *prefix) 159 159 { ··· 269 269 #define _STR(x) #x 270 270 #define STR(x) _STR(x) 271 271 272 - /* 273 - * Determine whether some value is a power of two, where zero is 274 - * *not* considered a power of two. 275 - */ 276 - 277 - static inline __attribute__((const)) 278 - bool is_power_of_2(unsigned long n) 279 - { 280 - return (n != 0 && ((n & (n - 1)) == 0)); 281 - } 282 - 283 - static inline unsigned next_pow2(unsigned x) 284 - { 285 - if (!x) 286 - return 1; 287 - return 1ULL << (32 - __builtin_clz(x - 1)); 288 - } 289 - 290 - static inline unsigned long next_pow2_l(unsigned long x) 291 - { 292 - #if BITS_PER_LONG == 64 293 - if (x <= (1UL << 31)) 294 - return next_pow2(x); 295 - return (unsigned long)next_pow2(x >> 32) << 32; 296 - #else 297 - return next_pow2(x); 298 - #endif 299 - } 300 - 301 272 size_t hex_width(u64 v); 302 273 int hex2u64(const char *ptr, u64 *val); 303 274 ··· 310 339 struct dso; 311 340 struct symbol; 312 341 313 - char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, 342 + char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 314 343 bool show_sym); 315 344 void free_srcline(char *srcline); 316 345 317 - int filename__read_int(const char *filename, int *value); 318 346 int filename__read_str(const char *filename, char **buf, size_t *sizep); 319 347 int perf_event_paranoid(void); 320 348
+3 -3
tools/thermal/tmon/sysfs.c
··· 446 446 return -1; 447 447 } 448 448 449 - ptdata.tzi = calloc(sizeof(struct tz_info), ptdata.max_tz_instance+1); 449 + ptdata.tzi = calloc(ptdata.max_tz_instance+1, sizeof(struct tz_info)); 450 450 if (!ptdata.tzi) { 451 451 fprintf(stderr, "Err: allocate tz_info\n"); 452 452 return -1; ··· 454 454 455 455 /* we still show thermal zone information if there is no cdev */ 456 456 if (ptdata.nr_cooling_dev) { 457 - ptdata.cdi = calloc(sizeof(struct cdev_info), 458 - ptdata.max_cdev_instance + 1); 457 + ptdata.cdi = calloc(ptdata.max_cdev_instance + 1, 458 + sizeof(struct cdev_info)); 459 459 if (!ptdata.cdi) { 460 460 free(ptdata.tzi); 461 461 fprintf(stderr, "Err: allocate cdev_info\n");