aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-12-18 01:23:55 -0500
committerIngo Molnar <mingo@kernel.org>2014-12-18 01:23:55 -0500
commit6aaba7c9011e0d34cf520808467bd7eb36e51b4c (patch)
treed8e8763a585680ce52245c93c764f3eff124f3df /tools
parent41e950c033b7df997d4b38653efe6554be9b96a7 (diff)
parent7ad74b41e56e4f7f42c6b765bc44428cd09310d7 (diff)
Merge tag 'perf-core-for-mingo-2' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - The mmap address range for the ring buffer now is calculated using the contents of /proc/sys/kernel/perf_event_mlock_kb. This fixes an -EPERM case where 'trace' was trying to use more than what is configured on perf_event_mlock_kb. (Arnaldo Carvalho de Melo) Infrastructure changes: - Move bitops definitions so that they match the header file hierarchy in the kernel sources where that code came from. (Arnaldo Carvalho de Melo) - Adopt round{down,up}_pow_of_two from the kernel and use it instead of equivalent code, so that we reuse more kernel code and make tools/ look more like kernel source code, to encourage further contributions from kernel hackers (Arnaldo Carvalho de Melo) - Fix use after free in filename__read_build_id (Mitchell Krome) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/include/asm-generic/bitops.h27
-rw-r--r--tools/include/asm-generic/bitops/__ffs.h43
-rw-r--r--tools/include/asm-generic/bitops/__fls.h1
-rw-r--r--tools/include/asm-generic/bitops/atomic.h22
-rw-r--r--tools/include/asm-generic/bitops/find.h33
-rw-r--r--tools/include/asm-generic/bitops/fls.h1
-rw-r--r--tools/include/asm-generic/bitops/fls64.h1
-rw-r--r--tools/include/linux/bitops.h53
-rw-r--r--tools/include/linux/log2.h185
-rw-r--r--tools/lib/util/find_next_bit.c89
-rw-r--r--tools/perf/MANIFEST16
-rw-r--r--tools/perf/Makefile.perf14
-rw-r--r--tools/perf/builtin-trace.c2
-rw-r--r--tools/perf/util/evlist.c46
-rw-r--r--tools/perf/util/include/linux/bitops.h162
-rw-r--r--tools/perf/util/symbol-minimal.c8
-rw-r--r--tools/perf/util/util.h29
17 files changed, 525 insertions, 207 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 */
12static __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
6static inline void set_bit(int nr, unsigned long *addr)
7{
8 addr[nr / __BITS_PER_LONG] |= 1UL << (nr % __BITS_PER_LONG);
9}
10
11static inline void clear_bit(int nr, unsigned long *addr)
12{
13 addr[nr / __BITS_PER_LONG] &= ~(1UL << (nr % __BITS_PER_LONG));
14}
15
16static __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 */
14extern 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 */
28extern 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
41static inline unsigned long hweight_long(unsigned long w)
42{
43 return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
44}
45
46static 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 */
18extern __attribute__((const, noreturn))
19int ____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 */
27static inline __attribute__((const))
28int __ilog2_u32(u32 n)
29{
30 return fls(n) - 1;
31}
32
33static inline __attribute__((const))
34int __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
44static inline __attribute__((const))
45bool 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 */
53static inline __attribute__((const))
54unsigned 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 */
62static inline __attribute__((const))
63unsigned 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/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 */
24unsigned 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
55found_first:
56 tmp &= (~0UL >> (BITS_PER_LONG - size));
57 if (tmp == 0UL) /* Are any bits set? */
58 return result + size; /* Nope. */
59found_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 */
68unsigned 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. */
86found:
87 return result + __ffs(tmp);
88}
89#endif
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
4tools/lib/api 4tools/lib/api
5tools/lib/symbol/kallsyms.c 5tools/lib/symbol/kallsyms.c
6tools/lib/symbol/kallsyms.h 6tools/lib/symbol/kallsyms.h
7tools/lib/util/find_next_bit.c
7tools/include/asm/bug.h 8tools/include/asm/bug.h
9tools/include/asm-generic/bitops/atomic.h
10tools/include/asm-generic/bitops/__ffs.h
11tools/include/asm-generic/bitops/__fls.h
12tools/include/asm-generic/bitops/find.h
13tools/include/asm-generic/bitops/fls64.h
14tools/include/asm-generic/bitops/fls.h
15tools/include/asm-generic/bitops.h
16tools/include/linux/bitops.h
8tools/include/linux/compiler.h 17tools/include/linux/compiler.h
9tools/include/linux/hash.h
10tools/include/linux/export.h 18tools/include/linux/export.h
19tools/include/linux/hash.h
20tools/include/linux/log2.h
11tools/include/linux/types.h 21tools/include/linux/types.h
22include/asm-generic/bitops/fls64.h
23include/asm-generic/bitops/__fls.h
24include/asm-generic/bitops/fls.h
12include/linux/const.h 25include/linux/const.h
13include/linux/perf_event.h 26include/linux/perf_event.h
14include/linux/rbtree.h 27include/linux/rbtree.h
15include/linux/list.h 28include/linux/list.h
16include/linux/hash.h 29include/linux/hash.h
17include/linux/stringify.h 30include/linux/stringify.h
31lib/find_next_bit.c
18lib/rbtree.c 32lib/rbtree.c
19include/linux/swab.h 33include/linux/swab.h
20arch/*/include/asm/unistd*.h 34arch/*/include/asm/unistd*.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 763e68fb5767..67a03a825b3c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -231,8 +231,16 @@ LIB_H += ../../include/uapi/linux/const.h
231LIB_H += ../include/linux/hash.h 231LIB_H += ../include/linux/hash.h
232LIB_H += ../../include/linux/stringify.h 232LIB_H += ../../include/linux/stringify.h
233LIB_H += util/include/linux/bitmap.h 233LIB_H += util/include/linux/bitmap.h
234LIB_H += util/include/linux/bitops.h 234LIB_H += ../include/linux/bitops.h
235LIB_H += ../include/asm-generic/bitops/atomic.h
236LIB_H += ../include/asm-generic/bitops/find.h
237LIB_H += ../include/asm-generic/bitops/fls64.h
238LIB_H += ../include/asm-generic/bitops/fls.h
239LIB_H += ../include/asm-generic/bitops/__ffs.h
240LIB_H += ../include/asm-generic/bitops/__fls.h
241LIB_H += ../include/asm-generic/bitops.h
235LIB_H += ../include/linux/compiler.h 242LIB_H += ../include/linux/compiler.h
243LIB_H += ../include/linux/log2.h
236LIB_H += util/include/linux/const.h 244LIB_H += util/include/linux/const.h
237LIB_H += util/include/linux/ctype.h 245LIB_H += util/include/linux/ctype.h
238LIB_H += util/include/linux/kernel.h 246LIB_H += util/include/linux/kernel.h
@@ -335,6 +343,7 @@ LIB_OBJS += $(OUTPUT)util/event.o
335LIB_OBJS += $(OUTPUT)util/evlist.o 343LIB_OBJS += $(OUTPUT)util/evlist.o
336LIB_OBJS += $(OUTPUT)util/evsel.o 344LIB_OBJS += $(OUTPUT)util/evsel.o
337LIB_OBJS += $(OUTPUT)util/exec_cmd.o 345LIB_OBJS += $(OUTPUT)util/exec_cmd.o
346LIB_OBJS += $(OUTPUT)util/find_next_bit.o
338LIB_OBJS += $(OUTPUT)util/help.o 347LIB_OBJS += $(OUTPUT)util/help.o
339LIB_OBJS += $(OUTPUT)util/kallsyms.o 348LIB_OBJS += $(OUTPUT)util/kallsyms.o
340LIB_OBJS += $(OUTPUT)util/levenshtein.o 349LIB_OBJS += $(OUTPUT)util/levenshtein.o
@@ -734,6 +743,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS
734$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS 743$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
735 $(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)"' $<
736 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
737$(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
738 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< 750 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
739 751
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 327541e43c7f..badfabc6a01f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -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/util/evlist.c b/tools/perf/util/evlist.c
index bb5dfc5d1e75..cbab1fb77b1d 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/bitops.h> 26#include <linux/bitops.h>
27#include <linux/hash.h> 27#include <linux/hash.h>
28#include <linux/log2.h>
28 29
29static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); 30static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
30static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); 31static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
@@ -893,10 +894,24 @@ out_unmap:
893 894
894static size_t perf_evlist__mmap_size(unsigned long pages) 895static size_t perf_evlist__mmap_size(unsigned long pages)
895{ 896{
896 /* 512 kiB: default amount of unprivileged mlocked memory */ 897 if (pages == UINT_MAX) {
897 if (pages == UINT_MAX) 898 int max;
898 pages = (512 * 1024) / page_size; 899
899 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))
900 return 0; 915 return 0;
901 916
902 return (pages + 1) * page_size; 917 return (pages + 1) * page_size;
@@ -933,7 +948,7 @@ static long parse_pages_arg(const char *str, unsigned long min,
933 /* leave number of pages at 0 */ 948 /* leave number of pages at 0 */
934 } else if (!is_power_of_2(pages)) { 949 } else if (!is_power_of_2(pages)) {
935 /* round pages up to next power of 2 */ 950 /* round pages up to next power of 2 */
936 pages = next_pow2_l(pages); 951 pages = roundup_pow_of_two(pages);
937 if (!pages) 952 if (!pages)
938 return -EINVAL; 953 return -EINVAL;
939 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",
@@ -1487,16 +1502,25 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
1487int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) 1502int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
1488{ 1503{
1489 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); 1504 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
1490 int value; 1505 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0;
1491 1506
1492 switch (err) { 1507 switch (err) {
1493 case EPERM: 1508 case EPERM:
1494 sysctl__read_int("kernel/perf_event_mlock_kb", &value); 1509 sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user);
1495 scnprintf(buf, size, "Error:\t%s.\n" 1510 printed += scnprintf(buf + printed, size - printed,
1511 "Error:\t%s.\n"
1496 "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" 1512 "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
1497 "Hint:\tTried using %zd kB.\n" 1513 "Hint:\tTried using %zd kB.\n",
1498 "Hint:\tTry using a bigger -m/--mmap-pages value.", 1514 emsg, pages_max_per_user, pages_attempted);
1499 emsg, value, evlist->mmap_len / 1024); 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.");
1500 break; 1524 break;
1501 default: 1525 default:
1502 scnprintf(buf, size, "%s", emsg); 1526 scnprintf(buf, size, "%s", emsg);
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
32static inline void set_bit(int nr, unsigned long *addr)
33{
34 addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
35}
36
37static inline void clear_bit(int nr, unsigned long *addr)
38{
39 addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
40}
41
42static __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
48static 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 */
61static __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
92typedef const unsigned long __attribute__((__may_alias__)) long_alias_t;
93
94/*
95 * Find the first set bit in a memory region.
96 */
97static inline unsigned long
98find_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. */
116found:
117 return result + __ffs(tmp);
118}
119
120/*
121 * Find the next set bit in a memory region.
122 */
123static inline unsigned long
124find_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
154found_first:
155 tmp &= (~0UL >> (BITS_PER_LONG - size));
156 if (tmp == 0UL) /* Are any bits set? */
157 return result + size; /* Nope. */
158found_middle:
159 return result + __ffs(tmp);
160}
161
162#endif
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.h b/tools/perf/util/util.h
index 008b361b1758..be198ac27031 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -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
277static inline __attribute__((const))
278bool is_power_of_2(unsigned long n)
279{
280 return (n != 0 && ((n & (n - 1)) == 0));
281}
282
283static inline unsigned next_pow2(unsigned x)
284{
285 if (!x)
286 return 1;
287 return 1ULL << (32 - __builtin_clz(x - 1));
288}
289
290static 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
301size_t hex_width(u64 v); 272size_t hex_width(u64 v);
302int hex2u64(const char *ptr, u64 *val); 273int hex2u64(const char *ptr, u64 *val);
303 274