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:
Коммит
a7b7b772bb
|
@ -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
|
||||
* 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
|
||||
* hold the top-level event's child_mutex, so any descendant that
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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) {
|
||||
/*
|
||||
* 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
|
||||
* in case new sample type is added, because we could eat
|
||||
* 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_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_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 */
|
||||
#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 */
|
||||
#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_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_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
|
||||
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#define _UAPI_ASM_X86_UNISTD_H
|
||||
|
||||
/* x32 syscall flag bit */
|
||||
#define __X32_SYSCALL_BIT 0x40000000
|
||||
#define __X32_SYSCALL_BIT 0x40000000UL
|
||||
|
||||
#ifndef __KERNEL__
|
||||
# ifdef __i386__
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#define _TOOLS_ASM_BUG_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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)
|
||||
#if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
|
||||
#define __NR_semtimedop 192
|
||||
__SC_COMP(__NR_semtimedop, sys_semtimedop, sys_semtimedop_time32)
|
||||
__SC_3264(__NR_semtimedop, sys_semtimedop_time32, sys_semtimedop)
|
||||
#endif
|
||||
#define __NR_semop 193
|
||||
__SYSCALL(__NR_semop, sys_semop)
|
||||
|
|
|
@ -181,7 +181,7 @@ struct prctl_mm_map {
|
|||
#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_DISABLE_MANAGEMENT 44
|
||||
|
@ -229,4 +229,9 @@ struct prctl_mm_map {
|
|||
# define PR_PAC_APDBKEY (1UL << 3)
|
||||
# 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 */
|
||||
|
|
|
@ -6,14 +6,3 @@ libtraceevent-y += parse-utils.o
|
|||
libtraceevent-y += kbuffer-parse.o
|
||||
libtraceevent-y += tep_strerror.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
|
||||
|
|
|
@ -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
|
||||
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
|
||||
pass in the kallsyms function names with their corresponding addresses with this
|
||||
or events have "%pS" parameter in its format string. It is common to pass in
|
||||
the kallsyms function names with their corresponding addresses with this
|
||||
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 start address of the function. The _mod_ is the kernel module
|
||||
the function may be in (NULL for none).
|
||||
the name of the function, the string is copied internally. The _addr_ is the
|
||||
start address of the function. The _mod_ is the kernel module the function may
|
||||
be in (NULL for none).
|
||||
|
||||
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
|
||||
|
|
|
@ -3,7 +3,7 @@ libtraceevent(3)
|
|||
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
|
@ -16,7 +16,7 @@ struct tep_handle pass:[*]*tep_alloc*(void);
|
|||
void *tep_free*(struct tep_handle pass:[*]_tep_);
|
||||
void *tep_ref*(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
|
||||
|
@ -57,9 +57,9 @@ EXAMPLE
|
|||
...
|
||||
struct tep_handle *tep = tep_alloc();
|
||||
...
|
||||
int ref = tep_ref_get(tep);
|
||||
int ref = tep_get_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 */
|
||||
}
|
||||
tep_unref(tep);
|
||||
|
|
|
@ -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_ref*(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_clear_flag*(struct tep_handle pass:[*]_tep_, enum tep_flag _flag_);
|
||||
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_);
|
||||
int *tep_get_page_size*(struct tep_handle pass:[*]_tep_);
|
||||
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_timestamp_size*(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_);
|
||||
|
||||
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_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_);
|
||||
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_);
|
||||
|
||||
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_);
|
||||
void *tep_print_event*(struct tep_handle pass:[*]_tep_, struct trace_seq pass:[*]_s_, struct tep_record pass:[*]_record_, const char pass:[*]_fmt_, _..._);
|
||||
|
||||
Event finding:
|
||||
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_);
|
||||
|
||||
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_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_);
|
||||
|
|
|
@ -58,30 +58,6 @@ export man_dir man_dir_SQ INSTALL
|
|||
export DESTDIR DESTDIR_SQ
|
||||
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
|
||||
|
||||
# copy a bit from Linux kbuild
|
||||
|
@ -105,7 +81,6 @@ export prefix libdir src obj
|
|||
# Shell quotes
|
||||
libdir_SQ = $(subst ','\'',$(libdir))
|
||||
libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
|
||||
plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
|
||||
|
||||
CONFIG_INCLUDES =
|
||||
CONFIG_LIBS =
|
||||
|
@ -151,29 +126,14 @@ MAKEOVERRIDES=
|
|||
export srctree OUTPUT CC LD CFLAGS V
|
||||
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
|
||||
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)
|
||||
|
||||
all: all_cmd
|
||||
all: all_cmd plugins
|
||||
|
||||
all_cmd: $(CMD_TARGETS)
|
||||
|
||||
|
@ -188,17 +148,6 @@ $(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN)
|
|||
$(OUTPUT)libtraceevent.a: $(TE_IN)
|
||||
$(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
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) -shared $(LDFLAGS) -nostartfiles -o $@ $^
|
||||
|
||||
|
@ -258,25 +207,6 @@ define do_install
|
|||
$(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
|
||||
|
||||
PKG_CONFIG_FILE = libtraceevent.pc
|
||||
define do_install_pkgconfig_file
|
||||
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)); \
|
||||
cp -fpR $(LIB_INSTALL) $(DESTDIR)$(libdir_SQ)
|
||||
|
||||
install_plugins: $(PLUGINS)
|
||||
$(call QUIET_INSTALL, trace_plugins) \
|
||||
$(call do_install_plugins, $(PLUGINS))
|
||||
|
||||
install_pkgconfig:
|
||||
$(call QUIET_INSTALL, $(PKG_CONFIG_FILE)) \
|
||||
$(call do_install_pkgconfig_file,$(prefix))
|
||||
|
@ -313,7 +239,7 @@ install_headers:
|
|||
|
||||
install: install_lib
|
||||
|
||||
clean:
|
||||
clean: clean_plugins
|
||||
$(call QUIET_CLEAN, libtraceevent) \
|
||||
$(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d .*.cmd; \
|
||||
$(RM) TRACEEVENT-CFLAGS tags TAGS; \
|
||||
|
@ -351,7 +277,19 @@ help:
|
|||
@echo ' doc-install - install the man pages'
|
||||
@echo ' doc-uninstall - uninstall the man pages'
|
||||
@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:
|
||||
|
||||
# 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) {
|
||||
case 's':
|
||||
case 'S':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'x':
|
||||
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:
|
||||
/*
|
||||
* Older kernels do not process
|
||||
|
@ -4487,12 +4497,12 @@ get_bprint_format(void *data, int size __maybe_unused,
|
|||
|
||||
printk = find_printk(tep, addr);
|
||||
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 format;
|
||||
}
|
||||
|
||||
if (asprintf(&format, "%s: %s", "%pf", printk->printk) < 0)
|
||||
if (asprintf(&format, "%s: %s", "%ps", printk->printk) < 0)
|
||||
return NULL;
|
||||
|
||||
return format;
|
||||
|
@ -5517,8 +5527,10 @@ static void print_event_time(struct tep_handle *tep, struct trace_seq *s,
|
|||
if (divstr && isdigit(*(divstr + 1)))
|
||||
div = atoi(divstr + 1);
|
||||
time = record->ts;
|
||||
if (div)
|
||||
if (div) {
|
||||
time += div / 2;
|
||||
time /= div;
|
||||
}
|
||||
pr = prec;
|
||||
while (pr--)
|
||||
p10 *= 10;
|
||||
|
|
|
@ -441,6 +441,8 @@ int tep_register_print_string(struct tep_handle *tep, const char *fmt,
|
|||
unsigned long long addr);
|
||||
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_RAW "INFO_RAW"
|
||||
#define TEP_PRINT_COMM "COMM"
|
||||
|
|
|
@ -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
|
|
@ -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}')
|
||||
else
|
||||
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
|
||||
ifndef JDIR
|
||||
|
|
|
@ -292,7 +292,7 @@ endif
|
|||
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
||||
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
|
||||
|
@ -567,7 +567,7 @@ all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
|
|||
# Create python binding output directory if not already present
|
||||
_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" \
|
||||
CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS)' \
|
||||
$(PYTHON_WORD) util/setup.py \
|
||||
|
@ -737,7 +737,7 @@ libtraceevent_plugins: FORCE
|
|||
$(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) 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:
|
||||
$(call QUIET_CLEAN, libtraceevent)
|
||||
|
|
|
@ -23,9 +23,10 @@
|
|||
#include "../../util/event.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/evsel_config.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/cs-etm.h"
|
||||
#include "../../util/util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/session.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
@ -416,7 +417,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
|
|||
if (err)
|
||||
goto out;
|
||||
|
||||
tracking_evsel = perf_evlist__last(evlist);
|
||||
tracking_evsel = evlist__last(evlist);
|
||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||
|
||||
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))
|
||||
return -EINVAL;
|
||||
|
||||
if (!session->evlist->nr_mmaps)
|
||||
if (!session->evlist->core.nr_mmaps)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the cpu_map is empty all online CPUs are involved */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "../../util/evsel.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/session.h"
|
||||
#include "../../util/util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/debug.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)
|
||||
return -EINVAL;
|
||||
|
||||
if (!session->evlist->nr_mmaps)
|
||||
if (!session->evlist->core.nr_mmaps)
|
||||
return -EINVAL;
|
||||
|
||||
auxtrace_info->type = PERF_AUXTRACE_ARM_SPE;
|
||||
|
@ -129,7 +129,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
tracking_evsel = perf_evlist__last(evlist);
|
||||
tracking_evsel = evlist__last(evlist);
|
||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||
|
||||
tracking_evsel->core.attr.freq = 0;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <dwarf-regs.h>
|
||||
#include <linux/ptrace.h> /* for struct user_pt_regs */
|
||||
#include <linux/stringify.h>
|
||||
#include "util.h"
|
||||
|
||||
struct pt_regs_dwarfnum {
|
||||
const char *name;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <api/fs/fs.h>
|
||||
#include "debug.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 */
|
||||
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,
|
||||
sysfs, cpus->map[cpu]);
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include <libunwind.h>
|
||||
#include "perf_regs.h"
|
||||
#include "../../util/unwind.h"
|
||||
#include "../../util/debug.h"
|
||||
#endif
|
||||
#include "../../util/debug.h"
|
||||
|
||||
int LIBUNWIND__ARCH_REG_ID(int regnum)
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <linux/ptrace.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "util.h"
|
||||
|
||||
struct pt_regs_dwarfnum {
|
||||
const char *name;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <string.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "header.h"
|
||||
#include "util.h"
|
||||
|
||||
#define mfspr(rn) ({unsigned long rval; \
|
||||
asm volatile("mfspr %0," __stringify(rn) \
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
#include "util/debug.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/pmu.h"
|
||||
|
||||
#include "book3s_hv_exits.h"
|
||||
#include "book3s_hcalls.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
|
||||
#define NR_TPS 4
|
||||
|
||||
|
@ -172,3 +174,46 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused)
|
|||
|
||||
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/debug.h"
|
||||
#include "util/dso.h"
|
||||
#include "util/event.h" // struct ip_callchain
|
||||
#include "util/map.h"
|
||||
#include "util/symbol.h"
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* Copyright (C) 2015 Naveen N. Rao, IBM Corporation
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "dso.h"
|
||||
#include "symbol.h"
|
||||
#include "map.h"
|
||||
|
|
|
@ -4,6 +4,7 @@ PERF_HAVE_DWARF_REGS := 1
|
|||
endif
|
||||
HAVE_KVM_STAT_SUPPORT := 1
|
||||
PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
|
||||
PERF_HAVE_JITDUMP := 1
|
||||
|
||||
#
|
||||
# Syscall table generation for perf
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bitops.h>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "machine.h"
|
||||
#include "api/fs/fs.h"
|
||||
#include "debug.h"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "evlist.h"
|
||||
#include "evsel.h"
|
||||
#include "arch-tests.h"
|
||||
#include "util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
|
||||
#include <signal.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;
|
||||
}
|
||||
|
||||
evsel = perf_evlist__first(evlist);
|
||||
evsel = evlist__first(evlist);
|
||||
if (!evsel) {
|
||||
pr_debug("perf_evlist__first failed\n");
|
||||
pr_debug("evlist__first failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
#include "evlist.h"
|
||||
#include "evsel.h"
|
||||
#include "thread_map.h"
|
||||
#include "cpumap.h"
|
||||
#include "record.h"
|
||||
#include "tsc.h"
|
||||
#include "util/mmap.h"
|
||||
#include "tests/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;
|
||||
u64 test_tsc, comm1_tsc, comm2_tsc;
|
||||
u64 test_time, comm1_time = 0, comm2_time = 0;
|
||||
struct perf_mmap *md;
|
||||
struct mmap *md;
|
||||
|
||||
threads = thread_map__new(-1, getpid(), UINT_MAX);
|
||||
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);
|
||||
|
||||
evsel = perf_evlist__first(evlist);
|
||||
evsel = evlist__first(evlist);
|
||||
|
||||
evsel->core.attr.comm = 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__(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);
|
||||
if (ret) {
|
||||
if (ret == -EOPNOTSUPP) {
|
||||
|
@ -115,7 +115,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
|
|||
|
||||
evlist__disable(evlist);
|
||||
|
||||
for (i = 0; i < evlist->nr_mmaps; i++) {
|
||||
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||
md = &evlist->mmap[i];
|
||||
if (perf_mmap__read_init(md) < 0)
|
||||
continue;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "tests/tests.h"
|
||||
#include "cloexec.h"
|
||||
#include "event.h"
|
||||
#include "util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "arch-tests.h"
|
||||
|
||||
static u64 rdpmc(unsigned int counter)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "../../../../arch/x86/include/asm/insn.h"
|
||||
#include "archinsn.h"
|
||||
#include "event.h"
|
||||
#include "machine.h"
|
||||
#include "thread.h"
|
||||
#include "symbol.h"
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
||||
#include "../../util/event.h"
|
||||
#include "../../util/synthetic-events.h"
|
||||
#include "../../util/machine.h"
|
||||
#include "../../util/tool.h"
|
||||
#include "../../util/map.h"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "../../util/event.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/mmap.h"
|
||||
#include "../../util/session.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/debug.h"
|
||||
|
@ -22,7 +23,7 @@
|
|||
#include "../../util/tsc.h"
|
||||
#include "../../util/auxtrace.h"
|
||||
#include "../../util/intel-bts.h"
|
||||
#include "../../util/util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
|
||||
#define KiB(x) ((x) * 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)
|
||||
return -EINVAL;
|
||||
|
||||
if (!session->evlist->nr_mmaps)
|
||||
if (!session->evlist->core.nr_mmaps)
|
||||
return -EINVAL;
|
||||
|
||||
pc = session->evlist->mmap[0].base;
|
||||
pc = session->evlist->mmap[0].core.base;
|
||||
if (pc) {
|
||||
err = perf_read_tsc_conversion(pc, &tc);
|
||||
if (err) {
|
||||
|
@ -230,7 +231,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
tracking_evsel = perf_evlist__last(evlist);
|
||||
tracking_evsel = evlist__last(evlist);
|
||||
|
||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "../../util/evlist.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/cpumap.h"
|
||||
#include "../../util/mmap.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "../../util/parse-events.h"
|
||||
#include "../../util/pmu.h"
|
||||
|
@ -26,7 +27,7 @@
|
|||
#include "../../util/record.h"
|
||||
#include "../../util/target.h"
|
||||
#include "../../util/tsc.h"
|
||||
#include "../../util/util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/intel-pt.h"
|
||||
|
||||
#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_str_len = filter ? strlen(filter) : 0;
|
||||
|
||||
if (!session->evlist->nr_mmaps)
|
||||
if (!session->evlist->core.nr_mmaps)
|
||||
return -EINVAL;
|
||||
|
||||
pc = session->evlist->mmap[0].base;
|
||||
pc = session->evlist->mmap[0].core.base;
|
||||
if (pc) {
|
||||
err = perf_read_tsc_conversion(pc, &tc);
|
||||
if (err) {
|
||||
|
@ -416,12 +417,12 @@ static int intel_pt_track_switches(struct evlist *evlist)
|
|||
return err;
|
||||
}
|
||||
|
||||
evsel = perf_evlist__last(evlist);
|
||||
evsel = evlist__last(evlist);
|
||||
|
||||
perf_evsel__set_sample_bit(evsel, CPU);
|
||||
perf_evsel__set_sample_bit(evsel, TIME);
|
||||
|
||||
evsel->system_wide = true;
|
||||
evsel->core.system_wide = true;
|
||||
evsel->no_aux_samples = true;
|
||||
evsel->immediate = true;
|
||||
|
||||
|
@ -716,13 +717,13 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
switch_evsel = perf_evlist__last(evlist);
|
||||
switch_evsel = evlist__last(evlist);
|
||||
|
||||
switch_evsel->core.attr.freq = 0;
|
||||
switch_evsel->core.attr.sample_period = 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->immediate = true;
|
||||
|
||||
|
@ -774,7 +775,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
tracking_evsel = perf_evlist__last(evlist);
|
||||
tracking_evsel = evlist__last(evlist);
|
||||
|
||||
perf_evlist__set_tracking_event(evlist, tracking_evsel);
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../util/util.h"
|
||||
#include <internal/lib.h> // page_size
|
||||
#include "../../util/machine.h"
|
||||
#include "../../util/map.h"
|
||||
#include "../../util/symbol.h"
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <linux/types.h>
|
||||
#include <asm/barrier.h>
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/event.h"
|
||||
#include "../../../util/synthetic-events.h"
|
||||
#include "../../../util/tsc.h"
|
||||
|
||||
int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <errno.h>
|
||||
#include "../../util/debug.h"
|
||||
#ifndef REMOTE_UNWIND_LIBUNWIND
|
||||
#include <libunwind.h>
|
||||
#include "perf_regs.h"
|
||||
#include "../../util/unwind.h"
|
||||
#include "../../util/debug.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
#include <sys/resource.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
|
||||
#include "../util/stat.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "bench.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
#include <err.h>
|
||||
|
||||
|
|
|
@ -76,12 +76,12 @@
|
|||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/types.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
|
||||
#include "../util/stat.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "bench.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
#include <err.h>
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/zalloc.h>
|
||||
#include <sys/time.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
|
||||
#include "../util/stat.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "bench.h"
|
||||
#include "futex.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
#include <err.h>
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/zalloc.h>
|
||||
#include <errno.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include "bench.h"
|
||||
#include "futex.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/time64.h>
|
||||
#include <errno.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include "bench.h"
|
||||
#include "futex.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
#include <err.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 <errno.h>
|
||||
#include "futex.h"
|
||||
#include "cpumap.h"
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/time64.h>
|
||||
#include <errno.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include "bench.h"
|
||||
#include "futex.h"
|
||||
#include "cpumap.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
/* For the CLR_() macros */
|
||||
#include <pthread.h>
|
||||
|
||||
#include "../builtin.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "../util/cloexec.h"
|
||||
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "../util/util.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "../builtin.h"
|
||||
#include "bench.h"
|
||||
|
||||
/* 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
|
||||
* Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
|
||||
*/
|
||||
#include "../util/util.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "../builtin.h"
|
||||
#include "bench.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "util/sort.h"
|
||||
#include "util/hist.h"
|
||||
#include "util/dso.h"
|
||||
#include "util/machine.h"
|
||||
#include "util/map.h"
|
||||
#include "util/session.h"
|
||||
#include "util/tool.h"
|
||||
|
@ -39,6 +40,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct perf_annotate {
|
||||
struct perf_tool tool;
|
||||
|
@ -583,8 +585,8 @@ int cmd_annotate(int argc, const char **argv)
|
|||
data.path = input_name;
|
||||
|
||||
annotate.session = perf_session__new(&data, false, &annotate.tool);
|
||||
if (annotate.session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(annotate.session))
|
||||
return PTR_ERR(annotate.session);
|
||||
|
||||
annotate.has_br_stack = perf_header__has_feat(&annotate.session->header,
|
||||
HEADER_BRANCH_STACK);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "util/util.h"
|
||||
#include "util/probe-file.h"
|
||||
#include <linux/string.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
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;
|
||||
|
||||
session = perf_session__new(&data, false, NULL);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
}
|
||||
|
||||
if (symbol__init(session ? &session->header.env : NULL) < 0)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "util/symbol.h"
|
||||
#include "util/data.h"
|
||||
#include <errno.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
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;
|
||||
|
||||
session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
/*
|
||||
* We take all buildids when the file contains AUX area tracing data
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
@ -20,6 +21,7 @@
|
|||
#include <sys/param.h>
|
||||
#include "debug.h"
|
||||
#include "builtin.h"
|
||||
#include <perf/cpumap.h>
|
||||
#include <subcmd/pager.h>
|
||||
#include <subcmd/parse-options.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);
|
||||
if (session == NULL) {
|
||||
pr_debug("No memory for session\n");
|
||||
if (IS_ERR(session)) {
|
||||
err = PTR_ERR(session);
|
||||
pr_debug("Error creating perf session\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "util/cache.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "util/util.h"
|
||||
#include "util/debug.h"
|
||||
#include "util/config.h"
|
||||
#include <linux/string.h>
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "util/time-utils.h"
|
||||
#include "util/annotate.h"
|
||||
#include "util/map.h"
|
||||
#include <linux/err.h>
|
||||
#include <linux/zalloc.h>
|
||||
#include <subcmd/pager.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
|
@ -1153,9 +1154,9 @@ static int check_file_brstack(void)
|
|||
|
||||
data__for_each_file(i, d) {
|
||||
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);
|
||||
return -1;
|
||||
return PTR_ERR(d->session);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
ret = -1;
|
||||
goto out_delete;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
*/
|
||||
#include "builtin.h"
|
||||
|
||||
#include "util/util.h"
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "perf.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evsel_fprintf.h"
|
||||
#include "util/parse-events.h"
|
||||
#include <subcmd/parse-options.h>
|
||||
#include "util/session.h"
|
||||
#include "util/data.h"
|
||||
#include "util/debug.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
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;
|
||||
|
||||
session = perf_session__new(&data, 0, NULL);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
evlist__for_each_entry(session->evlist, pos) {
|
||||
perf_evsel__fprintf(pos, details, stdout);
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
#include "util/auxtrace.h"
|
||||
#include "util/jit.h"
|
||||
#include "util/symbol.h"
|
||||
#include "util/synthetic-events.h"
|
||||
#include "util/thread.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <subcmd/parse-options.h>
|
||||
|
||||
|
@ -834,8 +836,8 @@ int cmd_inject(int argc, const char **argv)
|
|||
|
||||
data.path = inject.input_name;
|
||||
inject.session = perf_session__new(&data, true, &inject.tool);
|
||||
if (inject.session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(inject.session))
|
||||
return PTR_ERR(inject.session);
|
||||
|
||||
if (zstd_init(&(inject.session->zstd_data), 0) < 0)
|
||||
pr_warning("Decompression initialization failed.\n");
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "util/tool.h"
|
||||
#include "util/callchain.h"
|
||||
#include "util/time-utils.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <subcmd/pager.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
|
@ -1956,8 +1957,8 @@ int cmd_kmem(int argc, const char **argv)
|
|||
data.path = input_name;
|
||||
|
||||
kmem_session = session = perf_session__new(&data, false, &perf_kmem);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
ret = -1;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "util/build-id.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/mmap.h"
|
||||
#include "util/term.h"
|
||||
#include "util/symbol.h"
|
||||
#include "util/thread.h"
|
||||
|
@ -17,9 +18,11 @@
|
|||
#include "util/debug.h"
|
||||
#include "util/tool.h"
|
||||
#include "util/stat.h"
|
||||
#include "util/synthetic-events.h"
|
||||
#include "util/top.h"
|
||||
#include "util/data.h"
|
||||
#include "util/ordered-events.h"
|
||||
#include "util/kvm-stat.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include <sys/prctl.h>
|
||||
|
@ -31,6 +34,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/time64.h>
|
||||
|
@ -58,7 +62,6 @@ static const char *get_filename_for_perf_kvm(void)
|
|||
}
|
||||
|
||||
#ifdef HAVE_KVM_STAT_SUPPORT
|
||||
#include "util/kvm-stat.h"
|
||||
|
||||
void exit_event_get_key(struct evsel *evsel,
|
||||
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;
|
||||
union perf_event *event;
|
||||
struct perf_mmap *md;
|
||||
struct mmap *md;
|
||||
u64 timestamp;
|
||||
s64 n = 0;
|
||||
int err;
|
||||
|
@ -799,7 +802,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
|
|||
s64 n, ntotal = 0;
|
||||
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);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
|
@ -964,10 +967,10 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (perf_evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
|
||||
if (evlist__add_pollfd(kvm->evlist, kvm->timerfd) < 0)
|
||||
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)
|
||||
goto out;
|
||||
|
||||
|
@ -978,7 +981,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
|
|||
evlist__enable(kvm->evlist);
|
||||
|
||||
while (!done) {
|
||||
struct fdarray *fda = &kvm->evlist->pollfd;
|
||||
struct fdarray *fda = &kvm->evlist->core.pollfd;
|
||||
int rc;
|
||||
|
||||
rc = perf_kvm__mmap_read(kvm);
|
||||
|
@ -1058,7 +1061,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
|
|||
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",
|
||||
str_error_r(errno, sbuf, sizeof(sbuf)));
|
||||
evlist__close(evlist);
|
||||
|
@ -1090,9 +1093,9 @@ static int read_events(struct perf_kvm_stat *kvm)
|
|||
|
||||
kvm->tool = eops;
|
||||
kvm->session = perf_session__new(&file, false, &kvm->tool);
|
||||
if (!kvm->session) {
|
||||
if (IS_ERR(kvm->session)) {
|
||||
pr_err("Initializing perf session failed\n");
|
||||
return -1;
|
||||
return PTR_ERR(kvm->session);
|
||||
}
|
||||
|
||||
symbol__init(&kvm->session->header.env);
|
||||
|
@ -1445,8 +1448,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
|||
* perf session
|
||||
*/
|
||||
kvm->session = perf_session__new(&data, false, &kvm->tool);
|
||||
if (kvm->session == NULL) {
|
||||
err = -1;
|
||||
if (IS_ERR(kvm->session)) {
|
||||
err = PTR_ERR(kvm->session);
|
||||
goto out;
|
||||
}
|
||||
kvm->session->evlist = kvm->evlist;
|
||||
|
@ -1513,11 +1516,21 @@ perf_stat:
|
|||
}
|
||||
#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)
|
||||
{
|
||||
int rec_argc, i = 0, j;
|
||||
int rec_argc, i = 0, j, ret;
|
||||
const char **rec_argv;
|
||||
|
||||
ret = kvm_add_default_arch_event(&argc, argv);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
rec_argc = argc + 2;
|
||||
rec_argv = calloc(rec_argc + 1, sizeof(char *));
|
||||
rec_argv[i++] = strdup("record");
|
||||
|
|
|
@ -81,9 +81,9 @@ int cmd_list(int argc, const char **argv)
|
|||
long_desc_flag, details_flag);
|
||||
else if (strcmp(argv[i], "sdt") == 0)
|
||||
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);
|
||||
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);
|
||||
else if ((sep = strchr(argv[i], ':')) != NULL) {
|
||||
int sep_idx;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/hash.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/zalloc.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
static struct perf_session *session;
|
||||
|
||||
|
@ -872,9 +873,9 @@ static int __cmd_report(bool display_info)
|
|||
};
|
||||
|
||||
session = perf_session__new(&data, false, &eops);
|
||||
if (!session) {
|
||||
if (IS_ERR(session)) {
|
||||
pr_err("Initializing perf session failed\n");
|
||||
return -1;
|
||||
return PTR_ERR(session);
|
||||
}
|
||||
|
||||
symbol__init(&session->header.env);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "util/dso.h"
|
||||
#include "util/map.h"
|
||||
#include "util/symbol.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
#define MEM_OPERATION_LOAD 0x1
|
||||
#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,
|
||||
&mem->tool);
|
||||
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
if (mem->cpu_list) {
|
||||
ret = perf_session__cpu_bitmap(session, mem->cpu_list,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/debug.h"
|
||||
#include "util/mmap.h"
|
||||
#include "util/target.h"
|
||||
#include "util/session.h"
|
||||
#include "util/tool.h"
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "util/trigger.h"
|
||||
#include "util/perf-hooks.h"
|
||||
#include "util/cpu-set-sched.h"
|
||||
#include "util/synthetic-events.h"
|
||||
#include "util/time-utils.h"
|
||||
#include "util/units.h"
|
||||
#include "util/bpf-event.h"
|
||||
|
@ -53,6 +55,7 @@
|
|||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/time64.h>
|
||||
#include <linux/zalloc.h>
|
||||
|
@ -117,7 +120,7 @@ static bool switch_output_time(struct record *rec)
|
|||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
off_t rem_off;
|
||||
|
@ -212,7 +215,7 @@ static int record__aio_complete(struct perf_mmap *md, struct aiocb *cblock)
|
|||
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 *cblocks = md->aio.cblocks;
|
||||
|
@ -253,12 +256,12 @@ struct record_aio {
|
|||
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;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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;
|
||||
}
|
||||
|
||||
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 trace_fd = rec->session->data->file.fd;
|
||||
|
@ -349,15 +352,15 @@ static void record__aio_mmap_read_sync(struct record *rec)
|
|||
{
|
||||
int i;
|
||||
struct evlist *evlist = rec->evlist;
|
||||
struct perf_mmap *maps = evlist->mmap;
|
||||
struct mmap *maps = evlist->mmap;
|
||||
|
||||
if (!record__aio_enabled(rec))
|
||||
return;
|
||||
|
||||
for (i = 0; i < evlist->nr_mmaps; i++) {
|
||||
struct perf_mmap *map = &maps[i];
|
||||
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||
struct mmap *map = &maps[i];
|
||||
|
||||
if (map->base)
|
||||
if (map->core.base)
|
||||
record__aio_sync(map, true);
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +388,7 @@ static int record__aio_parse(const struct option *opt,
|
|||
#else /* HAVE_AIO_SUPPORT */
|
||||
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)
|
||||
{
|
||||
return -1;
|
||||
|
@ -437,7 +440,7 @@ static int record__mmap_flush_parse(const struct option *opt,
|
|||
if (!opts->mmap_flush)
|
||||
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;
|
||||
if (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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -525,7 +528,7 @@ static void record__sig_exit(void)
|
|||
#ifdef HAVE_AUXTRACE_SUPPORT
|
||||
|
||||
static int record__process_auxtrace(struct perf_tool *tool,
|
||||
struct perf_mmap *map,
|
||||
struct mmap *map,
|
||||
union perf_event *event, void *data1,
|
||||
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,
|
||||
struct perf_mmap *map)
|
||||
struct mmap *map)
|
||||
{
|
||||
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,
|
||||
struct perf_mmap *map)
|
||||
struct mmap *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -600,8 +603,8 @@ static int record__auxtrace_read_snapshot_all(struct record *rec)
|
|||
int i;
|
||||
int rc = 0;
|
||||
|
||||
for (i = 0; i < rec->evlist->nr_mmaps; i++) {
|
||||
struct perf_mmap *map = &rec->evlist->mmap[i];
|
||||
for (i = 0; i < rec->evlist->core.nr_mmaps; i++) {
|
||||
struct mmap *map = &rec->evlist->mmap[i];
|
||||
|
||||
if (!map->auxtrace_mmap.base)
|
||||
continue;
|
||||
|
@ -666,7 +669,7 @@ static int record__auxtrace_init(struct record *rec)
|
|||
|
||||
static inline
|
||||
int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
|
||||
struct perf_mmap *map __maybe_unused)
|
||||
struct mmap *map __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -705,7 +708,7 @@ static int record__mmap_evlist(struct record *rec,
|
|||
if (opts->affinity != PERF_AFFINITY_SYS)
|
||||
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_snapshot_mode,
|
||||
opts->nr_cblocks, opts->affinity,
|
||||
|
@ -753,9 +756,9 @@ static int record__open(struct record *rec)
|
|||
if (perf_evlist__add_dummy(evlist))
|
||||
return -ENOMEM;
|
||||
|
||||
pos = perf_evlist__first(evlist);
|
||||
pos = evlist__first(evlist);
|
||||
pos->tracking = 0;
|
||||
pos = perf_evlist__last(evlist);
|
||||
pos = evlist__last(evlist);
|
||||
pos->tracking = 1;
|
||||
pos->core.attr.enable_on_exec = 1;
|
||||
}
|
||||
|
@ -786,6 +789,17 @@ try_again:
|
|||
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)) {
|
||||
pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
|
||||
pos->filter, perf_evsel__name(pos), errno,
|
||||
|
@ -888,7 +902,7 @@ static struct perf_event_header finished_round_event = {
|
|||
.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 &&
|
||||
!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;
|
||||
int i;
|
||||
int rc = 0;
|
||||
struct perf_mmap *maps;
|
||||
struct mmap *maps;
|
||||
int trace_fd = rec->data.file.fd;
|
||||
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))
|
||||
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;
|
||||
struct perf_mmap *map = &maps[i];
|
||||
struct mmap *map = &maps[i];
|
||||
|
||||
if (map->base) {
|
||||
if (map->core.base) {
|
||||
record__adjust_affinity(rec, map);
|
||||
if (synch) {
|
||||
flush = map->flush;
|
||||
map->flush = 1;
|
||||
flush = map->core.flush;
|
||||
map->core.flush = 1;
|
||||
}
|
||||
if (!record__aio_enabled(rec)) {
|
||||
if (perf_mmap__push(map, rec, record__pushfn) < 0) {
|
||||
if (synch)
|
||||
map->flush = flush;
|
||||
map->core.flush = flush;
|
||||
rc = -1;
|
||||
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) {
|
||||
record__aio_set_pos(trace_fd, off);
|
||||
if (synch)
|
||||
map->flush = flush;
|
||||
map->core.flush = flush;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (synch)
|
||||
map->flush = flush;
|
||||
map->core.flush = flush;
|
||||
}
|
||||
|
||||
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 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 *
|
||||
perf_evlist__pick_pc(struct evlist *evlist)
|
||||
{
|
||||
if (evlist) {
|
||||
if (evlist->mmap && evlist->mmap[0].base)
|
||||
return evlist->mmap[0].base;
|
||||
if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].base)
|
||||
return evlist->overwrite_mmap[0].base;
|
||||
if (evlist->mmap && evlist->mmap[0].core.base)
|
||||
return evlist->mmap[0].core.base;
|
||||
if (evlist->overwrite_mmap && evlist->overwrite_mmap[0].core.base)
|
||||
return evlist->overwrite_mmap[0].core.base;
|
||||
}
|
||||
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);
|
||||
if (session == NULL) {
|
||||
if (IS_ERR(session)) {
|
||||
pr_err("Perf session creation failed.\n");
|
||||
return -1;
|
||||
return PTR_ERR(session);
|
||||
}
|
||||
|
||||
fd = perf_data__fd(data);
|
||||
|
@ -1407,7 +1412,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||
err = -1;
|
||||
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();
|
||||
if (err) {
|
||||
|
@ -1610,7 +1615,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||
if (hits == rec->samples) {
|
||||
if (done || draining)
|
||||
break;
|
||||
err = perf_evlist__poll(rec->evlist, -1);
|
||||
err = evlist__poll(rec->evlist, -1);
|
||||
/*
|
||||
* Propagate error, only if there's any. Ignore positive
|
||||
* 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;
|
||||
waking++;
|
||||
|
||||
if (perf_evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
|
||||
if (evlist__filter_pollfd(rec->evlist, POLLERR | POLLHUP) == 0)
|
||||
draining = true;
|
||||
}
|
||||
|
||||
|
@ -1976,7 +1981,7 @@ out_free:
|
|||
|
||||
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;
|
||||
|
||||
wakeup_size /= 2;
|
||||
|
@ -2371,16 +2376,6 @@ int cmd_record(int argc, const char **argv)
|
|||
|
||||
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) {
|
||||
disable_buildid_cache();
|
||||
} else if (rec->switch_output.enabled) {
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "util/auxtrace.h"
|
||||
#include "util/units.h"
|
||||
#include "util/branch.h"
|
||||
#include "util/util.h"
|
||||
#include "util/util.h" // perf_tip()
|
||||
#include "ui/ui.h"
|
||||
#include "ui/progress.h"
|
||||
|
||||
|
@ -1269,8 +1269,8 @@ int cmd_report(int argc, const char **argv)
|
|||
|
||||
repeat:
|
||||
session = perf_session__new(&data, false, &report.tool);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
ret = evswitch__init(&report.evswitch, session->evlist, stderr);
|
||||
if (ret)
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
#include "perf.h"
|
||||
#include "perf-sys.h"
|
||||
|
||||
#include "util/cpumap.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evsel_fprintf.h"
|
||||
#include "util/symbol.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/header.h"
|
||||
|
@ -23,6 +25,7 @@
|
|||
#include "util/trace-event.h"
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/event.h"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/log2.h>
|
||||
|
@ -36,7 +39,9 @@
|
|||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
#include <api/fs/fs.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include <linux/time64.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/ctype.h>
|
||||
|
||||
|
@ -1794,9 +1799,9 @@ static int perf_sched__read_events(struct perf_sched *sched)
|
|||
int rc = -1;
|
||||
|
||||
session = perf_session__new(&data, false, &sched->tool);
|
||||
if (session == NULL) {
|
||||
pr_debug("No Memory for session\n");
|
||||
return -1;
|
||||
if (IS_ERR(session)) {
|
||||
pr_debug("Error creating perf session");
|
||||
return PTR_ERR(session);
|
||||
}
|
||||
|
||||
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_CALLCHAIN_ARROW |
|
||||
EVSEL__PRINT_SKIP_IGNORED,
|
||||
&callchain_cursor, stdout);
|
||||
&callchain_cursor, symbol_conf.bt_stop_list, stdout);
|
||||
|
||||
out:
|
||||
printf("\n");
|
||||
|
@ -2986,8 +2991,8 @@ static int perf_sched__timehist(struct perf_sched *sched)
|
|||
symbol_conf.use_callchain = sched->show_callchain;
|
||||
|
||||
session = perf_session__new(&data, false, &sched->tool);
|
||||
if (session == NULL)
|
||||
return -ENOMEM;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
evlist = session->evlist;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "util/trace-event.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evsel_fprintf.h"
|
||||
#include "util/evswitch.h"
|
||||
#include "util/sort.h"
|
||||
#include "util/data.h"
|
||||
|
@ -52,6 +53,7 @@
|
|||
#include <unistd.h>
|
||||
#include <subcmd/pager.h>
|
||||
#include <perf/evlist.h>
|
||||
#include <linux/err.h>
|
||||
#include "util/record.h"
|
||||
#include "util/util.h"
|
||||
#include "perf.h"
|
||||
|
@ -1324,7 +1326,8 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample,
|
|||
} else
|
||||
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 */
|
||||
|
@ -1866,7 +1869,8 @@ static void process_event(struct perf_script *script,
|
|||
cursor = &callchain_cursor;
|
||||
|
||||
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))
|
||||
|
@ -1915,7 +1919,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
|
|||
int cpu, thread;
|
||||
static int header_printed;
|
||||
|
||||
if (counter->system_wide)
|
||||
if (counter->core.system_wide)
|
||||
nthreads = 1;
|
||||
|
||||
if (!header_printed) {
|
||||
|
@ -2042,7 +2046,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,
|
|||
return err;
|
||||
|
||||
evlist = *pevlist;
|
||||
evsel = perf_evlist__last(*pevlist);
|
||||
evsel = evlist__last(*pevlist);
|
||||
|
||||
if (!evsel->priv) {
|
||||
if (scr->per_event_dump) {
|
||||
|
@ -3083,8 +3087,8 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num,
|
|||
int i = 0;
|
||||
|
||||
session = perf_session__new(&data, false, NULL);
|
||||
if (!session)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
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);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
if (header || header_only) {
|
||||
script.tool.show_feat_hdr = SHOW_FEAT_HEADER;
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "util/tool.h"
|
||||
#include "util/string2.h"
|
||||
#include "util/metricgroup.h"
|
||||
#include "util/synthetic-events.h"
|
||||
#include "util/target.h"
|
||||
#include "util/time-utils.h"
|
||||
#include "util/top.h"
|
||||
|
@ -82,6 +83,7 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <linux/ctype.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) \
|
||||
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
|
||||
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)
|
||||
return -ENOENT;
|
||||
|
||||
if (counter->system_wide)
|
||||
if (counter->core.system_wide)
|
||||
nthreads = 1;
|
||||
|
||||
for (thread = 0; thread < nthreads; thread++) {
|
||||
|
@ -540,8 +542,8 @@ try_again:
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = perf_stat_synthesize_config(&stat_config, NULL, evsel_list,
|
||||
process_synthesized_event, is_pipe);
|
||||
err = perf_event__synthesize_stat_events(&stat_config, NULL, evsel_list,
|
||||
process_synthesized_event, is_pipe);
|
||||
if (err < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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
|
||||
* 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);
|
||||
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);
|
||||
if (session == NULL) {
|
||||
pr_err("Perf session creation failed.\n");
|
||||
return -1;
|
||||
if (IS_ERR(session)) {
|
||||
pr_err("Perf session creation failed\n");
|
||||
return PTR_ERR(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;
|
||||
|
||||
session = perf_session__new(&perf_stat.data, false, &perf_stat.tool);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
perf_stat.session = session;
|
||||
stat_config.output = stderr;
|
||||
|
@ -1681,7 +1671,7 @@ static void setup_system_wide(int forks)
|
|||
struct evsel *counter;
|
||||
|
||||
evlist__for_each_entry(evsel_list, counter) {
|
||||
if (!counter->system_wide)
|
||||
if (!counter->core.system_wide)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1963,8 +1953,11 @@ int cmd_stat(int argc, const char **argv)
|
|||
fprintf(output, "[ perf stat: executing run #%d ... ]\n",
|
||||
run_idx + 1);
|
||||
|
||||
if (run_idx != 0)
|
||||
perf_evlist__reset_prev_raw_counts(evsel_list);
|
||||
|
||||
status = run_perf_stat(argc, argv, run_idx);
|
||||
if (forever && status != -1) {
|
||||
if (forever && status != -1 && !interval) {
|
||||
print_counters(NULL, argc, argv);
|
||||
perf_stat__reset_stats();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "util/tool.h"
|
||||
#include "util/data.h"
|
||||
#include "util/debug.h"
|
||||
#include <linux/err.h>
|
||||
|
||||
#ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE
|
||||
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);
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
symbol__init(&session->header.env);
|
||||
|
||||
|
|
|
@ -27,11 +27,14 @@
|
|||
#include "util/dso.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evsel_config.h"
|
||||
#include "util/event.h"
|
||||
#include "util/machine.h"
|
||||
#include "util/map.h"
|
||||
#include "util/mmap.h"
|
||||
#include "util/session.h"
|
||||
#include "util/symbol.h"
|
||||
#include "util/synthetic-events.h"
|
||||
#include "util/top.h"
|
||||
#include "util/util.h"
|
||||
#include <linux/rbtree.h>
|
||||
|
@ -76,6 +79,7 @@
|
|||
#include <linux/stringify.h>
|
||||
#include <linux/time64.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/err.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");
|
||||
|
||||
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));
|
||||
sleep(1);
|
||||
break;
|
||||
|
@ -537,7 +541,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
|||
if (top->sym_evsel->idx == counter)
|
||||
break;
|
||||
} else
|
||||
top->sym_evsel = perf_evlist__first(top->evlist);
|
||||
top->sym_evsel = evlist__first(top->evlist);
|
||||
break;
|
||||
case 'f':
|
||||
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 evlist *evlist = top->evlist;
|
||||
struct perf_mmap *md;
|
||||
struct mmap *md;
|
||||
union perf_event *event;
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
if (overwrite) {
|
||||
|
@ -959,7 +963,7 @@ static int perf_top__overwrite_check(struct perf_top *top)
|
|||
/* has term for current event */
|
||||
if ((overwrite < 0) && (set >= 0)) {
|
||||
/* if it's first event, set overwrite */
|
||||
if (evsel == perf_evlist__first(evlist))
|
||||
if (evsel == evlist__first(evlist))
|
||||
overwrite = set;
|
||||
else
|
||||
return -1;
|
||||
|
@ -983,7 +987,7 @@ static int perf_top_overwrite_fallback(struct perf_top *top,
|
|||
return 0;
|
||||
|
||||
/* only fall back when first event fails */
|
||||
if (evsel != perf_evlist__first(evlist))
|
||||
if (evsel != evlist__first(evlist))
|
||||
return 0;
|
||||
|
||||
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",
|
||||
errno, str_error_r(errno, msg, sizeof(msg)));
|
||||
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 */
|
||||
perf_evlist__poll(top->evlist, 100);
|
||||
evlist__poll(top->evlist, 100);
|
||||
|
||||
perf_top__mmap_read(top);
|
||||
|
||||
|
@ -1314,7 +1318,7 @@ static int __cmd_top(struct perf_top *top)
|
|||
perf_top__mmap_read(top);
|
||||
|
||||
if (opts->overwrite || (hits == top->samples))
|
||||
ret = perf_evlist__poll(top->evlist, 100);
|
||||
ret = evlist__poll(top->evlist, 100);
|
||||
|
||||
if (resize) {
|
||||
perf_top__resize(top);
|
||||
|
@ -1641,7 +1645,7 @@ int cmd_top(int argc, const char **argv)
|
|||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
top.sym_evsel = perf_evlist__first(top.evlist);
|
||||
top.sym_evsel = evlist__first(top.evlist);
|
||||
|
||||
if (!callchain_param.enabled) {
|
||||
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);
|
||||
if (top.session == NULL) {
|
||||
status = -1;
|
||||
if (IS_ERR(top.session)) {
|
||||
status = PTR_ERR(top.session);
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,12 @@
|
|||
#include "util/dso.h"
|
||||
#include "util/env.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/evswitch.h"
|
||||
#include "util/mmap.h"
|
||||
#include <subcmd/pager.h>
|
||||
#include <subcmd/exec-cmd.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_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)
|
||||
|
@ -3408,7 +3412,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
if (trace->dump.map)
|
||||
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)
|
||||
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 ||
|
||||
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
|
||||
|
@ -3441,9 +3445,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
again:
|
||||
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;
|
||||
struct perf_mmap *md;
|
||||
struct mmap *md;
|
||||
|
||||
md = &evlist->mmap[i];
|
||||
if (perf_mmap__read_init(md) < 0)
|
||||
|
@ -3472,8 +3476,8 @@ again:
|
|||
if (trace->nr_events == before) {
|
||||
int timeout = done ? 100 : -1;
|
||||
|
||||
if (!draining && perf_evlist__poll(evlist, timeout) > 0) {
|
||||
if (perf_evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0)
|
||||
if (!draining && evlist__poll(evlist, timeout) > 0) {
|
||||
if (evlist__filter_pollfd(evlist, POLLERR | POLLHUP | POLLNVAL) == 0)
|
||||
draining = true;
|
||||
|
||||
goto again;
|
||||
|
@ -3584,8 +3588,8 @@ static int trace__replay(struct trace *trace)
|
|||
trace->multiple_threads = true;
|
||||
|
||||
session = perf_session__new(&data, false, &trace->tool);
|
||||
if (session == NULL)
|
||||
return -1;
|
||||
if (IS_ERR(session))
|
||||
return PTR_ERR(session);
|
||||
|
||||
if (trace->opts.target.pid)
|
||||
symbol_conf.pid_list_str = strdup(trace->opts.target.pid);
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
jvmti-y += libjvmti.o
|
||||
jvmti-y += jvmti_agent.o
|
||||
|
||||
# For strlcpy
|
||||
jvmti-y += libstring.o
|
||||
|
||||
CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux
|
||||
CFLAGS_REMOVE_jvmti = -Wmissing-declarations
|
||||
CFLAGS_REMOVE_jvmti += -Wstrict-prototypes
|
||||
CFLAGS_REMOVE_jvmti += -Wextra
|
||||
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
|
||||
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
|
||||
override CFLAGS += $(EXTRA_WARNINGS)
|
||||
|
@ -88,13 +94,34 @@ LIBPERF_PC := $(OUTPUT)libperf.pc
|
|||
|
||||
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
|
||||
$(Q)$(MAKE) $(build)=libperf
|
||||
|
||||
$(LIBPERF_A): $(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 \
|
||||
-Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@
|
||||
@ln -sf $(@F) $(OUTPUT)libperf.so
|
||||
|
@ -106,12 +133,12 @@ libs: $(LIBPERF_A) $(LIBPERF_SO) $(LIBPERF_PC)
|
|||
all: fixdep
|
||||
$(Q)$(MAKE) libs
|
||||
|
||||
clean:
|
||||
clean: $(LIBAPI)-clean
|
||||
$(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \
|
||||
*.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd LIBPERF-CFLAGS $(LIBPERF_PC)
|
||||
$(Q)$(MAKE) -C tests clean
|
||||
|
||||
tests:
|
||||
tests: libs
|
||||
$(Q)$(MAKE) -C tests
|
||||
$(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/evlist.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)
|
||||
$(call QUIET_INSTALL, $(LIBPERF_PC)) \
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <perf/core.h>
|
||||
#include <internal/lib.h>
|
||||
#include "internal.h"
|
||||
|
||||
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;
|
||||
|
||||
void libperf_set_print(libperf_print_fn_t fn)
|
||||
{
|
||||
__libperf_pr = fn;
|
||||
}
|
||||
|
||||
__printf(2, 3)
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
#include <perf/evlist.h>
|
||||
#include <perf/evsel.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/hash.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <internal/evlist.h>
|
||||
#include <internal/evsel.h>
|
||||
#include <internal/xyarray.h>
|
||||
#include <linux/zalloc.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/threadmap.h>
|
||||
#include <api/fd/array.h>
|
||||
|
||||
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);
|
||||
evlist->nr_entries = 0;
|
||||
}
|
||||
|
@ -157,3 +171,113 @@ void perf_evlist__disable(struct perf_evlist *evlist)
|
|||
perf_evlist__for_each_entry(evlist, 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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#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_thread_map;
|
||||
|
@ -13,8 +18,16 @@ struct perf_evlist {
|
|||
bool has_user_cpus;
|
||||
struct perf_cpu_map *cpus;
|
||||
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
|
||||
* @list: list_head instance to iterate
|
||||
|
@ -47,4 +60,24 @@ struct perf_evlist {
|
|||
#define perf_evlist__for_each_entry_reverse(evlist, 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 */
|
||||
|
|
|
@ -4,9 +4,35 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct perf_cpu_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 list_head node;
|
||||
|
@ -15,9 +41,13 @@ struct perf_evsel {
|
|||
struct perf_cpu_map *own_cpus;
|
||||
struct perf_thread_map *threads;
|
||||
struct xyarray *fd;
|
||||
struct xyarray *sample_id;
|
||||
u64 *id;
|
||||
u32 ids;
|
||||
|
||||
/* parse modifier helper */
|
||||
int nr_members;
|
||||
bool system_wide;
|
||||
};
|
||||
|
||||
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__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 */
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#ifndef __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 writen(int fd, const void *buf, size_t n);
|
||||
|
|
|
@ -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,
|
||||
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 */
|
||||
|
|
|
@ -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__nr(const struct perf_cpu_map *cpus);
|
||||
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) \
|
||||
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,
|
||||
struct perf_cpu_map *cpus,
|
||||
struct perf_thread_map *threads);
|
||||
LIBPERF_API int perf_evlist__poll(struct perf_evlist *evlist, int timeout);
|
||||
|
||||
#endif /* __LIBPERF_EVLIST_H */
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <internal/lib.h>
|
||||
|
||||
unsigned int page_size;
|
||||
|
||||
static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
|
||||
{
|
||||
void *buf_start = buf;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
LIBPERF_0.0.1 {
|
||||
global:
|
||||
libperf_set_print;
|
||||
libperf_init;
|
||||
perf_cpu_map__dummy_new;
|
||||
perf_cpu_map__get;
|
||||
perf_cpu_map__put;
|
||||
|
@ -9,6 +9,7 @@ LIBPERF_0.0.1 {
|
|||
perf_cpu_map__nr;
|
||||
perf_cpu_map__cpu;
|
||||
perf_cpu_map__empty;
|
||||
perf_cpu_map__max;
|
||||
perf_thread_map__new_dummy;
|
||||
perf_thread_map__set_pid;
|
||||
perf_thread_map__comm;
|
||||
|
@ -38,6 +39,7 @@ LIBPERF_0.0.1 {
|
|||
perf_evlist__remove;
|
||||
perf_evlist__next;
|
||||
perf_evlist__set_maps;
|
||||
perf_evlist__poll;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <perf/cpumap.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)
|
||||
{
|
||||
struct perf_cpu_map *cpus;
|
||||
|
||||
__T_START;
|
||||
|
||||
libperf_init(libperf_print);
|
||||
|
||||
cpus = perf_cpu_map__dummy_new();
|
||||
if (!cpus)
|
||||
return -1;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include <perf/threadmap.h>
|
||||
|
@ -6,6 +8,12 @@
|
|||
#include <perf/evsel.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)
|
||||
{
|
||||
struct perf_cpu_map *cpus;
|
||||
|
@ -177,6 +185,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
__T_START;
|
||||
|
||||
libperf_init(libperf_print);
|
||||
|
||||
test_stat_cpu();
|
||||
test_stat_thread();
|
||||
test_stat_thread_enable();
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче