Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull more perf updates from Ingo Molnar: "The only kernel change is comment typo fixes. The rest is mostly tooling fixes, but also new vendor event additions and updates, a bigger libperf/libtraceevent library and a header files reorganization that came in a bit late" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (108 commits) perf unwind: Fix libunwind build failure on i386 systems perf parser: Remove needless include directives perf build: Add detection of java-11-openjdk-devel package perf jvmti: Include JVMTI support for s390 perf vendor events: Remove P8 HW events which are not supported perf evlist: Fix access of freed id arrays perf stat: Fix free memory access / memory leaks in metrics perf tools: Replace needless mmap.h with what is needed, event.h perf evsel: Move config terms to a separate header perf evlist: Remove unused perf_evlist__fprintf() method perf evsel: Introduce evsel_fprintf.h perf evsel: Remove need for symbol_conf in evsel_fprintf.c perf copyfile: Move copyfile routines to separate files libperf: Add perf_evlist__poll() function libperf: Add perf_evlist__add_pollfd() function libperf: Add perf_evlist__alloc_pollfd() function libperf: Add libperf_init() call to the tests libperf: Merge libperf_set_print() into libperf_init() libperf: Add libperf dependency for tests targets libperf: Use sys/types.h to get ssize_t, not unistd.h ...
This commit is contained in:
@@ -2239,7 +2239,7 @@ static void __perf_event_disable(struct perf_event *event,
|
|||||||
*
|
*
|
||||||
* If event->ctx is a cloned context, callers must make sure that
|
* If event->ctx is a cloned context, callers must make sure that
|
||||||
* every task struct that event->ctx->task could possibly point to
|
* every task struct that event->ctx->task could possibly point to
|
||||||
* remains valid. This condition is satisifed when called through
|
* remains valid. This condition is satisfied when called through
|
||||||
* perf_event_for_each_child or perf_event_for_each because they
|
* perf_event_for_each_child or perf_event_for_each because they
|
||||||
* hold the top-level event's child_mutex, so any descendant that
|
* hold the top-level event's child_mutex, so any descendant that
|
||||||
* goes to exit will block in perf_event_exit_event().
|
* goes to exit will block in perf_event_exit_event().
|
||||||
@@ -6054,7 +6054,7 @@ static void perf_sample_regs_intr(struct perf_regs *regs_intr,
|
|||||||
* Get remaining task size from user stack pointer.
|
* Get remaining task size from user stack pointer.
|
||||||
*
|
*
|
||||||
* It'd be better to take stack vma map and limit this more
|
* It'd be better to take stack vma map and limit this more
|
||||||
* precisly, but there's no way to get it safely under interrupt,
|
* precisely, but there's no way to get it safely under interrupt,
|
||||||
* so using TASK_SIZE as limit.
|
* so using TASK_SIZE as limit.
|
||||||
*/
|
*/
|
||||||
static u64 perf_ustack_task_size(struct pt_regs *regs)
|
static u64 perf_ustack_task_size(struct pt_regs *regs)
|
||||||
@@ -6616,7 +6616,7 @@ void perf_prepare_sample(struct perf_event_header *header,
|
|||||||
|
|
||||||
if (sample_type & PERF_SAMPLE_STACK_USER) {
|
if (sample_type & PERF_SAMPLE_STACK_USER) {
|
||||||
/*
|
/*
|
||||||
* Either we need PERF_SAMPLE_STACK_USER bit to be allways
|
* Either we need PERF_SAMPLE_STACK_USER bit to be always
|
||||||
* processed as the last one or have additional check added
|
* processed as the last one or have additional check added
|
||||||
* in case new sample type is added, because we could eat
|
* in case new sample type is added, because we could eat
|
||||||
* up the rest of the sample size.
|
* up the rest of the sample size.
|
||||||
|
@@ -231,6 +231,8 @@
|
|||||||
#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer VMMCALL to VMCALL */
|
#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer VMMCALL to VMCALL */
|
||||||
#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
|
#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */
|
||||||
#define X86_FEATURE_EPT_AD ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
|
#define X86_FEATURE_EPT_AD ( 8*32+17) /* Intel Extended Page Table access-dirty bit */
|
||||||
|
#define X86_FEATURE_VMCALL ( 8*32+18) /* "" Hypervisor supports the VMCALL instruction */
|
||||||
|
#define X86_FEATURE_VMW_VMMCALL ( 8*32+19) /* "" VMware prefers VMMCALL hypercall instruction */
|
||||||
|
|
||||||
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
|
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EBX), word 9 */
|
||||||
#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
|
#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions*/
|
||||||
@@ -354,6 +356,7 @@
|
|||||||
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
|
/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
|
||||||
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
|
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
|
||||||
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
|
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
|
||||||
|
#define X86_FEATURE_AVX512_VP2INTERSECT (18*32+ 8) /* AVX-512 Intersect for D/Q */
|
||||||
#define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */
|
#define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */
|
||||||
#define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
|
#define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
|
||||||
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
|
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
#define _UAPI_ASM_X86_UNISTD_H
|
#define _UAPI_ASM_X86_UNISTD_H
|
||||||
|
|
||||||
/* x32 syscall flag bit */
|
/* x32 syscall flag bit */
|
||||||
#define __X32_SYSCALL_BIT 0x40000000
|
#define __X32_SYSCALL_BIT 0x40000000UL
|
||||||
|
|
||||||
#ifndef __KERNEL__
|
#ifndef __KERNEL__
|
||||||
# ifdef __i386__
|
# ifdef __i386__
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#define _TOOLS_ASM_BUG_H
|
#define _TOOLS_ASM_BUG_H
|
||||||
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0)
|
#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0)
|
||||||
|
|
||||||
|
@@ -569,7 +569,7 @@ __SYSCALL(__NR_semget, sys_semget)
|
|||||||
__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
|
__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
|
||||||
#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
|
#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
|
||||||
#define __NR_semtimedop 192
|
#define __NR_semtimedop 192
|
||||||
__SC_COMP(__NR_semtimedop, sys_semtimedop, sys_semtimedop_time32)
|
__SC_3264(__NR_semtimedop, sys_semtimedop_time32, sys_semtimedop)
|
||||||
#endif
|
#endif
|
||||||
#define __NR_semop 193
|
#define __NR_semop 193
|
||||||
__SYSCALL(__NR_semop, sys_semop)
|
__SYSCALL(__NR_semop, sys_semop)
|
||||||
|
@@ -181,7 +181,7 @@ struct prctl_mm_map {
|
|||||||
#define PR_GET_THP_DISABLE 42
|
#define PR_GET_THP_DISABLE 42
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell the kernel to start/stop helping userspace manage bounds tables.
|
* No longer implemented, but left here to ensure the numbers stay reserved:
|
||||||
*/
|
*/
|
||||||
#define PR_MPX_ENABLE_MANAGEMENT 43
|
#define PR_MPX_ENABLE_MANAGEMENT 43
|
||||||
#define PR_MPX_DISABLE_MANAGEMENT 44
|
#define PR_MPX_DISABLE_MANAGEMENT 44
|
||||||
@@ -229,4 +229,9 @@ struct prctl_mm_map {
|
|||||||
# define PR_PAC_APDBKEY (1UL << 3)
|
# define PR_PAC_APDBKEY (1UL << 3)
|
||||||
# define PR_PAC_APGAKEY (1UL << 4)
|
# define PR_PAC_APGAKEY (1UL << 4)
|
||||||
|
|
||||||
|
/* Tagged user address controls for arm64 */
|
||||||
|
#define PR_SET_TAGGED_ADDR_CTRL 55
|
||||||
|
#define PR_GET_TAGGED_ADDR_CTRL 56
|
||||||
|
# define PR_TAGGED_ADDR_ENABLE (1UL << 0)
|
||||||
|
|
||||||
#endif /* _LINUX_PRCTL_H */
|
#endif /* _LINUX_PRCTL_H */
|
||||||
|
@@ -6,14 +6,3 @@ libtraceevent-y += parse-utils.o
|
|||||||
libtraceevent-y += kbuffer-parse.o
|
libtraceevent-y += kbuffer-parse.o
|
||||||
libtraceevent-y += tep_strerror.o
|
libtraceevent-y += tep_strerror.o
|
||||||
libtraceevent-y += event-parse-api.o
|
libtraceevent-y += event-parse-api.o
|
||||||
|
|
||||||
plugin_jbd2-y += plugin_jbd2.o
|
|
||||||
plugin_hrtimer-y += plugin_hrtimer.o
|
|
||||||
plugin_kmem-y += plugin_kmem.o
|
|
||||||
plugin_kvm-y += plugin_kvm.o
|
|
||||||
plugin_mac80211-y += plugin_mac80211.o
|
|
||||||
plugin_sched_switch-y += plugin_sched_switch.o
|
|
||||||
plugin_function-y += plugin_function.o
|
|
||||||
plugin_xen-y += plugin_xen.o
|
|
||||||
plugin_scsi-y += plugin_scsi.o
|
|
||||||
plugin_cfg80211-y += plugin_cfg80211.o
|
|
||||||
|
130
tools/lib/traceevent/Documentation/libtraceevent-event_print.txt
Normal file
130
tools/lib/traceevent/Documentation/libtraceevent-event_print.txt
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
libtraceevent(3)
|
||||||
|
================
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
tep_print_event - Writes event information into a trace sequence.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
*#include <event-parse.h>*
|
||||||
|
*#include <trace-seq.h>*
|
||||||
|
|
||||||
|
void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seqpass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._)
|
||||||
|
--
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The _tep_print_event()_ function parses the event information of the given
|
||||||
|
_record_ and writes it into the trace sequence _s_, according to the format
|
||||||
|
string _fmt_. The desired information is specified after the format string.
|
||||||
|
The _fmt_ is printf-like format string, following arguments are supported:
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
TEP_PRINT_PID, "%d" - PID of the event.
|
||||||
|
TEP_PRINT_CPU, "%d" - Event CPU.
|
||||||
|
TEP_PRINT_COMM, "%s" - Event command string.
|
||||||
|
TEP_PRINT_NAME, "%s" - Event name.
|
||||||
|
TEP_PRINT_LATENCY, "%s" - Latency of the event. It prints 4 or more
|
||||||
|
fields - interrupt state, scheduling state,
|
||||||
|
current context, and preemption count.
|
||||||
|
Field 1 is the interrupt enabled state:
|
||||||
|
d : Interrupts are disabled
|
||||||
|
. : Interrupts are enabled
|
||||||
|
X : The architecture does not support this
|
||||||
|
information
|
||||||
|
Field 2 is the "need resched" state.
|
||||||
|
N : The task is set to call the scheduler when
|
||||||
|
possible, as another higher priority task
|
||||||
|
may need to be scheduled in.
|
||||||
|
. : The task is not set to call the scheduler.
|
||||||
|
Field 3 is the context state.
|
||||||
|
. : Normal context
|
||||||
|
s : Soft interrupt context
|
||||||
|
h : Hard interrupt context
|
||||||
|
H : Hard interrupt context which triggered
|
||||||
|
during soft interrupt context.
|
||||||
|
z : NMI context
|
||||||
|
Z : NMI context which triggered during hard
|
||||||
|
interrupt context
|
||||||
|
Field 4 is the preemption count.
|
||||||
|
. : The preempt count is zero.
|
||||||
|
On preemptible kernels (where the task can be scheduled
|
||||||
|
out in arbitrary locations while in kernel context), the
|
||||||
|
preempt count, when non zero, will prevent the kernel
|
||||||
|
from scheduling out the current task. The preempt count
|
||||||
|
number is displayed when it is not zero.
|
||||||
|
Depending on the kernel, it may show other fields
|
||||||
|
(lock depth, or migration disabled, which are unique to
|
||||||
|
specialized kernels).
|
||||||
|
TEP_PRINT_TIME, %d - event time stamp. A divisor and precision can be
|
||||||
|
specified as part of this format string:
|
||||||
|
"%precision.divisord". Example:
|
||||||
|
"%3.1000d" - divide the time by 1000 and print the first
|
||||||
|
3 digits before the dot. Thus, the time stamp
|
||||||
|
"123456000" will be printed as "123.456"
|
||||||
|
TEP_PRINT_INFO, "%s" - event information.
|
||||||
|
TEP_PRINT_INFO_RAW, "%s" - event information, in raw format.
|
||||||
|
|
||||||
|
--
|
||||||
|
EXAMPLE
|
||||||
|
-------
|
||||||
|
[source,c]
|
||||||
|
--
|
||||||
|
#include <event-parse.h>
|
||||||
|
#include <trace-seq.h>
|
||||||
|
...
|
||||||
|
struct trace_seq seq;
|
||||||
|
trace_seq_init(&seq);
|
||||||
|
struct tep_handle *tep = tep_alloc();
|
||||||
|
...
|
||||||
|
void print_my_event(struct tep_record *record)
|
||||||
|
{
|
||||||
|
trace_seq_reset(&seq);
|
||||||
|
tep_print_event(tep, s, record, "%16s-%-5d [%03d] %s %6.1000d %s %s",
|
||||||
|
TEP_PRINT_COMM, TEP_PRINT_PID, TEP_PRINT_CPU,
|
||||||
|
TEP_PRINT_LATENCY, TEP_PRINT_TIME, TEP_PRINT_NAME,
|
||||||
|
TEP_PRINT_INFO);
|
||||||
|
}
|
||||||
|
...
|
||||||
|
--
|
||||||
|
|
||||||
|
FILES
|
||||||
|
-----
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
*event-parse.h*
|
||||||
|
Header file to include in order to have access to the library APIs.
|
||||||
|
*trace-seq.h*
|
||||||
|
Header file to include in order to have access to trace sequences related APIs.
|
||||||
|
Trace sequences are used to allow a function to call several other functions
|
||||||
|
to create a string of data to use.
|
||||||
|
*-ltraceevent*
|
||||||
|
Linker switch to add when building a program that uses the library.
|
||||||
|
--
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
_libtraceevent(3)_, _trace-cmd(1)_
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
------
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
|
||||||
|
*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
|
||||||
|
--
|
||||||
|
REPORTING BUGS
|
||||||
|
--------------
|
||||||
|
Report bugs to <linux-trace-devel@vger.kernel.org>
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
-------
|
||||||
|
libtraceevent is Free Software licensed under the GNU LGPL 2.1
|
||||||
|
|
||||||
|
RESOURCES
|
||||||
|
---------
|
||||||
|
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
@@ -59,12 +59,12 @@ parser context.
|
|||||||
|
|
||||||
The _tep_register_function()_ function registers a function name mapped to an
|
The _tep_register_function()_ function registers a function name mapped to an
|
||||||
address and (optional) module. This mapping is used in case the function tracer
|
address and (optional) module. This mapping is used in case the function tracer
|
||||||
or events have "%pF" or "%pS" parameter in its format string. It is common to
|
or events have "%pS" parameter in its format string. It is common to pass in
|
||||||
pass in the kallsyms function names with their corresponding addresses with this
|
the kallsyms function names with their corresponding addresses with this
|
||||||
function. The _tep_ argument is the trace event parser context. The _name_ is
|
function. The _tep_ argument is the trace event parser context. The _name_ is
|
||||||
the name of the function, the string is copied internally. The _addr_ is
|
the name of the function, the string is copied internally. The _addr_ is the
|
||||||
the start address of the function. The _mod_ is the kernel module
|
start address of the function. The _mod_ is the kernel module the function may
|
||||||
the function may be in (NULL for none).
|
be in (NULL for none).
|
||||||
|
|
||||||
The _tep_register_print_string()_ function registers a string by the address
|
The _tep_register_print_string()_ function registers a string by the address
|
||||||
it was stored in the kernel. Some strings internal to the kernel with static
|
it was stored in the kernel. Some strings internal to the kernel with static
|
||||||
|
@@ -3,7 +3,7 @@ libtraceevent(3)
|
|||||||
|
|
||||||
NAME
|
NAME
|
||||||
----
|
----
|
||||||
tep_alloc, tep_free,tep_ref, tep_unref,tep_ref_get - Create, destroy, manage
|
tep_alloc, tep_free,tep_ref, tep_unref,tep_get_ref - Create, destroy, manage
|
||||||
references of trace event parser context.
|
references of trace event parser context.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@@ -16,7 +16,7 @@ struct tep_handle pass:[*]*tep_alloc*(void);
|
|||||||
void *tep_free*(struct tep_handle pass:[*]_tep_);
|
void *tep_free*(struct tep_handle pass:[*]_tep_);
|
||||||
void *tep_ref*(struct tep_handle pass:[*]_tep_);
|
void *tep_ref*(struct tep_handle pass:[*]_tep_);
|
||||||
void *tep_unref*(struct tep_handle pass:[*]_tep_);
|
void *tep_unref*(struct tep_handle pass:[*]_tep_);
|
||||||
int *tep_ref_get*(struct tep_handle pass:[*]_tep_);
|
int *tep_get_ref*(struct tep_handle pass:[*]_tep_);
|
||||||
--
|
--
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
@@ -57,9 +57,9 @@ EXAMPLE
|
|||||||
...
|
...
|
||||||
struct tep_handle *tep = tep_alloc();
|
struct tep_handle *tep = tep_alloc();
|
||||||
...
|
...
|
||||||
int ref = tep_ref_get(tep);
|
int ref = tep_get_ref(tep);
|
||||||
tep_ref(tep);
|
tep_ref(tep);
|
||||||
if ( (ref+1) != tep_ref_get(tep)) {
|
if ( (ref+1) != tep_get_ref(tep)) {
|
||||||
/* Something wrong happened, the counter is not incremented by 1 */
|
/* Something wrong happened, the counter is not incremented by 1 */
|
||||||
}
|
}
|
||||||
tep_unref(tep);
|
tep_unref(tep);
|
||||||
|
99
tools/lib/traceevent/Documentation/libtraceevent-plugins.txt
Normal file
99
tools/lib/traceevent/Documentation/libtraceevent-plugins.txt
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
libtraceevent(3)
|
||||||
|
================
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
tep_load_plugins, tep_unload_plugins - Load / unload traceevent plugins.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
*#include <event-parse.h>*
|
||||||
|
|
||||||
|
struct tep_plugin_list pass:[*]*tep_load_plugins*(struct tep_handle pass:[*]_tep_);
|
||||||
|
void *tep_unload_plugins*(struct tep_plugin_list pass:[*]_plugin_list_, struct tep_handle pass:[*]_tep_);
|
||||||
|
--
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
-----------
|
||||||
|
The _tep_load_plugins()_ function loads all plugins, located in the plugin
|
||||||
|
directories. The _tep_ argument is trace event parser context.
|
||||||
|
The plugin directories are :
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
- System's plugin directory, defined at the library compile time. It
|
||||||
|
depends on the library installation prefix and usually is
|
||||||
|
_(install_preffix)/lib/traceevent/plugins_
|
||||||
|
- Directory, defined by the environment variable _TRACEEVENT_PLUGIN_DIR_
|
||||||
|
- User's plugin directory, located at _~/.local/lib/traceevent/plugins_
|
||||||
|
--
|
||||||
|
Loading of plugins can be controlled by the _tep_flags_, using the
|
||||||
|
_tep_set_flag()_ API:
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
_TEP_DISABLE_SYS_PLUGINS_ - do not load plugins, located in
|
||||||
|
the system's plugin directory.
|
||||||
|
_TEP_DISABLE_PLUGINS_ - do not load any plugins.
|
||||||
|
--
|
||||||
|
The _tep_set_flag()_ API needs to be called before _tep_load_plugins()_, if
|
||||||
|
loading of all plugins is not the desired case.
|
||||||
|
|
||||||
|
The _tep_unload_plugins()_ function unloads the plugins, previously loaded by
|
||||||
|
_tep_load_plugins()_. The _tep_ argument is trace event parser context. The
|
||||||
|
_plugin_list_ is the list of loaded plugins, returned by
|
||||||
|
the _tep_load_plugins()_ function.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
------------
|
||||||
|
The _tep_load_plugins()_ function returns a list of successfully loaded plugins,
|
||||||
|
or NULL in case no plugins are loaded.
|
||||||
|
|
||||||
|
EXAMPLE
|
||||||
|
-------
|
||||||
|
[source,c]
|
||||||
|
--
|
||||||
|
#include <event-parse.h>
|
||||||
|
...
|
||||||
|
struct tep_handle *tep = tep_alloc();
|
||||||
|
...
|
||||||
|
struct tep_plugin_list *plugins = tep_load_plugins(tep);
|
||||||
|
if (plugins == NULL) {
|
||||||
|
/* no plugins are loaded */
|
||||||
|
}
|
||||||
|
...
|
||||||
|
tep_unload_plugins(plugins, tep);
|
||||||
|
--
|
||||||
|
|
||||||
|
FILES
|
||||||
|
-----
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
*event-parse.h*
|
||||||
|
Header file to include in order to have access to the library APIs.
|
||||||
|
*-ltraceevent*
|
||||||
|
Linker switch to add when building a program that uses the library.
|
||||||
|
--
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
_libtraceevent(3)_, _trace-cmd(1)_, _tep_set_flag(3)_
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
------
|
||||||
|
[verse]
|
||||||
|
--
|
||||||
|
*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
|
||||||
|
*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, author of this man page.
|
||||||
|
--
|
||||||
|
REPORTING BUGS
|
||||||
|
--------------
|
||||||
|
Report bugs to <linux-trace-devel@vger.kernel.org>
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
-------
|
||||||
|
libtraceevent is Free Software licensed under the GNU LGPL 2.1
|
||||||
|
|
||||||
|
RESOURCES
|
||||||
|
---------
|
||||||
|
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
@@ -16,7 +16,7 @@ Management of tep handler data structure and access of its members:
|
|||||||
void *tep_free*(struct tep_handle pass:[*]_tep_);
|
void *tep_free*(struct tep_handle pass:[*]_tep_);
|
||||||
void *tep_ref*(struct tep_handle pass:[*]_tep_);
|
void *tep_ref*(struct tep_handle pass:[*]_tep_);
|
||||||
void *tep_unref*(struct tep_handle pass:[*]_tep_);
|
void *tep_unref*(struct tep_handle pass:[*]_tep_);
|
||||||
int *tep_ref_get*(struct tep_handle pass:[*]_tep_);
|
int *tep_get_ref*(struct tep_handle pass:[*]_tep_);
|
||||||
void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
|
void *tep_set_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
|
||||||
void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
|
void *tep_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
|
||||||
bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_);
|
bool *tep_test_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flags_);
|
||||||
@@ -26,15 +26,12 @@ Management of tep handler data structure and access of its members:
|
|||||||
void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_);
|
void *tep_set_long_size*(struct tep_handle pass:[*]_tep_, int _long_size_);
|
||||||
int *tep_get_page_size*(struct tep_handle pass:[*]_tep_);
|
int *tep_get_page_size*(struct tep_handle pass:[*]_tep_);
|
||||||
void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_);
|
void *tep_set_page_size*(struct tep_handle pass:[*]_tep_, int _page_size_);
|
||||||
bool *tep_is_latency_format*(struct tep_handle pass:[*]_tep_);
|
|
||||||
void *tep_set_latency_format*(struct tep_handle pass:[*]_tep_, int _lat_);
|
|
||||||
int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_);
|
int *tep_get_header_page_size*(struct tep_handle pass:[*]_tep_);
|
||||||
int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_);
|
int *tep_get_header_timestamp_size*(struct tep_handle pass:[*]_tep_);
|
||||||
bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_);
|
bool *tep_is_old_format*(struct tep_handle pass:[*]_tep_);
|
||||||
int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_);
|
int *tep_strerror*(struct tep_handle pass:[*]_tep_, enum tep_errno _errnum_, char pass:[*]_buf_, size_t _buflen_);
|
||||||
|
|
||||||
Register / unregister APIs:
|
Register / unregister APIs:
|
||||||
int *tep_register_trace_clock*(struct tep_handle pass:[*]_tep_, const char pass:[*]_trace_clock_);
|
|
||||||
int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_);
|
int *tep_register_function*(struct tep_handle pass:[*]_tep_, char pass:[*]_name_, unsigned long long _addr_, char pass:[*]_mod_);
|
||||||
int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_);
|
int *tep_register_event_handler*(struct tep_handle pass:[*]_tep_, int _id_, const char pass:[*]_sys_name_, const char pass:[*]_event_name_, tep_event_handler_func _func_, void pass:[*]_context_);
|
||||||
int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_);
|
int *tep_unregister_event_handler*(struct tep_handle pass:[*]tep, int id, const char pass:[*]sys_name, const char pass:[*]event_name, tep_event_handler_func func, void pass:[*]_context_);
|
||||||
@@ -57,14 +54,7 @@ Event related APIs:
|
|||||||
int *tep_get_events_count*(struct tep_handle pass:[*]_tep_);
|
int *tep_get_events_count*(struct tep_handle pass:[*]_tep_);
|
||||||
struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
|
struct tep_event pass:[*]pass:[*]*tep_list_events*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
|
||||||
struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
|
struct tep_event pass:[*]pass:[*]*tep_list_events_copy*(struct tep_handle pass:[*]_tep_, enum tep_event_sort_type _sort_type_);
|
||||||
|
void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._);
|
||||||
Event printing:
|
|
||||||
void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, bool _use_trace_clock_);
|
|
||||||
void *tep_print_event_data*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_);
|
|
||||||
void *tep_event_info*(struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_);
|
|
||||||
void *tep_print_event_task*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]_record_);
|
|
||||||
void *tep_print_event_time*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_event pass:[*]_event_, struct tep_record pass:[*]record, bool _use_trace_clock_);
|
|
||||||
void *tep_set_print_raw*(struct tep_handle pass:[*]_tep_, int _print_raw_);
|
|
||||||
|
|
||||||
Event finding:
|
Event finding:
|
||||||
struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_);
|
struct tep_event pass:[*]*tep_find_event*(struct tep_handle pass:[*]_tep_, int _id_);
|
||||||
@@ -116,7 +106,6 @@ Filter management:
|
|||||||
int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_);
|
int *tep_filter_compare*(struct tep_event_filter pass:[*]_filter1_, struct tep_event_filter pass:[*]_filter2_);
|
||||||
|
|
||||||
Parsing various data from the records:
|
Parsing various data from the records:
|
||||||
void *tep_data_latency_format*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_);
|
|
||||||
int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
|
int *tep_data_type*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
|
||||||
int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
|
int *tep_data_pid*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
|
||||||
int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
|
int *tep_data_preempt_count*(struct tep_handle pass:[*]_tep_, struct tep_record pass:[*]_rec_);
|
||||||
|
@@ -58,30 +58,6 @@ export man_dir man_dir_SQ INSTALL
|
|||||||
export DESTDIR DESTDIR_SQ
|
export DESTDIR DESTDIR_SQ
|
||||||
export EVENT_PARSE_VERSION
|
export EVENT_PARSE_VERSION
|
||||||
|
|
||||||
set_plugin_dir := 1
|
|
||||||
|
|
||||||
# Set plugin_dir to preffered global plugin location
|
|
||||||
# If we install under $HOME directory we go under
|
|
||||||
# $(HOME)/.local/lib/traceevent/plugins
|
|
||||||
#
|
|
||||||
# We dont set PLUGIN_DIR in case we install under $HOME
|
|
||||||
# directory, because by default the code looks under:
|
|
||||||
# $(HOME)/.local/lib/traceevent/plugins by default.
|
|
||||||
#
|
|
||||||
ifeq ($(plugin_dir),)
|
|
||||||
ifeq ($(prefix),$(HOME))
|
|
||||||
override plugin_dir = $(HOME)/.local/lib/traceevent/plugins
|
|
||||||
set_plugin_dir := 0
|
|
||||||
else
|
|
||||||
override plugin_dir = $(libdir)/traceevent/plugins
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(set_plugin_dir),1)
|
|
||||||
PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
|
|
||||||
PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
|
|
||||||
endif
|
|
||||||
|
|
||||||
include ../../scripts/Makefile.include
|
include ../../scripts/Makefile.include
|
||||||
|
|
||||||
# copy a bit from Linux kbuild
|
# copy a bit from Linux kbuild
|
||||||
@@ -105,7 +81,6 @@ export prefix libdir src obj
|
|||||||
# Shell quotes
|
# Shell quotes
|
||||||
libdir_SQ = $(subst ','\'',$(libdir))
|
libdir_SQ = $(subst ','\'',$(libdir))
|
||||||
libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
|
libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
|
||||||
plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
|
|
||||||
|
|
||||||
CONFIG_INCLUDES =
|
CONFIG_INCLUDES =
|
||||||
CONFIG_LIBS =
|
CONFIG_LIBS =
|
||||||
@@ -151,29 +126,14 @@ MAKEOVERRIDES=
|
|||||||
export srctree OUTPUT CC LD CFLAGS V
|
export srctree OUTPUT CC LD CFLAGS V
|
||||||
build := -f $(srctree)/tools/build/Makefile.build dir=. obj
|
build := -f $(srctree)/tools/build/Makefile.build dir=. obj
|
||||||
|
|
||||||
PLUGINS = plugin_jbd2.so
|
|
||||||
PLUGINS += plugin_hrtimer.so
|
|
||||||
PLUGINS += plugin_kmem.so
|
|
||||||
PLUGINS += plugin_kvm.so
|
|
||||||
PLUGINS += plugin_mac80211.so
|
|
||||||
PLUGINS += plugin_sched_switch.so
|
|
||||||
PLUGINS += plugin_function.so
|
|
||||||
PLUGINS += plugin_xen.so
|
|
||||||
PLUGINS += plugin_scsi.so
|
|
||||||
PLUGINS += plugin_cfg80211.so
|
|
||||||
|
|
||||||
PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS))
|
|
||||||
PLUGINS_IN := $(PLUGINS:.so=-in.o)
|
|
||||||
|
|
||||||
TE_IN := $(OUTPUT)libtraceevent-in.o
|
TE_IN := $(OUTPUT)libtraceevent-in.o
|
||||||
LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET))
|
LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET))
|
||||||
DYNAMIC_LIST_FILE := $(OUTPUT)libtraceevent-dynamic-list
|
|
||||||
|
|
||||||
CMD_TARGETS = $(LIB_TARGET) $(PLUGINS) $(DYNAMIC_LIST_FILE)
|
CMD_TARGETS = $(LIB_TARGET)
|
||||||
|
|
||||||
TARGETS = $(CMD_TARGETS)
|
TARGETS = $(CMD_TARGETS)
|
||||||
|
|
||||||
all: all_cmd
|
all: all_cmd plugins
|
||||||
|
|
||||||
all_cmd: $(CMD_TARGETS)
|
all_cmd: $(CMD_TARGETS)
|
||||||
|
|
||||||
@@ -188,17 +148,6 @@ $(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN)
|
|||||||
$(OUTPUT)libtraceevent.a: $(TE_IN)
|
$(OUTPUT)libtraceevent.a: $(TE_IN)
|
||||||
$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
|
$(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
|
||||||
|
|
||||||
$(OUTPUT)libtraceevent-dynamic-list: $(PLUGINS)
|
|
||||||
$(QUIET_GEN)$(call do_generate_dynamic_list_file, $(PLUGINS), $@)
|
|
||||||
|
|
||||||
plugins: $(PLUGINS)
|
|
||||||
|
|
||||||
__plugin_obj = $(notdir $@)
|
|
||||||
plugin_obj = $(__plugin_obj:-in.o=)
|
|
||||||
|
|
||||||
$(PLUGINS_IN): force
|
|
||||||
$(Q)$(MAKE) $(build)=$(plugin_obj)
|
|
||||||
|
|
||||||
$(OUTPUT)%.so: $(OUTPUT)%-in.o
|
$(OUTPUT)%.so: $(OUTPUT)%-in.o
|
||||||
$(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^
|
$(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^
|
||||||
|
|
||||||
@@ -258,25 +207,6 @@ define do_install
|
|||||||
$(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2'
|
$(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2'
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define do_install_plugins
|
|
||||||
for plugin in $1; do \
|
|
||||||
$(call do_install,$$plugin,$(plugin_dir_SQ)); \
|
|
||||||
done
|
|
||||||
endef
|
|
||||||
|
|
||||||
define do_generate_dynamic_list_file
|
|
||||||
symbol_type=`$(NM) -u -D $1 | awk 'NF>1 {print $$1}' | \
|
|
||||||
xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\
|
|
||||||
if [ "$$symbol_type" = "U W" ];then \
|
|
||||||
(echo '{'; \
|
|
||||||
$(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\
|
|
||||||
echo '};'; \
|
|
||||||
) > $2; \
|
|
||||||
else \
|
|
||||||
(echo Either missing one of [$1] or bad version of $(NM)) 1>&2;\
|
|
||||||
fi
|
|
||||||
endef
|
|
||||||
|
|
||||||
PKG_CONFIG_FILE = libtraceevent.pc
|
PKG_CONFIG_FILE = libtraceevent.pc
|
||||||
define do_install_pkgconfig_file
|
define do_install_pkgconfig_file
|
||||||
if [ -n "${pkgconfig_dir}" ]; then \
|
if [ -n "${pkgconfig_dir}" ]; then \
|
||||||
@@ -296,10 +226,6 @@ install_lib: all_cmd install_plugins install_headers install_pkgconfig
|
|||||||
$(call do_install_mkdir,$(libdir_SQ)); \
|
$(call do_install_mkdir,$(libdir_SQ)); \
|
||||||
cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
|
cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
|
||||||
|
|
||||||
install_plugins: $(PLUGINS)
|
|
||||||
$(call QUIET_INSTALL, trace_plugins) \
|
|
||||||
$(call do_install_plugins, $(PLUGINS))
|
|
||||||
|
|
||||||
install_pkgconfig:
|
install_pkgconfig:
|
||||||
$(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \
|
$(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \
|
||||||
$(call do_install_pkgconfig_file,$(prefix))
|
$(call do_install_pkgconfig_file,$(prefix))
|
||||||
@@ -313,7 +239,7 @@ install_headers:
|
|||||||
|
|
||||||
install: install_lib
|
install: install_lib
|
||||||
|
|
||||||
clean:
|
clean: clean_plugins
|
||||||
$(call QUIET_CLEAN, libtraceevent) \
|
$(call QUIET_CLEAN, libtraceevent) \
|
||||||
$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \
|
$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \
|
||||||
$(RM) TRACEEVENT-CFLAGS tags TAGS; \
|
$(RM) TRACEEVENT-CFLAGS tags TAGS; \
|
||||||
@@ -351,7 +277,19 @@ help:
|
|||||||
@echo ' doc-install - install the man pages'
|
@echo ' doc-install - install the man pages'
|
||||||
@echo ' doc-uninstall - uninstall the man pages'
|
@echo ' doc-uninstall - uninstall the man pages'
|
||||||
@echo''
|
@echo''
|
||||||
PHONY += force plugins
|
|
||||||
|
PHONY += plugins
|
||||||
|
plugins:
|
||||||
|
$(call descend,plugins)
|
||||||
|
|
||||||
|
PHONY += install_plugins
|
||||||
|
install_plugins:
|
||||||
|
$(call descend,plugins,install)
|
||||||
|
|
||||||
|
PHONY += clean_plugins
|
||||||
|
clean_plugins:
|
||||||
|
$(call descend,plugins,clean)
|
||||||
|
|
||||||
force:
|
force:
|
||||||
|
|
||||||
# Declare the contents of the .PHONY variable as phony. We keep that
|
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||||
|
@@ -4367,10 +4367,20 @@ static struct tep_print_arg *make_bprint_args(char *fmt, void *data, int size, s
|
|||||||
switch (*ptr) {
|
switch (*ptr) {
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
case 'x':
|
case 'x':
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
/*
|
||||||
|
* Pre-5.5 kernels use %pf and
|
||||||
|
* %pF for printing symbols
|
||||||
|
* while kernels since 5.5 use
|
||||||
|
* %pfw for fwnodes. So check
|
||||||
|
* %p[fF] isn't followed by 'w'.
|
||||||
|
*/
|
||||||
|
if (ptr[1] != 'w')
|
||||||
|
break;
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* Older kernels do not process
|
* Older kernels do not process
|
||||||
@@ -4487,12 +4497,12 @@ get_bprint_format(void *data, int size __maybe_unused,
|
|||||||
|
|
||||||
printk = find_printk(tep, addr);
|
printk = find_printk(tep, addr);
|
||||||
if (!printk) {
|
if (!printk) {
|
||||||
if (asprintf(&format, "%%pf: (NO FORMAT FOUND at %llx)\n", addr) < 0)
|
if (asprintf(&format, "%%ps: (NO FORMAT FOUND at %llx)\n", addr) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0)
|
if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return format;
|
return format;
|
||||||
@@ -5517,8 +5527,10 @@ static void print_event_time(struct tep_handle *tep, struct trace_seq *s,
|
|||||||
if (divstr && isdigit(*(divstr + 1)))
|
if (divstr && isdigit(*(divstr + 1)))
|
||||||
div = atoi(divstr + 1);
|
div = atoi(divstr + 1);
|
||||||
time = record->ts;
|
time = record->ts;
|
||||||
if (div)
|
if (div) {
|
||||||
|
time += div / 2;
|
||||||
time /= div;
|
time /= div;
|
||||||
|
}
|
||||||
pr = prec;
|
pr = prec;
|
||||||
while (pr--)
|
while (pr--)
|
||||||
p10 *= 10;
|
p10 *= 10;
|
||||||
|
@@ -441,6 +441,8 @@ int tep_register_print_string(struct tep_handle *tep, const char *fmt,
|
|||||||
unsigned long long addr);
|
unsigned long long addr);
|
||||||
bool tep_is_pid_registered(struct tep_handle *tep, int pid);
|
bool tep_is_pid_registered(struct tep_handle *tep, int pid);
|
||||||
|
|
||||||
|
struct tep_event *tep_get_event(struct tep_handle *tep, int index);
|
||||||
|
|
||||||
#define TEP_PRINT_INFO "INFO"
|
#define TEP_PRINT_INFO "INFO"
|
||||||
#define TEP_PRINT_INFO_RAW "INFO_RAW"
|
#define TEP_PRINT_INFO_RAW "INFO_RAW"
|
||||||
#define TEP_PRINT_COMM "COMM"
|
#define TEP_PRINT_COMM "COMM"
|
||||||
|
10
tools/lib/traceevent/plugins/Build
Normal file
10
tools/lib/traceevent/plugins/Build
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
plugin_jbd2-y += plugin_jbd2.o
|
||||||
|
plugin_hrtimer-y += plugin_hrtimer.o
|
||||||
|
plugin_kmem-y += plugin_kmem.o
|
||||||
|
plugin_kvm-y += plugin_kvm.o
|
||||||
|
plugin_mac80211-y += plugin_mac80211.o
|
||||||
|
plugin_sched_switch-y += plugin_sched_switch.o
|
||||||
|
plugin_function-y += plugin_function.o
|
||||||
|
plugin_xen-y += plugin_xen.o
|
||||||
|
plugin_scsi-y += plugin_scsi.o
|
||||||
|
plugin_cfg80211-y += plugin_cfg80211.o
|
222
tools/lib/traceevent/plugins/Makefile
Normal file
222
tools/lib/traceevent/plugins/Makefile
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
#MAKEFLAGS += --no-print-directory
|
||||||
|
|
||||||
|
|
||||||
|
# Makefiles suck: This macro sets a default value of $(2) for the
|
||||||
|
# variable named by $(1), unless the variable has been set by
|
||||||
|
# environment or command line. This is necessary for CC and AR
|
||||||
|
# because make sets default values, so the simpler ?= approach
|
||||||
|
# won't work as expected.
|
||||||
|
define allow-override
|
||||||
|
$(if $(or $(findstring environment,$(origin $(1))),\
|
||||||
|
$(findstring command line,$(origin $(1)))),,\
|
||||||
|
$(eval $(1) = $(2)))
|
||||||
|
endef
|
||||||
|
|
||||||
|
# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
|
||||||
|
$(call allow-override,CC,$(CROSS_COMPILE)gcc)
|
||||||
|
$(call allow-override,AR,$(CROSS_COMPILE)ar)
|
||||||
|
$(call allow-override,NM,$(CROSS_COMPILE)nm)
|
||||||
|
$(call allow-override,PKG_CONFIG,pkg-config)
|
||||||
|
|
||||||
|
EXT = -std=gnu99
|
||||||
|
INSTALL = install
|
||||||
|
|
||||||
|
# Use DESTDIR for installing into a different root directory.
|
||||||
|
# This is useful for building a package. The program will be
|
||||||
|
# installed in this directory as if it was the root directory.
|
||||||
|
# Then the build tool can move it later.
|
||||||
|
DESTDIR ?=
|
||||||
|
DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
|
||||||
|
|
||||||
|
LP64 := $(shell echo __LP64__ | ${CC} ${CFLAGS} -E -x c - | tail -n 1)
|
||||||
|
ifeq ($(LP64), 1)
|
||||||
|
libdir_relative = lib64
|
||||||
|
else
|
||||||
|
libdir_relative = lib
|
||||||
|
endif
|
||||||
|
|
||||||
|
prefix ?= /usr/local
|
||||||
|
libdir = $(prefix)/$(libdir_relative)
|
||||||
|
|
||||||
|
set_plugin_dir := 1
|
||||||
|
|
||||||
|
# Set plugin_dir to preffered global plugin location
|
||||||
|
# If we install under $HOME directory we go under
|
||||||
|
# $(HOME)/.local/lib/traceevent/plugins
|
||||||
|
#
|
||||||
|
# We dont set PLUGIN_DIR in case we install under $HOME
|
||||||
|
# directory, because by default the code looks under:
|
||||||
|
# $(HOME)/.local/lib/traceevent/plugins by default.
|
||||||
|
#
|
||||||
|
ifeq ($(plugin_dir),)
|
||||||
|
ifeq ($(prefix),$(HOME))
|
||||||
|
override plugin_dir = $(HOME)/.local/lib/traceevent/plugins
|
||||||
|
set_plugin_dir := 0
|
||||||
|
else
|
||||||
|
override plugin_dir = $(libdir)/traceevent/plugins
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(set_plugin_dir),1)
|
||||||
|
PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)"
|
||||||
|
PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))'
|
||||||
|
endif
|
||||||
|
|
||||||
|
include ../../../scripts/Makefile.include
|
||||||
|
|
||||||
|
# copy a bit from Linux kbuild
|
||||||
|
|
||||||
|
ifeq ("$(origin V)", "command line")
|
||||||
|
VERBOSE = $(V)
|
||||||
|
endif
|
||||||
|
ifndef VERBOSE
|
||||||
|
VERBOSE = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(srctree),)
|
||||||
|
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
|
||||||
|
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||||
|
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||||
|
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||||
|
#$(info Determined 'srctree' to be $(srctree))
|
||||||
|
endif
|
||||||
|
|
||||||
|
export prefix libdir src obj
|
||||||
|
|
||||||
|
# Shell quotes
|
||||||
|
plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
|
||||||
|
|
||||||
|
CONFIG_INCLUDES =
|
||||||
|
CONFIG_LIBS =
|
||||||
|
CONFIG_FLAGS =
|
||||||
|
|
||||||
|
OBJ = $@
|
||||||
|
N =
|
||||||
|
|
||||||
|
INCLUDES = -I. -I.. -I $(srctree)/tools/include $(CONFIG_INCLUDES)
|
||||||
|
|
||||||
|
# Set compile option CFLAGS
|
||||||
|
ifdef EXTRA_CFLAGS
|
||||||
|
CFLAGS := $(EXTRA_CFLAGS)
|
||||||
|
else
|
||||||
|
CFLAGS := -g -Wall
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Append required CFLAGS
|
||||||
|
override CFLAGS += -fPIC
|
||||||
|
override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
|
||||||
|
override CFLAGS += $(udis86-flags) -D_GNU_SOURCE
|
||||||
|
|
||||||
|
ifeq ($(VERBOSE),1)
|
||||||
|
Q =
|
||||||
|
else
|
||||||
|
Q = @
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Disable command line variables (CFLAGS) override from top
|
||||||
|
# level Makefile (perf), otherwise build Makefile will get
|
||||||
|
# the same command line setup.
|
||||||
|
MAKEOVERRIDES=
|
||||||
|
|
||||||
|
export srctree OUTPUT CC LD CFLAGS V
|
||||||
|
|
||||||
|
build := -f $(srctree)/tools/build/Makefile.build dir=. obj
|
||||||
|
|
||||||
|
DYNAMIC_LIST_FILE := $(OUTPUT)libtraceevent-dynamic-list
|
||||||
|
|
||||||
|
PLUGINS = plugin_jbd2.so
|
||||||
|
PLUGINS += plugin_hrtimer.so
|
||||||
|
PLUGINS += plugin_kmem.so
|
||||||
|
PLUGINS += plugin_kvm.so
|
||||||
|
PLUGINS += plugin_mac80211.so
|
||||||
|
PLUGINS += plugin_sched_switch.so
|
||||||
|
PLUGINS += plugin_function.so
|
||||||
|
PLUGINS += plugin_xen.so
|
||||||
|
PLUGINS += plugin_scsi.so
|
||||||
|
PLUGINS += plugin_cfg80211.so
|
||||||
|
|
||||||
|
PLUGINS := $(addprefix $(OUTPUT),$(PLUGINS))
|
||||||
|
PLUGINS_IN := $(PLUGINS:.so=-in.o)
|
||||||
|
|
||||||
|
plugins: $(PLUGINS) $(DYNAMIC_LIST_FILE)
|
||||||
|
|
||||||
|
__plugin_obj = $(notdir $@)
|
||||||
|
plugin_obj = $(__plugin_obj:-in.o=)
|
||||||
|
|
||||||
|
$(PLUGINS_IN): force
|
||||||
|
$(Q)$(MAKE) $(build)=$(plugin_obj)
|
||||||
|
|
||||||
|
$(OUTPUT)libtraceevent-dynamic-list: $(PLUGINS)
|
||||||
|
$(QUIET_GEN)$(call do_generate_dynamic_list_file, $(PLUGINS), $@)
|
||||||
|
|
||||||
|
$(OUTPUT)%.so: $(OUTPUT)%-in.o
|
||||||
|
$(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^
|
||||||
|
|
||||||
|
define update_dir
|
||||||
|
(echo $1 > $@.tmp; \
|
||||||
|
if [ -r $@ ] && cmp -s $@ $@.tmp; then \
|
||||||
|
rm -f $@.tmp; \
|
||||||
|
else \
|
||||||
|
echo ' UPDATE $@'; \
|
||||||
|
mv -f $@.tmp $@; \
|
||||||
|
fi);
|
||||||
|
endef
|
||||||
|
|
||||||
|
tags: force
|
||||||
|
$(RM) tags
|
||||||
|
find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
|
||||||
|
--regex-c++='/_PE\(([^,)]*).*/TEP_ERRNO__\1/'
|
||||||
|
|
||||||
|
TAGS: force
|
||||||
|
$(RM) TAGS
|
||||||
|
find . -name '*.[ch]' | xargs etags \
|
||||||
|
--regex='/_PE(\([^,)]*\).*/TEP_ERRNO__\1/'
|
||||||
|
|
||||||
|
define do_install_mkdir
|
||||||
|
if [ ! -d '$(DESTDIR_SQ)$1' ]; then \
|
||||||
|
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
|
||||||
|
fi
|
||||||
|
endef
|
||||||
|
|
||||||
|
define do_install
|
||||||
|
$(call do_install_mkdir,$2); \
|
||||||
|
$(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR_SQ)$2'
|
||||||
|
endef
|
||||||
|
|
||||||
|
define do_install_plugins
|
||||||
|
for plugin in $1; do \
|
||||||
|
$(call do_install,$$plugin,$(plugin_dir_SQ)); \
|
||||||
|
done
|
||||||
|
endef
|
||||||
|
|
||||||
|
define do_generate_dynamic_list_file
|
||||||
|
symbol_type=`$(NM) -u -D $1 | awk 'NF>1 {print $$1}' | \
|
||||||
|
xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\
|
||||||
|
if [ "$$symbol_type" = "U W" ];then \
|
||||||
|
(echo '{'; \
|
||||||
|
$(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\
|
||||||
|
echo '};'; \
|
||||||
|
) > $2; \
|
||||||
|
else \
|
||||||
|
(echo Either missing one of [$1] or bad version of $(NM)) 1>&2;\
|
||||||
|
fi
|
||||||
|
endef
|
||||||
|
|
||||||
|
install: $(PLUGINS)
|
||||||
|
$(call QUIET_INSTALL, trace_plugins) \
|
||||||
|
$(call do_install_plugins, $(PLUGINS))
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(call QUIET_CLEAN, trace_plugins) \
|
||||||
|
$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \
|
||||||
|
$(RM) $(OUTPUT)libtraceevent-dynamic-list \
|
||||||
|
$(RM) TRACEEVENT-CFLAGS tags TAGS;
|
||||||
|
|
||||||
|
PHONY += force plugins
|
||||||
|
force:
|
||||||
|
|
||||||
|
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||||
|
# information in a variable so we can use it in if_changed and friends.
|
||||||
|
.PHONY: $(PHONY)
|
@@ -924,7 +924,7 @@ ifndef NO_JVMTI
|
|||||||
JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | awk '{print $$3}')
|
JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | awk '{print $$3}')
|
||||||
else
|
else
|
||||||
ifneq (,$(wildcard /usr/sbin/alternatives))
|
ifneq (,$(wildcard /usr/sbin/alternatives))
|
||||||
JDIR=$(shell /usr/sbin/alternatives --display java | tail -1 | cut -d' ' -f 5 | sed 's%/jre/bin/java.%%g')
|
JDIR=$(shell /usr/sbin/alternatives --display java | tail -1 | cut -d' ' -f 5 | sed -e 's%/jre/bin/java.%%g' -e 's%/bin/java.%%g')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifndef JDIR
|
ifndef JDIR
|
||||||
|
@@ -292,7 +292,7 @@ endif
|
|||||||
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
||||||
export LIBTRACEEVENT
|
export LIBTRACEEVENT
|
||||||
|
|
||||||
LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list
|
LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)plugins/libtraceevent-dynamic-list
|
||||||
|
|
||||||
#
|
#
|
||||||
# The static build has no dynsym table, so this does not work for
|
# The static build has no dynsym table, so this does not work for
|
||||||
@@ -567,7 +567,7 @@ all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
|
|||||||
# Create python binding output directory if not already present
|
# Create python binding output directory if not already present
|
||||||
_dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
|
_dummy := $(shell [ -d '$(OUTPUT)python' ] || mkdir -p '$(OUTPUT)python')
|
||||||
|
|
||||||
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST)
|
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) $(LIBPERF)
|
||||||
$(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \
|
$(QUIET_GEN)LDSHARED="$(CC) -pthread -shared" \
|
||||||
CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
|
CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
|
||||||
$(PYTHON_WORD) util/setup.py \
|
$(PYTHON_WORD) util/setup.py \
|
||||||
@@ -737,7 +737,7 @@ libtraceevent_plugins: FORCE
|
|||||||
$(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins
|
$(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) plugins
|
||||||
|
|
||||||
$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
|
$(LIBTRACEEVENT_DYNAMIC_LIST): libtraceevent_plugins
|
||||||
$(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent-dynamic-list
|
$(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)plugins/libtraceevent-dynamic-list
|
||||||
|
|
||||||
$(LIBTRACEEVENT)-clean:
|
$(LIBTRACEEVENT)-clean:
|
||||||
$(call QUIET_CLEAN, libtraceevent)
|
$(call QUIET_CLEAN, libtraceevent)
|
||||||
|
@@ -23,9 +23,10 @@
|
|||||||
#include "../../util/event.h"
|
#include "../../util/event.h"
|
||||||
#include "../../util/evlist.h"
|
#include "../../util/evlist.h"
|
||||||
#include "../../util/evsel.h"
|
#include "../../util/evsel.h"
|
||||||
|
#include "../../util/evsel_config.h"
|
||||||
#include "../../util/pmu.h"
|
#include "../../util/pmu.h"
|
||||||
#include "../../util/cs-etm.h"
|
#include "../../util/cs-etm.h"
|
||||||
#include "../../util/util.h"
|
#include <internal/lib.h> // page_size
|
||||||
#include "../../util/session.h"
|
#include "../../util/session.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -416,7 +417,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
tracking_evsel = perf_evlist__last(evlist);
|
tracking_evsel = evlist__last(evlist);
|
||||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||||
|
|
||||||
tracking_evsel->core.attr.freq = 0;
|
tracking_evsel->core.attr.freq = 0;
|
||||||
@@ -648,7 +649,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
|
|||||||
if (priv_size != cs_etm_info_priv_size(itr, session->evlist))
|
if (priv_size != cs_etm_info_priv_size(itr, session->evlist))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!session->evlist->nr_mmaps)
|
if (!session->evlist->core.nr_mmaps)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* If the cpu_map is empty all online CPUs are involved */
|
/* If the cpu_map is empty all online CPUs are involved */
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#include "../../util/evsel.h"
|
#include "../../util/evsel.h"
|
||||||
#include "../../util/evlist.h"
|
#include "../../util/evlist.h"
|
||||||
#include "../../util/session.h"
|
#include "../../util/session.h"
|
||||||
#include "../../util/util.h"
|
#include <internal/lib.h> // page_size
|
||||||
#include "../../util/pmu.h"
|
#include "../../util/pmu.h"
|
||||||
#include "../../util/debug.h"
|
#include "../../util/debug.h"
|
||||||
#include "../../util/auxtrace.h"
|
#include "../../util/auxtrace.h"
|
||||||
@@ -51,7 +51,7 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
|
|||||||
if (priv_size != ARM_SPE_AUXTRACE_PRIV_SIZE)
|
if (priv_size != ARM_SPE_AUXTRACE_PRIV_SIZE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!session->evlist->nr_mmaps)
|
if (!session->evlist->core.nr_mmaps)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
|
auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
|
||||||
@@ -129,7 +129,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
tracking_evsel = perf_evlist__last(evlist);
|
tracking_evsel = evlist__last(evlist);
|
||||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||||
|
|
||||||
tracking_evsel->core.attr.freq = 0;
|
tracking_evsel->core.attr.freq = 0;
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include <dwarf-regs.h>
|
#include <dwarf-regs.h>
|
||||||
#include <linux/ptrace.h> /* for struct user_pt_regs */
|
#include <linux/ptrace.h> /* for struct user_pt_regs */
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
struct pt_regs_dwarfnum {
|
struct pt_regs_dwarfnum {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <perf/cpumap.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <api/fs/fs.h>
|
#include <api/fs/fs.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
@@ -29,7 +31,7 @@ char *get_cpuid_str(struct perf_pmu *pmu)
|
|||||||
|
|
||||||
/* read midr from list of cpus mapped to this pmu */
|
/* read midr from list of cpus mapped to this pmu */
|
||||||
cpus = perf_cpu_map__get(pmu->cpus);
|
cpus = perf_cpu_map__get(pmu->cpus);
|
||||||
for (cpu = 0; cpu < cpus->nr; cpu++) {
|
for (cpu = 0; cpu < perf_cpu_map__nr(cpus); cpu++) {
|
||||||
scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR,
|
scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR,
|
||||||
sysfs, cpus->map[cpu]);
|
sysfs, cpus->map[cpu]);
|
||||||
|
|
||||||
|
@@ -5,8 +5,8 @@
|
|||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#include "perf_regs.h"
|
#include "perf_regs.h"
|
||||||
#include "../../util/unwind.h"
|
#include "../../util/unwind.h"
|
||||||
#include "../../util/debug.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
#include "../../util/debug.h"
|
||||||
|
|
||||||
int LIBUNWIND__ARCH_REG_ID(int regnum)
|
int LIBUNWIND__ARCH_REG_ID(int regnum)
|
||||||
{
|
{
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
#include <linux/ptrace.h>
|
#include <linux/ptrace.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
struct pt_regs_dwarfnum {
|
struct pt_regs_dwarfnum {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#define mfspr(rn) ({unsigned long rval; \
|
#define mfspr(rn) ({unsigned long rval; \
|
||||||
asm volatile("mfspr %0," __stringify(rn) \
|
asm volatile("mfspr %0," __stringify(rn) \
|
||||||
|
@@ -5,9 +5,11 @@
|
|||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
|
#include "util/pmu.h"
|
||||||
|
|
||||||
#include "book3s_hv_exits.h"
|
#include "book3s_hv_exits.h"
|
||||||
#include "book3s_hcalls.h"
|
#include "book3s_hcalls.h"
|
||||||
|
#include <subcmd/parse-options.h>
|
||||||
|
|
||||||
#define NR_TPS 4
|
#define NR_TPS 4
|
||||||
|
|
||||||
@@ -172,3 +174,46 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Incase of powerpc architecture, pmu registers are programmable
|
||||||
|
* by guest kernel. So monitoring guest via host may not provide
|
||||||
|
* valid samples with default 'cycles' event. It is better to use
|
||||||
|
* 'trace_imc/trace_cycles' event for guest profiling, since it
|
||||||
|
* can track the guest instruction pointer in the trace-record.
|
||||||
|
*
|
||||||
|
* Function to parse the arguments and return appropriate values.
|
||||||
|
*/
|
||||||
|
int kvm_add_default_arch_event(int *argc, const char **argv)
|
||||||
|
{
|
||||||
|
const char **tmp;
|
||||||
|
bool event = false;
|
||||||
|
int i, j = *argc;
|
||||||
|
|
||||||
|
const struct option event_options[] = {
|
||||||
|
OPT_BOOLEAN('e', "event", &event, NULL),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
tmp = calloc(j + 1, sizeof(char *));
|
||||||
|
if (!tmp)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < j; i++)
|
||||||
|
tmp[i] = argv[i];
|
||||||
|
|
||||||
|
parse_options(j, tmp, event_options, NULL, PARSE_OPT_KEEP_UNKNOWN);
|
||||||
|
if (!event) {
|
||||||
|
if (pmu_have_event("trace_imc", "trace_cycles")) {
|
||||||
|
argv[j++] = strdup("-e");
|
||||||
|
argv[j++] = strdup("trace_imc/trace_cycles/");
|
||||||
|
*argc += 2;
|
||||||
|
} else {
|
||||||
|
free(tmp);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "util/callchain.h"
|
#include "util/callchain.h"
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/dso.h"
|
#include "util/dso.h"
|
||||||
|
#include "util/event.h" // struct ip_callchain
|
||||||
#include "util/map.h"
|
#include "util/map.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
|
|
||||||
|
@@ -4,7 +4,6 @@
|
|||||||
* Copyright (C) 2015 Naveen N. Rao, IBM Corporation
|
* Copyright (C) 2015 Naveen N. Rao, IBM Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "dso.h"
|
#include "dso.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
@@ -4,6 +4,7 @@ PERF_HAVE_DWARF_REGS := 1
|
|||||||
endif
|
endif
|
||||||
HAVE_KVM_STAT_SUPPORT := 1
|
HAVE_KVM_STAT_SUPPORT := 1
|
||||||
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
|
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
|
||||||
|
PERF_HAVE_JITDUMP := 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Syscall table generation for perf
|
# Syscall table generation for perf
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "util.h"
|
#include <internal/lib.h> // page_size
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "api/fs/fs.h"
|
#include "api/fs/fs.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
#include "evlist.h"
|
#include "evlist.h"
|
||||||
#include "evsel.h"
|
#include "evsel.h"
|
||||||
#include "arch-tests.h"
|
#include "arch-tests.h"
|
||||||
#include "util.h"
|
#include <internal/lib.h> // page_size
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@@ -63,9 +63,9 @@ int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subt
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
evsel = perf_evlist__first(evlist);
|
evsel = evlist__first(evlist);
|
||||||
if (!evsel) {
|
if (!evsel) {
|
||||||
pr_debug("perf_evlist__first failed\n");
|
pr_debug("evlist__first failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,9 +15,9 @@
|
|||||||
#include "evlist.h"
|
#include "evlist.h"
|
||||||
#include "evsel.h"
|
#include "evsel.h"
|
||||||
#include "thread_map.h"
|
#include "thread_map.h"
|
||||||
#include "cpumap.h"
|
|
||||||
#include "record.h"
|
#include "record.h"
|
||||||
#include "tsc.h"
|
#include "tsc.h"
|
||||||
|
#include "util/mmap.h"
|
||||||
#include "tests/tests.h"
|
#include "tests/tests.h"
|
||||||
|
|
||||||
#include "arch-tests.h"
|
#include "arch-tests.h"
|
||||||
@@ -66,7 +66,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
|
|||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
u64 test_tsc, comm1_tsc, comm2_tsc;
|
u64 test_tsc, comm1_tsc, comm2_tsc;
|
||||||
u64 test_time, comm1_time = 0, comm2_time = 0;
|
u64 test_time, comm1_time = 0, comm2_time = 0;
|
||||||
struct perf_mmap *md;
|
struct mmap *md;
|
||||||
|
|
||||||
threads = thread_map__new(-1, getpid(), UINT_MAX);
|
threads = thread_map__new(-1, getpid(), UINT_MAX);
|
||||||
CHECK_NOT_NULL__(threads);
|
CHECK_NOT_NULL__(threads);
|
||||||
@@ -83,7 +83,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
|
|||||||
|
|
||||||
perf_evlist__config(evlist, &opts, NULL);
|
perf_evlist__config(evlist, &opts, NULL);
|
||||||
|
|
||||||
evsel = perf_evlist__first(evlist);
|
evsel = evlist__first(evlist);
|
||||||
|
|
||||||
evsel->core.attr.comm = 1;
|
evsel->core.attr.comm = 1;
|
||||||
evsel->core.attr.disabled = 1;
|
evsel->core.attr.disabled = 1;
|
||||||
@@ -91,9 +91,9 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
|
|||||||
|
|
||||||
CHECK__(evlist__open(evlist));
|
CHECK__(evlist__open(evlist));
|
||||||
|
|
||||||
CHECK__(perf_evlist__mmap(evlist, UINT_MAX));
|
CHECK__(evlist__mmap(evlist, UINT_MAX));
|
||||||
|
|
||||||
pc = evlist->mmap[0].base;
|
pc = evlist->mmap[0].core.base;
|
||||||
ret = perf_read_tsc_conversion(pc, &tc);
|
ret = perf_read_tsc_conversion(pc, &tc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret == -EOPNOTSUPP) {
|
if (ret == -EOPNOTSUPP) {
|
||||||
@@ -115,7 +115,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
|
|||||||
|
|
||||||
evlist__disable(evlist);
|
evlist__disable(evlist);
|
||||||
|
|
||||||
for (i = 0; i < evlist->nr_mmaps; i++) {
|
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||||
md = &evlist->mmap[i];
|
md = &evlist->mmap[i];
|
||||||
if (perf_mmap__read_init(md) < 0)
|
if (perf_mmap__read_init(md) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
#include "tests/tests.h"
|
#include "tests/tests.h"
|
||||||
#include "cloexec.h"
|
#include "cloexec.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "util.h"
|
#include <internal/lib.h> // page_size
|
||||||
#include "arch-tests.h"
|
#include "arch-tests.h"
|
||||||
|
|
||||||
static u64 rdpmc(unsigned int counter)
|
static u64 rdpmc(unsigned int counter)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include "../../../../arch/x86/include/asm/insn.h"
|
#include "../../../../arch/x86/include/asm/insn.h"
|
||||||
#include "archinsn.h"
|
#include "archinsn.h"
|
||||||
|
#include "event.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
|
|
||||||
|
#include "../../util/event.h"
|
||||||
|
#include "../../util/synthetic-events.h"
|
||||||
#include "../../util/machine.h"
|
#include "../../util/machine.h"
|
||||||
#include "../../util/tool.h"
|
#include "../../util/tool.h"
|
||||||
#include "../../util/map.h"
|
#include "../../util/map.h"
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "../../util/event.h"
|
#include "../../util/event.h"
|
||||||
#include "../../util/evsel.h"
|
#include "../../util/evsel.h"
|
||||||
#include "../../util/evlist.h"
|
#include "../../util/evlist.h"
|
||||||
|
#include "../../util/mmap.h"
|
||||||
#include "../../util/session.h"
|
#include "../../util/session.h"
|
||||||
#include "../../util/pmu.h"
|
#include "../../util/pmu.h"
|
||||||
#include "../../util/debug.h"
|
#include "../../util/debug.h"
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
#include "../../util/tsc.h"
|
#include "../../util/tsc.h"
|
||||||
#include "../../util/auxtrace.h"
|
#include "../../util/auxtrace.h"
|
||||||
#include "../../util/intel-bts.h"
|
#include "../../util/intel-bts.h"
|
||||||
#include "../../util/util.h"
|
#include <internal/lib.h> // page_size
|
||||||
|
|
||||||
#define KiB(x) ((x) * 1024)
|
#define KiB(x) ((x) * 1024)
|
||||||
#define MiB(x) ((x) * 1024 * 1024)
|
#define MiB(x) ((x) * 1024 * 1024)
|
||||||
@@ -74,10 +75,10 @@ static int intel_bts_info_fill(struct auxtrace_record *itr,
|
|||||||
if (priv_size != INTEL_BTS_AUXTRACE_PRIV_SIZE)
|
if (priv_size != INTEL_BTS_AUXTRACE_PRIV_SIZE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!session->evlist->nr_mmaps)
|
if (!session->evlist->core.nr_mmaps)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pc = session->evlist->mmap[0].base;
|
pc = session->evlist->mmap[0].core.base;
|
||||||
if (pc) {
|
if (pc) {
|
||||||
err = perf_read_tsc_conversion(pc, &tc);
|
err = perf_read_tsc_conversion(pc, &tc);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -230,7 +231,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
tracking_evsel = perf_evlist__last(evlist);
|
tracking_evsel = evlist__last(evlist);
|
||||||
|
|
||||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||||
|
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "../../util/evlist.h"
|
#include "../../util/evlist.h"
|
||||||
#include "../../util/evsel.h"
|
#include "../../util/evsel.h"
|
||||||
#include "../../util/cpumap.h"
|
#include "../../util/cpumap.h"
|
||||||
|
#include "../../util/mmap.h"
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "../../util/parse-events.h"
|
#include "../../util/parse-events.h"
|
||||||
#include "../../util/pmu.h"
|
#include "../../util/pmu.h"
|
||||||
@@ -26,7 +27,7 @@
|
|||||||
#include "../../util/record.h"
|
#include "../../util/record.h"
|
||||||
#include "../../util/target.h"
|
#include "../../util/target.h"
|
||||||
#include "../../util/tsc.h"
|
#include "../../util/tsc.h"
|
||||||
#include "../../util/util.h"
|
#include <internal/lib.h> // page_size
|
||||||
#include "../../util/intel-pt.h"
|
#include "../../util/intel-pt.h"
|
||||||
|
|
||||||
#define KiB(x) ((x) * 1024)
|
#define KiB(x) ((x) * 1024)
|
||||||
@@ -351,10 +352,10 @@ static int intel_pt_info_fill(struct auxtrace_record *itr,
|
|||||||
filter = intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu);
|
filter = intel_pt_find_filter(session->evlist, ptr->intel_pt_pmu);
|
||||||
filter_str_len = filter ? strlen(filter) : 0;
|
filter_str_len = filter ? strlen(filter) : 0;
|
||||||
|
|
||||||
if (!session->evlist->nr_mmaps)
|
if (!session->evlist->core.nr_mmaps)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pc = session->evlist->mmap[0].base;
|
pc = session->evlist->mmap[0].core.base;
|
||||||
if (pc) {
|
if (pc) {
|
||||||
err = perf_read_tsc_conversion(pc, &tc);
|
err = perf_read_tsc_conversion(pc, &tc);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -416,12 +417,12 @@ static int intel_pt_track_switches(struct evlist *evlist)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
evsel = perf_evlist__last(evlist);
|
evsel = evlist__last(evlist);
|
||||||
|
|
||||||
perf_evsel__set_sample_bit(evsel, CPU);
|
perf_evsel__set_sample_bit(evsel, CPU);
|
||||||
perf_evsel__set_sample_bit(evsel, TIME);
|
perf_evsel__set_sample_bit(evsel, TIME);
|
||||||
|
|
||||||
evsel->system_wide = true;
|
evsel->core.system_wide = true;
|
||||||
evsel->no_aux_samples = true;
|
evsel->no_aux_samples = true;
|
||||||
evsel->immediate = true;
|
evsel->immediate = true;
|
||||||
|
|
||||||
@@ -716,13 +717,13 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
switch_evsel = perf_evlist__last(evlist);
|
switch_evsel = evlist__last(evlist);
|
||||||
|
|
||||||
switch_evsel->core.attr.freq = 0;
|
switch_evsel->core.attr.freq = 0;
|
||||||
switch_evsel->core.attr.sample_period = 1;
|
switch_evsel->core.attr.sample_period = 1;
|
||||||
switch_evsel->core.attr.context_switch = 1;
|
switch_evsel->core.attr.context_switch = 1;
|
||||||
|
|
||||||
switch_evsel->system_wide = true;
|
switch_evsel->core.system_wide = true;
|
||||||
switch_evsel->no_aux_samples = true;
|
switch_evsel->no_aux_samples = true;
|
||||||
switch_evsel->immediate = true;
|
switch_evsel->immediate = true;
|
||||||
|
|
||||||
@@ -774,7 +775,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
tracking_evsel = perf_evlist__last(evlist);
|
tracking_evsel = evlist__last(evlist);
|
||||||
|
|
||||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||||
|
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../../util/util.h"
|
#include <internal/lib.h> // page_size
|
||||||
#include "../../util/machine.h"
|
#include "../../util/machine.h"
|
||||||
#include "../../util/map.h"
|
#include "../../util/map.h"
|
||||||
#include "../../util/symbol.h"
|
#include "../../util/symbol.h"
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/barrier.h>
|
#include <asm/barrier.h>
|
||||||
#include "../../../util/debug.h"
|
#include "../../../util/debug.h"
|
||||||
|
#include "../../../util/event.h"
|
||||||
|
#include "../../../util/synthetic-events.h"
|
||||||
#include "../../../util/tsc.h"
|
#include "../../../util/tsc.h"
|
||||||
|
|
||||||
int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "../../util/debug.h"
|
||||||
#ifndef REMOTE_UNWIND_LIBUNWIND
|
#ifndef REMOTE_UNWIND_LIBUNWIND
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#include "perf_regs.h"
|
#include "perf_regs.h"
|
||||||
#include "../../util/unwind.h"
|
#include "../../util/unwind.h"
|
||||||
#include "../../util/debug.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||||
|
@@ -21,12 +21,12 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
|
|
||||||
#include "../util/stat.h"
|
#include "../util/stat.h"
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "cpumap.h"
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
|
||||||
|
@@ -76,12 +76,12 @@
|
|||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
|
|
||||||
#include "../util/stat.h"
|
#include "../util/stat.h"
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "cpumap.h"
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
|
||||||
|
@@ -20,13 +20,13 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
|
|
||||||
#include "../util/stat.h"
|
#include "../util/stat.h"
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "futex.h"
|
#include "futex.h"
|
||||||
#include "cpumap.h"
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
|
||||||
|
@@ -14,10 +14,10 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "futex.h"
|
#include "futex.h"
|
||||||
#include "cpumap.h"
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -20,10 +20,10 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "futex.h"
|
#include "futex.h"
|
||||||
#include "cpumap.h"
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -29,7 +29,8 @@ int bench_futex_wake_parallel(int argc __maybe_unused, const char **argv __maybe
|
|||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "futex.h"
|
#include "futex.h"
|
||||||
#include "cpumap.h"
|
#include <internal/cpumap.h>
|
||||||
|
#include <perf/cpumap.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -20,10 +20,10 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <internal/cpumap.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
#include "futex.h"
|
#include "futex.h"
|
||||||
#include "cpumap.h"
|
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
/* For the CLR_() macros */
|
/* For the CLR_() macros */
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "../builtin.h"
|
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "../util/cloexec.h"
|
#include "../util/cloexec.h"
|
||||||
|
|
||||||
|
@@ -10,9 +10,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../util/util.h"
|
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "../builtin.h"
|
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
/* Test groups of 20 processes spraying to 20 receivers */
|
/* Test groups of 20 processes spraying to 20 receivers */
|
||||||
|
@@ -9,9 +9,7 @@
|
|||||||
* http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
|
* http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
|
||||||
* Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
|
* Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
|
||||||
*/
|
*/
|
||||||
#include "../util/util.h"
|
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "../builtin.h"
|
|
||||||
#include "bench.h"
|
#include "bench.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "util/sort.h"
|
#include "util/sort.h"
|
||||||
#include "util/hist.h"
|
#include "util/hist.h"
|
||||||
#include "util/dso.h"
|
#include "util/dso.h"
|
||||||
|
#include "util/machine.h"
|
||||||
#include "util/map.h"
|
#include "util/map.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
struct perf_annotate {
|
struct perf_annotate {
|
||||||
struct perf_tool tool;
|
struct perf_tool tool;
|
||||||
@@ -583,8 +585,8 @@ int cmd_annotate(int argc, const char **argv)
|
|||||||
data.path = input_name;
|
data.path = input_name;
|
||||||
|
|
||||||
annotate.session = perf_session__new(&data, false, &annotate.tool);
|
annotate.session = perf_session__new(&data, false, &annotate.tool);
|
||||||
if (annotate.session == NULL)
|
if (IS_ERR(annotate.session))
|
||||||
return -1;
|
return PTR_ERR(annotate.session);
|
||||||
|
|
||||||
annotate.has_br_stack = perf_header__has_feat(&annotate.session->header,
|
annotate.has_br_stack = perf_header__has_feat(&annotate.session->header,
|
||||||
HEADER_BRANCH_STACK);
|
HEADER_BRANCH_STACK);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
#include "util/probe-file.h"
|
#include "util/probe-file.h"
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
|
static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
|
||||||
{
|
{
|
||||||
@@ -422,8 +423,8 @@ int cmd_buildid_cache(int argc, const char **argv)
|
|||||||
data.force = force;
|
data.force = force;
|
||||||
|
|
||||||
session = perf_session__new(&data, false, NULL);
|
session = perf_session__new(&data, false, NULL);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol__init(session ? &session->header.env : NULL) < 0)
|
if (symbol__init(session ? &session->header.env : NULL) < 0)
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
#include "util/data.h"
|
#include "util/data.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
static int sysfs__fprintf_build_id(FILE *fp)
|
static int sysfs__fprintf_build_id(FILE *fp)
|
||||||
{
|
{
|
||||||
@@ -65,8 +66,8 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops);
|
session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We take all buildids when the file contains AUX area tracing data
|
* We take all buildids when the file contains AUX area tracing data
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/err.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
#include <perf/cpumap.h>
|
||||||
#include <subcmd/pager.h>
|
#include <subcmd/pager.h>
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "map_symbol.h"
|
#include "map_symbol.h"
|
||||||
@@ -2780,8 +2782,9 @@ static int perf_c2c__report(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
session = perf_session__new(&data, 0, &c2c.tool);
|
session = perf_session__new(&data, 0, &c2c.tool);
|
||||||
if (session == NULL) {
|
if (IS_ERR(session)) {
|
||||||
pr_debug("No memory for session\n");
|
err = PTR_ERR(session);
|
||||||
|
pr_debug("Error creating perf session\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "util/cache.h"
|
#include "util/cache.h"
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "util/util.h"
|
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/config.h"
|
#include "util/config.h"
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "util/time-utils.h"
|
#include "util/time-utils.h"
|
||||||
#include "util/annotate.h"
|
#include "util/annotate.h"
|
||||||
#include "util/map.h"
|
#include "util/map.h"
|
||||||
|
#include <linux/err.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
#include <subcmd/pager.h>
|
#include <subcmd/pager.h>
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
@@ -1153,9 +1154,9 @@ static int check_file_brstack(void)
|
|||||||
|
|
||||||
data__for_each_file(i, d) {
|
data__for_each_file(i, d) {
|
||||||
d->session = perf_session__new(&d->data, false, &pdiff.tool);
|
d->session = perf_session__new(&d->data, false, &pdiff.tool);
|
||||||
if (!d->session) {
|
if (IS_ERR(d->session)) {
|
||||||
pr_err("Failed to open %s\n", d->data.path);
|
pr_err("Failed to open %s\n", d->data.path);
|
||||||
return -1;
|
return PTR_ERR(d->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
has_br_stack = perf_header__has_feat(&d->session->header,
|
has_br_stack = perf_header__has_feat(&d->session->header,
|
||||||
@@ -1185,9 +1186,9 @@ static int __cmd_diff(void)
|
|||||||
|
|
||||||
data__for_each_file(i, d) {
|
data__for_each_file(i, d) {
|
||||||
d->session = perf_session__new(&d->data, false, &pdiff.tool);
|
d->session = perf_session__new(&d->data, false, &pdiff.tool);
|
||||||
if (!d->session) {
|
if (IS_ERR(d->session)) {
|
||||||
|
ret = PTR_ERR(d->session);
|
||||||
pr_err("Failed to open %s\n", d->data.path);
|
pr_err("Failed to open %s\n", d->data.path);
|
||||||
ret = -1;
|
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,18 +5,18 @@
|
|||||||
*/
|
*/
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
||||||
#include "util/util.h"
|
|
||||||
|
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
|
||||||
#include "perf.h"
|
#include "perf.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
|
#include "util/evsel_fprintf.h"
|
||||||
#include "util/parse-events.h"
|
#include "util/parse-events.h"
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/data.h"
|
#include "util/data.h"
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
|
static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
|
||||||
{
|
{
|
||||||
@@ -30,8 +30,8 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
|
|||||||
bool has_tracepoint = false;
|
bool has_tracepoint = false;
|
||||||
|
|
||||||
session = perf_session__new(&data, 0, NULL);
|
session = perf_session__new(&data, 0, NULL);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
evlist__for_each_entry(session->evlist, pos) {
|
evlist__for_each_entry(session->evlist, pos) {
|
||||||
perf_evsel__fprintf(pos, details, stdout);
|
perf_evsel__fprintf(pos, details, stdout);
|
||||||
|
@@ -21,7 +21,9 @@
|
|||||||
#include "util/auxtrace.h"
|
#include "util/auxtrace.h"
|
||||||
#include "util/jit.h"
|
#include "util/jit.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
|
#include "util/synthetic-events.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
|
|
||||||
@@ -834,8 +836,8 @@ int cmd_inject(int argc, const char **argv)
|
|||||||
|
|
||||||
data.path = inject.input_name;
|
data.path = inject.input_name;
|
||||||
inject.session = perf_session__new(&data, true, &inject.tool);
|
inject.session = perf_session__new(&data, true, &inject.tool);
|
||||||
if (inject.session == NULL)
|
if (IS_ERR(inject.session))
|
||||||
return -1;
|
return PTR_ERR(inject.session);
|
||||||
|
|
||||||
if (zstd_init(&(inject.session->zstd_data), 0) < 0)
|
if (zstd_init(&(inject.session->zstd_data), 0) < 0)
|
||||||
pr_warning("Decompression initialization failed.\n");
|
pr_warning("Decompression initialization failed.\n");
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/callchain.h"
|
#include "util/callchain.h"
|
||||||
#include "util/time-utils.h"
|
#include "util/time-utils.h"
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#include <subcmd/pager.h>
|
#include <subcmd/pager.h>
|
||||||
#include <subcmd/parse-options.h>
|
#include <subcmd/parse-options.h>
|
||||||
@@ -1956,8 +1957,8 @@ int cmd_kmem(int argc, const char **argv)
|
|||||||
data.path = input_name;
|
data.path = input_name;
|
||||||
|
|
||||||
kmem_session = session = perf_session__new(&data, false, &perf_kmem);
|
kmem_session = session = perf_session__new(&data, false, &perf_kmem);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include "util/build-id.h"
|
#include "util/build-id.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
|
#include "util/mmap.h"
|
||||||
#include "util/term.h"
|
#include "util/term.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
@@ -17,9 +18,11 @@
|
|||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/stat.h"
|
#include "util/stat.h"
|
||||||
|
#include "util/synthetic-events.h"
|
||||||
#include "util/top.h"
|
#include "util/top.h"
|
||||||
#include "util/data.h"
|
#include "util/data.h"
|
||||||
#include "util/ordered-events.h"
|
#include "util/ordered-events.h"
|
||||||
|
#include "util/kvm-stat.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
@@ -31,6 +34,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
@@ -58,7 +62,6 @@ static const char *get_filename_for_perf_kvm(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_KVM_STAT_SUPPORT
|
#ifdef HAVE_KVM_STAT_SUPPORT
|
||||||
#include "util/kvm-stat.h"
|
|
||||||
|
|
||||||
void exit_event_get_key(struct evsel *evsel,
|
void exit_event_get_key(struct evsel *evsel,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample,
|
||||||
@@ -748,7 +751,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
|
|||||||
{
|
{
|
||||||
struct evlist *evlist = kvm->evlist;
|
struct evlist *evlist = kvm->evlist;
|
||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
struct perf_mmap *md;
|
struct mmap *md;
|
||||||
u64 timestamp;
|
u64 timestamp;
|
||||||
s64 n = 0;
|
s64 n = 0;
|
||||||
int err;
|
int err;
|
||||||
@@ -799,7 +802,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
|
|||||||
s64 n, ntotal = 0;
|
s64 n, ntotal = 0;
|
||||||
u64 flush_time = ULLONG_MAX, mmap_time;
|
u64 flush_time = ULLONG_MAX, mmap_time;
|
||||||
|
|
||||||
for (i = 0; i < kvm->evlist->nr_mmaps; i++) {
|
for (i = 0; i < kvm->evlist->core.nr_mmaps; i++) {
|
||||||
n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
|
n = perf_kvm__mmap_read_idx(kvm, i, &mmap_time);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -964,10 +967,10 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
|
if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
nr_stdin = perf_evlist__add_pollfd(kvm->evlist, fileno(stdin));
|
nr_stdin = evlist__add_pollfd(kvm->evlist, fileno(stdin));
|
||||||
if (nr_stdin < 0)
|
if (nr_stdin < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -978,7 +981,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
|
|||||||
evlist__enable(kvm->evlist);
|
evlist__enable(kvm->evlist);
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
struct fdarray *fda = &kvm->evlist->pollfd;
|
struct fdarray *fda = &kvm->evlist->core.pollfd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = perf_kvm__mmap_read(kvm);
|
rc = perf_kvm__mmap_read(kvm);
|
||||||
@@ -1058,7 +1061,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) {
|
if (evlist__mmap(evlist, kvm->opts.mmap_pages) < 0) {
|
||||||
ui__error("Failed to mmap the events: %s\n",
|
ui__error("Failed to mmap the events: %s\n",
|
||||||
str_error_r(errno, sbuf, sizeof(sbuf)));
|
str_error_r(errno, sbuf, sizeof(sbuf)));
|
||||||
evlist__close(evlist);
|
evlist__close(evlist);
|
||||||
@@ -1090,9 +1093,9 @@ static int read_events(struct perf_kvm_stat *kvm)
|
|||||||
|
|
||||||
kvm->tool = eops;
|
kvm->tool = eops;
|
||||||
kvm->session = perf_session__new(&file, false, &kvm->tool);
|
kvm->session = perf_session__new(&file, false, &kvm->tool);
|
||||||
if (!kvm->session) {
|
if (IS_ERR(kvm->session)) {
|
||||||
pr_err("Initializing perf session failed\n");
|
pr_err("Initializing perf session failed\n");
|
||||||
return -1;
|
return PTR_ERR(kvm->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol__init(&kvm->session->header.env);
|
symbol__init(&kvm->session->header.env);
|
||||||
@@ -1445,8 +1448,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
|||||||
* perf session
|
* perf session
|
||||||
*/
|
*/
|
||||||
kvm->session = perf_session__new(&data, false, &kvm->tool);
|
kvm->session = perf_session__new(&data, false, &kvm->tool);
|
||||||
if (kvm->session == NULL) {
|
if (IS_ERR(kvm->session)) {
|
||||||
err = -1;
|
err = PTR_ERR(kvm->session);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
kvm->session->evlist = kvm->evlist;
|
kvm->session->evlist = kvm->evlist;
|
||||||
@@ -1513,11 +1516,21 @@ perf_stat:
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_KVM_STAT_SUPPORT */
|
#endif /* HAVE_KVM_STAT_SUPPORT */
|
||||||
|
|
||||||
|
int __weak kvm_add_default_arch_event(int *argc __maybe_unused,
|
||||||
|
const char **argv __maybe_unused)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int __cmd_record(const char *file_name, int argc, const char **argv)
|
static int __cmd_record(const char *file_name, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
int rec_argc, i = 0, j;
|
int rec_argc, i = 0, j, ret;
|
||||||
const char **rec_argv;
|
const char **rec_argv;
|
||||||
|
|
||||||
|
ret = kvm_add_default_arch_event(&argc, argv);
|
||||||
|
if (ret)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
rec_argc = argc + 2;
|
rec_argc = argc + 2;
|
||||||
rec_argv = calloc(rec_argc + 1, sizeof(char *));
|
rec_argv = calloc(rec_argc + 1, sizeof(char *));
|
||||||
rec_argv[i++] = strdup("record");
|
rec_argv[i++] = strdup("record");
|
||||||
|
@@ -81,9 +81,9 @@ int cmd_list(int argc, const char **argv)
|
|||||||
long_desc_flag, details_flag);
|
long_desc_flag, details_flag);
|
||||||
else if (strcmp(argv[i], "sdt") == 0)
|
else if (strcmp(argv[i], "sdt") == 0)
|
||||||
print_sdt_events(NULL, NULL, raw_dump);
|
print_sdt_events(NULL, NULL, raw_dump);
|
||||||
else if (strcmp(argv[i], "metric") == 0)
|
else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0)
|
||||||
metricgroup__print(true, false, NULL, raw_dump, details_flag);
|
metricgroup__print(true, false, NULL, raw_dump, details_flag);
|
||||||
else if (strcmp(argv[i], "metricgroup") == 0)
|
else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0)
|
||||||
metricgroup__print(false, true, NULL, raw_dump, details_flag);
|
metricgroup__print(false, true, NULL, raw_dump, details_flag);
|
||||||
else if ((sep = strchr(argv[i], ':')) != NULL) {
|
else if ((sep = strchr(argv[i], ':')) != NULL) {
|
||||||
int sep_idx;
|
int sep_idx;
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <linux/hash.h>
|
#include <linux/hash.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
static struct perf_session *session;
|
static struct perf_session *session;
|
||||||
|
|
||||||
@@ -872,9 +873,9 @@ static int __cmd_report(bool display_info)
|
|||||||
};
|
};
|
||||||
|
|
||||||
session = perf_session__new(&data, false, &eops);
|
session = perf_session__new(&data, false, &eops);
|
||||||
if (!session) {
|
if (IS_ERR(session)) {
|
||||||
pr_err("Initializing perf session failed\n");
|
pr_err("Initializing perf session failed\n");
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol__init(&session->header.env);
|
symbol__init(&session->header.env);
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "util/dso.h"
|
#include "util/dso.h"
|
||||||
#include "util/map.h"
|
#include "util/map.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#define MEM_OPERATION_LOAD 0x1
|
#define MEM_OPERATION_LOAD 0x1
|
||||||
#define MEM_OPERATION_STORE 0x2
|
#define MEM_OPERATION_STORE 0x2
|
||||||
@@ -249,8 +250,8 @@ static int report_raw_events(struct perf_mem *mem)
|
|||||||
struct perf_session *session = perf_session__new(&data, false,
|
struct perf_session *session = perf_session__new(&data, false,
|
||||||
&mem->tool);
|
&mem->tool);
|
||||||
|
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
if (mem->cpu_list) {
|
if (mem->cpu_list) {
|
||||||
ret = perf_session__cpu_bitmap(session, mem->cpu_list,
|
ret = perf_session__cpu_bitmap(session, mem->cpu_list,
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
|
#include "util/mmap.h"
|
||||||
#include "util/target.h"
|
#include "util/target.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
#include "util/trigger.h"
|
#include "util/trigger.h"
|
||||||
#include "util/perf-hooks.h"
|
#include "util/perf-hooks.h"
|
||||||
#include "util/cpu-set-sched.h"
|
#include "util/cpu-set-sched.h"
|
||||||
|
#include "util/synthetic-events.h"
|
||||||
#include "util/time-utils.h"
|
#include "util/time-utils.h"
|
||||||
#include "util/units.h"
|
#include "util/units.h"
|
||||||
#include "util/bpf-event.h"
|
#include "util/bpf-event.h"
|
||||||
@@ -53,6 +55,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <linux/err.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
@@ -117,7 +120,7 @@ static bool switch_output_time(struct record *rec)
|
|||||||
trigger_is_ready(&switch_output_trigger);
|
trigger_is_ready(&switch_output_trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int record__write(struct record *rec, struct perf_mmap *map __maybe_unused,
|
static int record__write(struct record *rec, struct mmap *map __maybe_unused,
|
||||||
void *bf, size_t size)
|
void *bf, size_t size)
|
||||||
{
|
{
|
||||||
struct perf_data_file *file = &rec->session->data->file;
|
struct perf_data_file *file = &rec->session->data->file;
|
||||||
@@ -166,7 +169,7 @@ static int record__aio_write(struct aiocb *cblock, int trace_fd,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
|
static int record__aio_complete(struct mmap *md, struct aiocb *cblock)
|
||||||
{
|
{
|
||||||
void *rem_buf;
|
void *rem_buf;
|
||||||
off_t rem_off;
|
off_t rem_off;
|
||||||
@@ -212,7 +215,7 @@ static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int record__aio_sync(struct perf_mmap *md, bool sync_all)
|
static int record__aio_sync(struct mmap *md, bool sync_all)
|
||||||
{
|
{
|
||||||
struct aiocb **aiocb = md->aio.aiocb;
|
struct aiocb **aiocb = md->aio.aiocb;
|
||||||
struct aiocb *cblocks = md->aio.cblocks;
|
struct aiocb *cblocks = md->aio.cblocks;
|
||||||
@@ -253,12 +256,12 @@ struct record_aio {
|
|||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t size)
|
static int record__aio_pushfn(struct mmap *map, void *to, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
struct record_aio *aio = to;
|
struct record_aio *aio = to;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* map->base data pointed by buf is copied into free map->aio.data[] buffer
|
* map->core.base data pointed by buf is copied into free map->aio.data[] buffer
|
||||||
* to release space in the kernel buffer as fast as possible, calling
|
* to release space in the kernel buffer as fast as possible, calling
|
||||||
* perf_mmap__consume() from perf_mmap__push() function.
|
* perf_mmap__consume() from perf_mmap__push() function.
|
||||||
*
|
*
|
||||||
@@ -298,7 +301,7 @@ static int record__aio_pushfn(struct perf_mmap *map, void *to, void *buf, size_t
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int record__aio_push(struct record *rec, struct perf_mmap *map, off_t *off)
|
static int record__aio_push(struct record *rec, struct mmap *map, off_t *off)
|
||||||
{
|
{
|
||||||
int ret, idx;
|
int ret, idx;
|
||||||
int trace_fd = rec->session->data->file.fd;
|
int trace_fd = rec->session->data->file.fd;
|
||||||
@@ -349,15 +352,15 @@ static void record__aio_mmap_read_sync(struct record *rec)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct evlist *evlist = rec->evlist;
|
struct evlist *evlist = rec->evlist;
|
||||||
struct perf_mmap *maps = evlist->mmap;
|
struct mmap *maps = evlist->mmap;
|
||||||
|
|
||||||
if (!record__aio_enabled(rec))
|
if (!record__aio_enabled(rec))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < evlist->nr_mmaps; i++) {
|
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||||
struct perf_mmap *map = &maps[i];
|
struct mmap *map = &maps[i];
|
||||||
|
|
||||||
if (map->base)
|
if (map->core.base)
|
||||||
record__aio_sync(map, true);
|
record__aio_sync(map, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,7 +388,7 @@ static int record__aio_parse(const struct option *opt,
|
|||||||
#else /* HAVE_AIO_SUPPORT */
|
#else /* HAVE_AIO_SUPPORT */
|
||||||
static int nr_cblocks_max = 0;
|
static int nr_cblocks_max = 0;
|
||||||
|
|
||||||
static int record__aio_push(struct record *rec __maybe_unused, struct perf_mmap *map __maybe_unused,
|
static int record__aio_push(struct record *rec __maybe_unused, struct mmap *map __maybe_unused,
|
||||||
off_t *off __maybe_unused)
|
off_t *off __maybe_unused)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@@ -437,7 +440,7 @@ static int record__mmap_flush_parse(const struct option *opt,
|
|||||||
if (!opts->mmap_flush)
|
if (!opts->mmap_flush)
|
||||||
opts->mmap_flush = MMAP_FLUSH_DEFAULT;
|
opts->mmap_flush = MMAP_FLUSH_DEFAULT;
|
||||||
|
|
||||||
flush_max = perf_evlist__mmap_size(opts->mmap_pages);
|
flush_max = evlist__mmap_size(opts->mmap_pages);
|
||||||
flush_max /= 4;
|
flush_max /= 4;
|
||||||
if (opts->mmap_flush > flush_max)
|
if (opts->mmap_flush > flush_max)
|
||||||
opts->mmap_flush = flush_max;
|
opts->mmap_flush = flush_max;
|
||||||
@@ -480,7 +483,7 @@ static int process_synthesized_event(struct perf_tool *tool,
|
|||||||
return record__write(rec, NULL, event, event->header.size);
|
return record__write(rec, NULL, event, event->header.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int record__pushfn(struct perf_mmap *map, void *to, void *bf, size_t size)
|
static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size)
|
||||||
{
|
{
|
||||||
struct record *rec = to;
|
struct record *rec = to;
|
||||||
|
|
||||||
@@ -525,7 +528,7 @@ static void record__sig_exit(void)
|
|||||||
#ifdef HAVE_AUXTRACE_SUPPORT
|
#ifdef HAVE_AUXTRACE_SUPPORT
|
||||||
|
|
||||||
static int record__process_auxtrace(struct perf_tool *tool,
|
static int record__process_auxtrace(struct perf_tool *tool,
|
||||||
struct perf_mmap *map,
|
struct mmap *map,
|
||||||
union perf_event *event, void *data1,
|
union perf_event *event, void *data1,
|
||||||
size_t len1, void *data2, size_t len2)
|
size_t len1, void *data2, size_t len2)
|
||||||
{
|
{
|
||||||
@@ -563,7 +566,7 @@ static int record__process_auxtrace(struct perf_tool *tool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int record__auxtrace_mmap_read(struct record *rec,
|
static int record__auxtrace_mmap_read(struct record *rec,
|
||||||
struct perf_mmap *map)
|
struct mmap *map)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -579,7 +582,7 @@ static int record__auxtrace_mmap_read(struct record *rec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int record__auxtrace_mmap_read_snapshot(struct record *rec,
|
static int record__auxtrace_mmap_read_snapshot(struct record *rec,
|
||||||
struct perf_mmap *map)
|
struct mmap *map)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -600,8 +603,8 @@ static int record__auxtrace_read_snapshot_all(struct record *rec)
|
|||||||
int i;
|
int i;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
for (i = 0; i < rec->evlist->nr_mmaps; i++) {
|
for (i = 0; i < rec->evlist->core.nr_mmaps; i++) {
|
||||||
struct perf_mmap *map = &rec->evlist->mmap[i];
|
struct mmap *map = &rec->evlist->mmap[i];
|
||||||
|
|
||||||
if (!map->auxtrace_mmap.base)
|
if (!map->auxtrace_mmap.base)
|
||||||
continue;
|
continue;
|
||||||
@@ -666,7 +669,7 @@ static int record__auxtrace_init(struct record *rec)
|
|||||||
|
|
||||||
static inline
|
static inline
|
||||||
int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
|
int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
|
||||||
struct perf_mmap *map __maybe_unused)
|
struct mmap *map __maybe_unused)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -705,7 +708,7 @@ static int record__mmap_evlist(struct record *rec,
|
|||||||
if (opts->affinity != PERF_AFFINITY_SYS)
|
if (opts->affinity != PERF_AFFINITY_SYS)
|
||||||
cpu__setup_cpunode_map();
|
cpu__setup_cpunode_map();
|
||||||
|
|
||||||
if (perf_evlist__mmap_ex(evlist, opts->mmap_pages,
|
if (evlist__mmap_ex(evlist, opts->mmap_pages,
|
||||||
opts->auxtrace_mmap_pages,
|
opts->auxtrace_mmap_pages,
|
||||||
opts->auxtrace_snapshot_mode,
|
opts->auxtrace_snapshot_mode,
|
||||||
opts->nr_cblocks, opts->affinity,
|
opts->nr_cblocks, opts->affinity,
|
||||||
@@ -753,9 +756,9 @@ static int record__open(struct record *rec)
|
|||||||
if (perf_evlist__add_dummy(evlist))
|
if (perf_evlist__add_dummy(evlist))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pos = perf_evlist__first(evlist);
|
pos = evlist__first(evlist);
|
||||||
pos->tracking = 0;
|
pos->tracking = 0;
|
||||||
pos = perf_evlist__last(evlist);
|
pos = evlist__last(evlist);
|
||||||
pos->tracking = 1;
|
pos->tracking = 1;
|
||||||
pos->core.attr.enable_on_exec = 1;
|
pos->core.attr.enable_on_exec = 1;
|
||||||
}
|
}
|
||||||
@@ -786,6 +789,17 @@ try_again:
|
|||||||
pos->supported = true;
|
pos->supported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(evlist)) {
|
||||||
|
pr_warning(
|
||||||
|
"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
|
||||||
|
"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n"
|
||||||
|
"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
|
||||||
|
"file is not found in the buildid cache or in the vmlinux path.\n\n"
|
||||||
|
"Samples in kernel modules won't be resolved at all.\n\n"
|
||||||
|
"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
|
||||||
|
"even with a suitable vmlinux or kallsyms file.\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (perf_evlist__apply_filters(evlist, &pos)) {
|
if (perf_evlist__apply_filters(evlist, &pos)) {
|
||||||
pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
|
pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
|
||||||
pos->filter, perf_evsel__name(pos), errno,
|
pos->filter, perf_evsel__name(pos), errno,
|
||||||
@@ -888,7 +902,7 @@ static struct perf_event_header finished_round_event = {
|
|||||||
.type = PERF_RECORD_FINISHED_ROUND,
|
.type = PERF_RECORD_FINISHED_ROUND,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void record__adjust_affinity(struct record *rec, struct perf_mmap *map)
|
static void record__adjust_affinity(struct record *rec, struct mmap *map)
|
||||||
{
|
{
|
||||||
if (rec->opts.affinity != PERF_AFFINITY_SYS &&
|
if (rec->opts.affinity != PERF_AFFINITY_SYS &&
|
||||||
!CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) {
|
!CPU_EQUAL(&rec->affinity_mask, &map->affinity_mask)) {
|
||||||
@@ -935,7 +949,7 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
|
|||||||
u64 bytes_written = rec->bytes_written;
|
u64 bytes_written = rec->bytes_written;
|
||||||
int i;
|
int i;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct perf_mmap *maps;
|
struct mmap *maps;
|
||||||
int trace_fd = rec->data.file.fd;
|
int trace_fd = rec->data.file.fd;
|
||||||
off_t off = 0;
|
off_t off = 0;
|
||||||
|
|
||||||
@@ -952,20 +966,20 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
|
|||||||
if (record__aio_enabled(rec))
|
if (record__aio_enabled(rec))
|
||||||
off = record__aio_get_pos(trace_fd);
|
off = record__aio_get_pos(trace_fd);
|
||||||
|
|
||||||
for (i = 0; i < evlist->nr_mmaps; i++) {
|
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||||
u64 flush = 0;
|
u64 flush = 0;
|
||||||
struct perf_mmap *map = &maps[i];
|
struct mmap *map = &maps[i];
|
||||||
|
|
||||||
if (map->base) {
|
if (map->core.base) {
|
||||||
record__adjust_affinity(rec, map);
|
record__adjust_affinity(rec, map);
|
||||||
if (synch) {
|
if (synch) {
|
||||||
flush = map->flush;
|
flush = map->core.flush;
|
||||||
map->flush = 1;
|
map->core.flush = 1;
|
||||||
}
|
}
|
||||||
if (!record__aio_enabled(rec)) {
|
if (!record__aio_enabled(rec)) {
|
||||||
if (perf_mmap__push(map, rec, record__pushfn) < 0) {
|
if (perf_mmap__push(map, rec, record__pushfn) < 0) {
|
||||||
if (synch)
|
if (synch)
|
||||||
map->flush = flush;
|
map->core.flush = flush;
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -973,13 +987,13 @@ static int record__mmap_read_evlist(struct record *rec, struct evlist *evlist,
|
|||||||
if (record__aio_push(rec, map, &off) < 0) {
|
if (record__aio_push(rec, map, &off) < 0) {
|
||||||
record__aio_set_pos(trace_fd, off);
|
record__aio_set_pos(trace_fd, off);
|
||||||
if (synch)
|
if (synch)
|
||||||
map->flush = flush;
|
map->core.flush = flush;
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (synch)
|
if (synch)
|
||||||
map->flush = flush;
|
map->core.flush = flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode &&
|
if (map->auxtrace_mmap.base && !rec->opts.auxtrace_snapshot_mode &&
|
||||||
@@ -1180,23 +1194,14 @@ static void workload_exec_failed_signal(int signo __maybe_unused,
|
|||||||
static void snapshot_sig_handler(int sig);
|
static void snapshot_sig_handler(int sig);
|
||||||
static void alarm_sig_handler(int sig);
|
static void alarm_sig_handler(int sig);
|
||||||
|
|
||||||
int __weak
|
|
||||||
perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused,
|
|
||||||
struct perf_tool *tool __maybe_unused,
|
|
||||||
perf_event__handler_t process __maybe_unused,
|
|
||||||
struct machine *machine __maybe_unused)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct perf_event_mmap_page *
|
static const struct perf_event_mmap_page *
|
||||||
perf_evlist__pick_pc(struct evlist *evlist)
|
perf_evlist__pick_pc(struct evlist *evlist)
|
||||||
{
|
{
|
||||||
if (evlist) {
|
if (evlist) {
|
||||||
if (evlist->mmap && evlist->mmap[0].base)
|
if (evlist->mmap && evlist->mmap[0].core.base)
|
||||||
return evlist->mmap[0].base;
|
return evlist->mmap[0].core.base;
|
||||||
if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base)
|
if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base)
|
||||||
return evlist->overwrite_mmap[0].base;
|
return evlist->overwrite_mmap[0].core.base;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1362,9 +1367,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
session = perf_session__new(data, false, tool);
|
session = perf_session__new(data, false, tool);
|
||||||
if (session == NULL) {
|
if (IS_ERR(session)) {
|
||||||
pr_err("Perf session creation failed.\n");
|
pr_err("Perf session creation failed.\n");
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = perf_data__fd(data);
|
fd = perf_data__fd(data);
|
||||||
@@ -1407,7 +1412,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||||||
err = -1;
|
err = -1;
|
||||||
goto out_child;
|
goto out_child;
|
||||||
}
|
}
|
||||||
session->header.env.comp_mmap_len = session->evlist->mmap_len;
|
session->header.env.comp_mmap_len = session->evlist->core.mmap_len;
|
||||||
|
|
||||||
err = bpf__apply_obj_config();
|
err = bpf__apply_obj_config();
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -1610,7 +1615,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||||||
if (hits == rec->samples) {
|
if (hits == rec->samples) {
|
||||||
if (done || draining)
|
if (done || draining)
|
||||||
break;
|
break;
|
||||||
err = perf_evlist__poll(rec->evlist, -1);
|
err = evlist__poll(rec->evlist, -1);
|
||||||
/*
|
/*
|
||||||
* Propagate error, only if there's any. Ignore positive
|
* Propagate error, only if there's any. Ignore positive
|
||||||
* number of returned events and interrupt error.
|
* number of returned events and interrupt error.
|
||||||
@@ -1619,7 +1624,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||||||
err = 0;
|
err = 0;
|
||||||
waking++;
|
waking++;
|
||||||
|
|
||||||
if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
|
if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
|
||||||
draining = true;
|
draining = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1976,7 +1981,7 @@ out_free:
|
|||||||
|
|
||||||
static void switch_output_size_warn(struct record *rec)
|
static void switch_output_size_warn(struct record *rec)
|
||||||
{
|
{
|
||||||
u64 wakeup_size = perf_evlist__mmap_size(rec->opts.mmap_pages);
|
u64 wakeup_size = evlist__mmap_size(rec->opts.mmap_pages);
|
||||||
struct switch_output *s = &rec->switch_output;
|
struct switch_output *s = &rec->switch_output;
|
||||||
|
|
||||||
wakeup_size /= 2;
|
wakeup_size /= 2;
|
||||||
@@ -2371,16 +2376,6 @@ int cmd_record(int argc, const char **argv)
|
|||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
|
||||||
if (symbol_conf.kptr_restrict && !perf_evlist__exclude_kernel(rec->evlist))
|
|
||||||
pr_warning(
|
|
||||||
"WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
|
|
||||||
"check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.\n\n"
|
|
||||||
"Samples in kernel functions may not be resolved if a suitable vmlinux\n"
|
|
||||||
"file is not found in the buildid cache or in the vmlinux path.\n\n"
|
|
||||||
"Samples in kernel modules won't be resolved at all.\n\n"
|
|
||||||
"If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
|
|
||||||
"even with a suitable vmlinux or kallsyms file.\n\n");
|
|
||||||
|
|
||||||
if (rec->no_buildid_cache || rec->no_buildid) {
|
if (rec->no_buildid_cache || rec->no_buildid) {
|
||||||
disable_buildid_cache();
|
disable_buildid_cache();
|
||||||
} else if (rec->switch_output.enabled) {
|
} else if (rec->switch_output.enabled) {
|
||||||
|
@@ -48,7 +48,7 @@
|
|||||||
#include "util/auxtrace.h"
|
#include "util/auxtrace.h"
|
||||||
#include "util/units.h"
|
#include "util/units.h"
|
||||||
#include "util/branch.h"
|
#include "util/branch.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h" // perf_tip()
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
#include "ui/progress.h"
|
#include "ui/progress.h"
|
||||||
|
|
||||||
@@ -1269,8 +1269,8 @@ int cmd_report(int argc, const char **argv)
|
|||||||
|
|
||||||
repeat:
|
repeat:
|
||||||
session = perf_session__new(&data, false, &report.tool);
|
session = perf_session__new(&data, false, &report.tool);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
ret = evswitch__init(&report.evswitch, session->evlist, stderr);
|
ret = evswitch__init(&report.evswitch, session->evlist, stderr);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@@ -3,8 +3,10 @@
|
|||||||
#include "perf.h"
|
#include "perf.h"
|
||||||
#include "perf-sys.h"
|
#include "perf-sys.h"
|
||||||
|
|
||||||
|
#include "util/cpumap.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
|
#include "util/evsel_fprintf.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
#include "util/header.h"
|
#include "util/header.h"
|
||||||
@@ -23,6 +25,7 @@
|
|||||||
#include "util/trace-event.h"
|
#include "util/trace-event.h"
|
||||||
|
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
|
#include "util/event.h"
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/log2.h>
|
#include <linux/log2.h>
|
||||||
@@ -36,7 +39,9 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <api/fs/fs.h>
|
#include <api/fs/fs.h>
|
||||||
|
#include <perf/cpumap.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
|
||||||
@@ -1794,9 +1799,9 @@ static int perf_sched__read_events(struct perf_sched *sched)
|
|||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
session = perf_session__new(&data, false, &sched->tool);
|
session = perf_session__new(&data, false, &sched->tool);
|
||||||
if (session == NULL) {
|
if (IS_ERR(session)) {
|
||||||
pr_debug("No Memory for session\n");
|
pr_debug("Error creating perf session");
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
symbol__init(&session->header.env);
|
symbol__init(&session->header.env);
|
||||||
@@ -2051,7 +2056,7 @@ static void timehist_print_sample(struct perf_sched *sched,
|
|||||||
EVSEL__PRINT_SYM | EVSEL__PRINT_ONELINE |
|
EVSEL__PRINT_SYM | EVSEL__PRINT_ONELINE |
|
||||||
EVSEL__PRINT_CALLCHAIN_ARROW |
|
EVSEL__PRINT_CALLCHAIN_ARROW |
|
||||||
EVSEL__PRINT_SKIP_IGNORED,
|
EVSEL__PRINT_SKIP_IGNORED,
|
||||||
&callchain_cursor, stdout);
|
&callchain_cursor, symbol_conf.bt_stop_list, stdout);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -2986,8 +2991,8 @@ static int perf_sched__timehist(struct perf_sched *sched)
|
|||||||
symbol_conf.use_callchain = sched->show_callchain;
|
symbol_conf.use_callchain = sched->show_callchain;
|
||||||
|
|
||||||
session = perf_session__new(&data, false, &sched->tool);
|
session = perf_session__new(&data, false, &sched->tool);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -ENOMEM;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
evlist = session->evlist;
|
evlist = session->evlist;
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "util/trace-event.h"
|
#include "util/trace-event.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
|
#include "util/evsel_fprintf.h"
|
||||||
#include "util/evswitch.h"
|
#include "util/evswitch.h"
|
||||||
#include "util/sort.h"
|
#include "util/sort.h"
|
||||||
#include "util/data.h"
|
#include "util/data.h"
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <subcmd/pager.h>
|
#include <subcmd/pager.h>
|
||||||
#include <perf/evlist.h>
|
#include <perf/evlist.h>
|
||||||
|
#include <linux/err.h>
|
||||||
#include "util/record.h"
|
#include "util/record.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
#include "perf.h"
|
#include "perf.h"
|
||||||
@@ -1324,7 +1326,8 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample,
|
|||||||
} else
|
} else
|
||||||
printed += fprintf(fp, "\n");
|
printed += fprintf(fp, "\n");
|
||||||
|
|
||||||
printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor, fp);
|
printed += sample__fprintf_sym(sample, al, 0, print_opts, cursor,
|
||||||
|
symbol_conf.bt_stop_list, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print branch_to information */
|
/* print branch_to information */
|
||||||
@@ -1866,7 +1869,8 @@ static void process_event(struct perf_script *script,
|
|||||||
cursor = &callchain_cursor;
|
cursor = &callchain_cursor;
|
||||||
|
|
||||||
fputc(cursor ? '\n' : ' ', fp);
|
fputc(cursor ? '\n' : ' ', fp);
|
||||||
sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor, fp);
|
sample__fprintf_sym(sample, al, 0, output[type].print_ip_opts, cursor,
|
||||||
|
symbol_conf.bt_stop_list, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PRINT_FIELD(IREGS))
|
if (PRINT_FIELD(IREGS))
|
||||||
@@ -1915,7 +1919,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
|
|||||||
int cpu, thread;
|
int cpu, thread;
|
||||||
static int header_printed;
|
static int header_printed;
|
||||||
|
|
||||||
if (counter->system_wide)
|
if (counter->core.system_wide)
|
||||||
nthreads = 1;
|
nthreads = 1;
|
||||||
|
|
||||||
if (!header_printed) {
|
if (!header_printed) {
|
||||||
@@ -2042,7 +2046,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
evlist = *pevlist;
|
evlist = *pevlist;
|
||||||
evsel = perf_evlist__last(*pevlist);
|
evsel = evlist__last(*pevlist);
|
||||||
|
|
||||||
if (!evsel->priv) {
|
if (!evsel->priv) {
|
||||||
if (scr->per_event_dump) {
|
if (scr->per_event_dump) {
|
||||||
@@ -3083,8 +3087,8 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num,
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
session = perf_session__new(&data, false, NULL);
|
session = perf_session__new(&data, false, NULL);
|
||||||
if (!session)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
|
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
|
||||||
|
|
||||||
@@ -3754,8 +3758,8 @@ int cmd_script(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
session = perf_session__new(&data, false, &script.tool);
|
session = perf_session__new(&data, false, &script.tool);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
if (header || header_only) {
|
if (header || header_only) {
|
||||||
script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
|
script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
|
||||||
|
@@ -61,6 +61,7 @@
|
|||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/string2.h"
|
#include "util/string2.h"
|
||||||
#include "util/metricgroup.h"
|
#include "util/metricgroup.h"
|
||||||
|
#include "util/synthetic-events.h"
|
||||||
#include "util/target.h"
|
#include "util/target.h"
|
||||||
#include "util/time-utils.h"
|
#include "util/time-utils.h"
|
||||||
#include "util/top.h"
|
#include "util/top.h"
|
||||||
@@ -82,6 +83,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <perf/evlist.h>
|
#include <perf/evlist.h>
|
||||||
@@ -233,7 +235,7 @@ static int write_stat_round_event(u64 tm, u64 type)
|
|||||||
#define WRITE_STAT_ROUND_EVENT(time, interval) \
|
#define WRITE_STAT_ROUND_EVENT(time, interval) \
|
||||||
write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
|
write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
|
||||||
|
|
||||||
#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
|
#define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
perf_evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
|
perf_evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
|
||||||
@@ -276,7 +278,7 @@ static int read_counter(struct evsel *counter, struct timespec *rs)
|
|||||||
if (!counter->supported)
|
if (!counter->supported)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
if (counter->system_wide)
|
if (counter->core.system_wide)
|
||||||
nthreads = 1;
|
nthreads = 1;
|
||||||
|
|
||||||
for (thread = 0; thread < nthreads; thread++) {
|
for (thread = 0; thread < nthreads; thread++) {
|
||||||
@@ -540,7 +542,7 @@ try_again:
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list,
|
err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list,
|
||||||
process_synthesized_event, is_pipe);
|
process_synthesized_event, is_pipe);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
@@ -822,18 +824,6 @@ static int perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
|
|||||||
return cpu_map__get_core(map, cpu, NULL);
|
return cpu_map__get_core(map, cpu, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpu_map__get_max(struct perf_cpu_map *map)
|
|
||||||
{
|
|
||||||
int i, max = -1;
|
|
||||||
|
|
||||||
for (i = 0; i < map->nr; i++) {
|
|
||||||
if (map->map[i] > max)
|
|
||||||
max = map->map[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int perf_stat__get_aggr(struct perf_stat_config *config,
|
static int perf_stat__get_aggr(struct perf_stat_config *config,
|
||||||
aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
|
aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
|
||||||
{
|
{
|
||||||
@@ -928,7 +918,7 @@ static int perf_stat_init_aggr_mode(void)
|
|||||||
* taking the highest cpu number to be the size of
|
* taking the highest cpu number to be the size of
|
||||||
* the aggregation translate cpumap.
|
* the aggregation translate cpumap.
|
||||||
*/
|
*/
|
||||||
nr = cpu_map__get_max(evsel_list->core.cpus);
|
nr = perf_cpu_map__max(evsel_list->core.cpus);
|
||||||
stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
|
stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
|
||||||
return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
|
return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -1447,9 +1437,9 @@ static int __cmd_record(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
session = perf_session__new(data, false, NULL);
|
session = perf_session__new(data, false, NULL);
|
||||||
if (session == NULL) {
|
if (IS_ERR(session)) {
|
||||||
pr_err("Perf session creation failed.\n");
|
pr_err("Perf session creation failed\n");
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_features(session);
|
init_features(session);
|
||||||
@@ -1646,8 +1636,8 @@ static int __cmd_report(int argc, const char **argv)
|
|||||||
perf_stat.data.mode = PERF_DATA_MODE_READ;
|
perf_stat.data.mode = PERF_DATA_MODE_READ;
|
||||||
|
|
||||||
session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
|
session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
perf_stat.session = session;
|
perf_stat.session = session;
|
||||||
stat_config.output = stderr;
|
stat_config.output = stderr;
|
||||||
@@ -1681,7 +1671,7 @@ static void setup_system_wide(int forks)
|
|||||||
struct evsel *counter;
|
struct evsel *counter;
|
||||||
|
|
||||||
evlist__for_each_entry(evsel_list, counter) {
|
evlist__for_each_entry(evsel_list, counter) {
|
||||||
if (!counter->system_wide)
|
if (!counter->core.system_wide)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1963,8 +1953,11 @@ int cmd_stat(int argc, const char **argv)
|
|||||||
fprintf(output, "[ perf stat: executing run #%d ... ]\n",
|
fprintf(output, "[ perf stat: executing run #%d ... ]\n",
|
||||||
run_idx + 1);
|
run_idx + 1);
|
||||||
|
|
||||||
|
if (run_idx != 0)
|
||||||
|
perf_evlist__reset_prev_raw_counts(evsel_list);
|
||||||
|
|
||||||
status = run_perf_stat(argc, argv, run_idx);
|
status = run_perf_stat(argc, argv, run_idx);
|
||||||
if (forever && status != -1) {
|
if (forever && status != -1 && !interval) {
|
||||||
print_counters(NULL, argc, argv);
|
print_counters(NULL, argc, argv);
|
||||||
perf_stat__reset_stats();
|
perf_stat__reset_stats();
|
||||||
}
|
}
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/data.h"
|
#include "util/data.h"
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE
|
#ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE
|
||||||
FILE *open_memstream(char **ptr, size_t *sizeloc);
|
FILE *open_memstream(char **ptr, size_t *sizeloc);
|
||||||
@@ -1601,8 +1602,8 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
|
|||||||
&tchart->tool);
|
&tchart->tool);
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
symbol__init(&session->header.env);
|
symbol__init(&session->header.env);
|
||||||
|
|
||||||
|
@@ -27,11 +27,14 @@
|
|||||||
#include "util/dso.h"
|
#include "util/dso.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
|
#include "util/evsel_config.h"
|
||||||
#include "util/event.h"
|
#include "util/event.h"
|
||||||
#include "util/machine.h"
|
#include "util/machine.h"
|
||||||
#include "util/map.h"
|
#include "util/map.h"
|
||||||
|
#include "util/mmap.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
|
#include "util/synthetic-events.h"
|
||||||
#include "util/top.h"
|
#include "util/top.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
#include <linux/rbtree.h>
|
#include <linux/rbtree.h>
|
||||||
@@ -76,6 +79,7 @@
|
|||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include <linux/time64.h>
|
#include <linux/time64.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
|
|
||||||
@@ -528,7 +532,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
|||||||
prompt_integer(&counter, "Enter details event counter");
|
prompt_integer(&counter, "Enter details event counter");
|
||||||
|
|
||||||
if (counter >= top->evlist->core.nr_entries) {
|
if (counter >= top->evlist->core.nr_entries) {
|
||||||
top->sym_evsel = perf_evlist__first(top->evlist);
|
top->sym_evsel = evlist__first(top->evlist);
|
||||||
fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel));
|
fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
break;
|
break;
|
||||||
@@ -537,7 +541,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
|||||||
if (top->sym_evsel->idx == counter)
|
if (top->sym_evsel->idx == counter)
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
top->sym_evsel = perf_evlist__first(top->evlist);
|
top->sym_evsel = evlist__first(top->evlist);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
prompt_integer(&top->count_filter, "Enter display event count filter");
|
prompt_integer(&top->count_filter, "Enter display event count filter");
|
||||||
@@ -861,7 +865,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx)
|
|||||||
{
|
{
|
||||||
struct record_opts *opts = &top->record_opts;
|
struct record_opts *opts = &top->record_opts;
|
||||||
struct evlist *evlist = top->evlist;
|
struct evlist *evlist = top->evlist;
|
||||||
struct perf_mmap *md;
|
struct mmap *md;
|
||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
|
|
||||||
md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx];
|
md = opts->overwrite ? &evlist->overwrite_mmap[idx] : &evlist->mmap[idx];
|
||||||
@@ -901,7 +905,7 @@ static void perf_top__mmap_read(struct perf_top *top)
|
|||||||
if (overwrite)
|
if (overwrite)
|
||||||
perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING);
|
perf_evlist__toggle_bkw_mmap(evlist, BKW_MMAP_DATA_PENDING);
|
||||||
|
|
||||||
for (i = 0; i < top->evlist->nr_mmaps; i++)
|
for (i = 0; i < top->evlist->core.nr_mmaps; i++)
|
||||||
perf_top__mmap_read_idx(top, i);
|
perf_top__mmap_read_idx(top, i);
|
||||||
|
|
||||||
if (overwrite) {
|
if (overwrite) {
|
||||||
@@ -959,7 +963,7 @@ static int perf_top__overwrite_check(struct perf_top *top)
|
|||||||
/* has term for current event */
|
/* has term for current event */
|
||||||
if ((overwrite < 0) && (set >= 0)) {
|
if ((overwrite < 0) && (set >= 0)) {
|
||||||
/* if it's first event, set overwrite */
|
/* if it's first event, set overwrite */
|
||||||
if (evsel == perf_evlist__first(evlist))
|
if (evsel == evlist__first(evlist))
|
||||||
overwrite = set;
|
overwrite = set;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
@@ -983,7 +987,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* only fall back when first event fails */
|
/* only fall back when first event fails */
|
||||||
if (evsel != perf_evlist__first(evlist))
|
if (evsel != evlist__first(evlist))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
evlist__for_each_entry(evlist, counter)
|
evlist__for_each_entry(evlist, counter)
|
||||||
@@ -1040,7 +1044,7 @@ try_again:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perf_evlist__mmap(evlist, opts->mmap_pages) < 0) {
|
if (evlist__mmap(evlist, opts->mmap_pages) < 0) {
|
||||||
ui__error("Failed to mmap with %d (%s)\n",
|
ui__error("Failed to mmap with %d (%s)\n",
|
||||||
errno, str_error_r(errno, msg, sizeof(msg)));
|
errno, str_error_r(errno, msg, sizeof(msg)));
|
||||||
goto out_err;
|
goto out_err;
|
||||||
@@ -1304,7 +1308,7 @@ static int __cmd_top(struct perf_top *top)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for a minimal set of events before starting the snapshot */
|
/* Wait for a minimal set of events before starting the snapshot */
|
||||||
perf_evlist__poll(top->evlist, 100);
|
evlist__poll(top->evlist, 100);
|
||||||
|
|
||||||
perf_top__mmap_read(top);
|
perf_top__mmap_read(top);
|
||||||
|
|
||||||
@@ -1314,7 +1318,7 @@ static int __cmd_top(struct perf_top *top)
|
|||||||
perf_top__mmap_read(top);
|
perf_top__mmap_read(top);
|
||||||
|
|
||||||
if (opts->overwrite || (hits == top->samples))
|
if (opts->overwrite || (hits == top->samples))
|
||||||
ret = perf_evlist__poll(top->evlist, 100);
|
ret = evlist__poll(top->evlist, 100);
|
||||||
|
|
||||||
if (resize) {
|
if (resize) {
|
||||||
perf_top__resize(top);
|
perf_top__resize(top);
|
||||||
@@ -1641,7 +1645,7 @@ int cmd_top(int argc, const char **argv)
|
|||||||
goto out_delete_evlist;
|
goto out_delete_evlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
top.sym_evsel = perf_evlist__first(top.evlist);
|
top.sym_evsel = evlist__first(top.evlist);
|
||||||
|
|
||||||
if (!callchain_param.enabled) {
|
if (!callchain_param.enabled) {
|
||||||
symbol_conf.cumulate_callchain = false;
|
symbol_conf.cumulate_callchain = false;
|
||||||
@@ -1671,8 +1675,8 @@ int cmd_top(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
top.session = perf_session__new(NULL, false, NULL);
|
top.session = perf_session__new(NULL, false, NULL);
|
||||||
if (top.session == NULL) {
|
if (IS_ERR(top.session)) {
|
||||||
status = -1;
|
status = PTR_ERR(top.session);
|
||||||
goto out_delete_evlist;
|
goto out_delete_evlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,8 +28,12 @@
|
|||||||
#include "util/dso.h"
|
#include "util/dso.h"
|
||||||
#include "util/env.h"
|
#include "util/env.h"
|
||||||
#include "util/event.h"
|
#include "util/event.h"
|
||||||
|
#include "util/evsel.h"
|
||||||
|
#include "util/evsel_fprintf.h"
|
||||||
|
#include "util/synthetic-events.h"
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evswitch.h"
|
#include "util/evswitch.h"
|
||||||
|
#include "util/mmap.h"
|
||||||
#include <subcmd/pager.h>
|
#include <subcmd/pager.h>
|
||||||
#include <subcmd/exec-cmd.h>
|
#include <subcmd/exec-cmd.h>
|
||||||
#include "util/machine.h"
|
#include "util/machine.h"
|
||||||
@@ -2074,7 +2078,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam
|
|||||||
EVSEL__PRINT_DSO |
|
EVSEL__PRINT_DSO |
|
||||||
EVSEL__PRINT_UNKNOWN_AS_ADDR;
|
EVSEL__PRINT_UNKNOWN_AS_ADDR;
|
||||||
|
|
||||||
return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output);
|
return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, symbol_conf.bt_stop_list, trace->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *errno_to_name(struct evsel *evsel, int err)
|
static const char *errno_to_name(struct evsel *evsel, int err)
|
||||||
@@ -3408,7 +3412,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||||||
if (trace->dump.map)
|
if (trace->dump.map)
|
||||||
bpf_map__fprintf(trace->dump.map, trace->output);
|
bpf_map__fprintf(trace->dump.map, trace->output);
|
||||||
|
|
||||||
err = perf_evlist__mmap(evlist, trace->opts.mmap_pages);
|
err = evlist__mmap(evlist, trace->opts.mmap_pages);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_error_mmap;
|
goto out_error_mmap;
|
||||||
|
|
||||||
@@ -3425,7 +3429,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||||||
|
|
||||||
trace->multiple_threads = perf_thread_map__pid(evlist->core.threads, 0) == -1 ||
|
trace->multiple_threads = perf_thread_map__pid(evlist->core.threads, 0) == -1 ||
|
||||||
evlist->core.threads->nr > 1 ||
|
evlist->core.threads->nr > 1 ||
|
||||||
perf_evlist__first(evlist)->core.attr.inherit;
|
evlist__first(evlist)->core.attr.inherit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that we already used evsel->core.attr to ask the kernel to setup the
|
* Now that we already used evsel->core.attr to ask the kernel to setup the
|
||||||
@@ -3441,9 +3445,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||||||
again:
|
again:
|
||||||
before = trace->nr_events;
|
before = trace->nr_events;
|
||||||
|
|
||||||
for (i = 0; i < evlist->nr_mmaps; i++) {
|
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
struct perf_mmap *md;
|
struct mmap *md;
|
||||||
|
|
||||||
md = &evlist->mmap[i];
|
md = &evlist->mmap[i];
|
||||||
if (perf_mmap__read_init(md) < 0)
|
if (perf_mmap__read_init(md) < 0)
|
||||||
@@ -3472,8 +3476,8 @@ again:
|
|||||||
if (trace->nr_events == before) {
|
if (trace->nr_events == before) {
|
||||||
int timeout = done ? 100 : -1;
|
int timeout = done ? 100 : -1;
|
||||||
|
|
||||||
if (!draining && perf_evlist__poll(evlist, timeout) > 0) {
|
if (!draining && evlist__poll(evlist, timeout) > 0) {
|
||||||
if (perf_evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0)
|
if (evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0)
|
||||||
draining = true;
|
draining = true;
|
||||||
|
|
||||||
goto again;
|
goto again;
|
||||||
@@ -3584,8 +3588,8 @@ static int trace__replay(struct trace *trace)
|
|||||||
trace->multiple_threads = true;
|
trace->multiple_threads = true;
|
||||||
|
|
||||||
session = perf_session__new(&data, false, &trace->tool);
|
session = perf_session__new(&data, false, &trace->tool);
|
||||||
if (session == NULL)
|
if (IS_ERR(session))
|
||||||
return -1;
|
return PTR_ERR(session);
|
||||||
|
|
||||||
if (trace->opts.target.pid)
|
if (trace->opts.target.pid)
|
||||||
symbol_conf.pid_list_str = strdup(trace->opts.target.pid);
|
symbol_conf.pid_list_str = strdup(trace->opts.target.pid);
|
||||||
|
@@ -1,8 +1,17 @@
|
|||||||
jvmti-y += libjvmti.o
|
jvmti-y += libjvmti.o
|
||||||
jvmti-y += jvmti_agent.o
|
jvmti-y += jvmti_agent.o
|
||||||
|
|
||||||
|
# For strlcpy
|
||||||
|
jvmti-y += libstring.o
|
||||||
|
|
||||||
CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux
|
CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux
|
||||||
CFLAGS_REMOVE_jvmti = -Wmissing-declarations
|
CFLAGS_REMOVE_jvmti = -Wmissing-declarations
|
||||||
CFLAGS_REMOVE_jvmti += -Wstrict-prototypes
|
CFLAGS_REMOVE_jvmti += -Wstrict-prototypes
|
||||||
CFLAGS_REMOVE_jvmti += -Wextra
|
CFLAGS_REMOVE_jvmti += -Wextra
|
||||||
CFLAGS_REMOVE_jvmti += -Wwrite-strings
|
CFLAGS_REMOVE_jvmti += -Wwrite-strings
|
||||||
|
|
||||||
|
CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
|
||||||
|
|
||||||
|
$(OUTPUT)jvmti/libstring.o: ../lib/string.c FORCE
|
||||||
|
$(call rule_mkdir)
|
||||||
|
$(call if_changed_dep,cc_o_c)
|
||||||
|
@@ -59,7 +59,13 @@ else
|
|||||||
CFLAGS := -g -Wall
|
CFLAGS := -g -Wall
|
||||||
endif
|
endif
|
||||||
|
|
||||||
INCLUDES = -I$(srctree)/tools/perf/lib/include -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(SRCARCH)/include/ -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi -I$(srctree)/tools/include/uapi
|
INCLUDES = \
|
||||||
|
-I$(srctree)/tools/perf/lib/include \
|
||||||
|
-I$(srctree)/tools/lib/ \
|
||||||
|
-I$(srctree)/tools/include \
|
||||||
|
-I$(srctree)/tools/arch/$(SRCARCH)/include/ \
|
||||||
|
-I$(srctree)/tools/arch/$(SRCARCH)/include/uapi \
|
||||||
|
-I$(srctree)/tools/include/uapi
|
||||||
|
|
||||||
# Append required CFLAGS
|
# Append required CFLAGS
|
||||||
override CFLAGS += $(EXTRA_WARNINGS)
|
override CFLAGS += $(EXTRA_WARNINGS)
|
||||||
@@ -88,13 +94,34 @@ LIBPERF_PC := $(OUTPUT)libperf.pc
|
|||||||
|
|
||||||
LIBPERF_ALL := $(LIBPERF_A) $(OUTPUT)libperf.so*
|
LIBPERF_ALL := $(LIBPERF_A) $(OUTPUT)libperf.so*
|
||||||
|
|
||||||
|
LIB_DIR := $(srctree)/tools/lib/api/
|
||||||
|
|
||||||
|
ifneq ($(OUTPUT),)
|
||||||
|
ifneq ($(subdir),)
|
||||||
|
API_PATH=$(OUTPUT)/../lib/api/
|
||||||
|
else
|
||||||
|
API_PATH=$(OUTPUT)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
API_PATH=$(LIB_DIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
LIBAPI = $(API_PATH)libapi.a
|
||||||
|
|
||||||
|
$(LIBAPI): FORCE
|
||||||
|
$(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) $(OUTPUT)libapi.a
|
||||||
|
|
||||||
|
$(LIBAPI)-clean:
|
||||||
|
$(call QUIET_CLEAN, libapi)
|
||||||
|
$(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null
|
||||||
|
|
||||||
$(LIBPERF_IN): FORCE
|
$(LIBPERF_IN): FORCE
|
||||||
$(Q)$(MAKE) $(build)=libperf
|
$(Q)$(MAKE) $(build)=libperf
|
||||||
|
|
||||||
$(LIBPERF_A): $(LIBPERF_IN)
|
$(LIBPERF_A): $(LIBPERF_IN)
|
||||||
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN)
|
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN)
|
||||||
|
|
||||||
$(LIBPERF_SO): $(LIBPERF_IN)
|
$(LIBPERF_SO): $(LIBPERF_IN) $(LIBAPI)
|
||||||
$(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so \
|
$(QUIET_LINK)$(CC) --shared -Wl,-soname,libperf.so \
|
||||||
-Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@
|
-Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@
|
||||||
@ln -sf $(@F) $(OUTPUT)libperf.so
|
@ln -sf $(@F) $(OUTPUT)libperf.so
|
||||||
@@ -106,12 +133,12 @@ libs: $(LIBPERF_A) $(LIBPERF_SO) $(LIBPERF_PC)
|
|||||||
all: fixdep
|
all: fixdep
|
||||||
$(Q)$(MAKE) libs
|
$(Q)$(MAKE) libs
|
||||||
|
|
||||||
clean:
|
clean: $(LIBAPI)-clean
|
||||||
$(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \
|
$(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \
|
||||||
*.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC)
|
*.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC)
|
||||||
$(Q)$(MAKE) -C tests clean
|
$(Q)$(MAKE) -C tests clean
|
||||||
|
|
||||||
tests:
|
tests: libs
|
||||||
$(Q)$(MAKE) -C tests
|
$(Q)$(MAKE) -C tests
|
||||||
$(Q)$(MAKE) -C tests run
|
$(Q)$(MAKE) -C tests run
|
||||||
|
|
||||||
@@ -146,6 +173,7 @@ install_headers:
|
|||||||
$(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \
|
$(call do_install,include/perf/threadmap.h,$(prefix)/include/perf,644); \
|
||||||
$(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \
|
$(call do_install,include/perf/evlist.h,$(prefix)/include/perf,644); \
|
||||||
$(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644);
|
$(call do_install,include/perf/evsel.h,$(prefix)/include/perf,644);
|
||||||
|
$(call do_install,include/perf/event.h,$(prefix)/include/perf,644);
|
||||||
|
|
||||||
install_pkgconfig: $(LIBPERF_PC)
|
install_pkgconfig: $(LIBPERF_PC)
|
||||||
$(call QUIET_INSTALL, $(LIBPERF_PC)) \
|
$(call QUIET_INSTALL, $(LIBPERF_PC)) \
|
||||||
|
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <perf/core.h>
|
#include <perf/core.h>
|
||||||
|
#include <internal/lib.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static int __base_pr(enum libperf_print_level level, const char *format,
|
static int __base_pr(enum libperf_print_level level, const char *format,
|
||||||
@@ -15,11 +17,6 @@ static int __base_pr(enum libperf_print_level level, const char *format,
|
|||||||
|
|
||||||
static libperf_print_fn_t __libperf_pr = __base_pr;
|
static libperf_print_fn_t __libperf_pr = __base_pr;
|
||||||
|
|
||||||
void libperf_set_print(libperf_print_fn_t fn)
|
|
||||||
{
|
|
||||||
__libperf_pr = fn;
|
|
||||||
}
|
|
||||||
|
|
||||||
__printf(2, 3)
|
__printf(2, 3)
|
||||||
void libperf_print(enum libperf_print_level level, const char *format, ...)
|
void libperf_print(enum libperf_print_level level, const char *format, ...)
|
||||||
{
|
{
|
||||||
@@ -32,3 +29,9 @@ void libperf_print(enum libperf_print_level level, const char *format, ...)
|
|||||||
__libperf_pr(level, format, args);
|
__libperf_pr(level, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void libperf_init(libperf_print_fn_t fn)
|
||||||
|
{
|
||||||
|
page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
|
__libperf_pr = fn;
|
||||||
|
}
|
||||||
|
@@ -260,3 +260,15 @@ int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu)
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int perf_cpu_map__max(struct perf_cpu_map *map)
|
||||||
|
{
|
||||||
|
int i, max = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < map->nr; i++) {
|
||||||
|
if (map->map[i] > max)
|
||||||
|
max = map->map[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
@@ -1,16 +1,30 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
#include <perf/evlist.h>
|
#include <perf/evlist.h>
|
||||||
#include <perf/evsel.h>
|
#include <perf/evsel.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
#include <linux/hash.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <internal/evlist.h>
|
#include <internal/evlist.h>
|
||||||
#include <internal/evsel.h>
|
#include <internal/evsel.h>
|
||||||
|
#include <internal/xyarray.h>
|
||||||
#include <linux/zalloc.h>
|
#include <linux/zalloc.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
#include <perf/threadmap.h>
|
#include <perf/threadmap.h>
|
||||||
|
#include <api/fd/array.h>
|
||||||
|
|
||||||
void perf_evlist__init(struct perf_evlist *evlist)
|
void perf_evlist__init(struct perf_evlist *evlist)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
|
||||||
|
INIT_HLIST_HEAD(&evlist->heads[i]);
|
||||||
INIT_LIST_HEAD(&evlist->entries);
|
INIT_LIST_HEAD(&evlist->entries);
|
||||||
evlist->nr_entries = 0;
|
evlist->nr_entries = 0;
|
||||||
}
|
}
|
||||||
@@ -157,3 +171,113 @@ void perf_evlist__disable(struct perf_evlist *evlist)
|
|||||||
perf_evlist__for_each_entry(evlist, evsel)
|
perf_evlist__for_each_entry(evlist, evsel)
|
||||||
perf_evsel__disable(evsel);
|
perf_evsel__disable(evsel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 perf_evlist__read_format(struct perf_evlist *evlist)
|
||||||
|
{
|
||||||
|
struct perf_evsel *first = perf_evlist__first(evlist);
|
||||||
|
|
||||||
|
return first->attr.read_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
|
||||||
|
|
||||||
|
static void perf_evlist__id_hash(struct perf_evlist *evlist,
|
||||||
|
struct perf_evsel *evsel,
|
||||||
|
int cpu, int thread, u64 id)
|
||||||
|
{
|
||||||
|
int hash;
|
||||||
|
struct perf_sample_id *sid = SID(evsel, cpu, thread);
|
||||||
|
|
||||||
|
sid->id = id;
|
||||||
|
sid->evsel = evsel;
|
||||||
|
hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
|
||||||
|
hlist_add_head(&sid->node, &evlist->heads[hash]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void perf_evlist__id_add(struct perf_evlist *evlist,
|
||||||
|
struct perf_evsel *evsel,
|
||||||
|
int cpu, int thread, u64 id)
|
||||||
|
{
|
||||||
|
perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
|
||||||
|
evsel->id[evsel->ids++] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_evlist__id_add_fd(struct perf_evlist *evlist,
|
||||||
|
struct perf_evsel *evsel,
|
||||||
|
int cpu, int thread, int fd)
|
||||||
|
{
|
||||||
|
u64 read_data[4] = { 0, };
|
||||||
|
int id_idx = 1; /* The first entry is the counter value */
|
||||||
|
u64 id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
|
||||||
|
if (!ret)
|
||||||
|
goto add;
|
||||||
|
|
||||||
|
if (errno != ENOTTY)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Legacy way to get event id.. All hail to old kernels! */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This way does not work with group format read, so bail
|
||||||
|
* out in that case.
|
||||||
|
*/
|
||||||
|
if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
|
||||||
|
read(fd, &read_data, sizeof(read_data)) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
|
||||||
|
++id_idx;
|
||||||
|
if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
|
||||||
|
++id_idx;
|
||||||
|
|
||||||
|
id = read_data[id_idx];
|
||||||
|
|
||||||
|
add:
|
||||||
|
perf_evlist__id_add(evlist, evsel, cpu, thread, id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
|
||||||
|
{
|
||||||
|
int nr_cpus = perf_cpu_map__nr(evlist->cpus);
|
||||||
|
int nr_threads = perf_thread_map__nr(evlist->threads);
|
||||||
|
int nfds = 0;
|
||||||
|
struct perf_evsel *evsel;
|
||||||
|
|
||||||
|
perf_evlist__for_each_entry(evlist, evsel) {
|
||||||
|
if (evsel->system_wide)
|
||||||
|
nfds += nr_cpus;
|
||||||
|
else
|
||||||
|
nfds += nr_cpus * nr_threads;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdarray__available_entries(&evlist->pollfd) < nfds &&
|
||||||
|
fdarray__grow(&evlist->pollfd, nfds) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd,
|
||||||
|
void *ptr, short revent)
|
||||||
|
{
|
||||||
|
int pos = fdarray__add(&evlist->pollfd, fd, revent | POLLERR | POLLHUP);
|
||||||
|
|
||||||
|
if (pos >= 0) {
|
||||||
|
evlist->pollfd.priv[pos].ptr = ptr;
|
||||||
|
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
|
||||||
|
{
|
||||||
|
return fdarray__poll(&evlist->pollfd, timeout);
|
||||||
|
}
|
||||||
|
@@ -230,3 +230,33 @@ struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel)
|
|||||||
{
|
{
|
||||||
return &evsel->attr;
|
return &evsel->attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
|
||||||
|
{
|
||||||
|
if (ncpus == 0 || nthreads == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (evsel->system_wide)
|
||||||
|
nthreads = 1;
|
||||||
|
|
||||||
|
evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
|
||||||
|
if (evsel->sample_id == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
evsel->id = zalloc(ncpus * nthreads * sizeof(u64));
|
||||||
|
if (evsel->id == NULL) {
|
||||||
|
xyarray__delete(evsel->sample_id);
|
||||||
|
evsel->sample_id = NULL;
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void perf_evsel__free_id(struct perf_evsel *evsel)
|
||||||
|
{
|
||||||
|
xyarray__delete(evsel->sample_id);
|
||||||
|
evsel->sample_id = NULL;
|
||||||
|
zfree(&evsel->id);
|
||||||
|
evsel->ids = 0;
|
||||||
|
}
|
||||||
|
@@ -3,6 +3,11 @@
|
|||||||
#define __LIBPERF_INTERNAL_EVLIST_H
|
#define __LIBPERF_INTERNAL_EVLIST_H
|
||||||
|
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
#include <api/fd/array.h>
|
||||||
|
#include <internal/evsel.h>
|
||||||
|
|
||||||
|
#define PERF_EVLIST__HLIST_BITS 8
|
||||||
|
#define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS)
|
||||||
|
|
||||||
struct perf_cpu_map;
|
struct perf_cpu_map;
|
||||||
struct perf_thread_map;
|
struct perf_thread_map;
|
||||||
@@ -13,8 +18,16 @@ struct perf_evlist {
|
|||||||
bool has_user_cpus;
|
bool has_user_cpus;
|
||||||
struct perf_cpu_map *cpus;
|
struct perf_cpu_map *cpus;
|
||||||
struct perf_thread_map *threads;
|
struct perf_thread_map *threads;
|
||||||
|
int nr_mmaps;
|
||||||
|
size_t mmap_len;
|
||||||
|
struct fdarray pollfd;
|
||||||
|
struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int perf_evlist__alloc_pollfd(struct perf_evlist *evlist);
|
||||||
|
int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd,
|
||||||
|
void *ptr, short revent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __perf_evlist__for_each_entry - iterate thru all the evsels
|
* __perf_evlist__for_each_entry - iterate thru all the evsels
|
||||||
* @list: list_head instance to iterate
|
* @list: list_head instance to iterate
|
||||||
@@ -47,4 +60,24 @@ struct perf_evlist {
|
|||||||
#define perf_evlist__for_each_entry_reverse(evlist, evsel) \
|
#define perf_evlist__for_each_entry_reverse(evlist, evsel) \
|
||||||
__perf_evlist__for_each_entry_reverse(&(evlist)->entries, evsel)
|
__perf_evlist__for_each_entry_reverse(&(evlist)->entries, evsel)
|
||||||
|
|
||||||
|
static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist)
|
||||||
|
{
|
||||||
|
return list_entry(evlist->entries.next, struct perf_evsel, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist)
|
||||||
|
{
|
||||||
|
return list_entry(evlist->entries.prev, struct perf_evsel, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 perf_evlist__read_format(struct perf_evlist *evlist);
|
||||||
|
|
||||||
|
void perf_evlist__id_add(struct perf_evlist *evlist,
|
||||||
|
struct perf_evsel *evsel,
|
||||||
|
int cpu, int thread, u64 id);
|
||||||
|
|
||||||
|
int perf_evlist__id_add_fd(struct perf_evlist *evlist,
|
||||||
|
struct perf_evsel *evsel,
|
||||||
|
int cpu, int thread, int fd);
|
||||||
|
|
||||||
#endif /* __LIBPERF_INTERNAL_EVLIST_H */
|
#endif /* __LIBPERF_INTERNAL_EVLIST_H */
|
||||||
|
@@ -4,9 +4,35 @@
|
|||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
struct perf_cpu_map;
|
struct perf_cpu_map;
|
||||||
struct perf_thread_map;
|
struct perf_thread_map;
|
||||||
|
struct xyarray;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there are
|
||||||
|
* more than one entry in the evlist.
|
||||||
|
*/
|
||||||
|
struct perf_sample_id {
|
||||||
|
struct hlist_node node;
|
||||||
|
u64 id;
|
||||||
|
struct perf_evsel *evsel;
|
||||||
|
/*
|
||||||
|
* 'idx' will be used for AUX area sampling. A sample will have AUX area
|
||||||
|
* data that will be queued for decoding, where there are separate
|
||||||
|
* queues for each CPU (per-cpu tracing) or task (per-thread tracing).
|
||||||
|
* The sample ID can be used to lookup 'idx' which is effectively the
|
||||||
|
* queue number.
|
||||||
|
*/
|
||||||
|
int idx;
|
||||||
|
int cpu;
|
||||||
|
pid_t tid;
|
||||||
|
|
||||||
|
/* Holds total ID period value for PERF_SAMPLE_READ processing. */
|
||||||
|
u64 period;
|
||||||
|
};
|
||||||
|
|
||||||
struct perf_evsel {
|
struct perf_evsel {
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
@@ -15,9 +41,13 @@ struct perf_evsel {
|
|||||||
struct perf_cpu_map *own_cpus;
|
struct perf_cpu_map *own_cpus;
|
||||||
struct perf_thread_map *threads;
|
struct perf_thread_map *threads;
|
||||||
struct xyarray *fd;
|
struct xyarray *fd;
|
||||||
|
struct xyarray *sample_id;
|
||||||
|
u64 *id;
|
||||||
|
u32 ids;
|
||||||
|
|
||||||
/* parse modifier helper */
|
/* parse modifier helper */
|
||||||
int nr_members;
|
int nr_members;
|
||||||
|
bool system_wide;
|
||||||
};
|
};
|
||||||
|
|
||||||
int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
|
int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
|
||||||
@@ -26,4 +56,7 @@ void perf_evsel__free_fd(struct perf_evsel *evsel);
|
|||||||
int perf_evsel__read_size(struct perf_evsel *evsel);
|
int perf_evsel__read_size(struct perf_evsel *evsel);
|
||||||
int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
|
int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter);
|
||||||
|
|
||||||
|
int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
|
||||||
|
void perf_evsel__free_id(struct perf_evsel *evsel);
|
||||||
|
|
||||||
#endif /* __LIBPERF_INTERNAL_EVSEL_H */
|
#endif /* __LIBPERF_INTERNAL_EVSEL_H */
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
#ifndef __LIBPERF_INTERNAL_LIB_H
|
#ifndef __LIBPERF_INTERNAL_LIB_H
|
||||||
#define __LIBPERF_INTERNAL_LIB_H
|
#define __LIBPERF_INTERNAL_LIB_H
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
extern unsigned int page_size;
|
||||||
|
|
||||||
ssize_t readn(int fd, void *buf, size_t n);
|
ssize_t readn(int fd, void *buf, size_t n);
|
||||||
ssize_t writen(int fd, const void *buf, size_t n);
|
ssize_t writen(int fd, const void *buf, size_t n);
|
||||||
|
32
tools/perf/lib/include/internal/mmap.h
Normal file
32
tools/perf/lib/include/internal/mmap.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef __LIBPERF_INTERNAL_MMAP_H
|
||||||
|
#define __LIBPERF_INTERNAL_MMAP_H
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/refcount.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* perf sample has 16 bits size limit */
|
||||||
|
#define PERF_SAMPLE_MAX_SIZE (1 << 16)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct perf_mmap - perf's ring buffer mmap details
|
||||||
|
*
|
||||||
|
* @refcnt - e.g. code using PERF_EVENT_IOC_SET_OUTPUT to share this
|
||||||
|
*/
|
||||||
|
struct perf_mmap {
|
||||||
|
void *base;
|
||||||
|
int mask;
|
||||||
|
int fd;
|
||||||
|
int cpu;
|
||||||
|
refcount_t refcnt;
|
||||||
|
u64 prev;
|
||||||
|
u64 start;
|
||||||
|
u64 end;
|
||||||
|
bool overwrite;
|
||||||
|
u64 flush;
|
||||||
|
char event_copy[PERF_SAMPLE_MAX_SIZE] __aligned(8);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __LIBPERF_INTERNAL_MMAP_H */
|
@@ -17,6 +17,6 @@ enum libperf_print_level {
|
|||||||
typedef int (*libperf_print_fn_t)(enum libperf_print_level level,
|
typedef int (*libperf_print_fn_t)(enum libperf_print_level level,
|
||||||
const char *, va_list ap);
|
const char *, va_list ap);
|
||||||
|
|
||||||
LIBPERF_API void libperf_set_print(libperf_print_fn_t fn);
|
LIBPERF_API void libperf_init(libperf_print_fn_t fn);
|
||||||
|
|
||||||
#endif /* __LIBPERF_CORE_H */
|
#endif /* __LIBPERF_CORE_H */
|
||||||
|
@@ -16,6 +16,7 @@ LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map);
|
|||||||
LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
|
LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
|
||||||
LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
|
LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
|
||||||
LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
|
LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
|
||||||
|
LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map);
|
||||||
|
|
||||||
#define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \
|
#define perf_cpu_map__for_each_cpu(cpu, idx, cpus) \
|
||||||
for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \
|
for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx); \
|
||||||
|
@@ -31,5 +31,6 @@ LIBPERF_API void perf_evlist__disable(struct perf_evlist *evlist);
|
|||||||
LIBPERF_API void perf_evlist__set_maps(struct perf_evlist *evlist,
|
LIBPERF_API void perf_evlist__set_maps(struct perf_evlist *evlist,
|
||||||
struct perf_cpu_map *cpus,
|
struct perf_cpu_map *cpus,
|
||||||
struct perf_thread_map *threads);
|
struct perf_thread_map *threads);
|
||||||
|
LIBPERF_API int perf_evlist__poll(struct perf_evlist *evlist, int timeout);
|
||||||
|
|
||||||
#endif /* __LIBPERF_EVLIST_H */
|
#endif /* __LIBPERF_EVLIST_H */
|
||||||
|
@@ -5,6 +5,8 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <internal/lib.h>
|
#include <internal/lib.h>
|
||||||
|
|
||||||
|
unsigned int page_size;
|
||||||
|
|
||||||
static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
|
static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
|
||||||
{
|
{
|
||||||
void *buf_start = buf;
|
void *buf_start = buf;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
LIBPERF_0.0.1 {
|
LIBPERF_0.0.1 {
|
||||||
global:
|
global:
|
||||||
libperf_set_print;
|
libperf_init;
|
||||||
perf_cpu_map__dummy_new;
|
perf_cpu_map__dummy_new;
|
||||||
perf_cpu_map__get;
|
perf_cpu_map__get;
|
||||||
perf_cpu_map__put;
|
perf_cpu_map__put;
|
||||||
@@ -9,6 +9,7 @@ LIBPERF_0.0.1 {
|
|||||||
perf_cpu_map__nr;
|
perf_cpu_map__nr;
|
||||||
perf_cpu_map__cpu;
|
perf_cpu_map__cpu;
|
||||||
perf_cpu_map__empty;
|
perf_cpu_map__empty;
|
||||||
|
perf_cpu_map__max;
|
||||||
perf_thread_map__new_dummy;
|
perf_thread_map__new_dummy;
|
||||||
perf_thread_map__set_pid;
|
perf_thread_map__set_pid;
|
||||||
perf_thread_map__comm;
|
perf_thread_map__comm;
|
||||||
@@ -38,6 +39,7 @@ LIBPERF_0.0.1 {
|
|||||||
perf_evlist__remove;
|
perf_evlist__remove;
|
||||||
perf_evlist__next;
|
perf_evlist__next;
|
||||||
perf_evlist__set_maps;
|
perf_evlist__set_maps;
|
||||||
|
perf_evlist__poll;
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
|
@@ -1,13 +1,23 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
#include <internal/tests.h>
|
#include <internal/tests.h>
|
||||||
|
|
||||||
|
static int libperf_print(enum libperf_print_level level,
|
||||||
|
const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vfprintf(stderr, fmt, ap);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct perf_cpu_map *cpus;
|
struct perf_cpu_map *cpus;
|
||||||
|
|
||||||
__T_START;
|
__T_START;
|
||||||
|
|
||||||
|
libperf_init(libperf_print);
|
||||||
|
|
||||||
cpus = perf_cpu_map__dummy_new();
|
cpus = perf_cpu_map__dummy_new();
|
||||||
if (!cpus)
|
if (!cpus)
|
||||||
return -1;
|
return -1;
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
#include <perf/cpumap.h>
|
#include <perf/cpumap.h>
|
||||||
#include <perf/threadmap.h>
|
#include <perf/threadmap.h>
|
||||||
@@ -6,6 +8,12 @@
|
|||||||
#include <perf/evsel.h>
|
#include <perf/evsel.h>
|
||||||
#include <internal/tests.h>
|
#include <internal/tests.h>
|
||||||
|
|
||||||
|
static int libperf_print(enum libperf_print_level level,
|
||||||
|
const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vfprintf(stderr, fmt, ap);
|
||||||
|
}
|
||||||
|
|
||||||
static int test_stat_cpu(void)
|
static int test_stat_cpu(void)
|
||||||
{
|
{
|
||||||
struct perf_cpu_map *cpus;
|
struct perf_cpu_map *cpus;
|
||||||
@@ -177,6 +185,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
__T_START;
|
__T_START;
|
||||||
|
|
||||||
|
libperf_init(libperf_print);
|
||||||
|
|
||||||
test_stat_cpu();
|
test_stat_cpu();
|
||||||
test_stat_thread();
|
test_stat_thread();
|
||||||
test_stat_thread_enable();
|
test_stat_thread_enable();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user