mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 15:18:19 +00:00
perf/core improvements and fixes:
User visible: - 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: - 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> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJUkZsbAAoJEBpxZoYYoA71kRMIALWRoHarn5glw7/hQkLvYLzc rGnOp1MN07Fn/O7CagNDzIotYIzz0n/kGz4YaxFGS6ssmZqgQ8CraQM/XnyCpkyu PWB1HSTAONEyqAnO8/mm/KvQw4daMn82mYGx25X4E9XXtUvH4+al6xU7Om93omxT Mt/4Zgzrf5RL5fUvIs7CT+sk5CF67T5SDI7VuH55pbDeJkgGiHWbSwF+Jr5yafPd vRkHU5xYy+z8oSqb8NTo+ofDh0vJ1pifhvNncKtOBD3446D00XwUUwILy7HPLXFR MHT0+DiCPGRUnFnhT2gJl7oJMntp4DMAJvfJ3KC09e7yZ5BuU2R4mfNPg0INsfg= =6IJe -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
6aaba7c901
17 changed files with 525 additions and 207 deletions
27
tools/include/asm-generic/bitops.h
Normal file
27
tools/include/asm-generic/bitops.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef __TOOLS_ASM_GENERIC_BITOPS_H
|
||||||
|
#define __TOOLS_ASM_GENERIC_BITOPS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tools/ copied this from include/asm-generic/bitops.h, bit by bit as it needed
|
||||||
|
* some functions.
|
||||||
|
*
|
||||||
|
* For the benefit of those who are trying to port Linux to another
|
||||||
|
* architecture, here are some C-language equivalents. You should
|
||||||
|
* recode these in the native assembly language, if at all possible.
|
||||||
|
*
|
||||||
|
* C language equivalents written by Theodore Ts'o, 9/26/92
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm-generic/bitops/__ffs.h>
|
||||||
|
#include <asm-generic/bitops/fls.h>
|
||||||
|
#include <asm-generic/bitops/__fls.h>
|
||||||
|
#include <asm-generic/bitops/fls64.h>
|
||||||
|
#include <asm-generic/bitops/find.h>
|
||||||
|
|
||||||
|
#ifndef _TOOLS_LINUX_BITOPS_H_
|
||||||
|
#error only <linux/bitops.h> can be included directly
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <asm-generic/bitops/atomic.h>
|
||||||
|
|
||||||
|
#endif /* __TOOLS_ASM_GENERIC_BITOPS_H */
|
43
tools/include/asm-generic/bitops/__ffs.h
Normal file
43
tools/include/asm-generic/bitops/__ffs.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_
|
||||||
|
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_
|
||||||
|
|
||||||
|
#include <asm/types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __ffs - find first bit in word.
|
||||||
|
* @word: The word to search
|
||||||
|
*
|
||||||
|
* Undefined if no bit exists, so code should check against 0 first.
|
||||||
|
*/
|
||||||
|
static __always_inline unsigned long __ffs(unsigned long word)
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
#if __BITS_PER_LONG == 64
|
||||||
|
if ((word & 0xffffffff) == 0) {
|
||||||
|
num += 32;
|
||||||
|
word >>= 32;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((word & 0xffff) == 0) {
|
||||||
|
num += 16;
|
||||||
|
word >>= 16;
|
||||||
|
}
|
||||||
|
if ((word & 0xff) == 0) {
|
||||||
|
num += 8;
|
||||||
|
word >>= 8;
|
||||||
|
}
|
||||||
|
if ((word & 0xf) == 0) {
|
||||||
|
num += 4;
|
||||||
|
word >>= 4;
|
||||||
|
}
|
||||||
|
if ((word & 0x3) == 0) {
|
||||||
|
num += 2;
|
||||||
|
word >>= 2;
|
||||||
|
}
|
||||||
|
if ((word & 0x1) == 0)
|
||||||
|
num += 1;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ */
|
1
tools/include/asm-generic/bitops/__fls.h
Normal file
1
tools/include/asm-generic/bitops/__fls.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include <../../../../include/asm-generic/bitops/__fls.h>
|
22
tools/include/asm-generic/bitops/atomic.h
Normal file
22
tools/include/asm-generic/bitops/atomic.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_
|
||||||
|
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_
|
||||||
|
|
||||||
|
#include <asm/types.h>
|
||||||
|
|
||||||
|
static inline void set_bit(int nr, unsigned long *addr)
|
||||||
|
{
|
||||||
|
addr[nr / __BITS_PER_LONG] |= 1UL << (nr % __BITS_PER_LONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void clear_bit(int nr, unsigned long *addr)
|
||||||
|
{
|
||||||
|
addr[nr / __BITS_PER_LONG] &= ~(1UL << (nr % __BITS_PER_LONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
|
||||||
|
{
|
||||||
|
return ((1UL << (nr % __BITS_PER_LONG)) &
|
||||||
|
(((unsigned long *)addr)[nr / __BITS_PER_LONG])) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ */
|
33
tools/include/asm-generic/bitops/find.h
Normal file
33
tools/include/asm-generic/bitops/find.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
||||||
|
#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
|
||||||
|
|
||||||
|
#ifndef find_next_bit
|
||||||
|
/**
|
||||||
|
* find_next_bit - find the next set bit in a memory region
|
||||||
|
* @addr: The address to base the search on
|
||||||
|
* @offset: The bitnumber to start searching at
|
||||||
|
* @size: The bitmap size in bits
|
||||||
|
*
|
||||||
|
* Returns the bit number for the next set bit
|
||||||
|
* If no bits are set, returns @size.
|
||||||
|
*/
|
||||||
|
extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
|
||||||
|
size, unsigned long offset);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_first_bit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_first_bit - find the first set bit in a memory region
|
||||||
|
* @addr: The address to start the search at
|
||||||
|
* @size: The maximum number of bits to search
|
||||||
|
*
|
||||||
|
* Returns the bit number of the first set bit.
|
||||||
|
* If no bits are set, returns @size.
|
||||||
|
*/
|
||||||
|
extern unsigned long find_first_bit(const unsigned long *addr,
|
||||||
|
unsigned long size);
|
||||||
|
|
||||||
|
#endif /* find_first_bit */
|
||||||
|
|
||||||
|
#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
|
1
tools/include/asm-generic/bitops/fls.h
Normal file
1
tools/include/asm-generic/bitops/fls.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include <../../../../include/asm-generic/bitops/fls.h>
|
1
tools/include/asm-generic/bitops/fls64.h
Normal file
1
tools/include/asm-generic/bitops/fls64.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include <../../../../include/asm-generic/bitops/fls64.h>
|
53
tools/include/linux/bitops.h
Normal file
53
tools/include/linux/bitops.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef _TOOLS_LINUX_BITOPS_H_
|
||||||
|
#define _TOOLS_LINUX_BITOPS_H_
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <asm/hweight.h>
|
||||||
|
|
||||||
|
#ifndef __WORDSIZE
|
||||||
|
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BITS_PER_LONG __WORDSIZE
|
||||||
|
|
||||||
|
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
||||||
|
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||||
|
#define BITS_PER_BYTE 8
|
||||||
|
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
|
||||||
|
#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
|
||||||
|
#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
|
||||||
|
#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include this here because some architectures need generic_ffs/fls in
|
||||||
|
* scope
|
||||||
|
*
|
||||||
|
* XXX: this needs to be asm/bitops.h, when we get to per arch optimizations
|
||||||
|
*/
|
||||||
|
#include <asm-generic/bitops.h>
|
||||||
|
|
||||||
|
#define for_each_set_bit(bit, addr, size) \
|
||||||
|
for ((bit) = find_first_bit((addr), (size)); \
|
||||||
|
(bit) < (size); \
|
||||||
|
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||||
|
|
||||||
|
/* same as for_each_set_bit() but use bit as value to start with */
|
||||||
|
#define for_each_set_bit_from(bit, addr, size) \
|
||||||
|
for ((bit) = find_next_bit((addr), (size), (bit)); \
|
||||||
|
(bit) < (size); \
|
||||||
|
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
||||||
|
|
||||||
|
static inline unsigned long hweight_long(unsigned long w)
|
||||||
|
{
|
||||||
|
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned fls_long(unsigned long l)
|
||||||
|
{
|
||||||
|
if (sizeof(l) == 4)
|
||||||
|
return fls(l);
|
||||||
|
return fls64(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
185
tools/include/linux/log2.h
Normal file
185
tools/include/linux/log2.h
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
/* Integer base 2 logarithm calculation
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TOOLS_LINUX_LOG2_H
|
||||||
|
#define _TOOLS_LINUX_LOG2_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* deal with unrepresentable constant logarithms
|
||||||
|
*/
|
||||||
|
extern __attribute__((const, noreturn))
|
||||||
|
int ____ilog2_NaN(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* non-constant log of base 2 calculators
|
||||||
|
* - the arch may override these in asm/bitops.h if they can be implemented
|
||||||
|
* more efficiently than using fls() and fls64()
|
||||||
|
* - the arch is not required to handle n==0 if implementing the fallback
|
||||||
|
*/
|
||||||
|
static inline __attribute__((const))
|
||||||
|
int __ilog2_u32(u32 n)
|
||||||
|
{
|
||||||
|
return fls(n) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((const))
|
||||||
|
int __ilog2_u64(u64 n)
|
||||||
|
{
|
||||||
|
return fls64(n) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine whether some value is a power of two, where zero is
|
||||||
|
* *not* considered a power of two.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline __attribute__((const))
|
||||||
|
bool is_power_of_2(unsigned long n)
|
||||||
|
{
|
||||||
|
return (n != 0 && ((n & (n - 1)) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* round up to nearest power of two
|
||||||
|
*/
|
||||||
|
static inline __attribute__((const))
|
||||||
|
unsigned long __roundup_pow_of_two(unsigned long n)
|
||||||
|
{
|
||||||
|
return 1UL << fls_long(n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* round down to nearest power of two
|
||||||
|
*/
|
||||||
|
static inline __attribute__((const))
|
||||||
|
unsigned long __rounddown_pow_of_two(unsigned long n)
|
||||||
|
{
|
||||||
|
return 1UL << (fls_long(n) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
|
||||||
|
* @n - parameter
|
||||||
|
*
|
||||||
|
* constant-capable log of base 2 calculation
|
||||||
|
* - this can be used to initialise global variables from constant data, hence
|
||||||
|
* the massive ternary operator construction
|
||||||
|
*
|
||||||
|
* selects the appropriately-sized optimised version depending on sizeof(n)
|
||||||
|
*/
|
||||||
|
#define ilog2(n) \
|
||||||
|
( \
|
||||||
|
__builtin_constant_p(n) ? ( \
|
||||||
|
(n) < 1 ? ____ilog2_NaN() : \
|
||||||
|
(n) & (1ULL << 63) ? 63 : \
|
||||||
|
(n) & (1ULL << 62) ? 62 : \
|
||||||
|
(n) & (1ULL << 61) ? 61 : \
|
||||||
|
(n) & (1ULL << 60) ? 60 : \
|
||||||
|
(n) & (1ULL << 59) ? 59 : \
|
||||||
|
(n) & (1ULL << 58) ? 58 : \
|
||||||
|
(n) & (1ULL << 57) ? 57 : \
|
||||||
|
(n) & (1ULL << 56) ? 56 : \
|
||||||
|
(n) & (1ULL << 55) ? 55 : \
|
||||||
|
(n) & (1ULL << 54) ? 54 : \
|
||||||
|
(n) & (1ULL << 53) ? 53 : \
|
||||||
|
(n) & (1ULL << 52) ? 52 : \
|
||||||
|
(n) & (1ULL << 51) ? 51 : \
|
||||||
|
(n) & (1ULL << 50) ? 50 : \
|
||||||
|
(n) & (1ULL << 49) ? 49 : \
|
||||||
|
(n) & (1ULL << 48) ? 48 : \
|
||||||
|
(n) & (1ULL << 47) ? 47 : \
|
||||||
|
(n) & (1ULL << 46) ? 46 : \
|
||||||
|
(n) & (1ULL << 45) ? 45 : \
|
||||||
|
(n) & (1ULL << 44) ? 44 : \
|
||||||
|
(n) & (1ULL << 43) ? 43 : \
|
||||||
|
(n) & (1ULL << 42) ? 42 : \
|
||||||
|
(n) & (1ULL << 41) ? 41 : \
|
||||||
|
(n) & (1ULL << 40) ? 40 : \
|
||||||
|
(n) & (1ULL << 39) ? 39 : \
|
||||||
|
(n) & (1ULL << 38) ? 38 : \
|
||||||
|
(n) & (1ULL << 37) ? 37 : \
|
||||||
|
(n) & (1ULL << 36) ? 36 : \
|
||||||
|
(n) & (1ULL << 35) ? 35 : \
|
||||||
|
(n) & (1ULL << 34) ? 34 : \
|
||||||
|
(n) & (1ULL << 33) ? 33 : \
|
||||||
|
(n) & (1ULL << 32) ? 32 : \
|
||||||
|
(n) & (1ULL << 31) ? 31 : \
|
||||||
|
(n) & (1ULL << 30) ? 30 : \
|
||||||
|
(n) & (1ULL << 29) ? 29 : \
|
||||||
|
(n) & (1ULL << 28) ? 28 : \
|
||||||
|
(n) & (1ULL << 27) ? 27 : \
|
||||||
|
(n) & (1ULL << 26) ? 26 : \
|
||||||
|
(n) & (1ULL << 25) ? 25 : \
|
||||||
|
(n) & (1ULL << 24) ? 24 : \
|
||||||
|
(n) & (1ULL << 23) ? 23 : \
|
||||||
|
(n) & (1ULL << 22) ? 22 : \
|
||||||
|
(n) & (1ULL << 21) ? 21 : \
|
||||||
|
(n) & (1ULL << 20) ? 20 : \
|
||||||
|
(n) & (1ULL << 19) ? 19 : \
|
||||||
|
(n) & (1ULL << 18) ? 18 : \
|
||||||
|
(n) & (1ULL << 17) ? 17 : \
|
||||||
|
(n) & (1ULL << 16) ? 16 : \
|
||||||
|
(n) & (1ULL << 15) ? 15 : \
|
||||||
|
(n) & (1ULL << 14) ? 14 : \
|
||||||
|
(n) & (1ULL << 13) ? 13 : \
|
||||||
|
(n) & (1ULL << 12) ? 12 : \
|
||||||
|
(n) & (1ULL << 11) ? 11 : \
|
||||||
|
(n) & (1ULL << 10) ? 10 : \
|
||||||
|
(n) & (1ULL << 9) ? 9 : \
|
||||||
|
(n) & (1ULL << 8) ? 8 : \
|
||||||
|
(n) & (1ULL << 7) ? 7 : \
|
||||||
|
(n) & (1ULL << 6) ? 6 : \
|
||||||
|
(n) & (1ULL << 5) ? 5 : \
|
||||||
|
(n) & (1ULL << 4) ? 4 : \
|
||||||
|
(n) & (1ULL << 3) ? 3 : \
|
||||||
|
(n) & (1ULL << 2) ? 2 : \
|
||||||
|
(n) & (1ULL << 1) ? 1 : \
|
||||||
|
(n) & (1ULL << 0) ? 0 : \
|
||||||
|
____ilog2_NaN() \
|
||||||
|
) : \
|
||||||
|
(sizeof(n) <= 4) ? \
|
||||||
|
__ilog2_u32(n) : \
|
||||||
|
__ilog2_u64(n) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* roundup_pow_of_two - round the given value up to nearest power of two
|
||||||
|
* @n - parameter
|
||||||
|
*
|
||||||
|
* round the given value up to the nearest power of two
|
||||||
|
* - the result is undefined when n == 0
|
||||||
|
* - this can be used to initialise global variables from constant data
|
||||||
|
*/
|
||||||
|
#define roundup_pow_of_two(n) \
|
||||||
|
( \
|
||||||
|
__builtin_constant_p(n) ? ( \
|
||||||
|
(n == 1) ? 1 : \
|
||||||
|
(1UL << (ilog2((n) - 1) + 1)) \
|
||||||
|
) : \
|
||||||
|
__roundup_pow_of_two(n) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rounddown_pow_of_two - round the given value down to nearest power of two
|
||||||
|
* @n - parameter
|
||||||
|
*
|
||||||
|
* round the given value down to the nearest power of two
|
||||||
|
* - the result is undefined when n == 0
|
||||||
|
* - this can be used to initialise global variables from constant data
|
||||||
|
*/
|
||||||
|
#define rounddown_pow_of_two(n) \
|
||||||
|
( \
|
||||||
|
__builtin_constant_p(n) ? ( \
|
||||||
|
(1UL << ilog2(n))) : \
|
||||||
|
__rounddown_pow_of_two(n) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#endif /* _TOOLS_LINUX_LOG2_H */
|
89
tools/lib/util/find_next_bit.c
Normal file
89
tools/lib/util/find_next_bit.c
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/* find_next_bit.c: fallback find next bit implementation
|
||||||
|
*
|
||||||
|
* Copied from lib/find_next_bit.c to tools/lib/next_bit.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
|
||||||
|
|
||||||
|
#ifndef find_next_bit
|
||||||
|
/*
|
||||||
|
* Find the next set bit in a memory region.
|
||||||
|
*/
|
||||||
|
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||||
|
unsigned long offset)
|
||||||
|
{
|
||||||
|
const unsigned long *p = addr + BITOP_WORD(offset);
|
||||||
|
unsigned long result = offset & ~(BITS_PER_LONG-1);
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
if (offset >= size)
|
||||||
|
return size;
|
||||||
|
size -= result;
|
||||||
|
offset %= BITS_PER_LONG;
|
||||||
|
if (offset) {
|
||||||
|
tmp = *(p++);
|
||||||
|
tmp &= (~0UL << offset);
|
||||||
|
if (size < BITS_PER_LONG)
|
||||||
|
goto found_first;
|
||||||
|
if (tmp)
|
||||||
|
goto found_middle;
|
||||||
|
size -= BITS_PER_LONG;
|
||||||
|
result += BITS_PER_LONG;
|
||||||
|
}
|
||||||
|
while (size & ~(BITS_PER_LONG-1)) {
|
||||||
|
if ((tmp = *(p++)))
|
||||||
|
goto found_middle;
|
||||||
|
result += BITS_PER_LONG;
|
||||||
|
size -= BITS_PER_LONG;
|
||||||
|
}
|
||||||
|
if (!size)
|
||||||
|
return result;
|
||||||
|
tmp = *p;
|
||||||
|
|
||||||
|
found_first:
|
||||||
|
tmp &= (~0UL >> (BITS_PER_LONG - size));
|
||||||
|
if (tmp == 0UL) /* Are any bits set? */
|
||||||
|
return result + size; /* Nope. */
|
||||||
|
found_middle:
|
||||||
|
return result + __ffs(tmp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef find_first_bit
|
||||||
|
/*
|
||||||
|
* Find the first set bit in a memory region.
|
||||||
|
*/
|
||||||
|
unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
|
||||||
|
{
|
||||||
|
const unsigned long *p = addr;
|
||||||
|
unsigned long result = 0;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
while (size & ~(BITS_PER_LONG-1)) {
|
||||||
|
if ((tmp = *(p++)))
|
||||||
|
goto found;
|
||||||
|
result += BITS_PER_LONG;
|
||||||
|
size -= BITS_PER_LONG;
|
||||||
|
}
|
||||||
|
if (!size)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
|
||||||
|
if (tmp == 0UL) /* Are any bits set? */
|
||||||
|
return result + size; /* Nope. */
|
||||||
|
found:
|
||||||
|
return result + __ffs(tmp);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -4,17 +4,31 @@ tools/lib/traceevent
|
||||||
tools/lib/api
|
tools/lib/api
|
||||||
tools/lib/symbol/kallsyms.c
|
tools/lib/symbol/kallsyms.c
|
||||||
tools/lib/symbol/kallsyms.h
|
tools/lib/symbol/kallsyms.h
|
||||||
|
tools/lib/util/find_next_bit.c
|
||||||
tools/include/asm/bug.h
|
tools/include/asm/bug.h
|
||||||
|
tools/include/asm-generic/bitops/atomic.h
|
||||||
|
tools/include/asm-generic/bitops/__ffs.h
|
||||||
|
tools/include/asm-generic/bitops/__fls.h
|
||||||
|
tools/include/asm-generic/bitops/find.h
|
||||||
|
tools/include/asm-generic/bitops/fls64.h
|
||||||
|
tools/include/asm-generic/bitops/fls.h
|
||||||
|
tools/include/asm-generic/bitops.h
|
||||||
|
tools/include/linux/bitops.h
|
||||||
tools/include/linux/compiler.h
|
tools/include/linux/compiler.h
|
||||||
tools/include/linux/hash.h
|
|
||||||
tools/include/linux/export.h
|
tools/include/linux/export.h
|
||||||
|
tools/include/linux/hash.h
|
||||||
|
tools/include/linux/log2.h
|
||||||
tools/include/linux/types.h
|
tools/include/linux/types.h
|
||||||
|
include/asm-generic/bitops/fls64.h
|
||||||
|
include/asm-generic/bitops/__fls.h
|
||||||
|
include/asm-generic/bitops/fls.h
|
||||||
include/linux/const.h
|
include/linux/const.h
|
||||||
include/linux/perf_event.h
|
include/linux/perf_event.h
|
||||||
include/linux/rbtree.h
|
include/linux/rbtree.h
|
||||||
include/linux/list.h
|
include/linux/list.h
|
||||||
include/linux/hash.h
|
include/linux/hash.h
|
||||||
include/linux/stringify.h
|
include/linux/stringify.h
|
||||||
|
lib/find_next_bit.c
|
||||||
lib/rbtree.c
|
lib/rbtree.c
|
||||||
include/linux/swab.h
|
include/linux/swab.h
|
||||||
arch/*/include/asm/unistd*.h
|
arch/*/include/asm/unistd*.h
|
||||||
|
|
|
@ -231,8 +231,16 @@ LIB_H += ../../include/uapi/linux/const.h
|
||||||
LIB_H += ../include/linux/hash.h
|
LIB_H += ../include/linux/hash.h
|
||||||
LIB_H += ../../include/linux/stringify.h
|
LIB_H += ../../include/linux/stringify.h
|
||||||
LIB_H += util/include/linux/bitmap.h
|
LIB_H += util/include/linux/bitmap.h
|
||||||
LIB_H += util/include/linux/bitops.h
|
LIB_H += ../include/linux/bitops.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops/atomic.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops/find.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops/fls64.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops/fls.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops/__ffs.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops/__fls.h
|
||||||
|
LIB_H += ../include/asm-generic/bitops.h
|
||||||
LIB_H += ../include/linux/compiler.h
|
LIB_H += ../include/linux/compiler.h
|
||||||
|
LIB_H += ../include/linux/log2.h
|
||||||
LIB_H += util/include/linux/const.h
|
LIB_H += util/include/linux/const.h
|
||||||
LIB_H += util/include/linux/ctype.h
|
LIB_H += util/include/linux/ctype.h
|
||||||
LIB_H += util/include/linux/kernel.h
|
LIB_H += util/include/linux/kernel.h
|
||||||
|
@ -335,6 +343,7 @@ LIB_OBJS += $(OUTPUT)util/event.o
|
||||||
LIB_OBJS += $(OUTPUT)util/evlist.o
|
LIB_OBJS += $(OUTPUT)util/evlist.o
|
||||||
LIB_OBJS += $(OUTPUT)util/evsel.o
|
LIB_OBJS += $(OUTPUT)util/evsel.o
|
||||||
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
|
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
|
||||||
|
LIB_OBJS += $(OUTPUT)util/find_next_bit.o
|
||||||
LIB_OBJS += $(OUTPUT)util/help.o
|
LIB_OBJS += $(OUTPUT)util/help.o
|
||||||
LIB_OBJS += $(OUTPUT)util/kallsyms.o
|
LIB_OBJS += $(OUTPUT)util/kallsyms.o
|
||||||
LIB_OBJS += $(OUTPUT)util/levenshtein.o
|
LIB_OBJS += $(OUTPUT)util/levenshtein.o
|
||||||
|
@ -734,6 +743,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS
|
||||||
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
|
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
|
||||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
||||||
|
|
||||||
|
$(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS
|
||||||
|
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
||||||
|
|
||||||
$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
|
$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
|
||||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
|
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
|
||||||
|
|
||||||
|
|
|
@ -2485,7 +2485,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
.user_freq = UINT_MAX,
|
.user_freq = UINT_MAX,
|
||||||
.user_interval = ULLONG_MAX,
|
.user_interval = ULLONG_MAX,
|
||||||
.no_buffering = true,
|
.no_buffering = true,
|
||||||
.mmap_pages = 1024,
|
.mmap_pages = UINT_MAX,
|
||||||
},
|
},
|
||||||
.output = stdout,
|
.output = stdout,
|
||||||
.show_comm = true,
|
.show_comm = true,
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/hash.h>
|
#include <linux/hash.h>
|
||||||
|
#include <linux/log2.h>
|
||||||
|
|
||||||
static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
|
static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
|
||||||
static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
|
static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
|
||||||
|
@ -893,10 +894,24 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist,
|
||||||
|
|
||||||
static size_t perf_evlist__mmap_size(unsigned long pages)
|
static size_t perf_evlist__mmap_size(unsigned long pages)
|
||||||
{
|
{
|
||||||
/* 512 kiB: default amount of unprivileged mlocked memory */
|
if (pages == UINT_MAX) {
|
||||||
if (pages == UINT_MAX)
|
int max;
|
||||||
pages = (512 * 1024) / page_size;
|
|
||||||
else if (!is_power_of_2(pages))
|
if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
|
||||||
|
/*
|
||||||
|
* Pick a once upon a time good value, i.e. things look
|
||||||
|
* strange since we can't read a sysctl value, but lets not
|
||||||
|
* die yet...
|
||||||
|
*/
|
||||||
|
max = 512;
|
||||||
|
} else {
|
||||||
|
max -= (page_size / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
pages = (max * 1024) / page_size;
|
||||||
|
if (!is_power_of_2(pages))
|
||||||
|
pages = rounddown_pow_of_two(pages);
|
||||||
|
} else if (!is_power_of_2(pages))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (pages + 1) * page_size;
|
return (pages + 1) * page_size;
|
||||||
|
@ -933,7 +948,7 @@ static long parse_pages_arg(const char *str, unsigned long min,
|
||||||
/* leave number of pages at 0 */
|
/* leave number of pages at 0 */
|
||||||
} else if (!is_power_of_2(pages)) {
|
} else if (!is_power_of_2(pages)) {
|
||||||
/* round pages up to next power of 2 */
|
/* round pages up to next power of 2 */
|
||||||
pages = next_pow2_l(pages);
|
pages = roundup_pow_of_two(pages);
|
||||||
if (!pages)
|
if (!pages)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
|
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,
|
||||||
int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
|
int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
|
char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
|
||||||
int value;
|
int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0;
|
||||||
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case EPERM:
|
case EPERM:
|
||||||
sysctl__read_int("kernel/perf_event_mlock_kb", &value);
|
sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user);
|
||||||
scnprintf(buf, size, "Error:\t%s.\n"
|
printed += scnprintf(buf + printed, size - printed,
|
||||||
|
"Error:\t%s.\n"
|
||||||
"Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
|
"Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
|
||||||
"Hint:\tTried using %zd kB.\n"
|
"Hint:\tTried using %zd kB.\n",
|
||||||
"Hint:\tTry using a bigger -m/--mmap-pages value.",
|
emsg, pages_max_per_user, pages_attempted);
|
||||||
emsg, value, evlist->mmap_len / 1024);
|
|
||||||
|
if (pages_attempted >= pages_max_per_user) {
|
||||||
|
printed += scnprintf(buf + printed, size - printed,
|
||||||
|
"Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n",
|
||||||
|
pages_max_per_user + pages_attempted);
|
||||||
|
}
|
||||||
|
|
||||||
|
printed += scnprintf(buf + printed, size - printed,
|
||||||
|
"Hint:\tTry using a smaller -m/--mmap-pages value.");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scnprintf(buf, size, "%s", emsg);
|
scnprintf(buf, size, "%s", emsg);
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
#ifndef _PERF_LINUX_BITOPS_H_
|
|
||||||
#define _PERF_LINUX_BITOPS_H_
|
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <asm/hweight.h>
|
|
||||||
|
|
||||||
#ifndef __WORDSIZE
|
|
||||||
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BITS_PER_LONG __WORDSIZE
|
|
||||||
#define BITS_PER_BYTE 8
|
|
||||||
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
|
|
||||||
#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
|
|
||||||
#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
|
|
||||||
#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE)
|
|
||||||
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
|
|
||||||
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
|
||||||
|
|
||||||
#define for_each_set_bit(bit, addr, size) \
|
|
||||||
for ((bit) = find_first_bit((addr), (size)); \
|
|
||||||
(bit) < (size); \
|
|
||||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
|
||||||
|
|
||||||
/* same as for_each_set_bit() but use bit as value to start with */
|
|
||||||
#define for_each_set_bit_from(bit, addr, size) \
|
|
||||||
for ((bit) = find_next_bit((addr), (size), (bit)); \
|
|
||||||
(bit) < (size); \
|
|
||||||
(bit) = find_next_bit((addr), (size), (bit) + 1))
|
|
||||||
|
|
||||||
static inline void set_bit(int nr, unsigned long *addr)
|
|
||||||
{
|
|
||||||
addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clear_bit(int nr, unsigned long *addr)
|
|
||||||
{
|
|
||||||
addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
|
|
||||||
}
|
|
||||||
|
|
||||||
static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
|
|
||||||
{
|
|
||||||
return ((1UL << (nr % BITS_PER_LONG)) &
|
|
||||||
(((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long hweight_long(unsigned long w)
|
|
||||||
{
|
|
||||||
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __ffs - find first bit in word.
|
|
||||||
* @word: The word to search
|
|
||||||
*
|
|
||||||
* Undefined if no bit exists, so code should check against 0 first.
|
|
||||||
*/
|
|
||||||
static __always_inline unsigned long __ffs(unsigned long word)
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
|
|
||||||
#if BITS_PER_LONG == 64
|
|
||||||
if ((word & 0xffffffff) == 0) {
|
|
||||||
num += 32;
|
|
||||||
word >>= 32;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ((word & 0xffff) == 0) {
|
|
||||||
num += 16;
|
|
||||||
word >>= 16;
|
|
||||||
}
|
|
||||||
if ((word & 0xff) == 0) {
|
|
||||||
num += 8;
|
|
||||||
word >>= 8;
|
|
||||||
}
|
|
||||||
if ((word & 0xf) == 0) {
|
|
||||||
num += 4;
|
|
||||||
word >>= 4;
|
|
||||||
}
|
|
||||||
if ((word & 0x3) == 0) {
|
|
||||||
num += 2;
|
|
||||||
word >>= 2;
|
|
||||||
}
|
|
||||||
if ((word & 0x1) == 0)
|
|
||||||
num += 1;
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef const unsigned long __attribute__((__may_alias__)) long_alias_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the first set bit in a memory region.
|
|
||||||
*/
|
|
||||||
static inline unsigned long
|
|
||||||
find_first_bit(const unsigned long *addr, unsigned long size)
|
|
||||||
{
|
|
||||||
long_alias_t *p = (long_alias_t *) addr;
|
|
||||||
unsigned long result = 0;
|
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
while (size & ~(BITS_PER_LONG-1)) {
|
|
||||||
if ((tmp = *(p++)))
|
|
||||||
goto found;
|
|
||||||
result += BITS_PER_LONG;
|
|
||||||
size -= BITS_PER_LONG;
|
|
||||||
}
|
|
||||||
if (!size)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
|
|
||||||
if (tmp == 0UL) /* Are any bits set? */
|
|
||||||
return result + size; /* Nope. */
|
|
||||||
found:
|
|
||||||
return result + __ffs(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the next set bit in a memory region.
|
|
||||||
*/
|
|
||||||
static inline unsigned long
|
|
||||||
find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
|
|
||||||
{
|
|
||||||
const unsigned long *p = addr + BITOP_WORD(offset);
|
|
||||||
unsigned long result = offset & ~(BITS_PER_LONG-1);
|
|
||||||
unsigned long tmp;
|
|
||||||
|
|
||||||
if (offset >= size)
|
|
||||||
return size;
|
|
||||||
size -= result;
|
|
||||||
offset %= BITS_PER_LONG;
|
|
||||||
if (offset) {
|
|
||||||
tmp = *(p++);
|
|
||||||
tmp &= (~0UL << offset);
|
|
||||||
if (size < BITS_PER_LONG)
|
|
||||||
goto found_first;
|
|
||||||
if (tmp)
|
|
||||||
goto found_middle;
|
|
||||||
size -= BITS_PER_LONG;
|
|
||||||
result += BITS_PER_LONG;
|
|
||||||
}
|
|
||||||
while (size & ~(BITS_PER_LONG-1)) {
|
|
||||||
if ((tmp = *(p++)))
|
|
||||||
goto found_middle;
|
|
||||||
result += BITS_PER_LONG;
|
|
||||||
size -= BITS_PER_LONG;
|
|
||||||
}
|
|
||||||
if (!size)
|
|
||||||
return result;
|
|
||||||
tmp = *p;
|
|
||||||
|
|
||||||
found_first:
|
|
||||||
tmp &= (~0UL >> (BITS_PER_LONG - size));
|
|
||||||
if (tmp == 0UL) /* Are any bits set? */
|
|
||||||
return result + size; /* Nope. */
|
|
||||||
found_middle:
|
|
||||||
return result + __ffs(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -129,6 +129,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
|
||||||
|
|
||||||
for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
|
for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
long offset;
|
||||||
|
|
||||||
if (need_swap) {
|
if (need_swap) {
|
||||||
phdr->p_type = bswap_32(phdr->p_type);
|
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)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
buf_size = phdr->p_filesz;
|
buf_size = phdr->p_filesz;
|
||||||
|
offset = phdr->p_offset;
|
||||||
tmp = realloc(buf, buf_size);
|
tmp = realloc(buf, buf_size);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
buf = tmp;
|
buf = tmp;
|
||||||
fseek(fp, phdr->p_offset, SEEK_SET);
|
fseek(fp, offset, SEEK_SET);
|
||||||
if (fread(buf, buf_size, 1, fp) != 1)
|
if (fread(buf, buf_size, 1, fp) != 1)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
@ -178,6 +180,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
|
||||||
|
|
||||||
for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
|
for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
|
||||||
void *tmp;
|
void *tmp;
|
||||||
|
long offset;
|
||||||
|
|
||||||
if (need_swap) {
|
if (need_swap) {
|
||||||
phdr->p_type = bswap_32(phdr->p_type);
|
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)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
buf_size = phdr->p_filesz;
|
buf_size = phdr->p_filesz;
|
||||||
|
offset = phdr->p_offset;
|
||||||
tmp = realloc(buf, buf_size);
|
tmp = realloc(buf, buf_size);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
buf = tmp;
|
buf = tmp;
|
||||||
fseek(fp, phdr->p_offset, SEEK_SET);
|
fseek(fp, offset, SEEK_SET);
|
||||||
if (fread(buf, buf_size, 1, fp) != 1)
|
if (fread(buf, buf_size, 1, fp) != 1)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
|
|
@ -269,35 +269,6 @@ void event_attr_init(struct perf_event_attr *attr);
|
||||||
#define _STR(x) #x
|
#define _STR(x) #x
|
||||||
#define STR(x) _STR(x)
|
#define STR(x) _STR(x)
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine whether some value is a power of two, where zero is
|
|
||||||
* *not* considered a power of two.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline __attribute__((const))
|
|
||||||
bool is_power_of_2(unsigned long n)
|
|
||||||
{
|
|
||||||
return (n != 0 && ((n & (n - 1)) == 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned next_pow2(unsigned x)
|
|
||||||
{
|
|
||||||
if (!x)
|
|
||||||
return 1;
|
|
||||||
return 1ULL << (32 - __builtin_clz(x - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned long next_pow2_l(unsigned long x)
|
|
||||||
{
|
|
||||||
#if BITS_PER_LONG == 64
|
|
||||||
if (x <= (1UL << 31))
|
|
||||||
return next_pow2(x);
|
|
||||||
return (unsigned long)next_pow2(x >> 32) << 32;
|
|
||||||
#else
|
|
||||||
return next_pow2(x);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t hex_width(u64 v);
|
size_t hex_width(u64 v);
|
||||||
int hex2u64(const char *ptr, u64 *val);
|
int hex2u64(const char *ptr, u64 *val);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue