diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-19 16:15:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-19 16:15:24 -0500 |
commit | 88a57667f2990f00b019d46c8426441c9e516d51 (patch) | |
tree | 392f5dcb9724e688aa307e2ed2cc8ee13e66f570 /tools | |
parent | 34b85e3574424beb30e4cd163e6da2e2282d2683 (diff) | |
parent | ac931f87a647ca156f65a4c00e7297165e4fa2d8 (diff) |
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
...
Diffstat (limited to 'tools')
38 files changed, 874 insertions, 707 deletions
diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h new file mode 100644 index 000000000000..6eedba1f7732 --- /dev/null +++ b/tools/include/asm-generic/bitops.h | |||
@@ -0,0 +1,27 @@ | |||
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 */ | ||
diff --git a/tools/include/asm-generic/bitops/__ffs.h b/tools/include/asm-generic/bitops/__ffs.h new file mode 100644 index 000000000000..c94175015a82 --- /dev/null +++ b/tools/include/asm-generic/bitops/__ffs.h | |||
@@ -0,0 +1,43 @@ | |||
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_ */ | ||
diff --git a/tools/include/asm-generic/bitops/__fls.h b/tools/include/asm-generic/bitops/__fls.h new file mode 100644 index 000000000000..2218b9add4c1 --- /dev/null +++ b/tools/include/asm-generic/bitops/__fls.h | |||
@@ -0,0 +1 @@ | |||
#include <../../../../include/asm-generic/bitops/__fls.h> | |||
diff --git a/tools/include/asm-generic/bitops/atomic.h b/tools/include/asm-generic/bitops/atomic.h new file mode 100644 index 000000000000..4bccd7c3d5d6 --- /dev/null +++ b/tools/include/asm-generic/bitops/atomic.h | |||
@@ -0,0 +1,22 @@ | |||
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_ */ | ||
diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h new file mode 100644 index 000000000000..31f51547fcd4 --- /dev/null +++ b/tools/include/asm-generic/bitops/find.h | |||
@@ -0,0 +1,33 @@ | |||
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_ */ | ||
diff --git a/tools/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h new file mode 100644 index 000000000000..dbf711a28f71 --- /dev/null +++ b/tools/include/asm-generic/bitops/fls.h | |||
@@ -0,0 +1 @@ | |||
#include <../../../../include/asm-generic/bitops/fls.h> | |||
diff --git a/tools/include/asm-generic/bitops/fls64.h b/tools/include/asm-generic/bitops/fls64.h new file mode 100644 index 000000000000..980b1f63c047 --- /dev/null +++ b/tools/include/asm-generic/bitops/fls64.h | |||
@@ -0,0 +1 @@ | |||
#include <../../../../include/asm-generic/bitops/fls64.h> | |||
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h new file mode 100644 index 000000000000..26005a15e7e2 --- /dev/null +++ b/tools/include/linux/bitops.h | |||
@@ -0,0 +1,53 @@ | |||
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 | ||
diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h new file mode 100644 index 000000000000..41446668ccce --- /dev/null +++ b/tools/include/linux/log2.h | |||
@@ -0,0 +1,185 @@ | |||
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 */ | ||
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c index c1b49c36a951..65d9be3f9887 100644 --- a/tools/lib/api/fs/fs.c +++ b/tools/lib/api/fs/fs.c | |||
@@ -7,6 +7,10 @@ | |||
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <sys/vfs.h> | 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 | #include "debugfs.h" | 15 | #include "debugfs.h" |
12 | #include "fs.h" | 16 | #include "fs.h" |
@@ -163,3 +167,33 @@ const char *name##__mountpoint(void) \ | |||
163 | 167 | ||
164 | FS__MOUNTPOINT(sysfs, FS__SYSFS); | 168 | FS__MOUNTPOINT(sysfs, FS__SYSFS); |
165 | FS__MOUNTPOINT(procfs, FS__PROCFS); | 169 | FS__MOUNTPOINT(procfs, FS__PROCFS); |
170 | |||
171 | int filename__read_int(const char *filename, int *value) | ||
172 | { | ||
173 | char line[64]; | ||
174 | int fd = open(filename, O_RDONLY), err = -1; | ||
175 | |||
176 | if (fd < 0) | ||
177 | return -1; | ||
178 | |||
179 | if (read(fd, line, sizeof(line)) > 0) { | ||
180 | *value = atoi(line); | ||
181 | err = 0; | ||
182 | } | ||
183 | |||
184 | close(fd); | ||
185 | return err; | ||
186 | } | ||
187 | |||
188 | int sysctl__read_int(const char *sysctl, int *value) | ||
189 | { | ||
190 | char path[PATH_MAX]; | ||
191 | const char *procfs = procfs__mountpoint(); | ||
192 | |||
193 | if (!procfs) | ||
194 | return -1; | ||
195 | |||
196 | snprintf(path, sizeof(path), "%s/sys/%s", procfs, sysctl); | ||
197 | |||
198 | return filename__read_int(path, value); | ||
199 | } | ||
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h index cb7049551f33..6caa2bbc6cec 100644 --- a/tools/lib/api/fs/fs.h +++ b/tools/lib/api/fs/fs.h | |||
@@ -11,4 +11,7 @@ | |||
11 | 11 | ||
12 | const char *sysfs__mountpoint(void); | 12 | const char *sysfs__mountpoint(void); |
13 | const char *procfs__mountpoint(void); | 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 | #endif /* __API_FS__ */ | 17 | #endif /* __API_FS__ */ |
diff --git a/tools/lib/util/find_next_bit.c b/tools/lib/util/find_next_bit.c new file mode 100644 index 000000000000..41b44f65a79e --- /dev/null +++ b/tools/lib/util/find_next_bit.c | |||
@@ -0,0 +1,89 @@ | |||
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 | ||
diff --git a/tools/perf/Documentation/perf.txt b/tools/perf/Documentation/perf.txt index d240bb2e5b22..1e8e400b4493 100644 --- a/tools/perf/Documentation/perf.txt +++ b/tools/perf/Documentation/perf.txt | |||
@@ -18,6 +18,10 @@ OPTIONS | |||
18 | --debug verbose # sets verbose = 1 | 18 | --debug verbose # sets verbose = 1 |
19 | --debug verbose=2 # sets verbose = 2 | 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 | DESCRIPTION | 25 | DESCRIPTION |
22 | ----------- | 26 | ----------- |
23 | Performance counters for Linux are a new kernel-based subsystem | 27 | Performance counters for Linux are a new kernel-based subsystem |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 344c4d3d0a4a..83e2887f91a3 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -4,17 +4,31 @@ tools/lib/traceevent | |||
4 | tools/lib/api | 4 | tools/lib/api |
5 | tools/lib/symbol/kallsyms.c | 5 | tools/lib/symbol/kallsyms.c |
6 | tools/lib/symbol/kallsyms.h | 6 | tools/lib/symbol/kallsyms.h |
7 | tools/lib/util/find_next_bit.c | ||
7 | tools/include/asm/bug.h | 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 | tools/include/linux/compiler.h | 17 | tools/include/linux/compiler.h |
9 | tools/include/linux/hash.h | ||
10 | tools/include/linux/export.h | 18 | tools/include/linux/export.h |
19 | tools/include/linux/hash.h | ||
20 | tools/include/linux/log2.h | ||
11 | tools/include/linux/types.h | 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 | include/linux/const.h | 25 | include/linux/const.h |
13 | include/linux/perf_event.h | 26 | include/linux/perf_event.h |
14 | include/linux/rbtree.h | 27 | include/linux/rbtree.h |
15 | include/linux/list.h | 28 | include/linux/list.h |
16 | include/linux/hash.h | 29 | include/linux/hash.h |
17 | include/linux/stringify.h | 30 | include/linux/stringify.h |
31 | lib/find_next_bit.c | ||
18 | lib/rbtree.c | 32 | lib/rbtree.c |
19 | include/linux/swab.h | 33 | include/linux/swab.h |
20 | arch/*/include/asm/unistd*.h | 34 | arch/*/include/asm/unistd*.h |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 478efa9b2364..67a03a825b3c 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -231,8 +231,16 @@ LIB_H += ../../include/uapi/linux/const.h | |||
231 | LIB_H += ../include/linux/hash.h | 231 | LIB_H += ../include/linux/hash.h |
232 | LIB_H += ../../include/linux/stringify.h | 232 | LIB_H += ../../include/linux/stringify.h |
233 | LIB_H += util/include/linux/bitmap.h | 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 | LIB_H += ../include/linux/compiler.h | 242 | LIB_H += ../include/linux/compiler.h |
243 | LIB_H += ../include/linux/log2.h | ||
236 | LIB_H += util/include/linux/const.h | 244 | LIB_H += util/include/linux/const.h |
237 | LIB_H += util/include/linux/ctype.h | 245 | LIB_H += util/include/linux/ctype.h |
238 | LIB_H += util/include/linux/kernel.h | 246 | LIB_H += util/include/linux/kernel.h |
@@ -335,6 +343,7 @@ LIB_OBJS += $(OUTPUT)util/event.o | |||
335 | LIB_OBJS += $(OUTPUT)util/evlist.o | 343 | LIB_OBJS += $(OUTPUT)util/evlist.o |
336 | LIB_OBJS += $(OUTPUT)util/evsel.o | 344 | LIB_OBJS += $(OUTPUT)util/evsel.o |
337 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o | 345 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o |
346 | LIB_OBJS += $(OUTPUT)util/find_next_bit.o | ||
338 | LIB_OBJS += $(OUTPUT)util/help.o | 347 | LIB_OBJS += $(OUTPUT)util/help.o |
339 | LIB_OBJS += $(OUTPUT)util/kallsyms.o | 348 | LIB_OBJS += $(OUTPUT)util/kallsyms.o |
340 | LIB_OBJS += $(OUTPUT)util/levenshtein.o | 349 | LIB_OBJS += $(OUTPUT)util/levenshtein.o |
@@ -458,7 +467,6 @@ BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o | |||
458 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o | 467 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o |
459 | endif | 468 | endif |
460 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o | 469 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o |
461 | BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o | ||
462 | BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o | 470 | BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o |
463 | BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o | 471 | BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o |
464 | BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o | 472 | BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o |
@@ -735,6 +743,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS | |||
735 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS | 743 | $(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)"' $< | 744 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
737 | 745 | ||
746 | $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS | ||
747 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | ||
748 | |||
738 | $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS | 749 | $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS |
739 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< | 750 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< |
740 | 751 | ||
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c index 2465141b554b..6c14afe8c1b1 100644 --- a/tools/perf/bench/mem-memcpy.c +++ b/tools/perf/bench/mem-memcpy.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "../util/cloexec.h" | 13 | #include "../util/cloexec.h" |
14 | #include "bench.h" | 14 | #include "bench.h" |
15 | #include "mem-memcpy-arch.h" | 15 | #include "mem-memcpy-arch.h" |
16 | #include "mem-memset-arch.h" | ||
16 | 17 | ||
17 | #include <stdio.h> | 18 | #include <stdio.h> |
18 | #include <stdlib.h> | 19 | #include <stdlib.h> |
@@ -48,20 +49,24 @@ static const struct option options[] = { | |||
48 | }; | 49 | }; |
49 | 50 | ||
50 | typedef void *(*memcpy_t)(void *, const void *, size_t); | 51 | typedef void *(*memcpy_t)(void *, const void *, size_t); |
52 | typedef void *(*memset_t)(void *, int, size_t); | ||
51 | 53 | ||
52 | struct routine { | 54 | struct routine { |
53 | const char *name; | 55 | const char *name; |
54 | const char *desc; | 56 | const char *desc; |
55 | memcpy_t fn; | 57 | union { |
58 | memcpy_t memcpy; | ||
59 | memset_t memset; | ||
60 | } fn; | ||
56 | }; | 61 | }; |
57 | 62 | ||
58 | struct routine routines[] = { | 63 | struct routine memcpy_routines[] = { |
59 | { "default", | 64 | { .name = "default", |
60 | "Default memcpy() provided by glibc", | 65 | .desc = "Default memcpy() provided by glibc", |
61 | memcpy }, | 66 | .fn.memcpy = memcpy }, |
62 | #ifdef HAVE_ARCH_X86_64_SUPPORT | 67 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
63 | 68 | ||
64 | #define MEMCPY_FN(fn, name, desc) { name, desc, fn }, | 69 | #define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, |
65 | #include "mem-memcpy-x86-64-asm-def.h" | 70 | #include "mem-memcpy-x86-64-asm-def.h" |
66 | #undef MEMCPY_FN | 71 | #undef MEMCPY_FN |
67 | 72 | ||
@@ -69,7 +74,7 @@ struct routine routines[] = { | |||
69 | 74 | ||
70 | { NULL, | 75 | { NULL, |
71 | NULL, | 76 | NULL, |
72 | NULL } | 77 | {NULL} } |
73 | }; | 78 | }; |
74 | 79 | ||
75 | static const char * const bench_mem_memcpy_usage[] = { | 80 | static const char * const bench_mem_memcpy_usage[] = { |
@@ -110,63 +115,6 @@ static double timeval2double(struct timeval *ts) | |||
110 | (double)ts->tv_usec / (double)1000000; | 115 | (double)ts->tv_usec / (double)1000000; |
111 | } | 116 | } |
112 | 117 | ||
113 | static void alloc_mem(void **dst, void **src, size_t length) | ||
114 | { | ||
115 | *dst = zalloc(length); | ||
116 | if (!*dst) | ||
117 | die("memory allocation failed - maybe length is too large?\n"); | ||
118 | |||
119 | *src = zalloc(length); | ||
120 | if (!*src) | ||
121 | die("memory allocation failed - maybe length is too large?\n"); | ||
122 | /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ | ||
123 | memset(*src, 0, length); | ||
124 | } | ||
125 | |||
126 | static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault) | ||
127 | { | ||
128 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
129 | void *src = NULL, *dst = NULL; | ||
130 | int i; | ||
131 | |||
132 | alloc_mem(&src, &dst, len); | ||
133 | |||
134 | if (prefault) | ||
135 | fn(dst, src, len); | ||
136 | |||
137 | cycle_start = get_cycle(); | ||
138 | for (i = 0; i < iterations; ++i) | ||
139 | fn(dst, src, len); | ||
140 | cycle_end = get_cycle(); | ||
141 | |||
142 | free(src); | ||
143 | free(dst); | ||
144 | return cycle_end - cycle_start; | ||
145 | } | ||
146 | |||
147 | static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) | ||
148 | { | ||
149 | struct timeval tv_start, tv_end, tv_diff; | ||
150 | void *src = NULL, *dst = NULL; | ||
151 | int i; | ||
152 | |||
153 | alloc_mem(&src, &dst, len); | ||
154 | |||
155 | if (prefault) | ||
156 | fn(dst, src, len); | ||
157 | |||
158 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
159 | for (i = 0; i < iterations; ++i) | ||
160 | fn(dst, src, len); | ||
161 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
162 | |||
163 | timersub(&tv_end, &tv_start, &tv_diff); | ||
164 | |||
165 | free(src); | ||
166 | free(dst); | ||
167 | return (double)((double)len / timeval2double(&tv_diff)); | ||
168 | } | ||
169 | |||
170 | #define pf (no_prefault ? 0 : 1) | 118 | #define pf (no_prefault ? 0 : 1) |
171 | 119 | ||
172 | #define print_bps(x) do { \ | 120 | #define print_bps(x) do { \ |
@@ -180,16 +128,25 @@ static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) | |||
180 | printf(" %14lf GB/Sec", x / K / K / K); \ | 128 | printf(" %14lf GB/Sec", x / K / K / K); \ |
181 | } while (0) | 129 | } while (0) |
182 | 130 | ||
183 | int bench_mem_memcpy(int argc, const char **argv, | 131 | struct bench_mem_info { |
184 | const char *prefix __maybe_unused) | 132 | const struct routine *routines; |
133 | u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault); | ||
134 | double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault); | ||
135 | const char *const *usage; | ||
136 | }; | ||
137 | |||
138 | static int bench_mem_common(int argc, const char **argv, | ||
139 | const char *prefix __maybe_unused, | ||
140 | struct bench_mem_info *info) | ||
185 | { | 141 | { |
186 | int i; | 142 | int i; |
187 | size_t len; | 143 | size_t len; |
144 | double totallen; | ||
188 | double result_bps[2]; | 145 | double result_bps[2]; |
189 | u64 result_cycle[2]; | 146 | u64 result_cycle[2]; |
190 | 147 | ||
191 | argc = parse_options(argc, argv, options, | 148 | argc = parse_options(argc, argv, options, |
192 | bench_mem_memcpy_usage, 0); | 149 | info->usage, 0); |
193 | 150 | ||
194 | if (no_prefault && only_prefault) { | 151 | if (no_prefault && only_prefault) { |
195 | fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); | 152 | fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); |
@@ -200,6 +157,7 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
200 | init_cycle(); | 157 | init_cycle(); |
201 | 158 | ||
202 | len = (size_t)perf_atoll((char *)length_str); | 159 | len = (size_t)perf_atoll((char *)length_str); |
160 | totallen = (double)len * iterations; | ||
203 | 161 | ||
204 | result_cycle[0] = result_cycle[1] = 0ULL; | 162 | result_cycle[0] = result_cycle[1] = 0ULL; |
205 | result_bps[0] = result_bps[1] = 0.0; | 163 | result_bps[0] = result_bps[1] = 0.0; |
@@ -213,16 +171,16 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
213 | if (only_prefault && no_prefault) | 171 | if (only_prefault && no_prefault) |
214 | only_prefault = no_prefault = false; | 172 | only_prefault = no_prefault = false; |
215 | 173 | ||
216 | for (i = 0; routines[i].name; i++) { | 174 | for (i = 0; info->routines[i].name; i++) { |
217 | if (!strcmp(routines[i].name, routine)) | 175 | if (!strcmp(info->routines[i].name, routine)) |
218 | break; | 176 | break; |
219 | } | 177 | } |
220 | if (!routines[i].name) { | 178 | if (!info->routines[i].name) { |
221 | printf("Unknown routine:%s\n", routine); | 179 | printf("Unknown routine:%s\n", routine); |
222 | printf("Available routines...\n"); | 180 | printf("Available routines...\n"); |
223 | for (i = 0; routines[i].name; i++) { | 181 | for (i = 0; info->routines[i].name; i++) { |
224 | printf("\t%s ... %s\n", | 182 | printf("\t%s ... %s\n", |
225 | routines[i].name, routines[i].desc); | 183 | info->routines[i].name, info->routines[i].desc); |
226 | } | 184 | } |
227 | return 1; | 185 | return 1; |
228 | } | 186 | } |
@@ -234,25 +192,25 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
234 | /* show both of results */ | 192 | /* show both of results */ |
235 | if (use_cycle) { | 193 | if (use_cycle) { |
236 | result_cycle[0] = | 194 | result_cycle[0] = |
237 | do_memcpy_cycle(routines[i].fn, len, false); | 195 | info->do_cycle(&info->routines[i], len, false); |
238 | result_cycle[1] = | 196 | result_cycle[1] = |
239 | do_memcpy_cycle(routines[i].fn, len, true); | 197 | info->do_cycle(&info->routines[i], len, true); |
240 | } else { | 198 | } else { |
241 | result_bps[0] = | 199 | result_bps[0] = |
242 | do_memcpy_gettimeofday(routines[i].fn, | 200 | info->do_gettimeofday(&info->routines[i], |
243 | len, false); | 201 | len, false); |
244 | result_bps[1] = | 202 | result_bps[1] = |
245 | do_memcpy_gettimeofday(routines[i].fn, | 203 | info->do_gettimeofday(&info->routines[i], |
246 | len, true); | 204 | len, true); |
247 | } | 205 | } |
248 | } else { | 206 | } else { |
249 | if (use_cycle) { | 207 | if (use_cycle) { |
250 | result_cycle[pf] = | 208 | result_cycle[pf] = |
251 | do_memcpy_cycle(routines[i].fn, | 209 | info->do_cycle(&info->routines[i], |
252 | len, only_prefault); | 210 | len, only_prefault); |
253 | } else { | 211 | } else { |
254 | result_bps[pf] = | 212 | result_bps[pf] = |
255 | do_memcpy_gettimeofday(routines[i].fn, | 213 | info->do_gettimeofday(&info->routines[i], |
256 | len, only_prefault); | 214 | len, only_prefault); |
257 | } | 215 | } |
258 | } | 216 | } |
@@ -263,10 +221,10 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
263 | if (use_cycle) { | 221 | if (use_cycle) { |
264 | printf(" %14lf Cycle/Byte\n", | 222 | printf(" %14lf Cycle/Byte\n", |
265 | (double)result_cycle[0] | 223 | (double)result_cycle[0] |
266 | / (double)len); | 224 | / totallen); |
267 | printf(" %14lf Cycle/Byte (with prefault)\n", | 225 | printf(" %14lf Cycle/Byte (with prefault)\n", |
268 | (double)result_cycle[1] | 226 | (double)result_cycle[1] |
269 | / (double)len); | 227 | / totallen); |
270 | } else { | 228 | } else { |
271 | print_bps(result_bps[0]); | 229 | print_bps(result_bps[0]); |
272 | printf("\n"); | 230 | printf("\n"); |
@@ -277,7 +235,7 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
277 | if (use_cycle) { | 235 | if (use_cycle) { |
278 | printf(" %14lf Cycle/Byte", | 236 | printf(" %14lf Cycle/Byte", |
279 | (double)result_cycle[pf] | 237 | (double)result_cycle[pf] |
280 | / (double)len); | 238 | / totallen); |
281 | } else | 239 | } else |
282 | print_bps(result_bps[pf]); | 240 | print_bps(result_bps[pf]); |
283 | 241 | ||
@@ -288,8 +246,8 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
288 | if (!only_prefault && !no_prefault) { | 246 | if (!only_prefault && !no_prefault) { |
289 | if (use_cycle) { | 247 | if (use_cycle) { |
290 | printf("%lf %lf\n", | 248 | printf("%lf %lf\n", |
291 | (double)result_cycle[0] / (double)len, | 249 | (double)result_cycle[0] / totallen, |
292 | (double)result_cycle[1] / (double)len); | 250 | (double)result_cycle[1] / totallen); |
293 | } else { | 251 | } else { |
294 | printf("%lf %lf\n", | 252 | printf("%lf %lf\n", |
295 | result_bps[0], result_bps[1]); | 253 | result_bps[0], result_bps[1]); |
@@ -297,7 +255,7 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
297 | } else { | 255 | } else { |
298 | if (use_cycle) { | 256 | if (use_cycle) { |
299 | printf("%lf\n", (double)result_cycle[pf] | 257 | printf("%lf\n", (double)result_cycle[pf] |
300 | / (double)len); | 258 | / totallen); |
301 | } else | 259 | } else |
302 | printf("%lf\n", result_bps[pf]); | 260 | printf("%lf\n", result_bps[pf]); |
303 | } | 261 | } |
@@ -310,3 +268,163 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
310 | 268 | ||
311 | return 0; | 269 | return 0; |
312 | } | 270 | } |
271 | |||
272 | static void memcpy_alloc_mem(void **dst, void **src, size_t length) | ||
273 | { | ||
274 | *dst = zalloc(length); | ||
275 | if (!*dst) | ||
276 | die("memory allocation failed - maybe length is too large?\n"); | ||
277 | |||
278 | *src = zalloc(length); | ||
279 | if (!*src) | ||
280 | die("memory allocation failed - maybe length is too large?\n"); | ||
281 | /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ | ||
282 | memset(*src, 0, length); | ||
283 | } | ||
284 | |||
285 | static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault) | ||
286 | { | ||
287 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
288 | void *src = NULL, *dst = NULL; | ||
289 | memcpy_t fn = r->fn.memcpy; | ||
290 | int i; | ||
291 | |||
292 | memcpy_alloc_mem(&src, &dst, len); | ||
293 | |||
294 | if (prefault) | ||
295 | fn(dst, src, len); | ||
296 | |||
297 | cycle_start = get_cycle(); | ||
298 | for (i = 0; i < iterations; ++i) | ||
299 | fn(dst, src, len); | ||
300 | cycle_end = get_cycle(); | ||
301 | |||
302 | free(src); | ||
303 | free(dst); | ||
304 | return cycle_end - cycle_start; | ||
305 | } | ||
306 | |||
307 | static double do_memcpy_gettimeofday(const struct routine *r, size_t len, | ||
308 | bool prefault) | ||
309 | { | ||
310 | struct timeval tv_start, tv_end, tv_diff; | ||
311 | memcpy_t fn = r->fn.memcpy; | ||
312 | void *src = NULL, *dst = NULL; | ||
313 | int i; | ||
314 | |||
315 | memcpy_alloc_mem(&src, &dst, len); | ||
316 | |||
317 | if (prefault) | ||
318 | fn(dst, src, len); | ||
319 | |||
320 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
321 | for (i = 0; i < iterations; ++i) | ||
322 | fn(dst, src, len); | ||
323 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
324 | |||
325 | timersub(&tv_end, &tv_start, &tv_diff); | ||
326 | |||
327 | free(src); | ||
328 | free(dst); | ||
329 | return (double)(((double)len * iterations) / timeval2double(&tv_diff)); | ||
330 | } | ||
331 | |||
332 | int bench_mem_memcpy(int argc, const char **argv, | ||
333 | const char *prefix __maybe_unused) | ||
334 | { | ||
335 | struct bench_mem_info info = { | ||
336 | .routines = memcpy_routines, | ||
337 | .do_cycle = do_memcpy_cycle, | ||
338 | .do_gettimeofday = do_memcpy_gettimeofday, | ||
339 | .usage = bench_mem_memcpy_usage, | ||
340 | }; | ||
341 | |||
342 | return bench_mem_common(argc, argv, prefix, &info); | ||
343 | } | ||
344 | |||
345 | static void memset_alloc_mem(void **dst, size_t length) | ||
346 | { | ||
347 | *dst = zalloc(length); | ||
348 | if (!*dst) | ||
349 | die("memory allocation failed - maybe length is too large?\n"); | ||
350 | } | ||
351 | |||
352 | static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault) | ||
353 | { | ||
354 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | ||
355 | memset_t fn = r->fn.memset; | ||
356 | void *dst = NULL; | ||
357 | int i; | ||
358 | |||
359 | memset_alloc_mem(&dst, len); | ||
360 | |||
361 | if (prefault) | ||
362 | fn(dst, -1, len); | ||
363 | |||
364 | cycle_start = get_cycle(); | ||
365 | for (i = 0; i < iterations; ++i) | ||
366 | fn(dst, i, len); | ||
367 | cycle_end = get_cycle(); | ||
368 | |||
369 | free(dst); | ||
370 | return cycle_end - cycle_start; | ||
371 | } | ||
372 | |||
373 | static double do_memset_gettimeofday(const struct routine *r, size_t len, | ||
374 | bool prefault) | ||
375 | { | ||
376 | struct timeval tv_start, tv_end, tv_diff; | ||
377 | memset_t fn = r->fn.memset; | ||
378 | void *dst = NULL; | ||
379 | int i; | ||
380 | |||
381 | memset_alloc_mem(&dst, len); | ||
382 | |||
383 | if (prefault) | ||
384 | fn(dst, -1, len); | ||
385 | |||
386 | BUG_ON(gettimeofday(&tv_start, NULL)); | ||
387 | for (i = 0; i < iterations; ++i) | ||
388 | fn(dst, i, len); | ||
389 | BUG_ON(gettimeofday(&tv_end, NULL)); | ||
390 | |||
391 | timersub(&tv_end, &tv_start, &tv_diff); | ||
392 | |||
393 | free(dst); | ||
394 | return (double)(((double)len * iterations) / timeval2double(&tv_diff)); | ||
395 | } | ||
396 | |||
397 | static const char * const bench_mem_memset_usage[] = { | ||
398 | "perf bench mem memset <options>", | ||
399 | NULL | ||
400 | }; | ||
401 | |||
402 | static const struct routine memset_routines[] = { | ||
403 | { .name ="default", | ||
404 | .desc = "Default memset() provided by glibc", | ||
405 | .fn.memset = memset }, | ||
406 | #ifdef HAVE_ARCH_X86_64_SUPPORT | ||
407 | |||
408 | #define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, | ||
409 | #include "mem-memset-x86-64-asm-def.h" | ||
410 | #undef MEMSET_FN | ||
411 | |||
412 | #endif | ||
413 | |||
414 | { .name = NULL, | ||
415 | .desc = NULL, | ||
416 | .fn.memset = NULL } | ||
417 | }; | ||
418 | |||
419 | int bench_mem_memset(int argc, const char **argv, | ||
420 | const char *prefix __maybe_unused) | ||
421 | { | ||
422 | struct bench_mem_info info = { | ||
423 | .routines = memset_routines, | ||
424 | .do_cycle = do_memset_cycle, | ||
425 | .do_gettimeofday = do_memset_gettimeofday, | ||
426 | .usage = bench_mem_memset_usage, | ||
427 | }; | ||
428 | |||
429 | return bench_mem_common(argc, argv, prefix, &info); | ||
430 | } | ||
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c deleted file mode 100644 index 75fc3e65fb2a..000000000000 --- a/tools/perf/bench/mem-memset.c +++ /dev/null | |||
@@ -1,304 +0,0 @@ | |||
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 | } | ||
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 70385756da63..77d5cae54c6a 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c | |||
@@ -285,12 +285,11 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
285 | struct str_node *pos; | 285 | struct str_node *pos; |
286 | int ret = 0; | 286 | int ret = 0; |
287 | bool force = false; | 287 | bool force = false; |
288 | char debugdir[PATH_MAX]; | ||
289 | char const *add_name_list_str = NULL, | 288 | char const *add_name_list_str = NULL, |
290 | *remove_name_list_str = NULL, | 289 | *remove_name_list_str = NULL, |
291 | *missing_filename = NULL, | 290 | *missing_filename = NULL, |
292 | *update_name_list_str = NULL, | 291 | *update_name_list_str = NULL, |
293 | *kcore_filename; | 292 | *kcore_filename = NULL; |
294 | char sbuf[STRERR_BUFSIZE]; | 293 | char sbuf[STRERR_BUFSIZE]; |
295 | 294 | ||
296 | struct perf_data_file file = { | 295 | struct perf_data_file file = { |
@@ -335,13 +334,11 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
335 | 334 | ||
336 | setup_pager(); | 335 | setup_pager(); |
337 | 336 | ||
338 | snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); | ||
339 | |||
340 | if (add_name_list_str) { | 337 | if (add_name_list_str) { |
341 | list = strlist__new(true, add_name_list_str); | 338 | list = strlist__new(true, add_name_list_str); |
342 | if (list) { | 339 | if (list) { |
343 | strlist__for_each(pos, list) | 340 | strlist__for_each(pos, list) |
344 | if (build_id_cache__add_file(pos->s, debugdir)) { | 341 | if (build_id_cache__add_file(pos->s, buildid_dir)) { |
345 | if (errno == EEXIST) { | 342 | if (errno == EEXIST) { |
346 | pr_debug("%s already in the cache\n", | 343 | pr_debug("%s already in the cache\n", |
347 | pos->s); | 344 | pos->s); |
@@ -359,7 +356,7 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
359 | list = strlist__new(true, remove_name_list_str); | 356 | list = strlist__new(true, remove_name_list_str); |
360 | if (list) { | 357 | if (list) { |
361 | strlist__for_each(pos, list) | 358 | strlist__for_each(pos, list) |
362 | if (build_id_cache__remove_file(pos->s, debugdir)) { | 359 | if (build_id_cache__remove_file(pos->s, buildid_dir)) { |
363 | if (errno == ENOENT) { | 360 | if (errno == ENOENT) { |
364 | pr_debug("%s wasn't in the cache\n", | 361 | pr_debug("%s wasn't in the cache\n", |
365 | pos->s); | 362 | pos->s); |
@@ -380,7 +377,7 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
380 | list = strlist__new(true, update_name_list_str); | 377 | list = strlist__new(true, update_name_list_str); |
381 | if (list) { | 378 | if (list) { |
382 | strlist__for_each(pos, list) | 379 | strlist__for_each(pos, list) |
383 | if (build_id_cache__update_file(pos->s, debugdir)) { | 380 | if (build_id_cache__update_file(pos->s, buildid_dir)) { |
384 | if (errno == ENOENT) { | 381 | if (errno == ENOENT) { |
385 | pr_debug("%s wasn't in the cache\n", | 382 | pr_debug("%s wasn't in the cache\n", |
386 | pos->s); | 383 | pos->s); |
@@ -395,7 +392,7 @@ int cmd_buildid_cache(int argc, const char **argv, | |||
395 | } | 392 | } |
396 | 393 | ||
397 | if (kcore_filename && | 394 | if (kcore_filename && |
398 | build_id_cache__add_kcore(kcore_filename, debugdir, force)) | 395 | build_id_cache__add_kcore(kcore_filename, buildid_dir, force)) |
399 | pr_warning("Couldn't add %s\n", kcore_filename); | 396 | pr_warning("Couldn't add %s\n", kcore_filename); |
400 | 397 | ||
401 | out: | 398 | out: |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 3c0f3d4fb021..0894a817f67e 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
@@ -1293,7 +1293,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, | |||
1293 | OPT_UINTEGER('d', "display", &kvm->display_time, | 1293 | OPT_UINTEGER('d', "display", &kvm->display_time, |
1294 | "time in seconds between display updates"), | 1294 | "time in seconds between display updates"), |
1295 | OPT_STRING(0, "event", &kvm->report_event, "report event", | 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 | OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, | 1298 | OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, |
1298 | "vcpu id to report"), | 1299 | "vcpu id to report"), |
1299 | OPT_STRING('k', "key", &kvm->sort_key, "sort-key", | 1300 | OPT_STRING('k', "key", &kvm->sort_key, "sort-key", |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 83a4835c8118..badfabc6a01f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -2045,7 +2045,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
2045 | unsigned long before; | 2045 | unsigned long before; |
2046 | const bool forks = argc > 0; | 2046 | const bool forks = argc > 0; |
2047 | bool draining = false; | 2047 | bool draining = false; |
2048 | char sbuf[STRERR_BUFSIZE]; | ||
2049 | 2048 | ||
2050 | trace->live = true; | 2049 | trace->live = true; |
2051 | 2050 | ||
@@ -2106,11 +2105,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
2106 | goto out_error_open; | 2105 | goto out_error_open; |
2107 | 2106 | ||
2108 | err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); | 2107 | err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); |
2109 | if (err < 0) { | 2108 | if (err < 0) |
2110 | fprintf(trace->output, "Couldn't mmap the events: %s\n", | 2109 | goto out_error_mmap; |
2111 | strerror_r(errno, sbuf, sizeof(sbuf))); | ||
2112 | goto out_delete_evlist; | ||
2113 | } | ||
2114 | 2110 | ||
2115 | perf_evlist__enable(evlist); | 2111 | perf_evlist__enable(evlist); |
2116 | 2112 | ||
@@ -2210,6 +2206,10 @@ out_error_tp: | |||
2210 | perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); | 2206 | perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); |
2211 | goto out_error; | 2207 | goto out_error; |
2212 | 2208 | ||
2209 | out_error_mmap: | ||
2210 | perf_evlist__strerror_mmap(evlist, errno, errbuf, sizeof(errbuf)); | ||
2211 | goto out_error; | ||
2212 | |||
2213 | out_error_open: | 2213 | out_error_open: |
2214 | perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); | 2214 | perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); |
2215 | 2215 | ||
@@ -2485,7 +2485,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) | |||
2485 | .user_freq = UINT_MAX, | 2485 | .user_freq = UINT_MAX, |
2486 | .user_interval = ULLONG_MAX, | 2486 | .user_interval = ULLONG_MAX, |
2487 | .no_buffering = true, | 2487 | .no_buffering = true, |
2488 | .mmap_pages = 1024, | 2488 | .mmap_pages = UINT_MAX, |
2489 | }, | 2489 | }, |
2490 | .output = stdout, | 2490 | .output = stdout, |
2491 | .show_comm = true, | 2491 | .show_comm = true, |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 452a8474d29d..3700a7faca6c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
@@ -200,6 +200,16 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) | |||
200 | *envchanged = 1; | 200 | *envchanged = 1; |
201 | (*argv)++; | 201 | (*argv)++; |
202 | (*argc)--; | 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 | } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { | 213 | } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { |
204 | perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); | 214 | perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); |
205 | fprintf(stderr, "dir: %s\n", debugfs_mountpoint); | 215 | fprintf(stderr, "dir: %s\n", debugfs_mountpoint); |
@@ -499,7 +509,7 @@ int main(int argc, const char **argv) | |||
499 | } | 509 | } |
500 | if (!prefixcmp(cmd, "trace")) { | 510 | if (!prefixcmp(cmd, "trace")) { |
501 | #ifdef HAVE_LIBAUDIT_SUPPORT | 511 | #ifdef HAVE_LIBAUDIT_SUPPORT |
502 | set_buildid_dir(); | 512 | set_buildid_dir(NULL); |
503 | setup_path(); | 513 | setup_path(); |
504 | argv[0] = "trace"; | 514 | argv[0] = "trace"; |
505 | return cmd_trace(argc, argv, NULL); | 515 | return cmd_trace(argc, argv, NULL); |
@@ -514,7 +524,7 @@ int main(int argc, const char **argv) | |||
514 | argc--; | 524 | argc--; |
515 | handle_options(&argv, &argc, NULL); | 525 | handle_options(&argv, &argc, NULL); |
516 | commit_pager_choice(); | 526 | commit_pager_choice(); |
517 | set_buildid_dir(); | 527 | set_buildid_dir(NULL); |
518 | 528 | ||
519 | if (argc > 0) { | 529 | if (argc > 0) { |
520 | if (!prefixcmp(argv[0], "--")) | 530 | if (!prefixcmp(argv[0], "--")) |
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record index f710b92ccff6..d3095dafed36 100644 --- a/tools/perf/tests/attr/base-record +++ b/tools/perf/tests/attr/base-record | |||
@@ -5,7 +5,7 @@ group_fd=-1 | |||
5 | flags=0|8 | 5 | flags=0|8 |
6 | cpu=* | 6 | cpu=* |
7 | type=0|1 | 7 | type=0|1 |
8 | size=96 | 8 | size=104 |
9 | config=0 | 9 | config=0 |
10 | sample_period=4000 | 10 | sample_period=4000 |
11 | sample_type=263 | 11 | sample_type=263 |
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat index dc3ada2470c0..872ed7e24c7c 100644 --- a/tools/perf/tests/attr/base-stat +++ b/tools/perf/tests/attr/base-stat | |||
@@ -5,7 +5,7 @@ group_fd=-1 | |||
5 | flags=0|8 | 5 | flags=0|8 |
6 | cpu=* | 6 | cpu=* |
7 | type=0 | 7 | type=0 |
8 | size=96 | 8 | size=104 |
9 | config=0 | 9 | config=0 |
10 | sample_period=0 | 10 | sample_period=0 |
11 | sample_type=0 | 11 | sample_type=0 |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 502daff76ceb..e6bb04b5b09b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -1252,7 +1252,7 @@ static int hists__browser_title(struct hists *hists, | |||
1252 | 1252 | ||
1253 | nr_samples = convert_unit(nr_samples, &unit); | 1253 | nr_samples = convert_unit(nr_samples, &unit); |
1254 | printed = scnprintf(bf, size, | 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 | nr_samples, unit, ev_name, nr_events); | 1256 | nr_samples, unit, ev_name, nr_events); |
1257 | 1257 | ||
1258 | 1258 | ||
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 2af18376b077..dc0d095f318c 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c | |||
@@ -162,8 +162,8 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b, | |||
162 | return ret; | 162 | return ret; |
163 | 163 | ||
164 | nr_members = evsel->nr_members; | 164 | nr_members = evsel->nr_members; |
165 | fields_a = calloc(sizeof(*fields_a), nr_members); | 165 | fields_a = calloc(nr_members, sizeof(*fields_a)); |
166 | fields_b = calloc(sizeof(*fields_b), nr_members); | 166 | fields_b = calloc(nr_members, sizeof(*fields_b)); |
167 | 167 | ||
168 | if (!fields_a || !fields_b) | 168 | if (!fields_a || !fields_b) |
169 | goto out; | 169 | goto out; |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e8d79e5bfaf7..0c72680a977f 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -410,21 +410,18 @@ int perf_session__cache_build_ids(struct perf_session *session) | |||
410 | { | 410 | { |
411 | struct rb_node *nd; | 411 | struct rb_node *nd; |
412 | int ret; | 412 | int ret; |
413 | char debugdir[PATH_MAX]; | ||
414 | 413 | ||
415 | if (no_buildid_cache) | 414 | if (no_buildid_cache) |
416 | return 0; | 415 | return 0; |
417 | 416 | ||
418 | snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); | 417 | if (mkdir(buildid_dir, 0755) != 0 && errno != EEXIST) |
419 | |||
420 | if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) | ||
421 | return -1; | 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 | for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { | 422 | for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { |
426 | struct machine *pos = rb_entry(nd, struct machine, rb_node); | 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 | return ret ? -1 : 0; | 426 | return ret ? -1 : 0; |
430 | } | 427 | } |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index cf524a35cc84..64b377e591e4 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -77,7 +77,7 @@ int parse_callchain_record_opt(const char *arg) | |||
77 | ret = 0; | 77 | ret = 0; |
78 | } else | 78 | } else |
79 | pr_err("callchain: No more arguments " | 79 | pr_err("callchain: No more arguments " |
80 | "needed for -g fp\n"); | 80 | "needed for --call-graph fp\n"); |
81 | break; | 81 | break; |
82 | 82 | ||
83 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | 83 | #ifdef HAVE_DWARF_UNWIND_SUPPORT |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 57ff826f150b..e18f653cd7db 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -522,7 +522,7 @@ static int buildid_dir_command_config(const char *var, const char *value, | |||
522 | const char *v; | 522 | const char *v; |
523 | 523 | ||
524 | /* same dir for all commands */ | 524 | /* same dir for all commands */ |
525 | if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) { | 525 | if (!strcmp(var, "buildid.dir")) { |
526 | v = perf_config_dirname(var, value); | 526 | v = perf_config_dirname(var, value); |
527 | if (!v) | 527 | if (!v) |
528 | return -1; | 528 | return -1; |
@@ -539,12 +539,14 @@ static void check_buildid_dir_config(void) | |||
539 | perf_config(buildid_dir_command_config, &c); | 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 | /* try config file */ | 547 | /* try config file */ |
547 | check_buildid_dir_config(); | 548 | if (buildid_dir[0] == '\0') |
549 | check_buildid_dir_config(); | ||
548 | 550 | ||
549 | /* default to $HOME/.debug */ | 551 | /* default to $HOME/.debug */ |
550 | if (buildid_dir[0] == '\0') { | 552 | if (buildid_dir[0] == '\0') { |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index cfbe2b99b9aa..cbab1fb77b1d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | #include "util.h" | 9 | #include "util.h" |
10 | #include <api/fs/debugfs.h> | 10 | #include <api/fs/debugfs.h> |
11 | #include <api/fs/fs.h> | ||
11 | #include <poll.h> | 12 | #include <poll.h> |
12 | #include "cpumap.h" | 13 | #include "cpumap.h" |
13 | #include "thread_map.h" | 14 | #include "thread_map.h" |
@@ -24,6 +25,7 @@ | |||
24 | 25 | ||
25 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
26 | #include <linux/hash.h> | 27 | #include <linux/hash.h> |
28 | #include <linux/log2.h> | ||
27 | 29 | ||
28 | static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); | 30 | static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); |
29 | static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); | 31 | static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); |
@@ -892,10 +894,24 @@ out_unmap: | |||
892 | 894 | ||
893 | static size_t perf_evlist__mmap_size(unsigned long pages) | 895 | static size_t perf_evlist__mmap_size(unsigned long pages) |
894 | { | 896 | { |
895 | /* 512 kiB: default amount of unprivileged mlocked memory */ | 897 | if (pages == UINT_MAX) { |
896 | if (pages == UINT_MAX) | 898 | int max; |
897 | pages = (512 * 1024) / page_size; | 899 | |
898 | else if (!is_power_of_2(pages)) | 900 | if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { |
901 | /* | ||
902 | * Pick a once upon a time good value, i.e. things look | ||
903 | * strange since we can't read a sysctl value, but lets not | ||
904 | * die yet... | ||
905 | */ | ||
906 | max = 512; | ||
907 | } else { | ||
908 | max -= (page_size / 1024); | ||
909 | } | ||
910 | |||
911 | pages = (max * 1024) / page_size; | ||
912 | if (!is_power_of_2(pages)) | ||
913 | pages = rounddown_pow_of_two(pages); | ||
914 | } else if (!is_power_of_2(pages)) | ||
899 | return 0; | 915 | return 0; |
900 | 916 | ||
901 | return (pages + 1) * page_size; | 917 | return (pages + 1) * page_size; |
@@ -932,7 +948,7 @@ static long parse_pages_arg(const char *str, unsigned long min, | |||
932 | /* leave number of pages at 0 */ | 948 | /* leave number of pages at 0 */ |
933 | } else if (!is_power_of_2(pages)) { | 949 | } else if (!is_power_of_2(pages)) { |
934 | /* round pages up to next power of 2 */ | 950 | /* round pages up to next power of 2 */ |
935 | pages = next_pow2_l(pages); | 951 | pages = roundup_pow_of_two(pages); |
936 | if (!pages) | 952 | if (!pages) |
937 | return -EINVAL; | 953 | return -EINVAL; |
938 | pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", | 954 | pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", |
@@ -1483,6 +1499,37 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, | |||
1483 | return 0; | 1499 | return 0; |
1484 | } | 1500 | } |
1485 | 1501 | ||
1502 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) | ||
1503 | { | ||
1504 | char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); | ||
1505 | int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; | ||
1506 | |||
1507 | switch (err) { | ||
1508 | case EPERM: | ||
1509 | sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); | ||
1510 | printed += scnprintf(buf + printed, size - printed, | ||
1511 | "Error:\t%s.\n" | ||
1512 | "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" | ||
1513 | "Hint:\tTried using %zd kB.\n", | ||
1514 | emsg, pages_max_per_user, pages_attempted); | ||
1515 | |||
1516 | if (pages_attempted >= pages_max_per_user) { | ||
1517 | printed += scnprintf(buf + printed, size - printed, | ||
1518 | "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", | ||
1519 | pages_max_per_user + pages_attempted); | ||
1520 | } | ||
1521 | |||
1522 | printed += scnprintf(buf + printed, size - printed, | ||
1523 | "Hint:\tTry using a smaller -m/--mmap-pages value."); | ||
1524 | break; | ||
1525 | default: | ||
1526 | scnprintf(buf, size, "%s", emsg); | ||
1527 | break; | ||
1528 | } | ||
1529 | |||
1530 | return 0; | ||
1531 | } | ||
1532 | |||
1486 | void perf_evlist__to_front(struct perf_evlist *evlist, | 1533 | void perf_evlist__to_front(struct perf_evlist *evlist, |
1487 | struct perf_evsel *move_evsel) | 1534 | struct perf_evsel *move_evsel) |
1488 | { | 1535 | { |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 649b0c597283..0ba93f67ab94 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -185,6 +185,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); | |||
185 | 185 | ||
186 | int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); | 186 | int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); |
187 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); | 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 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) | 190 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) |
190 | { | 191 | { |
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h deleted file mode 100644 index c3294163de17..000000000000 --- a/tools/perf/util/include/linux/bitops.h +++ /dev/null | |||
@@ -1,162 +0,0 @@ | |||
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 | ||
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 15dd0a9691ce..94de3e48b490 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -1385,19 +1385,46 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, | |||
1385 | static int add_callchain_ip(struct thread *thread, | 1385 | static int add_callchain_ip(struct thread *thread, |
1386 | struct symbol **parent, | 1386 | struct symbol **parent, |
1387 | struct addr_location *root_al, | 1387 | struct addr_location *root_al, |
1388 | int cpumode, | 1388 | bool branch_history, |
1389 | u64 ip) | 1389 | u64 ip) |
1390 | { | 1390 | { |
1391 | struct addr_location al; | 1391 | struct addr_location al; |
1392 | 1392 | ||
1393 | al.filtered = 0; | 1393 | al.filtered = 0; |
1394 | al.sym = NULL; | 1394 | al.sym = NULL; |
1395 | if (cpumode == -1) | 1395 | if (branch_history) |
1396 | thread__find_cpumode_addr_location(thread, MAP__FUNCTION, | 1396 | thread__find_cpumode_addr_location(thread, MAP__FUNCTION, |
1397 | ip, &al); | 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 | thread__find_addr_location(thread, cpumode, MAP__FUNCTION, | 1424 | thread__find_addr_location(thread, cpumode, MAP__FUNCTION, |
1400 | ip, &al); | 1425 | ip, &al); |
1426 | } | ||
1427 | |||
1401 | if (al.sym != NULL) { | 1428 | if (al.sym != NULL) { |
1402 | if (sort__has_parent && !*parent && | 1429 | if (sort__has_parent && !*parent && |
1403 | symbol__match_regex(al.sym, &parent_regex)) | 1430 | symbol__match_regex(al.sym, &parent_regex)) |
@@ -1480,11 +1507,8 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1480 | struct addr_location *root_al, | 1507 | struct addr_location *root_al, |
1481 | int max_stack) | 1508 | int max_stack) |
1482 | { | 1509 | { |
1483 | u8 cpumode = PERF_RECORD_MISC_USER; | ||
1484 | int chain_nr = min(max_stack, (int)chain->nr); | 1510 | int chain_nr = min(max_stack, (int)chain->nr); |
1485 | int i; | 1511 | int i, j, err; |
1486 | int j; | ||
1487 | int err; | ||
1488 | int skip_idx = -1; | 1512 | int skip_idx = -1; |
1489 | int first_call = 0; | 1513 | int first_call = 0; |
1490 | 1514 | ||
@@ -1542,10 +1566,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, | |||
1542 | 1566 | ||
1543 | for (i = 0; i < nr; i++) { | 1567 | for (i = 0; i < nr; i++) { |
1544 | err = add_callchain_ip(thread, parent, root_al, | 1568 | err = add_callchain_ip(thread, parent, root_al, |
1545 | -1, be[i].to); | 1569 | true, be[i].to); |
1546 | if (!err) | 1570 | if (!err) |
1547 | err = add_callchain_ip(thread, parent, root_al, | 1571 | err = add_callchain_ip(thread, parent, root_al, |
1548 | -1, be[i].from); | 1572 | true, be[i].from); |
1549 | if (err == -EINVAL) | 1573 | if (err == -EINVAL) |
1550 | break; | 1574 | break; |
1551 | if (err) | 1575 | if (err) |
@@ -1574,36 +1598,10 @@ check_calls: | |||
1574 | #endif | 1598 | #endif |
1575 | ip = chain->ips[j]; | 1599 | ip = chain->ips[j]; |
1576 | 1600 | ||
1577 | if (ip >= PERF_CONTEXT_MAX) { | 1601 | err = add_callchain_ip(thread, parent, root_al, false, ip); |
1578 | switch (ip) { | ||
1579 | case PERF_CONTEXT_HV: | ||
1580 | cpumode = PERF_RECORD_MISC_HYPERVISOR; | ||
1581 | break; | ||
1582 | case PERF_CONTEXT_KERNEL: | ||
1583 | cpumode = PERF_RECORD_MISC_KERNEL; | ||
1584 | break; | ||
1585 | case PERF_CONTEXT_USER: | ||
1586 | cpumode = PERF_RECORD_MISC_USER; | ||
1587 | break; | ||
1588 | default: | ||
1589 | pr_debug("invalid callchain context: " | ||
1590 | "%"PRId64"\n", (s64) ip); | ||
1591 | /* | ||
1592 | * It seems the callchain is corrupted. | ||
1593 | * Discard all. | ||
1594 | */ | ||
1595 | callchain_cursor_reset(&callchain_cursor); | ||
1596 | return 0; | ||
1597 | } | ||
1598 | continue; | ||
1599 | } | ||
1600 | 1602 | ||
1601 | err = add_callchain_ip(thread, parent, root_al, | ||
1602 | cpumode, ip); | ||
1603 | if (err == -EINVAL) | ||
1604 | break; | ||
1605 | if (err) | 1603 | if (err) |
1606 | return err; | 1604 | return (err < 0) ? err : 0; |
1607 | } | 1605 | } |
1608 | 1606 | ||
1609 | return 0; | 1607 | return 0; |
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index cf69325b985f..8acd0df88b5c 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c | |||
@@ -137,16 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) | |||
137 | 137 | ||
138 | static int get_max_rate(unsigned int *rate) | 138 | static int get_max_rate(unsigned int *rate) |
139 | { | 139 | { |
140 | char path[PATH_MAX]; | 140 | return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate); |
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); | ||
150 | } | 141 | } |
151 | 142 | ||
152 | static int record_opts__config_freq(struct record_opts *opts) | 143 | static int record_opts__config_freq(struct record_opts *opts) |
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index e73b6a5c9e0f..c93fb0c5bd0b 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c | |||
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | struct a2l_data { | 21 | struct a2l_data { |
22 | const char *input; | 22 | const char *input; |
23 | unsigned long addr; | 23 | u64 addr; |
24 | 24 | ||
25 | bool found; | 25 | bool found; |
26 | const char *filename; | 26 | const char *filename; |
@@ -147,7 +147,7 @@ static void addr2line_cleanup(struct a2l_data *a2l) | |||
147 | free(a2l); | 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 | char **file, unsigned int *line, struct dso *dso) | 151 | char **file, unsigned int *line, struct dso *dso) |
152 | { | 152 | { |
153 | int ret = 0; | 153 | int ret = 0; |
@@ -193,7 +193,7 @@ void dso__free_a2l(struct dso *dso) | |||
193 | 193 | ||
194 | #else /* HAVE_LIBBFD_SUPPORT */ | 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 | char **file, unsigned int *line_nr, | 197 | char **file, unsigned int *line_nr, |
198 | struct dso *dso __maybe_unused) | 198 | struct dso *dso __maybe_unused) |
199 | { | 199 | { |
@@ -252,7 +252,7 @@ void dso__free_a2l(struct dso *dso __maybe_unused) | |||
252 | */ | 252 | */ |
253 | #define A2L_FAIL_LIMIT 123 | 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 | bool show_sym) | 256 | bool show_sym) |
257 | { | 257 | { |
258 | char *file = NULL; | 258 | char *file = NULL; |
@@ -293,10 +293,10 @@ out: | |||
293 | dso__free_a2l(dso); | 293 | dso__free_a2l(dso); |
294 | } | 294 | } |
295 | if (sym) { | 295 | if (sym) { |
296 | if (asprintf(&srcline, "%s+%ld", show_sym ? sym->name : "", | 296 | if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "", |
297 | addr - sym->start) < 0) | 297 | addr - sym->start) < 0) |
298 | return SRCLINE_UNKNOWN; | 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 | return SRCLINE_UNKNOWN; | 300 | return SRCLINE_UNKNOWN; |
301 | return srcline; | 301 | return srcline; |
302 | } | 302 | } |
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index fa585c63f56a..d7efb03b3f9a 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
@@ -129,6 +129,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
129 | 129 | ||
130 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { | 130 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { |
131 | void *tmp; | 131 | void *tmp; |
132 | long offset; | ||
132 | 133 | ||
133 | if (need_swap) { | 134 | if (need_swap) { |
134 | phdr->p_type = bswap_32(phdr->p_type); | 135 | phdr->p_type = bswap_32(phdr->p_type); |
@@ -140,12 +141,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
140 | continue; | 141 | continue; |
141 | 142 | ||
142 | buf_size = phdr->p_filesz; | 143 | buf_size = phdr->p_filesz; |
144 | offset = phdr->p_offset; | ||
143 | tmp = realloc(buf, buf_size); | 145 | tmp = realloc(buf, buf_size); |
144 | if (tmp == NULL) | 146 | if (tmp == NULL) |
145 | goto out_free; | 147 | goto out_free; |
146 | 148 | ||
147 | buf = tmp; | 149 | buf = tmp; |
148 | fseek(fp, phdr->p_offset, SEEK_SET); | 150 | fseek(fp, offset, SEEK_SET); |
149 | if (fread(buf, buf_size, 1, fp) != 1) | 151 | if (fread(buf, buf_size, 1, fp) != 1) |
150 | goto out_free; | 152 | goto out_free; |
151 | 153 | ||
@@ -178,6 +180,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
178 | 180 | ||
179 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { | 181 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { |
180 | void *tmp; | 182 | void *tmp; |
183 | long offset; | ||
181 | 184 | ||
182 | if (need_swap) { | 185 | if (need_swap) { |
183 | phdr->p_type = bswap_32(phdr->p_type); | 186 | phdr->p_type = bswap_32(phdr->p_type); |
@@ -189,12 +192,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
189 | continue; | 192 | continue; |
190 | 193 | ||
191 | buf_size = phdr->p_filesz; | 194 | buf_size = phdr->p_filesz; |
195 | offset = phdr->p_offset; | ||
192 | tmp = realloc(buf, buf_size); | 196 | tmp = realloc(buf, buf_size); |
193 | if (tmp == NULL) | 197 | if (tmp == NULL) |
194 | goto out_free; | 198 | goto out_free; |
195 | 199 | ||
196 | buf = tmp; | 200 | buf = tmp; |
197 | fseek(fp, phdr->p_offset, SEEK_SET); | 201 | fseek(fp, offset, SEEK_SET); |
198 | if (fread(buf, buf_size, 1, fp) != 1) | 202 | if (fread(buf, buf_size, 1, fp) != 1) |
199 | goto out_free; | 203 | goto out_free; |
200 | 204 | ||
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index d5eab3f3323f..b86744f29eef 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -442,23 +442,6 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags) | |||
442 | return (unsigned long) -1; | 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 | int filename__read_str(const char *filename, char **buf, size_t *sizep) | 445 | int filename__read_str(const char *filename, char **buf, size_t *sizep) |
463 | { | 446 | { |
464 | size_t size = 0, alloc_size = 0; | 447 | size_t size = 0, alloc_size = 0; |
@@ -523,16 +506,9 @@ const char *get_filename_for_perf_kvm(void) | |||
523 | 506 | ||
524 | int perf_event_paranoid(void) | 507 | int perf_event_paranoid(void) |
525 | { | 508 | { |
526 | char path[PATH_MAX]; | ||
527 | const char *procfs = procfs__mountpoint(); | ||
528 | int value; | 509 | int value; |
529 | 510 | ||
530 | if (!procfs) | 511 | if (sysctl__read_int("kernel/perf_event_paranoid", &value)) |
531 | return INT_MAX; | ||
532 | |||
533 | scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs); | ||
534 | |||
535 | if (filename__read_int(path, &value)) | ||
536 | return INT_MAX; | 512 | return INT_MAX; |
537 | 513 | ||
538 | return value; | 514 | return value; |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 419bee030f83..027a5153495c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -153,7 +153,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))) | |||
153 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); | 153 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); |
154 | 154 | ||
155 | extern int prefixcmp(const char *str, const char *prefix); | 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 | static inline const char *skip_prefix(const char *str, const char *prefix) | 158 | static inline const char *skip_prefix(const char *str, const char *prefix) |
159 | { | 159 | { |
@@ -269,35 +269,6 @@ void event_attr_init(struct perf_event_attr *attr); | |||
269 | #define _STR(x) #x | 269 | #define _STR(x) #x |
270 | #define STR(x) _STR(x) | 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 | size_t hex_width(u64 v); | 272 | size_t hex_width(u64 v); |
302 | int hex2u64(const char *ptr, u64 *val); | 273 | int hex2u64(const char *ptr, u64 *val); |
303 | 274 | ||
@@ -339,11 +310,10 @@ static inline int path__join3(char *bf, size_t size, | |||
339 | struct dso; | 310 | struct dso; |
340 | struct symbol; | 311 | struct symbol; |
341 | 312 | ||
342 | char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, | 313 | char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, |
343 | bool show_sym); | 314 | bool show_sym); |
344 | void free_srcline(char *srcline); | 315 | void free_srcline(char *srcline); |
345 | 316 | ||
346 | int filename__read_int(const char *filename, int *value); | ||
347 | int filename__read_str(const char *filename, char **buf, size_t *sizep); | 317 | int filename__read_str(const char *filename, char **buf, size_t *sizep); |
348 | int perf_event_paranoid(void); | 318 | int perf_event_paranoid(void); |
349 | 319 | ||
diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c index dfe454855cd2..1c12536f2081 100644 --- a/tools/thermal/tmon/sysfs.c +++ b/tools/thermal/tmon/sysfs.c | |||
@@ -446,7 +446,7 @@ int probe_thermal_sysfs(void) | |||
446 | return -1; | 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 | if (!ptdata.tzi) { | 450 | if (!ptdata.tzi) { |
451 | fprintf(stderr, "Err: allocate tz_info\n"); | 451 | fprintf(stderr, "Err: allocate tz_info\n"); |
452 | return -1; | 452 | return -1; |
@@ -454,8 +454,8 @@ int probe_thermal_sysfs(void) | |||
454 | 454 | ||
455 | /* we still show thermal zone information if there is no cdev */ | 455 | /* we still show thermal zone information if there is no cdev */ |
456 | if (ptdata.nr_cooling_dev) { | 456 | if (ptdata.nr_cooling_dev) { |
457 | ptdata.cdi = calloc(sizeof(struct cdev_info), | 457 | ptdata.cdi = calloc(ptdata.max_cdev_instance + 1, |
458 | ptdata.max_cdev_instance + 1); | 458 | sizeof(struct cdev_info)); |
459 | if (!ptdata.cdi) { | 459 | if (!ptdata.cdi) { |
460 | free(ptdata.tzi); | 460 | free(ptdata.tzi); |
461 | fprintf(stderr, "Err: allocate cdev_info\n"); | 461 | fprintf(stderr, "Err: allocate cdev_info\n"); |