mirror of
https://github.com/torvalds/linux.git
synced 2026-06-05 13:06:59 +02:00
perf/core improvements and fixes:
perf record:
- Introduce --switch-output-event to use arbitrary events to be setup
and read from a side band thread and, when they take place a signal
be sent to the main 'perf record' thread, reusing the --switch-output
code to take perf.data snapshots from the --overwrite ring buffer, e.g.:
# perf record --overwrite -e sched:* \
--switch-output-event syscalls:*connect* \
workload
will take perf.data.YYYYMMDDHHMMSS snapshots up to around the
connect syscalls.
Stephane Eranian:
- Add --num-synthesize-threads option to control degree of parallelism of the
synthesize_mmap() code which is scanning /proc/PID/task/PID/maps and can be
time consuming. This mimics pre-existing behaviour in 'perf top'.
Intel PT:
Adrian Hunter:
- Add support for synthesizing branch stacks for regular events (cycles,
instructions, etc) from Intel PT data.
perf bench:
Ian Rogers:
- Add a multi-threaded synthesize benchmark.
- Add kallsyms parsing benchmark.
Tommi Rantala:
- Fix div-by-zero if runtime is zero.
perf synthetic events:
- Remove use of sscanf from /proc reading when parsing pre-existing
threads to generate synthetic PERF_RECORD_{FORK,MMAP,COMM,etc} events.
tools api:
- Add a lightweight buffered reading API.
libsymbols:
- Parse kallsyms using new lightweight buffered reading io API.
perf parse-events:
- Fix memory leaks found on parse_events.
perf mem2node:
- Avoid double free related to realloc().
perf stat:
Jin Yao:
- Zero all the 'ena' and 'run' array slot stats for interval mode.
- Improve runtime stat for interval mode
Kajol Jain:
- Enable Hz/hz printing for --metric-only option
- Enhance JSON/metric infrastructure to handle "?".
perf tests:
Kajol Jain:
- Added test for runtime param in metric expression.
Tommi Rantala:
- Fix data path in the session topology test.
perf vendor events power9:
Kajol Jain:
- Add hv_24x7 socket/chip level metric events
Coresight:
Leo Yan:
- Move definition of 'traceid_list' global variable from header file.
Mike Leach:
- Update to build with latest opencsd version.
perf pmu:
Shaokun Zhang:
- Fix function name in comment, its get_cpuid_str(), not get_cpustr()
Stephane Eranian:
- Add perf_pmu__find_by_type() helper
perf script:
Stephane Eranian:
- Remove extraneous newline in perf_sample__fprintf_regs().
Ian Rogers:
- Avoid NULL dereference on symbol.
tools feature:
Stephane Eranian:
- Add support for detecting libpfm4.
perf symbol:
Thomas Richter:
- Fix kernel symbol address display in TUI verbose mode.
perf cgroup:
Tommi Rantala:
- Avoid needless closing of unopened fd
libperf:
He Zhe:
- Add NULL pointer check for cpu_map iteration and NULL
assignment for all_cpus.
Ian Rogers:
- Fix a refcount leak in evlist method.
Arnaldo Carvalho de Melo:
- Rename the code in tools/perf/util, i.e. perf tooling specific, that
operates on 'struct evsel' to evsel__, leaving the perf_evsel__
namespace for the routines in tools/lib/perf/ that operate on
'struct perf_evsel__'.
tools/perf specific libraries:
Konstantin Khlebnikov:
- Fix reading new topology attribute "core_cpus"
- Simplify checking if SMT is active.
perf flamegraph:
Arnaldo Carvalho de Melo:
- Use /bin/bash for report and record scripts, just like all other
such scripts, fixing a package dependency bug in a Linaro
OpenEmbedded build checker.
perf evlist:
Jagadeesh Pagadala:
- Remove duplicate headers.
Miscelaneous:
Zou Wei:
- Remove unneeded semicolon in libtraceevent, 'perf c2c' and others.
- Fix warning assignment of 0/1 to bool variable in 'perf report'
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-----BEGIN PGP SIGNATURE-----
iHUEABYIAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCXrK7rAAKCRCyPKLppCJ+
J1poAQDaFfafx7PTkj/c1gJAEEd/4vPa/p2/ZPu6M3s1EUprXQD+I1He5Gk57KRn
VmJ7dESTeTeBUgfqRdBq2LIhi/GK7A4=
=T6lV
-----END PGP SIGNATURE-----
Merge tag 'perf-core-for-mingo-5.8-20200506' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf updates from Arnaldo:
perf/core improvements and fixes:
perf record:
- Introduce --switch-output-event to use arbitrary events to be setup
and read from a side band thread and, when they take place a signal
be sent to the main 'perf record' thread, reusing the --switch-output
code to take perf.data snapshots from the --overwrite ring buffer, e.g.:
# perf record --overwrite -e sched:* \
--switch-output-event syscalls:*connect* \
workload
will take perf.data.YYYYMMDDHHMMSS snapshots up to around the
connect syscalls.
Stephane Eranian:
- Add --num-synthesize-threads option to control degree of parallelism of the
synthesize_mmap() code which is scanning /proc/PID/task/PID/maps and can be
time consuming. This mimics pre-existing behaviour in 'perf top'.
Intel PT:
Adrian Hunter:
- Add support for synthesizing branch stacks for regular events (cycles,
instructions, etc) from Intel PT data.
perf bench:
Ian Rogers:
- Add a multi-threaded synthesize benchmark.
- Add kallsyms parsing benchmark.
Tommi Rantala:
- Fix div-by-zero if runtime is zero.
perf synthetic events:
- Remove use of sscanf from /proc reading when parsing pre-existing
threads to generate synthetic PERF_RECORD_{FORK,MMAP,COMM,etc} events.
tools api:
- Add a lightweight buffered reading API.
libsymbols:
- Parse kallsyms using new lightweight buffered reading io API.
perf parse-events:
- Fix memory leaks found on parse_events.
perf mem2node:
- Avoid double free related to realloc().
perf stat:
Jin Yao:
- Zero all the 'ena' and 'run' array slot stats for interval mode.
- Improve runtime stat for interval mode
Kajol Jain:
- Enable Hz/hz printing for --metric-only option
- Enhance JSON/metric infrastructure to handle "?".
perf tests:
Kajol Jain:
- Added test for runtime param in metric expression.
Tommi Rantala:
- Fix data path in the session topology test.
perf vendor events power9:
Kajol Jain:
- Add hv_24x7 socket/chip level metric events
Coresight:
Leo Yan:
- Move definition of 'traceid_list' global variable from header file.
Mike Leach:
- Update to build with latest opencsd version.
perf pmu:
Shaokun Zhang:
- Fix function name in comment, its get_cpuid_str(), not get_cpustr()
Stephane Eranian:
- Add perf_pmu__find_by_type() helper
perf script:
Stephane Eranian:
- Remove extraneous newline in perf_sample__fprintf_regs().
Ian Rogers:
- Avoid NULL dereference on symbol.
tools feature:
Stephane Eranian:
- Add support for detecting libpfm4.
perf symbol:
Thomas Richter:
- Fix kernel symbol address display in TUI verbose mode.
perf cgroup:
Tommi Rantala:
- Avoid needless closing of unopened fd
libperf:
He Zhe:
- Add NULL pointer check for cpu_map iteration and NULL
assignment for all_cpus.
Ian Rogers:
- Fix a refcount leak in evlist method.
Arnaldo Carvalho de Melo:
- Rename the code in tools/perf/util, i.e. perf tooling specific, that
operates on 'struct evsel' to evsel__, leaving the perf_evsel__
namespace for the routines in tools/lib/perf/ that operate on
'struct perf_evsel__'.
tools/perf specific libraries:
Konstantin Khlebnikov:
- Fix reading new topology attribute "core_cpus"
- Simplify checking if SMT is active.
perf flamegraph:
Arnaldo Carvalho de Melo:
- Use /bin/bash for report and record scripts, just like all other
such scripts, fixing a package dependency bug in a Linaro
OpenEmbedded build checker.
perf evlist:
Jagadeesh Pagadala:
- Remove duplicate headers.
Miscelaneous:
Zou Wei:
- Remove unneeded semicolon in libtraceevent, 'perf c2c' and others.
- Fix warning assignment of 0/1 to bool variable in 'perf report'
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
commit
059c6d68cf
|
|
@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA := \
|
|||
llvm \
|
||||
llvm-version \
|
||||
clang \
|
||||
libbpf
|
||||
libbpf \
|
||||
libpfm4
|
||||
|
||||
FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ FILES= \
|
|||
test-libaio.bin \
|
||||
test-libzstd.bin \
|
||||
test-clang-bpf-global-var.bin \
|
||||
test-file-handle.bin
|
||||
test-file-handle.bin \
|
||||
test-libpfm4.bin
|
||||
|
||||
FILES := $(addprefix $(OUTPUT),$(FILES))
|
||||
|
||||
|
|
@ -331,6 +332,9 @@ $(OUTPUT)test-clang-bpf-global-var.bin:
|
|||
$(OUTPUT)test-file-handle.bin:
|
||||
$(BUILD)
|
||||
|
||||
$(OUTPUT)test-libpfm4.bin:
|
||||
$(BUILD) -lpfm
|
||||
|
||||
###############################
|
||||
|
||||
clean:
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
/*
|
||||
* Check OpenCSD library version is sufficient to provide required features
|
||||
*/
|
||||
#define OCSD_MIN_VER ((0 << 16) | (11 << 8) | (0))
|
||||
#define OCSD_MIN_VER ((0 << 16) | (14 << 8) | (0))
|
||||
#if !defined(OCSD_VER_NUM) || (OCSD_VER_NUM < OCSD_MIN_VER)
|
||||
#error "OpenCSD >= 0.11.0 is required"
|
||||
#error "OpenCSD >= 0.14.0 is required"
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
|
|
|
|||
9
tools/build/feature/test-libpfm4.c
Normal file
9
tools/build/feature/test-libpfm4.c
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <sys/types.h>
|
||||
#include <perfmon/pfmlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pfm_initialize();
|
||||
return 0;
|
||||
}
|
||||
115
tools/lib/api/io.h
Normal file
115
tools/lib/api/io.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Lightweight buffered reading library.
|
||||
*
|
||||
* Copyright 2019 Google LLC.
|
||||
*/
|
||||
#ifndef __API_IO__
|
||||
#define __API_IO__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct io {
|
||||
/* File descriptor being read/ */
|
||||
int fd;
|
||||
/* Size of the read buffer. */
|
||||
unsigned int buf_len;
|
||||
/* Pointer to storage for buffering read. */
|
||||
char *buf;
|
||||
/* End of the storage. */
|
||||
char *end;
|
||||
/* Currently accessed data pointer. */
|
||||
char *data;
|
||||
/* Set true on when the end of file on read error. */
|
||||
bool eof;
|
||||
};
|
||||
|
||||
static inline void io__init(struct io *io, int fd,
|
||||
char *buf, unsigned int buf_len)
|
||||
{
|
||||
io->fd = fd;
|
||||
io->buf_len = buf_len;
|
||||
io->buf = buf;
|
||||
io->end = buf;
|
||||
io->data = buf;
|
||||
io->eof = false;
|
||||
}
|
||||
|
||||
/* Reads one character from the "io" file with similar semantics to fgetc. */
|
||||
static inline int io__get_char(struct io *io)
|
||||
{
|
||||
char *ptr = io->data;
|
||||
|
||||
if (io->eof)
|
||||
return -1;
|
||||
|
||||
if (ptr == io->end) {
|
||||
ssize_t n = read(io->fd, io->buf, io->buf_len);
|
||||
|
||||
if (n <= 0) {
|
||||
io->eof = true;
|
||||
return -1;
|
||||
}
|
||||
ptr = &io->buf[0];
|
||||
io->end = &io->buf[n];
|
||||
}
|
||||
io->data = ptr + 1;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
/* Read a hexadecimal value with no 0x prefix into the out argument hex. If the
|
||||
* first character isn't hexadecimal returns -2, io->eof returns -1, otherwise
|
||||
* returns the character after the hexadecimal value which may be -1 for eof.
|
||||
* If the read value is larger than a u64 the high-order bits will be dropped.
|
||||
*/
|
||||
static inline int io__get_hex(struct io *io, __u64 *hex)
|
||||
{
|
||||
bool first_read = true;
|
||||
|
||||
*hex = 0;
|
||||
while (true) {
|
||||
int ch = io__get_char(io);
|
||||
|
||||
if (ch < 0)
|
||||
return ch;
|
||||
if (ch >= '0' && ch <= '9')
|
||||
*hex = (*hex << 4) | (ch - '0');
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
*hex = (*hex << 4) | (ch - 'a' + 10);
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
*hex = (*hex << 4) | (ch - 'A' + 10);
|
||||
else if (first_read)
|
||||
return -2;
|
||||
else
|
||||
return ch;
|
||||
first_read = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a positive decimal value with out argument dec. If the first character
|
||||
* isn't a decimal returns -2, io->eof returns -1, otherwise returns the
|
||||
* character after the decimal value which may be -1 for eof. If the read value
|
||||
* is larger than a u64 the high-order bits will be dropped.
|
||||
*/
|
||||
static inline int io__get_dec(struct io *io, __u64 *dec)
|
||||
{
|
||||
bool first_read = true;
|
||||
|
||||
*dec = 0;
|
||||
while (true) {
|
||||
int ch = io__get_char(io);
|
||||
|
||||
if (ch < 0)
|
||||
return ch;
|
||||
if (ch >= '0' && ch <= '9')
|
||||
*dec = (*dec * 10) + ch - '0';
|
||||
else if (first_read)
|
||||
return -2;
|
||||
else
|
||||
return ch;
|
||||
first_read = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __API_IO__ */
|
||||
|
|
@ -247,7 +247,7 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list)
|
|||
|
||||
int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx)
|
||||
{
|
||||
if (idx < cpus->nr)
|
||||
if (cpus && idx < cpus->nr)
|
||||
return cpus->map[idx];
|
||||
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -11,10 +11,8 @@
|
|||
#include <internal/mmap.h>
|
||||
#include <internal/cpumap.h>
|
||||
#include <internal/threadmap.h>
|
||||
#include <internal/xyarray.h>
|
||||
#include <internal/lib.h>
|
||||
#include <linux/zalloc.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -125,8 +123,10 @@ static void perf_evlist__purge(struct perf_evlist *evlist)
|
|||
void perf_evlist__exit(struct perf_evlist *evlist)
|
||||
{
|
||||
perf_cpu_map__put(evlist->cpus);
|
||||
perf_cpu_map__put(evlist->all_cpus);
|
||||
perf_thread_map__put(evlist->threads);
|
||||
evlist->cpus = NULL;
|
||||
evlist->all_cpus = NULL;
|
||||
evlist->threads = NULL;
|
||||
fdarray__exit(&evlist->pollfd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ struct option {
|
|||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
|
||||
#define OPT_CALLBACK(s, l, v, a, h, f) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f) }
|
||||
#define OPT_CALLBACK_SET(s, l, v, os, a, h, f) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .set = check_vtype(os, bool *)}
|
||||
#define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .flags = PARSE_OPT_NOARG }
|
||||
#define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "symbol/kallsyms.h"
|
||||
#include "api/io.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
u8 kallsyms2elf_type(char type)
|
||||
{
|
||||
|
|
@ -15,74 +17,62 @@ bool kallsyms__is_function(char symbol_type)
|
|||
return symbol_type == 'T' || symbol_type == 'W';
|
||||
}
|
||||
|
||||
/*
|
||||
* While we find nice hex chars, build a long_val.
|
||||
* Return number of chars processed.
|
||||
*/
|
||||
int hex2u64(const char *ptr, u64 *long_val)
|
||||
static void read_to_eol(struct io *io)
|
||||
{
|
||||
char *p;
|
||||
int ch;
|
||||
|
||||
*long_val = strtoull(ptr, &p, 16);
|
||||
|
||||
return p - ptr;
|
||||
for (;;) {
|
||||
ch = io__get_char(io);
|
||||
if (ch < 0 || ch == '\n')
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int kallsyms__parse(const char *filename, void *arg,
|
||||
int (*process_symbol)(void *arg, const char *name,
|
||||
char type, u64 start))
|
||||
{
|
||||
char *line = NULL;
|
||||
size_t n;
|
||||
int err = -1;
|
||||
FILE *file = fopen(filename, "r");
|
||||
struct io io;
|
||||
char bf[BUFSIZ];
|
||||
int err;
|
||||
|
||||
if (file == NULL)
|
||||
goto out_failure;
|
||||
io.fd = open(filename, O_RDONLY, 0);
|
||||
|
||||
if (io.fd < 0)
|
||||
return -1;
|
||||
|
||||
io__init(&io, io.fd, bf, sizeof(bf));
|
||||
|
||||
err = 0;
|
||||
|
||||
while (!feof(file)) {
|
||||
u64 start;
|
||||
int line_len, len;
|
||||
while (!io.eof) {
|
||||
__u64 start;
|
||||
int ch;
|
||||
size_t i;
|
||||
char symbol_type;
|
||||
char *symbol_name;
|
||||
char symbol_name[KSYM_NAME_LEN + 1];
|
||||
|
||||
line_len = getline(&line, &n, file);
|
||||
if (line_len < 0 || !line)
|
||||
break;
|
||||
|
||||
line[--line_len] = '\0'; /* \n */
|
||||
|
||||
len = hex2u64(line, &start);
|
||||
|
||||
/* Skip the line if we failed to parse the address. */
|
||||
if (!len)
|
||||
if (io__get_hex(&io, &start) != ' ') {
|
||||
read_to_eol(&io);
|
||||
continue;
|
||||
|
||||
len++;
|
||||
if (len + 2 >= line_len)
|
||||
continue;
|
||||
|
||||
symbol_type = line[len];
|
||||
len += 2;
|
||||
symbol_name = line + len;
|
||||
len = line_len - len;
|
||||
|
||||
if (len >= KSYM_NAME_LEN) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
symbol_type = io__get_char(&io);
|
||||
if (io__get_char(&io) != ' ') {
|
||||
read_to_eol(&io);
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < sizeof(symbol_name); i++) {
|
||||
ch = io__get_char(&io);
|
||||
if (ch < 0 || ch == '\n')
|
||||
break;
|
||||
symbol_name[i] = ch;
|
||||
}
|
||||
symbol_name[i] = '\0';
|
||||
|
||||
err = process_symbol(arg, symbol_name, symbol_type, start);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
close(io.fd);
|
||||
return err;
|
||||
|
||||
out_failure:
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ static inline u8 kallsyms2elf_binding(char type)
|
|||
return isupper(type) ? STB_GLOBAL : STB_LOCAL;
|
||||
}
|
||||
|
||||
int hex2u64(const char *ptr, u64 *long_val);
|
||||
|
||||
u8 kallsyms2elf_type(char type);
|
||||
|
||||
bool kallsyms__is_function(char symbol_type);
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ void *kbuffer_translate_data(int swap, void *data, unsigned int *size)
|
|||
case KBUFFER_TYPE_TIME_EXTEND:
|
||||
case KBUFFER_TYPE_TIME_STAMP:
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
|
||||
*size = length;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
g synthesize a call chain (use with i or x)
|
||||
G synthesize a call chain on existing event records
|
||||
l synthesize last branch entries (use with i or x)
|
||||
L synthesize last branch entries on existing event records
|
||||
s skip initial number of events
|
||||
|
||||
The default is all events i.e. the same as --itrace=ibxwpe,
|
||||
|
|
@ -32,6 +33,10 @@
|
|||
Also the number of last branch entries (default 64, max. 1024) for
|
||||
instructions or transactions events can be specified.
|
||||
|
||||
Similar to options g and l, size may also be specified for options G and L.
|
||||
On x86, note that G and L work poorly when data has been recorded with
|
||||
large PEBS. Refer linkperf:perf-intel-pt[1] man page for details.
|
||||
|
||||
It is also possible to skip events generated (instructions, branches, transactions,
|
||||
ptwrite, power) at the beginning. This is useful to ignore initialization code.
|
||||
|
||||
|
|
|
|||
|
|
@ -69,22 +69,22 @@ And profiled with 'perf report' e.g.
|
|||
To also trace kernel space presents a problem, namely kernel self-modifying
|
||||
code. A fairly good kernel image is available in /proc/kcore but to get an
|
||||
accurate image a copy of /proc/kcore needs to be made under the same conditions
|
||||
as the data capture. A script perf-with-kcore can do that, but beware that the
|
||||
script makes use of 'sudo' to copy /proc/kcore. If you have perf installed
|
||||
locally from the source tree you can do:
|
||||
as the data capture. 'perf record' can make a copy of /proc/kcore if the option
|
||||
--kcore is used, but access to /proc/kcore is restricted e.g.
|
||||
|
||||
~/libexec/perf-core/perf-with-kcore record pt_ls -e intel_pt// -- ls
|
||||
sudo perf record -o pt_ls --kcore -e intel_pt// -- ls
|
||||
|
||||
which will create a directory named 'pt_ls' and put the perf.data file and
|
||||
copies of /proc/kcore, /proc/kallsyms and /proc/modules into it. Then to use
|
||||
'perf report' becomes:
|
||||
which will create a directory named 'pt_ls' and put the perf.data file (named
|
||||
simply 'data') and copies of /proc/kcore, /proc/kallsyms and /proc/modules into
|
||||
it. The other tools understand the directory format, so to use 'perf report'
|
||||
becomes:
|
||||
|
||||
~/libexec/perf-core/perf-with-kcore report pt_ls
|
||||
sudo perf report -i pt_ls
|
||||
|
||||
Because samples are synthesized after-the-fact, the sampling period can be
|
||||
selected for reporting. e.g. sample every microsecond
|
||||
|
||||
~/libexec/perf-core/perf-with-kcore report pt_ls --itrace=i1usge
|
||||
sudo perf report pt_ls --itrace=i1usge
|
||||
|
||||
See the sections below for more information about the --itrace option.
|
||||
|
||||
|
|
@ -821,7 +821,9 @@ The letters are:
|
|||
e synthesize tracing error events
|
||||
d create a debug log
|
||||
g synthesize a call chain (use with i or x)
|
||||
G synthesize a call chain on existing event records
|
||||
l synthesize last branch entries (use with i or x)
|
||||
L synthesize last branch entries on existing event records
|
||||
s skip initial number of events
|
||||
|
||||
"Instructions" events look like they were recorded by "perf record -e
|
||||
|
|
@ -912,6 +914,39 @@ transactions events can be specified. e.g.
|
|||
Note that last branch entries are cleared for each sample, so there is no overlap
|
||||
from one sample to the next.
|
||||
|
||||
The G and L options are designed in particular for sample mode, and work much
|
||||
like g and l but add call chain and branch stack to the other selected events
|
||||
instead of synthesized events. For example, to record branch-misses events for
|
||||
'ls' and then add a call chain derived from the Intel PT trace:
|
||||
|
||||
perf record --aux-sample -e '{intel_pt//u,branch-misses:u}' -- ls
|
||||
perf report --itrace=Ge
|
||||
|
||||
Although in fact G is a default for perf report, so that is the same as just:
|
||||
|
||||
perf report
|
||||
|
||||
One caveat with the G and L options is that they work poorly with "Large PEBS".
|
||||
Large PEBS means PEBS records will be accumulated by hardware and the written
|
||||
into the event buffer in one go. That reduces interrupts, but can give very
|
||||
late timestamps. Because the Intel PT trace is synchronized by timestamps,
|
||||
the PEBS events do not match the trace. Currently, Large PEBS is used only in
|
||||
certain circumstances:
|
||||
- hardware supports it
|
||||
- PEBS is used
|
||||
- event period is specified, instead of frequency
|
||||
- the sample type is limited to the following flags:
|
||||
PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR |
|
||||
PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID |
|
||||
PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER |
|
||||
PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR |
|
||||
PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER |
|
||||
PERF_SAMPLE_PERIOD (and sometimes) | PERF_SAMPLE_TIME
|
||||
Because Intel PT sample mode uses a different sample type to the list above,
|
||||
Large PEBS is not used with Intel PT sample mode. To avoid Large PEBS in other
|
||||
cases, avoid specifying the event period i.e. avoid the 'perf record' -c option,
|
||||
--count option, or 'period' config term.
|
||||
|
||||
To disable trace decoding entirely, use the option --no-itrace.
|
||||
|
||||
It is also possible to skip events generated (instructions, branches, transactions)
|
||||
|
|
|
|||
|
|
@ -556,6 +556,19 @@ overhead. You can still switch them on with:
|
|||
|
||||
--switch-output --no-no-buildid --no-no-buildid-cache
|
||||
|
||||
--switch-output-event::
|
||||
Events that will cause the switch of the perf.data file, auto-selecting
|
||||
--switch-output=signal, the results are similar as internally the side band
|
||||
thread will also send a SIGUSR2 to the main one.
|
||||
|
||||
Uses the same syntax as --event, it will just not be recorded, serving only to
|
||||
switch the perf.data file as soon as the --switch-output event is processed by
|
||||
a separate sideband thread.
|
||||
|
||||
This sideband thread is also used to other purposes, like processing the
|
||||
PERF_RECORD_BPF_EVENT records as they happen, asking the kernel for extra BPF
|
||||
information, etc.
|
||||
|
||||
--switch-max-files=N::
|
||||
|
||||
When rotating perf.data with --switch-output, only keep N files.
|
||||
|
|
@ -596,6 +609,10 @@ Make a copy of /proc/kcore and place it into a directory with the perf data file
|
|||
Limit the sample data max size, <size> is expected to be a number with
|
||||
appended unit character - B/K/M/G
|
||||
|
||||
--num-thread-synthesize::
|
||||
The number of threads to run when synthesizing events for existing processes.
|
||||
By default, the number of threads equals 1.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-stat[1], linkperf:perf-list[1], linkperf:perf-intel-pt[1]
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ Print count deltas every N milliseconds (minimum: 1ms)
|
|||
The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals. Use with caution.
|
||||
example: 'perf stat -I 1000 -e cycles -a sleep 5'
|
||||
|
||||
If the metric exists, it is calculated by the counts generated in this interval and the metric is printed after #.
|
||||
|
||||
--interval-count times::
|
||||
Print count deltas for fixed number of times.
|
||||
This option should be used together with "-I" option.
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ AWK = awk
|
|||
# non-config cases
|
||||
config := 1
|
||||
|
||||
NON_CONFIG_TARGETS := clean python-clean TAGS tags cscope help install-doc install-man install-html install-info install-pdf doc man html info pdf
|
||||
NON_CONFIG_TARGETS := clean python-clean TAGS tags cscope help
|
||||
|
||||
ifdef MAKECMDGOALS
|
||||
ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
|
||||
|
|
@ -832,7 +832,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
|
|||
|
||||
# 'make doc' should call 'make -C Documentation all'
|
||||
$(DOC_TARGETS):
|
||||
$(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:doc=all)
|
||||
$(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:doc=all) ASCIIDOC_EXTRA=$(ASCIIDOC_EXTRA)
|
||||
|
||||
TAG_FOLDERS= . ../lib ../include
|
||||
TAG_FILES= ../../include/uapi/linux/perf_event.h
|
||||
|
|
@ -959,7 +959,7 @@ install-python_ext:
|
|||
|
||||
# 'make install-doc' should call 'make -C Documentation install'
|
||||
$(INSTALL_DOC_TARGETS):
|
||||
$(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:-doc=)
|
||||
$(Q)$(MAKE) -C $(DOC_DIR) O=$(OUTPUT) $(@:-doc=) ASCIIDOC_EXTRA=$(ASCIIDOC_EXTRA)
|
||||
|
||||
### Cleaning rules
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "../../util/event.h"
|
||||
#include "../../util/evlist.h"
|
||||
#include "../../util/evsel.h"
|
||||
#include "../../util/perf_api_probe.h"
|
||||
#include "../../util/evsel_config.h"
|
||||
#include "../../util/pmu.h"
|
||||
#include "../../util/cs-etm.h"
|
||||
|
|
@ -232,7 +233,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
|
|||
ret = perf_pmu__scan_file(pmu, path, "%x", &hash);
|
||||
if (ret != 1) {
|
||||
pr_err("failed to set sink \"%s\" on event %s with %d (%s)\n",
|
||||
sink, perf_evsel__name(evsel), errno,
|
||||
sink, evsel__name(evsel), errno,
|
||||
str_error_r(errno, msg, sizeof(msg)));
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -401,7 +402,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
|
|||
* when a context switch happened.
|
||||
*/
|
||||
if (!perf_cpu_map__empty(cpus)) {
|
||||
perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
|
||||
evsel__set_sample_bit(cs_etm_evsel, CPU);
|
||||
|
||||
err = cs_etm_set_option(itr, cs_etm_evsel,
|
||||
ETM_OPT_CTXTID | ETM_OPT_TS);
|
||||
|
|
@ -425,7 +426,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
|
|||
|
||||
/* In per-cpu case, always need the time of mmap events etc */
|
||||
if (!perf_cpu_map__empty(cpus))
|
||||
perf_evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -120,9 +120,9 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
|
|||
*/
|
||||
perf_evlist__to_front(evlist, arm_spe_evsel);
|
||||
|
||||
perf_evsel__set_sample_bit(arm_spe_evsel, CPU);
|
||||
perf_evsel__set_sample_bit(arm_spe_evsel, TIME);
|
||||
perf_evsel__set_sample_bit(arm_spe_evsel, TID);
|
||||
evsel__set_sample_bit(arm_spe_evsel, CPU);
|
||||
evsel__set_sample_bit(arm_spe_evsel, TIME);
|
||||
evsel__set_sample_bit(arm_spe_evsel, TID);
|
||||
|
||||
/* Add dummy event to keep tracking */
|
||||
err = parse_events(evlist, "dummy:u", NULL);
|
||||
|
|
@ -134,9 +134,9 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
|
|||
|
||||
tracking_evsel->core.attr.freq = 0;
|
||||
tracking_evsel->core.attr.sample_period = 1;
|
||||
perf_evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
perf_evsel__set_sample_bit(tracking_evsel, CPU);
|
||||
perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
|
||||
evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
evsel__set_sample_bit(tracking_evsel, CPU);
|
||||
evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include <string.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "header.h"
|
||||
#include "metricgroup.h"
|
||||
#include <api/fs/fs.h>
|
||||
|
||||
#define mfspr(rn) ({unsigned long rval; \
|
||||
asm volatile("mfspr %0," __stringify(rn) \
|
||||
|
|
@ -44,3 +46,9 @@ get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
|
|||
|
||||
return bufp;
|
||||
}
|
||||
|
||||
int arch_get_runtimeparam(void)
|
||||
{
|
||||
int count;
|
||||
return sysfs__read_int("/devices/hv_24x7/interface/sockets", &count) < 0 ? 1 : count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ static void hcall_event_get_key(struct evsel *evsel,
|
|||
struct event_key *key)
|
||||
{
|
||||
key->info = 0;
|
||||
key->key = perf_evsel__intval(evsel, sample, "req");
|
||||
key->key = evsel__intval(evsel, sample, "req");
|
||||
}
|
||||
|
||||
static const char *get_hcall_exit_reason(u64 exit_code)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static void event_icpt_insn_get_key(struct evsel *evsel,
|
|||
{
|
||||
unsigned long insn;
|
||||
|
||||
insn = perf_evsel__intval(evsel, sample, "instruction");
|
||||
insn = evsel__intval(evsel, sample, "instruction");
|
||||
key->key = icpt_insn_decoder(insn);
|
||||
key->exit_reasons = sie_icpt_insn_codes;
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ static void event_sigp_get_key(struct evsel *evsel,
|
|||
struct perf_sample *sample,
|
||||
struct event_key *key)
|
||||
{
|
||||
key->key = perf_evsel__intval(evsel, sample, "order_code");
|
||||
key->key = evsel__intval(evsel, sample, "order_code");
|
||||
key->exit_reasons = sie_sigp_order_codes;
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ static void event_diag_get_key(struct evsel *evsel,
|
|||
struct perf_sample *sample,
|
||||
struct event_key *key)
|
||||
{
|
||||
key->key = perf_evsel__intval(evsel, sample, "code");
|
||||
key->key = evsel__intval(evsel, sample, "code");
|
||||
key->exit_reasons = sie_diagnose_codes;
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ static void event_icpt_prog_get_key(struct evsel *evsel,
|
|||
struct perf_sample *sample,
|
||||
struct event_key *key)
|
||||
{
|
||||
key->key = perf_evsel__intval(evsel, sample, "code");
|
||||
key->key = evsel__intval(evsel, sample, "code");
|
||||
key->exit_reasons = sie_icpt_prog_codes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,13 +130,11 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
|
|||
goto next_event;
|
||||
|
||||
if (strcmp(event->comm.comm, comm1) == 0) {
|
||||
CHECK__(perf_evsel__parse_sample(evsel, event,
|
||||
&sample));
|
||||
CHECK__(evsel__parse_sample(evsel, event, &sample));
|
||||
comm1_time = sample.time;
|
||||
}
|
||||
if (strcmp(event->comm.comm, comm2) == 0) {
|
||||
CHECK__(perf_evsel__parse_sample(evsel, event,
|
||||
&sample));
|
||||
CHECK__(evsel__parse_sample(evsel, event, &sample));
|
||||
comm2_time = sample.time;
|
||||
}
|
||||
next_event:
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ static int intel_bts_recording_options(struct auxtrace_record *itr,
|
|||
* AUX event.
|
||||
*/
|
||||
if (!perf_cpu_map__empty(cpus))
|
||||
perf_evsel__set_sample_bit(intel_bts_evsel, CPU);
|
||||
evsel__set_sample_bit(intel_bts_evsel, CPU);
|
||||
}
|
||||
|
||||
/* Add dummy event to keep tracking */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "../../../util/pmu.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/auxtrace.h"
|
||||
#include "../../../util/perf_api_probe.h"
|
||||
#include "../../../util/record.h"
|
||||
#include "../../../util/target.h"
|
||||
#include "../../../util/tsc.h"
|
||||
|
|
@ -420,8 +421,8 @@ static int intel_pt_track_switches(struct evlist *evlist)
|
|||
|
||||
evsel = evlist__last(evlist);
|
||||
|
||||
perf_evsel__set_sample_bit(evsel, CPU);
|
||||
perf_evsel__set_sample_bit(evsel, TIME);
|
||||
evsel__set_sample_bit(evsel, CPU);
|
||||
evsel__set_sample_bit(evsel, TIME);
|
||||
|
||||
evsel->core.system_wide = true;
|
||||
evsel->no_aux_samples = true;
|
||||
|
|
@ -801,10 +802,10 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||
switch_evsel->no_aux_samples = true;
|
||||
switch_evsel->immediate = true;
|
||||
|
||||
perf_evsel__set_sample_bit(switch_evsel, TID);
|
||||
perf_evsel__set_sample_bit(switch_evsel, TIME);
|
||||
perf_evsel__set_sample_bit(switch_evsel, CPU);
|
||||
perf_evsel__reset_sample_bit(switch_evsel, BRANCH_STACK);
|
||||
evsel__set_sample_bit(switch_evsel, TID);
|
||||
evsel__set_sample_bit(switch_evsel, TIME);
|
||||
evsel__set_sample_bit(switch_evsel, CPU);
|
||||
evsel__reset_sample_bit(switch_evsel, BRANCH_STACK);
|
||||
|
||||
opts->record_switch_events = false;
|
||||
ptr->have_sched_switch = 3;
|
||||
|
|
@ -838,7 +839,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||
* AUX event.
|
||||
*/
|
||||
if (!perf_cpu_map__empty(cpus))
|
||||
perf_evsel__set_sample_bit(intel_pt_evsel, CPU);
|
||||
evsel__set_sample_bit(intel_pt_evsel, CPU);
|
||||
}
|
||||
|
||||
/* Add dummy event to keep tracking */
|
||||
|
|
@ -862,11 +863,11 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
|
|||
|
||||
/* In per-cpu case, always need the time of mmap events etc */
|
||||
if (!perf_cpu_map__empty(cpus)) {
|
||||
perf_evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
/* And the CPU for switch events */
|
||||
perf_evsel__set_sample_bit(tracking_evsel, CPU);
|
||||
evsel__set_sample_bit(tracking_evsel, CPU);
|
||||
}
|
||||
perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
|
||||
evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ const char *kvm_exit_trace = "kvm:kvm_exit";
|
|||
static void mmio_event_get_key(struct evsel *evsel, struct perf_sample *sample,
|
||||
struct event_key *key)
|
||||
{
|
||||
key->key = perf_evsel__intval(evsel, sample, "gpa");
|
||||
key->info = perf_evsel__intval(evsel, sample, "type");
|
||||
key->key = evsel__intval(evsel, sample, "gpa");
|
||||
key->info = evsel__intval(evsel, sample, "type");
|
||||
}
|
||||
|
||||
#define KVM_TRACE_MMIO_READ_UNSATISFIED 0
|
||||
|
|
@ -48,7 +48,7 @@ static bool mmio_event_begin(struct evsel *evsel,
|
|||
|
||||
/* MMIO write begin event in kernel. */
|
||||
if (!strcmp(evsel->name, "kvm:kvm_mmio") &&
|
||||
perf_evsel__intval(evsel, sample, "type") == KVM_TRACE_MMIO_WRITE) {
|
||||
evsel__intval(evsel, sample, "type") == KVM_TRACE_MMIO_WRITE) {
|
||||
mmio_event_get_key(evsel, sample, key);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ static bool mmio_event_end(struct evsel *evsel, struct perf_sample *sample,
|
|||
|
||||
/* MMIO read end event in kernel.*/
|
||||
if (!strcmp(evsel->name, "kvm:kvm_mmio") &&
|
||||
perf_evsel__intval(evsel, sample, "type") == KVM_TRACE_MMIO_READ) {
|
||||
evsel__intval(evsel, sample, "type") == KVM_TRACE_MMIO_READ) {
|
||||
mmio_event_get_key(evsel, sample, key);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -94,8 +94,8 @@ static void ioport_event_get_key(struct evsel *evsel,
|
|||
struct perf_sample *sample,
|
||||
struct event_key *key)
|
||||
{
|
||||
key->key = perf_evsel__intval(evsel, sample, "port");
|
||||
key->info = perf_evsel__intval(evsel, sample, "rw");
|
||||
key->key = evsel__intval(evsel, sample, "port");
|
||||
key->info = evsel__intval(evsel, sample, "rw");
|
||||
}
|
||||
|
||||
static bool ioport_event_begin(struct evsel *evsel,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ perf-y += futex-lock-pi.o
|
|||
perf-y += epoll-wait.o
|
||||
perf-y += epoll-ctl.o
|
||||
perf-y += synthesize.o
|
||||
perf-y += kallsyms-parse.o
|
||||
|
||||
perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-lib.o
|
||||
perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ int bench_futex_lock_pi(int argc, const char **argv);
|
|||
int bench_epoll_wait(int argc, const char **argv);
|
||||
int bench_epoll_ctl(int argc, const char **argv);
|
||||
int bench_synthesize(int argc, const char **argv);
|
||||
int bench_kallsyms_parse(int argc, const char **argv);
|
||||
|
||||
#define BENCH_FORMAT_DEFAULT_STR "default"
|
||||
#define BENCH_FORMAT_DEFAULT 0
|
||||
|
|
|
|||
|
|
@ -519,7 +519,8 @@ int bench_epoll_wait(int argc, const char **argv)
|
|||
qsort(worker, nthreads, sizeof(struct worker), cmpworker);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
unsigned long t = bench__runtime.tv_sec > 0 ?
|
||||
worker[i].ops / bench__runtime.tv_sec : 0;
|
||||
|
||||
update_stats(&throughput_stats, t);
|
||||
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ int bench_futex_hash(int argc, const char **argv)
|
|||
pthread_mutex_destroy(&thread_lock);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
unsigned long t = bench__runtime.tv_sec > 0 ?
|
||||
worker[i].ops / bench__runtime.tv_sec : 0;
|
||||
update_stats(&throughput_stats, t);
|
||||
if (!silent) {
|
||||
if (nfutexes == 1)
|
||||
|
|
|
|||
|
|
@ -211,7 +211,8 @@ int bench_futex_lock_pi(int argc, const char **argv)
|
|||
pthread_mutex_destroy(&thread_lock);
|
||||
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
unsigned long t = worker[i].ops / bench__runtime.tv_sec;
|
||||
unsigned long t = bench__runtime.tv_sec > 0 ?
|
||||
worker[i].ops / bench__runtime.tv_sec : 0;
|
||||
|
||||
update_stats(&throughput_stats, t);
|
||||
if (!silent)
|
||||
|
|
|
|||
75
tools/perf/bench/kallsyms-parse.c
Normal file
75
tools/perf/bench/kallsyms-parse.c
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Benchmark of /proc/kallsyms parsing.
|
||||
*
|
||||
* Copyright 2020 Google LLC.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include "bench.h"
|
||||
#include "../util/stat.h"
|
||||
#include <linux/time64.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
#include <symbol/kallsyms.h>
|
||||
|
||||
static unsigned int iterations = 100;
|
||||
|
||||
static const struct option options[] = {
|
||||
OPT_UINTEGER('i', "iterations", &iterations,
|
||||
"Number of iterations used to compute average"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
static const char *const bench_usage[] = {
|
||||
"perf bench internals kallsyms-parse <options>",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int bench_process_symbol(void *arg __maybe_unused,
|
||||
const char *name __maybe_unused,
|
||||
char type __maybe_unused,
|
||||
u64 start __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_kallsyms_parse(void)
|
||||
{
|
||||
struct timeval start, end, diff;
|
||||
u64 runtime_us;
|
||||
unsigned int i;
|
||||
double time_average, time_stddev;
|
||||
int err;
|
||||
struct stats time_stats;
|
||||
|
||||
init_stats(&time_stats);
|
||||
|
||||
for (i = 0; i < iterations; i++) {
|
||||
gettimeofday(&start, NULL);
|
||||
err = kallsyms__parse("/proc/kallsyms", NULL,
|
||||
bench_process_symbol);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &diff);
|
||||
runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
|
||||
update_stats(&time_stats, runtime_us);
|
||||
}
|
||||
|
||||
time_average = avg_stats(&time_stats) / USEC_PER_MSEC;
|
||||
time_stddev = stddev_stats(&time_stats) / USEC_PER_MSEC;
|
||||
printf(" Average kallsyms__parse took: %.3f ms (+- %.3f ms)\n",
|
||||
time_average, time_stddev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bench_kallsyms_parse(int argc, const char **argv)
|
||||
{
|
||||
argc = parse_options(argc, argv, options, bench_usage, 0);
|
||||
if (argc) {
|
||||
usage_with_options(bench_usage, options);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return do_kallsyms_parse();
|
||||
}
|
||||
|
|
@ -10,60 +10,105 @@
|
|||
#include "bench.h"
|
||||
#include "../util/debug.h"
|
||||
#include "../util/session.h"
|
||||
#include "../util/stat.h"
|
||||
#include "../util/synthetic-events.h"
|
||||
#include "../util/target.h"
|
||||
#include "../util/thread_map.h"
|
||||
#include "../util/tool.h"
|
||||
#include "../util/util.h"
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/time64.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
|
||||
static unsigned int iterations = 10000;
|
||||
static unsigned int min_threads = 1;
|
||||
static unsigned int max_threads = UINT_MAX;
|
||||
static unsigned int single_iterations = 10000;
|
||||
static unsigned int multi_iterations = 10;
|
||||
static bool run_st;
|
||||
static bool run_mt;
|
||||
|
||||
static const struct option options[] = {
|
||||
OPT_UINTEGER('i', "iterations", &iterations,
|
||||
"Number of iterations used to compute average"),
|
||||
OPT_BOOLEAN('s', "st", &run_st, "Run single threaded benchmark"),
|
||||
OPT_BOOLEAN('t', "mt", &run_mt, "Run multi-threaded benchmark"),
|
||||
OPT_UINTEGER('m', "min-threads", &min_threads,
|
||||
"Minimum number of threads in multithreaded bench"),
|
||||
OPT_UINTEGER('M', "max-threads", &max_threads,
|
||||
"Maximum number of threads in multithreaded bench"),
|
||||
OPT_UINTEGER('i', "single-iterations", &single_iterations,
|
||||
"Number of iterations used to compute single-threaded average"),
|
||||
OPT_UINTEGER('I', "multi-iterations", &multi_iterations,
|
||||
"Number of iterations used to compute multi-threaded average"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
static const char *const usage[] = {
|
||||
static const char *const bench_usage[] = {
|
||||
"perf bench internals synthesize <options>",
|
||||
NULL
|
||||
};
|
||||
|
||||
static atomic_t event_count;
|
||||
|
||||
static int do_synthesize(struct perf_session *session,
|
||||
struct perf_thread_map *threads,
|
||||
struct target *target, bool data_mmap)
|
||||
static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
|
||||
union perf_event *event __maybe_unused,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
struct machine *machine __maybe_unused)
|
||||
{
|
||||
atomic_inc(&event_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_run_single_threaded(struct perf_session *session,
|
||||
struct perf_thread_map *threads,
|
||||
struct target *target, bool data_mmap)
|
||||
{
|
||||
const unsigned int nr_threads_synthesize = 1;
|
||||
struct timeval start, end, diff;
|
||||
u64 runtime_us;
|
||||
unsigned int i;
|
||||
double average;
|
||||
double time_average, time_stddev, event_average, event_stddev;
|
||||
int err;
|
||||
struct stats time_stats, event_stats;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
for (i = 0; i < iterations; i++) {
|
||||
err = machine__synthesize_threads(&session->machines.host,
|
||||
target, threads, data_mmap,
|
||||
init_stats(&time_stats);
|
||||
init_stats(&event_stats);
|
||||
|
||||
for (i = 0; i < single_iterations; i++) {
|
||||
atomic_set(&event_count, 0);
|
||||
gettimeofday(&start, NULL);
|
||||
err = __machine__synthesize_threads(&session->machines.host,
|
||||
NULL,
|
||||
target, threads,
|
||||
process_synthesized_event,
|
||||
data_mmap,
|
||||
nr_threads_synthesize);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &diff);
|
||||
runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
|
||||
update_stats(&time_stats, runtime_us);
|
||||
update_stats(&event_stats, atomic_read(&event_count));
|
||||
}
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &diff);
|
||||
runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
|
||||
average = (double)runtime_us/(double)iterations;
|
||||
printf("Average %ssynthesis took: %f usec\n",
|
||||
data_mmap ? "data " : "", average);
|
||||
time_average = avg_stats(&time_stats);
|
||||
time_stddev = stddev_stats(&time_stats);
|
||||
printf(" Average %ssynthesis took: %.3f usec (+- %.3f usec)\n",
|
||||
data_mmap ? "data " : "", time_average, time_stddev);
|
||||
|
||||
event_average = avg_stats(&event_stats);
|
||||
event_stddev = stddev_stats(&event_stats);
|
||||
printf(" Average num. events: %.3f (+- %.3f)\n",
|
||||
event_average, event_stddev);
|
||||
|
||||
printf(" Average time per event %.3f usec\n",
|
||||
time_average / event_average);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bench_synthesize(int argc, const char **argv)
|
||||
static int run_single_threaded(void)
|
||||
{
|
||||
struct perf_tool tool;
|
||||
struct perf_session *session;
|
||||
struct target target = {
|
||||
.pid = "self",
|
||||
|
|
@ -71,8 +116,7 @@ int bench_synthesize(int argc, const char **argv)
|
|||
struct perf_thread_map *threads;
|
||||
int err;
|
||||
|
||||
argc = parse_options(argc, argv, options, usage, 0);
|
||||
|
||||
perf_set_singlethreaded();
|
||||
session = perf_session__new(NULL, false, NULL);
|
||||
if (IS_ERR(session)) {
|
||||
pr_err("Session creation failed.\n");
|
||||
|
|
@ -84,13 +128,16 @@ int bench_synthesize(int argc, const char **argv)
|
|||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
perf_tool__fill_defaults(&tool);
|
||||
|
||||
err = do_synthesize(session, threads, &target, false);
|
||||
puts(
|
||||
"Computing performance of single threaded perf event synthesis by\n"
|
||||
"synthesizing events on the perf process itself:");
|
||||
|
||||
err = do_run_single_threaded(session, threads, &target, false);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
err = do_synthesize(session, threads, &target, true);
|
||||
err = do_run_single_threaded(session, threads, &target, true);
|
||||
|
||||
err_out:
|
||||
if (threads)
|
||||
|
|
@ -99,3 +146,117 @@ int bench_synthesize(int argc, const char **argv)
|
|||
perf_session__delete(session);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int do_run_multi_threaded(struct target *target,
|
||||
unsigned int nr_threads_synthesize)
|
||||
{
|
||||
struct timeval start, end, diff;
|
||||
u64 runtime_us;
|
||||
unsigned int i;
|
||||
double time_average, time_stddev, event_average, event_stddev;
|
||||
int err;
|
||||
struct stats time_stats, event_stats;
|
||||
struct perf_session *session;
|
||||
|
||||
init_stats(&time_stats);
|
||||
init_stats(&event_stats);
|
||||
for (i = 0; i < multi_iterations; i++) {
|
||||
session = perf_session__new(NULL, false, NULL);
|
||||
if (!session)
|
||||
return -ENOMEM;
|
||||
|
||||
atomic_set(&event_count, 0);
|
||||
gettimeofday(&start, NULL);
|
||||
err = __machine__synthesize_threads(&session->machines.host,
|
||||
NULL,
|
||||
target, NULL,
|
||||
process_synthesized_event,
|
||||
false,
|
||||
nr_threads_synthesize);
|
||||
if (err) {
|
||||
perf_session__delete(session);
|
||||
return err;
|
||||
}
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
timersub(&end, &start, &diff);
|
||||
runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
|
||||
update_stats(&time_stats, runtime_us);
|
||||
update_stats(&event_stats, atomic_read(&event_count));
|
||||
perf_session__delete(session);
|
||||
}
|
||||
|
||||
time_average = avg_stats(&time_stats);
|
||||
time_stddev = stddev_stats(&time_stats);
|
||||
printf(" Average synthesis took: %.3f usec (+- %.3f usec)\n",
|
||||
time_average, time_stddev);
|
||||
|
||||
event_average = avg_stats(&event_stats);
|
||||
event_stddev = stddev_stats(&event_stats);
|
||||
printf(" Average num. events: %.3f (+- %.3f)\n",
|
||||
event_average, event_stddev);
|
||||
|
||||
printf(" Average time per event %.3f usec\n",
|
||||
time_average / event_average);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run_multi_threaded(void)
|
||||
{
|
||||
struct target target = {
|
||||
.cpu_list = "0"
|
||||
};
|
||||
unsigned int nr_threads_synthesize;
|
||||
int err;
|
||||
|
||||
if (max_threads == UINT_MAX)
|
||||
max_threads = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
|
||||
puts(
|
||||
"Computing performance of multi threaded perf event synthesis by\n"
|
||||
"synthesizing events on CPU 0:");
|
||||
|
||||
for (nr_threads_synthesize = min_threads;
|
||||
nr_threads_synthesize <= max_threads;
|
||||
nr_threads_synthesize++) {
|
||||
if (nr_threads_synthesize == 1)
|
||||
perf_set_singlethreaded();
|
||||
else
|
||||
perf_set_multithreaded();
|
||||
|
||||
printf(" Number of synthesis threads: %u\n",
|
||||
nr_threads_synthesize);
|
||||
|
||||
err = do_run_multi_threaded(&target, nr_threads_synthesize);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
perf_set_singlethreaded();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bench_synthesize(int argc, const char **argv)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
argc = parse_options(argc, argv, options, bench_usage, 0);
|
||||
if (argc) {
|
||||
usage_with_options(bench_usage, options);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* If neither single threaded or multi-threaded are specified, default
|
||||
* to running just single threaded.
|
||||
*/
|
||||
if (!run_st && !run_mt)
|
||||
run_st = true;
|
||||
|
||||
if (run_st)
|
||||
err = run_single_threaded();
|
||||
|
||||
if (!err && run_mt)
|
||||
err = run_multi_threaded();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,11 +212,9 @@ static bool has_annotation(struct perf_annotate *ann)
|
|||
return ui__has_annotation() || ann->use_stdio2;
|
||||
}
|
||||
|
||||
static int perf_evsel__add_sample(struct evsel *evsel,
|
||||
struct perf_sample *sample,
|
||||
struct addr_location *al,
|
||||
struct perf_annotate *ann,
|
||||
struct machine *machine)
|
||||
static int evsel__add_sample(struct evsel *evsel, struct perf_sample *sample,
|
||||
struct addr_location *al, struct perf_annotate *ann,
|
||||
struct machine *machine)
|
||||
{
|
||||
struct hists *hists = evsel__hists(evsel);
|
||||
struct hist_entry *he;
|
||||
|
|
@ -278,7 +276,7 @@ static int process_sample_event(struct perf_tool *tool,
|
|||
goto out_put;
|
||||
|
||||
if (!al.filtered &&
|
||||
perf_evsel__add_sample(evsel, sample, &al, ann, machine)) {
|
||||
evsel__add_sample(evsel, sample, &al, ann, machine)) {
|
||||
pr_warning("problem incrementing symbol count, "
|
||||
"skipping event\n");
|
||||
ret = -1;
|
||||
|
|
@ -433,11 +431,10 @@ static int __cmd_annotate(struct perf_annotate *ann)
|
|||
total_nr_samples += nr_samples;
|
||||
hists__collapse_resort(hists, NULL);
|
||||
/* Don't sort callchain */
|
||||
perf_evsel__reset_sample_bit(pos, CALLCHAIN);
|
||||
evsel__reset_sample_bit(pos, CALLCHAIN);
|
||||
perf_evsel__output_resort(pos, NULL);
|
||||
|
||||
if (symbol_conf.event_group &&
|
||||
!perf_evsel__is_group_leader(pos))
|
||||
if (symbol_conf.event_group && !evsel__is_group_leader(pos))
|
||||
continue;
|
||||
|
||||
hists__find_annotations(hists, pos, ann);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ static struct bench epoll_benchmarks[] = {
|
|||
|
||||
static struct bench internals_benchmarks[] = {
|
||||
{ "synthesize", "Benchmark perf event synthesis", bench_synthesize },
|
||||
{ "kallsyms-parse", "Benchmark kallsyms parsing", bench_kallsyms_parse },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1709,7 +1709,7 @@ static struct c2c_dimension *get_dimension(const char *name)
|
|||
|
||||
if (!strcmp(dim->name, name))
|
||||
return dim;
|
||||
};
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1925,7 +1925,7 @@ static bool he__display(struct hist_entry *he, struct c2c_stats *stats)
|
|||
FILTER_HITM(tot_hitm);
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
#undef FILTER_HITM
|
||||
|
||||
|
|
@ -2259,8 +2259,7 @@ static void print_c2c_info(FILE *out, struct perf_session *session)
|
|||
fprintf(out, "=================================================\n");
|
||||
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
fprintf(out, "%-36s: %s\n", first ? " Events" : "",
|
||||
perf_evsel__name(evsel));
|
||||
fprintf(out, "%-36s: %s\n", first ? " Events" : "", evsel__name(evsel));
|
||||
first = false;
|
||||
}
|
||||
fprintf(out, " Cachelines sort on : %s HITMs\n",
|
||||
|
|
@ -2959,7 +2958,7 @@ static int perf_c2c__record(int argc, const char **argv)
|
|||
|
||||
rec_argv[i++] = "-e";
|
||||
rec_argv[i++] = perf_mem_events__name(j);
|
||||
};
|
||||
}
|
||||
|
||||
if (all_user)
|
||||
rec_argv[i++] = "--all-user";
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ static struct evsel *evsel_match(struct evsel *evsel,
|
|||
struct evsel *e;
|
||||
|
||||
evlist__for_each_entry(evlist, e) {
|
||||
if (perf_evsel__match2(evsel, e))
|
||||
if (evsel__match2(evsel, e))
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -981,7 +981,7 @@ static void data_process(void)
|
|||
|
||||
if (!quiet) {
|
||||
fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
|
||||
perf_evsel__name(evsel_base));
|
||||
evsel__name(evsel_base));
|
||||
}
|
||||
|
||||
first = false;
|
||||
|
|
@ -990,7 +990,7 @@ static void data_process(void)
|
|||
data__fprintf();
|
||||
|
||||
/* Don't sort callchain for perf diff */
|
||||
perf_evsel__reset_sample_bit(evsel_base, CALLCHAIN);
|
||||
evsel__reset_sample_bit(evsel_base, CALLCHAIN);
|
||||
|
||||
hists__process(hists_base);
|
||||
}
|
||||
|
|
@ -1562,7 +1562,7 @@ hpp__entry_pair(struct hist_entry *he, struct hist_entry *pair,
|
|||
|
||||
default:
|
||||
BUG_ON(1);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ static int perf_inject__sched_stat(struct perf_tool *tool,
|
|||
union perf_event *event_sw;
|
||||
struct perf_sample sample_sw;
|
||||
struct perf_inject *inject = container_of(tool, struct perf_inject, tool);
|
||||
u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
|
||||
list_for_each_entry(ent, &inject->samples, node) {
|
||||
if (pid == ent->tid)
|
||||
|
|
@ -546,7 +546,7 @@ static int perf_inject__sched_stat(struct perf_tool *tool,
|
|||
return 0;
|
||||
found:
|
||||
event_sw = &ent->event[0];
|
||||
perf_evsel__parse_sample(evsel, event_sw, &sample_sw);
|
||||
evsel__parse_sample(evsel, event_sw, &sample_sw);
|
||||
|
||||
sample_sw.period = sample->period;
|
||||
sample_sw.time = sample->time;
|
||||
|
|
@ -561,11 +561,10 @@ static void sig_handler(int sig __maybe_unused)
|
|||
session_done = 1;
|
||||
}
|
||||
|
||||
static int perf_evsel__check_stype(struct evsel *evsel,
|
||||
u64 sample_type, const char *sample_msg)
|
||||
static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg)
|
||||
{
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
const char *name = evsel__name(evsel);
|
||||
|
||||
if (!(attr->sample_type & sample_type)) {
|
||||
pr_err("Samples for %s event do not have %s attribute set.",
|
||||
|
|
@ -622,10 +621,10 @@ static int __cmd_inject(struct perf_inject *inject)
|
|||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
const char *name = evsel__name(evsel);
|
||||
|
||||
if (!strcmp(name, "sched:sched_switch")) {
|
||||
if (perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
|
||||
if (evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID"))
|
||||
return -EINVAL;
|
||||
|
||||
evsel->handler = perf_inject__sched_switch;
|
||||
|
|
@ -684,14 +683,14 @@ static int __cmd_inject(struct perf_inject *inject)
|
|||
|
||||
perf_header__clear_feat(&session->header,
|
||||
HEADER_AUXTRACE);
|
||||
if (inject->itrace_synth_opts.last_branch)
|
||||
if (inject->itrace_synth_opts.last_branch ||
|
||||
inject->itrace_synth_opts.add_last_branch)
|
||||
perf_header__set_feat(&session->header,
|
||||
HEADER_BRANCH_STACK);
|
||||
evsel = perf_evlist__id2evsel_strict(session->evlist,
|
||||
inject->aux_id);
|
||||
if (evsel) {
|
||||
pr_debug("Deleting %s\n",
|
||||
perf_evsel__name(evsel));
|
||||
pr_debug("Deleting %s\n", evsel__name(evsel));
|
||||
evlist__remove(session->evlist, evsel);
|
||||
evsel__delete(evsel);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,13 +169,12 @@ static int insert_caller_stat(unsigned long call_site,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_alloc_event(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_alloc_event(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr"),
|
||||
call_site = perf_evsel__intval(evsel, sample, "call_site");
|
||||
int bytes_req = perf_evsel__intval(evsel, sample, "bytes_req"),
|
||||
bytes_alloc = perf_evsel__intval(evsel, sample, "bytes_alloc");
|
||||
unsigned long ptr = evsel__intval(evsel, sample, "ptr"),
|
||||
call_site = evsel__intval(evsel, sample, "call_site");
|
||||
int bytes_req = evsel__intval(evsel, sample, "bytes_req"),
|
||||
bytes_alloc = evsel__intval(evsel, sample, "bytes_alloc");
|
||||
|
||||
if (insert_alloc_stat(call_site, ptr, bytes_req, bytes_alloc, sample->cpu) ||
|
||||
insert_caller_stat(call_site, bytes_req, bytes_alloc))
|
||||
|
|
@ -188,14 +187,13 @@ static int perf_evsel__process_alloc_event(struct evsel *evsel,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_alloc_node_event(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_alloc_node_event(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
int ret = perf_evsel__process_alloc_event(evsel, sample);
|
||||
int ret = evsel__process_alloc_event(evsel, sample);
|
||||
|
||||
if (!ret) {
|
||||
int node1 = cpu__get_node(sample->cpu),
|
||||
node2 = perf_evsel__intval(evsel, sample, "node");
|
||||
node2 = evsel__intval(evsel, sample, "node");
|
||||
|
||||
if (node1 != node2)
|
||||
nr_cross_allocs++;
|
||||
|
|
@ -232,10 +230,9 @@ static struct alloc_stat *search_alloc_stat(unsigned long ptr,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_free_event(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_free_event(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
unsigned long ptr = perf_evsel__intval(evsel, sample, "ptr");
|
||||
unsigned long ptr = evsel__intval(evsel, sample, "ptr");
|
||||
struct alloc_stat *s_alloc, *s_caller;
|
||||
|
||||
s_alloc = search_alloc_stat(ptr, 0, &root_alloc_stat, ptr_cmp);
|
||||
|
|
@ -784,13 +781,12 @@ static int parse_gfp_flags(struct evsel *evsel, struct perf_sample *sample,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_page_alloc_event(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_page_alloc_event(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
u64 page;
|
||||
unsigned int order = perf_evsel__intval(evsel, sample, "order");
|
||||
unsigned int gfp_flags = perf_evsel__intval(evsel, sample, "gfp_flags");
|
||||
unsigned int migrate_type = perf_evsel__intval(evsel, sample,
|
||||
unsigned int order = evsel__intval(evsel, sample, "order");
|
||||
unsigned int gfp_flags = evsel__intval(evsel, sample, "gfp_flags");
|
||||
unsigned int migrate_type = evsel__intval(evsel, sample,
|
||||
"migratetype");
|
||||
u64 bytes = kmem_page_size << order;
|
||||
u64 callsite;
|
||||
|
|
@ -802,9 +798,9 @@ static int perf_evsel__process_page_alloc_event(struct evsel *evsel,
|
|||
};
|
||||
|
||||
if (use_pfn)
|
||||
page = perf_evsel__intval(evsel, sample, "pfn");
|
||||
page = evsel__intval(evsel, sample, "pfn");
|
||||
else
|
||||
page = perf_evsel__intval(evsel, sample, "page");
|
||||
page = evsel__intval(evsel, sample, "page");
|
||||
|
||||
nr_page_allocs++;
|
||||
total_page_alloc_bytes += bytes;
|
||||
|
|
@ -857,11 +853,10 @@ static int perf_evsel__process_page_alloc_event(struct evsel *evsel,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_page_free_event(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_page_free_event(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
u64 page;
|
||||
unsigned int order = perf_evsel__intval(evsel, sample, "order");
|
||||
unsigned int order = evsel__intval(evsel, sample, "order");
|
||||
u64 bytes = kmem_page_size << order;
|
||||
struct page_stat *pstat;
|
||||
struct page_stat this = {
|
||||
|
|
@ -869,9 +864,9 @@ static int perf_evsel__process_page_free_event(struct evsel *evsel,
|
|||
};
|
||||
|
||||
if (use_pfn)
|
||||
page = perf_evsel__intval(evsel, sample, "pfn");
|
||||
page = evsel__intval(evsel, sample, "pfn");
|
||||
else
|
||||
page = perf_evsel__intval(evsel, sample, "page");
|
||||
page = evsel__intval(evsel, sample, "page");
|
||||
|
||||
nr_page_frees++;
|
||||
total_page_free_bytes += bytes;
|
||||
|
|
@ -1371,15 +1366,15 @@ static int __cmd_kmem(struct perf_session *session)
|
|||
struct evsel *evsel;
|
||||
const struct evsel_str_handler kmem_tracepoints[] = {
|
||||
/* slab allocator */
|
||||
{ "kmem:kmalloc", perf_evsel__process_alloc_event, },
|
||||
{ "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, },
|
||||
{ "kmem:kmalloc_node", perf_evsel__process_alloc_node_event, },
|
||||
{ "kmem:kmem_cache_alloc_node", perf_evsel__process_alloc_node_event, },
|
||||
{ "kmem:kfree", perf_evsel__process_free_event, },
|
||||
{ "kmem:kmem_cache_free", perf_evsel__process_free_event, },
|
||||
{ "kmem:kmalloc", evsel__process_alloc_event, },
|
||||
{ "kmem:kmem_cache_alloc", evsel__process_alloc_event, },
|
||||
{ "kmem:kmalloc_node", evsel__process_alloc_node_event, },
|
||||
{ "kmem:kmem_cache_alloc_node", evsel__process_alloc_node_event, },
|
||||
{ "kmem:kfree", evsel__process_free_event, },
|
||||
{ "kmem:kmem_cache_free", evsel__process_free_event, },
|
||||
/* page allocator */
|
||||
{ "kmem:mm_page_alloc", perf_evsel__process_page_alloc_event, },
|
||||
{ "kmem:mm_page_free", perf_evsel__process_page_free_event, },
|
||||
{ "kmem:mm_page_alloc", evsel__process_page_alloc_event, },
|
||||
{ "kmem:mm_page_free", evsel__process_page_free_event, },
|
||||
};
|
||||
|
||||
if (!perf_session__has_traces(session, "kmem record"))
|
||||
|
|
@ -1391,8 +1386,8 @@ static int __cmd_kmem(struct perf_session *session)
|
|||
}
|
||||
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (!strcmp(perf_evsel__name(evsel), "kmem:mm_page_alloc") &&
|
||||
perf_evsel__field(evsel, "pfn")) {
|
||||
if (!strcmp(evsel__name(evsel), "kmem:mm_page_alloc") &&
|
||||
evsel__field(evsel, "pfn")) {
|
||||
use_pfn = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ void exit_event_get_key(struct evsel *evsel,
|
|||
struct event_key *key)
|
||||
{
|
||||
key->info = 0;
|
||||
key->key = perf_evsel__intval(evsel, sample, kvm_exit_reason);
|
||||
key->key = evsel__intval(evsel, sample, kvm_exit_reason);
|
||||
}
|
||||
|
||||
bool kvm_exit_event(struct evsel *evsel)
|
||||
|
|
@ -416,8 +416,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
vcpu_record->vcpu_id = perf_evsel__intval(evsel, sample,
|
||||
vcpu_id_str);
|
||||
vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str);
|
||||
thread__set_priv(thread, vcpu_record);
|
||||
}
|
||||
|
||||
|
|
@ -1033,16 +1032,16 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
|
|||
struct perf_event_attr *attr = &pos->core.attr;
|
||||
|
||||
/* make sure these *are* set */
|
||||
perf_evsel__set_sample_bit(pos, TID);
|
||||
perf_evsel__set_sample_bit(pos, TIME);
|
||||
perf_evsel__set_sample_bit(pos, CPU);
|
||||
perf_evsel__set_sample_bit(pos, RAW);
|
||||
evsel__set_sample_bit(pos, TID);
|
||||
evsel__set_sample_bit(pos, TIME);
|
||||
evsel__set_sample_bit(pos, CPU);
|
||||
evsel__set_sample_bit(pos, RAW);
|
||||
/* make sure these are *not*; want as small a sample as possible */
|
||||
perf_evsel__reset_sample_bit(pos, PERIOD);
|
||||
perf_evsel__reset_sample_bit(pos, IP);
|
||||
perf_evsel__reset_sample_bit(pos, CALLCHAIN);
|
||||
perf_evsel__reset_sample_bit(pos, ADDR);
|
||||
perf_evsel__reset_sample_bit(pos, READ);
|
||||
evsel__reset_sample_bit(pos, PERIOD);
|
||||
evsel__reset_sample_bit(pos, IP);
|
||||
evsel__reset_sample_bit(pos, CALLCHAIN);
|
||||
evsel__reset_sample_bit(pos, ADDR);
|
||||
evsel__reset_sample_bit(pos, READ);
|
||||
attr->mmap = 0;
|
||||
attr->comm = 0;
|
||||
attr->task = 0;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ struct lock_stat {
|
|||
struct rb_node rb; /* used for sorting */
|
||||
|
||||
/*
|
||||
* FIXME: perf_evsel__intval() returns u64,
|
||||
* FIXME: evsel__intval() returns u64,
|
||||
* so address of lockdep_map should be dealed as 64bit.
|
||||
* Is there more better solution?
|
||||
*/
|
||||
|
|
@ -404,9 +404,9 @@ static int report_lock_acquire_event(struct evsel *evsel,
|
|||
struct lock_stat *ls;
|
||||
struct thread_stat *ts;
|
||||
struct lock_seq_stat *seq;
|
||||
const char *name = perf_evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
|
||||
int flag = perf_evsel__intval(evsel, sample, "flag");
|
||||
const char *name = evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = evsel__intval(evsel, sample, "lockdep_addr");
|
||||
int flag = evsel__intval(evsel, sample, "flag");
|
||||
|
||||
memcpy(&addr, &tmp, sizeof(void *));
|
||||
|
||||
|
|
@ -477,8 +477,8 @@ static int report_lock_acquired_event(struct evsel *evsel,
|
|||
struct thread_stat *ts;
|
||||
struct lock_seq_stat *seq;
|
||||
u64 contended_term;
|
||||
const char *name = perf_evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
|
||||
const char *name = evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = evsel__intval(evsel, sample, "lockdep_addr");
|
||||
|
||||
memcpy(&addr, &tmp, sizeof(void *));
|
||||
|
||||
|
|
@ -539,8 +539,8 @@ static int report_lock_contended_event(struct evsel *evsel,
|
|||
struct lock_stat *ls;
|
||||
struct thread_stat *ts;
|
||||
struct lock_seq_stat *seq;
|
||||
const char *name = perf_evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
|
||||
const char *name = evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = evsel__intval(evsel, sample, "lockdep_addr");
|
||||
|
||||
memcpy(&addr, &tmp, sizeof(void *));
|
||||
|
||||
|
|
@ -594,8 +594,8 @@ static int report_lock_release_event(struct evsel *evsel,
|
|||
struct lock_stat *ls;
|
||||
struct thread_stat *ts;
|
||||
struct lock_seq_stat *seq;
|
||||
const char *name = perf_evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr");
|
||||
const char *name = evsel__strval(evsel, sample, "name");
|
||||
u64 tmp = evsel__intval(evsel, sample, "lockdep_addr");
|
||||
|
||||
memcpy(&addr, &tmp, sizeof(void *));
|
||||
|
||||
|
|
@ -657,32 +657,28 @@ static struct trace_lock_handler report_lock_ops = {
|
|||
|
||||
static struct trace_lock_handler *trace_handler;
|
||||
|
||||
static int perf_evsel__process_lock_acquire(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_lock_acquire(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
if (trace_handler->acquire_event)
|
||||
return trace_handler->acquire_event(evsel, sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_lock_acquired(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_lock_acquired(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
if (trace_handler->acquired_event)
|
||||
return trace_handler->acquired_event(evsel, sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_lock_contended(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_lock_contended(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
if (trace_handler->contended_event)
|
||||
return trace_handler->contended_event(evsel, sample);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__process_lock_release(struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
static int evsel__process_lock_release(struct evsel *evsel, struct perf_sample *sample)
|
||||
{
|
||||
if (trace_handler->release_event)
|
||||
return trace_handler->release_event(evsel, sample);
|
||||
|
|
@ -775,7 +771,7 @@ static void dump_threads(void)
|
|||
pr_info("%10d: %s\n", st->tid, thread__comm_str(t));
|
||||
node = rb_next(node);
|
||||
thread__put(t);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_map(void)
|
||||
|
|
@ -849,10 +845,10 @@ static void sort_result(void)
|
|||
}
|
||||
|
||||
static const struct evsel_str_handler lock_tracepoints[] = {
|
||||
{ "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
|
||||
{ "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_contended", perf_evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
|
||||
{ "lock:lock_acquire", evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
|
||||
{ "lock:lock_acquired", evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_contended", evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_release", evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
|
||||
};
|
||||
|
||||
static bool force;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
|
|||
|
||||
rec_argv[i++] = "-e";
|
||||
rec_argv[i++] = perf_mem_events__name(j);
|
||||
};
|
||||
}
|
||||
|
||||
if (all_user)
|
||||
rec_argv[i++] = "--all-user";
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "util/tsc.h"
|
||||
#include "util/parse-branch-options.h"
|
||||
#include "util/parse-regs-options.h"
|
||||
#include "util/perf_api_probe.h"
|
||||
#include "util/llvm-utils.h"
|
||||
#include "util/bpf-loader.h"
|
||||
#include "util/trigger.h"
|
||||
|
|
@ -43,6 +44,7 @@
|
|||
#include "util/time-utils.h"
|
||||
#include "util/units.h"
|
||||
#include "util/bpf-event.h"
|
||||
#include "util/util.h"
|
||||
#include "asm/bug.h"
|
||||
#include "perf.h"
|
||||
|
||||
|
|
@ -50,6 +52,7 @@
|
|||
#include <inttypes.h>
|
||||
#include <locale.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
|
|
@ -84,7 +87,10 @@ struct record {
|
|||
struct auxtrace_record *itr;
|
||||
struct evlist *evlist;
|
||||
struct perf_session *session;
|
||||
struct evlist *sb_evlist;
|
||||
pthread_t thread_id;
|
||||
int realtime_prio;
|
||||
bool switch_output_event_set;
|
||||
bool no_buildid;
|
||||
bool no_buildid_set;
|
||||
bool no_buildid_cache;
|
||||
|
|
@ -503,6 +509,20 @@ static int process_synthesized_event(struct perf_tool *tool,
|
|||
return record__write(rec, NULL, event, event->header.size);
|
||||
}
|
||||
|
||||
static int process_locked_synthesized_event(struct perf_tool *tool,
|
||||
union perf_event *event,
|
||||
struct perf_sample *sample __maybe_unused,
|
||||
struct machine *machine __maybe_unused)
|
||||
{
|
||||
static pthread_mutex_t synth_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
int ret;
|
||||
|
||||
pthread_mutex_lock(&synth_lock);
|
||||
ret = process_synthesized_event(tool, event, sample, machine);
|
||||
pthread_mutex_unlock(&synth_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size)
|
||||
{
|
||||
struct record *rec = to;
|
||||
|
|
@ -825,7 +845,7 @@ static int record__open(struct record *rec)
|
|||
evlist__for_each_entry(evlist, pos) {
|
||||
try_again:
|
||||
if (evsel__open(pos, pos->core.cpus, pos->core.threads) < 0) {
|
||||
if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
|
||||
if (evsel__fallback(pos, errno, msg, sizeof(msg))) {
|
||||
if (verbose > 0)
|
||||
ui__warning("%s\n", msg);
|
||||
goto try_again;
|
||||
|
|
@ -837,8 +857,7 @@ static int record__open(struct record *rec)
|
|||
goto try_again;
|
||||
}
|
||||
rc = -errno;
|
||||
perf_evsel__open_strerror(pos, &opts->target,
|
||||
errno, msg, sizeof(msg));
|
||||
evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg));
|
||||
ui__error("%s\n", msg);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -859,7 +878,7 @@ static int record__open(struct record *rec)
|
|||
|
||||
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,
|
||||
pos->filter, evsel__name(pos), errno,
|
||||
str_error_r(errno, msg, sizeof(msg)));
|
||||
rc = -1;
|
||||
goto out;
|
||||
|
|
@ -1288,6 +1307,7 @@ static int record__synthesize(struct record *rec, bool tail)
|
|||
struct perf_tool *tool = &rec->tool;
|
||||
int fd = perf_data__fd(data);
|
||||
int err = 0;
|
||||
event_op f = process_synthesized_event;
|
||||
|
||||
if (rec->opts.tail_synthesize != tail)
|
||||
return 0;
|
||||
|
|
@ -1402,13 +1422,67 @@ static int record__synthesize(struct record *rec, bool tail)
|
|||
if (err < 0)
|
||||
pr_warning("Couldn't synthesize cgroup events.\n");
|
||||
|
||||
if (rec->opts.nr_threads_synthesize > 1) {
|
||||
perf_set_multithreaded();
|
||||
f = process_locked_synthesized_event;
|
||||
}
|
||||
|
||||
err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads,
|
||||
process_synthesized_event, opts->sample_address,
|
||||
1);
|
||||
f, opts->sample_address,
|
||||
rec->opts.nr_threads_synthesize);
|
||||
|
||||
if (rec->opts.nr_threads_synthesize > 1)
|
||||
perf_set_singlethreaded();
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int record__process_signal_event(union perf_event *event __maybe_unused, void *data)
|
||||
{
|
||||
struct record *rec = data;
|
||||
pthread_kill(rec->thread_id, SIGUSR2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int record__setup_sb_evlist(struct record *rec)
|
||||
{
|
||||
struct record_opts *opts = &rec->opts;
|
||||
|
||||
if (rec->sb_evlist != NULL) {
|
||||
/*
|
||||
* We get here if --switch-output-event populated the
|
||||
* sb_evlist, so associate a callback that will send a SIGUSR2
|
||||
* to the main thread.
|
||||
*/
|
||||
evlist__set_cb(rec->sb_evlist, record__process_signal_event, rec);
|
||||
rec->thread_id = pthread_self();
|
||||
}
|
||||
|
||||
if (!opts->no_bpf_event) {
|
||||
if (rec->sb_evlist == NULL) {
|
||||
rec->sb_evlist = evlist__new();
|
||||
|
||||
if (rec->sb_evlist == NULL) {
|
||||
pr_err("Couldn't create side band evlist.\n.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (evlist__add_bpf_sb_event(rec->sb_evlist, &rec->session->header.env)) {
|
||||
pr_err("Couldn't ask for PERF_RECORD_BPF_EVENT side band events.\n.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (perf_evlist__start_sb_thread(rec->sb_evlist, &rec->opts.target)) {
|
||||
pr_debug("Couldn't start the BPF side band thread:\nBPF programs starting from now on won't be annotatable\n");
|
||||
opts->no_bpf_event = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cmd_record(struct record *rec, int argc, const char **argv)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -1420,7 +1494,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||
struct perf_data *data = &rec->data;
|
||||
struct perf_session *session;
|
||||
bool disabled = false, draining = false;
|
||||
struct evlist *sb_evlist = NULL;
|
||||
int fd;
|
||||
float ratio = 0;
|
||||
|
||||
|
|
@ -1546,21 +1619,17 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||
goto out_child;
|
||||
}
|
||||
|
||||
err = -1;
|
||||
if (!rec->no_buildid
|
||||
&& !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) {
|
||||
pr_err("Couldn't generate buildids. "
|
||||
"Use --no-buildid to profile anyway.\n");
|
||||
err = -1;
|
||||
goto out_child;
|
||||
}
|
||||
|
||||
if (!opts->no_bpf_event)
|
||||
bpf_event__add_sb_event(&sb_evlist, &session->header.env);
|
||||
|
||||
if (perf_evlist__start_sb_thread(sb_evlist, &rec->opts.target)) {
|
||||
pr_debug("Couldn't start the BPF side band thread:\nBPF programs starting from now on won't be annotatable\n");
|
||||
opts->no_bpf_event = true;
|
||||
}
|
||||
err = record__setup_sb_evlist(rec);
|
||||
if (err)
|
||||
goto out_child;
|
||||
|
||||
err = record__synthesize(rec, false);
|
||||
if (err < 0)
|
||||
|
|
@ -1831,7 +1900,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|||
perf_session__delete(session);
|
||||
|
||||
if (!opts->no_bpf_event)
|
||||
perf_evlist__stop_sb_thread(sb_evlist);
|
||||
perf_evlist__stop_sb_thread(rec->sb_evlist);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -2142,10 +2211,19 @@ static int switch_output_setup(struct record *rec)
|
|||
};
|
||||
unsigned long val;
|
||||
|
||||
/*
|
||||
* If we're using --switch-output-events, then we imply its
|
||||
* --switch-output=signal, as we'll send a SIGUSR2 from the side band
|
||||
* thread to its parent.
|
||||
*/
|
||||
if (rec->switch_output_event_set)
|
||||
goto do_signal;
|
||||
|
||||
if (!s->set)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(s->str, "signal")) {
|
||||
do_signal:
|
||||
s->signal = true;
|
||||
pr_debug("switch-output with SIGUSR2 signal\n");
|
||||
goto enabled;
|
||||
|
|
@ -2232,6 +2310,7 @@ static struct record record = {
|
|||
.default_per_cpu = true,
|
||||
},
|
||||
.mmap_flush = MMAP_FLUSH_DEFAULT,
|
||||
.nr_threads_synthesize = 1,
|
||||
},
|
||||
.tool = {
|
||||
.sample = process_sample_event,
|
||||
|
|
@ -2402,6 +2481,9 @@ static struct option __record_options[] = {
|
|||
&record.switch_output.set, "signal or size[BKMG] or time[smhd]",
|
||||
"Switch output when receiving SIGUSR2 (signal) or cross a size or time threshold",
|
||||
"signal"),
|
||||
OPT_CALLBACK_SET(0, "switch-output-event", &record.sb_evlist, &record.switch_output_event_set, "switch output event",
|
||||
"switch output event selector. use 'perf list' to list available events",
|
||||
parse_events_option_new_evlist),
|
||||
OPT_INTEGER(0, "switch-max-files", &record.switch_output.num_files,
|
||||
"Limit number of switch output generated files"),
|
||||
OPT_BOOLEAN(0, "dry-run", &dry_run,
|
||||
|
|
@ -2421,6 +2503,9 @@ static struct option __record_options[] = {
|
|||
#endif
|
||||
OPT_CALLBACK(0, "max-size", &record.output_max_size,
|
||||
"size", "Limit the maximum size of the output file", parse_output_max_size),
|
||||
OPT_UINTEGER(0, "num-thread-synthesize",
|
||||
&record.opts.nr_threads_synthesize,
|
||||
"number of threads to run for event synthesis"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ static int process_read_event(struct perf_tool *tool,
|
|||
struct report *rep = container_of(tool, struct report, tool);
|
||||
|
||||
if (rep->show_threads) {
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
const char *name = evsel__name(evsel);
|
||||
int err = perf_read_values_add_value(&rep->show_threads_values,
|
||||
event->read.pid, event->read.tid,
|
||||
evsel->idx,
|
||||
|
|
@ -349,7 +349,8 @@ static int report__setup_sample_type(struct report *rep)
|
|||
!session->itrace_synth_opts->set))
|
||||
sample_type |= PERF_SAMPLE_CALLCHAIN;
|
||||
|
||||
if (session->itrace_synth_opts->last_branch)
|
||||
if (session->itrace_synth_opts->last_branch ||
|
||||
session->itrace_synth_opts->add_last_branch)
|
||||
sample_type |= PERF_SAMPLE_BRANCH_STACK;
|
||||
|
||||
if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
|
||||
|
|
@ -458,10 +459,10 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
|
|||
nr_events = hists->stats.total_non_filtered_period;
|
||||
}
|
||||
|
||||
if (perf_evsel__is_group_event(evsel)) {
|
||||
if (evsel__is_group_event(evsel)) {
|
||||
struct evsel *pos;
|
||||
|
||||
perf_evsel__group_desc(evsel, buf, size);
|
||||
evsel__group_desc(evsel, buf, size);
|
||||
evname = buf;
|
||||
|
||||
for_each_group_member(pos, evsel) {
|
||||
|
|
@ -536,10 +537,9 @@ static int perf_evlist__tty_browse_hists(struct evlist *evlist,
|
|||
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
const char *evname = perf_evsel__name(pos);
|
||||
const char *evname = evsel__name(pos);
|
||||
|
||||
if (symbol_conf.event_group &&
|
||||
!perf_evsel__is_group_leader(pos))
|
||||
if (symbol_conf.event_group && !evsel__is_group_leader(pos))
|
||||
continue;
|
||||
|
||||
hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
|
||||
|
|
@ -681,8 +681,7 @@ static int report__collapse_hists(struct report *rep)
|
|||
break;
|
||||
|
||||
/* Non-group events are considered as leader */
|
||||
if (symbol_conf.event_group &&
|
||||
!perf_evsel__is_group_leader(pos)) {
|
||||
if (symbol_conf.event_group && !evsel__is_group_leader(pos)) {
|
||||
struct hists *leader_hists = evsel__hists(pos->leader);
|
||||
|
||||
hists__match(leader_hists, hists);
|
||||
|
|
@ -1393,7 +1392,7 @@ int cmd_report(int argc, const char **argv)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (itrace_synth_opts.last_branch)
|
||||
if (itrace_synth_opts.last_branch || itrace_synth_opts.add_last_branch)
|
||||
has_br_stack = true;
|
||||
|
||||
if (has_br_stack && branch_call_mode)
|
||||
|
|
@ -1413,7 +1412,7 @@ int cmd_report(int argc, const char **argv)
|
|||
}
|
||||
if (branch_call_mode) {
|
||||
callchain_param.key = CCKEY_ADDRESS;
|
||||
callchain_param.branch_callstack = 1;
|
||||
callchain_param.branch_callstack = true;
|
||||
symbol_conf.use_callchain = true;
|
||||
callchain_register_param(&callchain_param);
|
||||
if (sort_order == NULL)
|
||||
|
|
|
|||
|
|
@ -811,8 +811,8 @@ replay_wakeup_event(struct perf_sched *sched,
|
|||
struct evsel *evsel, struct perf_sample *sample,
|
||||
struct machine *machine __maybe_unused)
|
||||
{
|
||||
const char *comm = perf_evsel__strval(evsel, sample, "comm");
|
||||
const u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
const char *comm = evsel__strval(evsel, sample, "comm");
|
||||
const u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
struct task_desc *waker, *wakee;
|
||||
|
||||
if (verbose > 0) {
|
||||
|
|
@ -833,11 +833,11 @@ static int replay_switch_event(struct perf_sched *sched,
|
|||
struct perf_sample *sample,
|
||||
struct machine *machine __maybe_unused)
|
||||
{
|
||||
const char *prev_comm = perf_evsel__strval(evsel, sample, "prev_comm"),
|
||||
*next_comm = perf_evsel__strval(evsel, sample, "next_comm");
|
||||
const u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"),
|
||||
next_pid = perf_evsel__intval(evsel, sample, "next_pid");
|
||||
const u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state");
|
||||
const char *prev_comm = evsel__strval(evsel, sample, "prev_comm"),
|
||||
*next_comm = evsel__strval(evsel, sample, "next_comm");
|
||||
const u32 prev_pid = evsel__intval(evsel, sample, "prev_pid"),
|
||||
next_pid = evsel__intval(evsel, sample, "next_pid");
|
||||
const u64 prev_state = evsel__intval(evsel, sample, "prev_state");
|
||||
struct task_desc *prev, __maybe_unused *next;
|
||||
u64 timestamp0, timestamp = sample->time;
|
||||
int cpu = sample->cpu;
|
||||
|
|
@ -1106,9 +1106,9 @@ static int latency_switch_event(struct perf_sched *sched,
|
|||
struct perf_sample *sample,
|
||||
struct machine *machine)
|
||||
{
|
||||
const u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"),
|
||||
next_pid = perf_evsel__intval(evsel, sample, "next_pid");
|
||||
const u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state");
|
||||
const u32 prev_pid = evsel__intval(evsel, sample, "prev_pid"),
|
||||
next_pid = evsel__intval(evsel, sample, "next_pid");
|
||||
const u64 prev_state = evsel__intval(evsel, sample, "prev_state");
|
||||
struct work_atoms *out_events, *in_events;
|
||||
struct thread *sched_out, *sched_in;
|
||||
u64 timestamp0, timestamp = sample->time;
|
||||
|
|
@ -1176,8 +1176,8 @@ static int latency_runtime_event(struct perf_sched *sched,
|
|||
struct perf_sample *sample,
|
||||
struct machine *machine)
|
||||
{
|
||||
const u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
const u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
|
||||
const u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
const u64 runtime = evsel__intval(evsel, sample, "runtime");
|
||||
struct thread *thread = machine__findnew_thread(machine, -1, pid);
|
||||
struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
|
||||
u64 timestamp = sample->time;
|
||||
|
|
@ -1211,7 +1211,7 @@ static int latency_wakeup_event(struct perf_sched *sched,
|
|||
struct perf_sample *sample,
|
||||
struct machine *machine)
|
||||
{
|
||||
const u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
const u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
struct work_atoms *atoms;
|
||||
struct work_atom *atom;
|
||||
struct thread *wakee;
|
||||
|
|
@ -1272,7 +1272,7 @@ static int latency_migrate_task_event(struct perf_sched *sched,
|
|||
struct perf_sample *sample,
|
||||
struct machine *machine)
|
||||
{
|
||||
const u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
const u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
u64 timestamp = sample->time;
|
||||
struct work_atoms *atoms;
|
||||
struct work_atom *atom;
|
||||
|
|
@ -1526,7 +1526,7 @@ map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid
|
|||
static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
|
||||
struct perf_sample *sample, struct machine *machine)
|
||||
{
|
||||
const u32 next_pid = perf_evsel__intval(evsel, sample, "next_pid");
|
||||
const u32 next_pid = evsel__intval(evsel, sample, "next_pid");
|
||||
struct thread *sched_in;
|
||||
struct thread_runtime *tr;
|
||||
int new_shortname;
|
||||
|
|
@ -1670,8 +1670,8 @@ static int process_sched_switch_event(struct perf_tool *tool,
|
|||
{
|
||||
struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
|
||||
int this_cpu = sample->cpu, err = 0;
|
||||
u32 prev_pid = perf_evsel__intval(evsel, sample, "prev_pid"),
|
||||
next_pid = perf_evsel__intval(evsel, sample, "next_pid");
|
||||
u32 prev_pid = evsel__intval(evsel, sample, "prev_pid"),
|
||||
next_pid = evsel__intval(evsel, sample, "next_pid");
|
||||
|
||||
if (sched->curr_pid[this_cpu] != (u32)-1) {
|
||||
/*
|
||||
|
|
@ -1848,7 +1848,7 @@ static inline void print_sched_time(unsigned long long nsecs, int width)
|
|||
* returns runtime data for event, allocating memory for it the
|
||||
* first time it is used.
|
||||
*/
|
||||
static struct evsel_runtime *perf_evsel__get_runtime(struct evsel *evsel)
|
||||
static struct evsel_runtime *evsel__get_runtime(struct evsel *evsel)
|
||||
{
|
||||
struct evsel_runtime *r = evsel->priv;
|
||||
|
||||
|
|
@ -1863,10 +1863,9 @@ static struct evsel_runtime *perf_evsel__get_runtime(struct evsel *evsel)
|
|||
/*
|
||||
* save last time event was seen per cpu
|
||||
*/
|
||||
static void perf_evsel__save_time(struct evsel *evsel,
|
||||
u64 timestamp, u32 cpu)
|
||||
static void evsel__save_time(struct evsel *evsel, u64 timestamp, u32 cpu)
|
||||
{
|
||||
struct evsel_runtime *r = perf_evsel__get_runtime(evsel);
|
||||
struct evsel_runtime *r = evsel__get_runtime(evsel);
|
||||
|
||||
if (r == NULL)
|
||||
return;
|
||||
|
|
@ -1890,9 +1889,9 @@ static void perf_evsel__save_time(struct evsel *evsel,
|
|||
}
|
||||
|
||||
/* returns last time this event was seen on the given cpu */
|
||||
static u64 perf_evsel__get_time(struct evsel *evsel, u32 cpu)
|
||||
static u64 evsel__get_time(struct evsel *evsel, u32 cpu)
|
||||
{
|
||||
struct evsel_runtime *r = perf_evsel__get_runtime(evsel);
|
||||
struct evsel_runtime *r = evsel__get_runtime(evsel);
|
||||
|
||||
if ((r == NULL) || (r->last_time == NULL) || (cpu >= r->ncpu))
|
||||
return 0;
|
||||
|
|
@ -2004,8 +2003,8 @@ static void timehist_print_sample(struct perf_sched *sched,
|
|||
u64 t, int state)
|
||||
{
|
||||
struct thread_runtime *tr = thread__priv(thread);
|
||||
const char *next_comm = perf_evsel__strval(evsel, sample, "next_comm");
|
||||
const u32 next_pid = perf_evsel__intval(evsel, sample, "next_pid");
|
||||
const char *next_comm = evsel__strval(evsel, sample, "next_comm");
|
||||
const u32 next_pid = evsel__intval(evsel, sample, "next_pid");
|
||||
u32 max_cpus = sched->max_cpu + 1;
|
||||
char tstr[64];
|
||||
char nstr[30];
|
||||
|
|
@ -2136,8 +2135,8 @@ static bool is_idle_sample(struct perf_sample *sample,
|
|||
struct evsel *evsel)
|
||||
{
|
||||
/* pid 0 == swapper == idle task */
|
||||
if (strcmp(perf_evsel__name(evsel), "sched:sched_switch") == 0)
|
||||
return perf_evsel__intval(evsel, sample, "prev_pid") == 0;
|
||||
if (strcmp(evsel__name(evsel), "sched:sched_switch") == 0)
|
||||
return evsel__intval(evsel, sample, "prev_pid") == 0;
|
||||
|
||||
return sample->pid == 0;
|
||||
}
|
||||
|
|
@ -2334,7 +2333,7 @@ static struct thread *timehist_get_thread(struct perf_sched *sched,
|
|||
itr->last_thread = thread;
|
||||
|
||||
/* copy task callchain when entering to idle */
|
||||
if (perf_evsel__intval(evsel, sample, "next_pid") == 0)
|
||||
if (evsel__intval(evsel, sample, "next_pid") == 0)
|
||||
save_idle_callchain(sched, itr, sample);
|
||||
}
|
||||
}
|
||||
|
|
@ -2355,10 +2354,10 @@ static bool timehist_skip_sample(struct perf_sched *sched,
|
|||
}
|
||||
|
||||
if (sched->idle_hist) {
|
||||
if (strcmp(perf_evsel__name(evsel), "sched:sched_switch"))
|
||||
if (strcmp(evsel__name(evsel), "sched:sched_switch"))
|
||||
rc = true;
|
||||
else if (perf_evsel__intval(evsel, sample, "prev_pid") != 0 &&
|
||||
perf_evsel__intval(evsel, sample, "next_pid") != 0)
|
||||
else if (evsel__intval(evsel, sample, "prev_pid") != 0 &&
|
||||
evsel__intval(evsel, sample, "next_pid") != 0)
|
||||
rc = true;
|
||||
}
|
||||
|
||||
|
|
@ -2409,7 +2408,7 @@ static int timehist_sched_wakeup_event(struct perf_tool *tool,
|
|||
struct thread *thread;
|
||||
struct thread_runtime *tr = NULL;
|
||||
/* want pid of awakened task not pid in sample */
|
||||
const u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
const u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
|
||||
thread = machine__findnew_thread(machine, 0, pid);
|
||||
if (thread == NULL)
|
||||
|
|
@ -2445,8 +2444,8 @@ static void timehist_print_migration_event(struct perf_sched *sched,
|
|||
return;
|
||||
|
||||
max_cpus = sched->max_cpu + 1;
|
||||
ocpu = perf_evsel__intval(evsel, sample, "orig_cpu");
|
||||
dcpu = perf_evsel__intval(evsel, sample, "dest_cpu");
|
||||
ocpu = evsel__intval(evsel, sample, "orig_cpu");
|
||||
dcpu = evsel__intval(evsel, sample, "dest_cpu");
|
||||
|
||||
thread = machine__findnew_thread(machine, sample->pid, sample->tid);
|
||||
if (thread == NULL)
|
||||
|
|
@ -2493,7 +2492,7 @@ static int timehist_migrate_task_event(struct perf_tool *tool,
|
|||
struct thread *thread;
|
||||
struct thread_runtime *tr = NULL;
|
||||
/* want pid of migrated task not pid in sample */
|
||||
const u32 pid = perf_evsel__intval(evsel, sample, "pid");
|
||||
const u32 pid = evsel__intval(evsel, sample, "pid");
|
||||
|
||||
thread = machine__findnew_thread(machine, 0, pid);
|
||||
if (thread == NULL)
|
||||
|
|
@ -2524,8 +2523,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,
|
|||
struct thread_runtime *tr = NULL;
|
||||
u64 tprev, t = sample->time;
|
||||
int rc = 0;
|
||||
int state = perf_evsel__intval(evsel, sample, "prev_state");
|
||||
|
||||
int state = evsel__intval(evsel, sample, "prev_state");
|
||||
|
||||
if (machine__resolve(machine, &al, sample) < 0) {
|
||||
pr_err("problem processing %d event. skipping it\n",
|
||||
|
|
@ -2549,7 +2547,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,
|
|||
goto out;
|
||||
}
|
||||
|
||||
tprev = perf_evsel__get_time(evsel, sample->cpu);
|
||||
tprev = evsel__get_time(evsel, sample->cpu);
|
||||
|
||||
/*
|
||||
* If start time given:
|
||||
|
|
@ -2632,7 +2630,7 @@ static int timehist_sched_change_event(struct perf_tool *tool,
|
|||
tr->ready_to_run = 0;
|
||||
}
|
||||
|
||||
perf_evsel__save_time(evsel, sample->time, sample->cpu);
|
||||
evsel__save_time(evsel, sample->time, sample->cpu);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -2942,7 +2940,7 @@ static int timehist_check_attr(struct perf_sched *sched,
|
|||
struct evsel_runtime *er;
|
||||
|
||||
list_for_each_entry(evsel, &evlist->core.entries, core.node) {
|
||||
er = perf_evsel__get_runtime(evsel);
|
||||
er = evsel__get_runtime(evsel);
|
||||
if (er == NULL) {
|
||||
pr_err("Failed to allocate memory for evsel runtime data\n");
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ static struct evsel_script *perf_evsel_script__new(struct evsel *evsel,
|
|||
struct evsel_script *es = zalloc(sizeof(*es));
|
||||
|
||||
if (es != NULL) {
|
||||
if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0)
|
||||
if (asprintf(&es->filename, "%s.%s.dump", data->file.path, evsel__name(evsel)) < 0)
|
||||
goto out_free;
|
||||
es->fp = fopen(es->filename, "w");
|
||||
if (es->fp == NULL)
|
||||
|
|
@ -351,10 +351,8 @@ static const char *output_field2str(enum perf_output_field field)
|
|||
|
||||
#define PRINT_FIELD(x) (output[output_type(attr->type)].fields & PERF_OUTPUT_##x)
|
||||
|
||||
static int perf_evsel__do_check_stype(struct evsel *evsel,
|
||||
u64 sample_type, const char *sample_msg,
|
||||
enum perf_output_field field,
|
||||
bool allow_user_set)
|
||||
static int evsel__do_check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
|
||||
enum perf_output_field field, bool allow_user_set)
|
||||
{
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
int type = output_type(attr->type);
|
||||
|
|
@ -366,7 +364,7 @@ static int perf_evsel__do_check_stype(struct evsel *evsel,
|
|||
if (output[type].user_set_fields & field) {
|
||||
if (allow_user_set)
|
||||
return 0;
|
||||
evname = perf_evsel__name(evsel);
|
||||
evname = evsel__name(evsel);
|
||||
pr_err("Samples for '%s' event do not have %s attribute set. "
|
||||
"Cannot print '%s' field.\n",
|
||||
evname, sample_msg, output_field2str(field));
|
||||
|
|
@ -375,7 +373,7 @@ static int perf_evsel__do_check_stype(struct evsel *evsel,
|
|||
|
||||
/* user did not ask for it explicitly so remove from the default list */
|
||||
output[type].fields &= ~field;
|
||||
evname = perf_evsel__name(evsel);
|
||||
evname = evsel__name(evsel);
|
||||
pr_debug("Samples for '%s' event do not have %s attribute set. "
|
||||
"Skipping '%s' field.\n",
|
||||
evname, sample_msg, output_field2str(field));
|
||||
|
|
@ -383,16 +381,13 @@ static int perf_evsel__do_check_stype(struct evsel *evsel,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int perf_evsel__check_stype(struct evsel *evsel,
|
||||
u64 sample_type, const char *sample_msg,
|
||||
enum perf_output_field field)
|
||||
static int evsel__check_stype(struct evsel *evsel, u64 sample_type, const char *sample_msg,
|
||||
enum perf_output_field field)
|
||||
{
|
||||
return perf_evsel__do_check_stype(evsel, sample_type, sample_msg, field,
|
||||
false);
|
||||
return evsel__do_check_stype(evsel, sample_type, sample_msg, field, false);
|
||||
}
|
||||
|
||||
static int perf_evsel__check_attr(struct evsel *evsel,
|
||||
struct perf_session *session)
|
||||
static int perf_evsel__check_attr(struct evsel *evsel, struct perf_session *session)
|
||||
{
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
bool allow_user_set;
|
||||
|
|
@ -404,32 +399,28 @@ static int perf_evsel__check_attr(struct evsel *evsel,
|
|||
HEADER_AUXTRACE);
|
||||
|
||||
if (PRINT_FIELD(TRACE) &&
|
||||
!perf_session__has_traces(session, "record -R"))
|
||||
!perf_session__has_traces(session, "record -R"))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(IP)) {
|
||||
if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP",
|
||||
PERF_OUTPUT_IP))
|
||||
if (evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (PRINT_FIELD(ADDR) &&
|
||||
perf_evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR",
|
||||
PERF_OUTPUT_ADDR, allow_user_set))
|
||||
evsel__do_check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", PERF_OUTPUT_ADDR, allow_user_set))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(DATA_SRC) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC",
|
||||
PERF_OUTPUT_DATA_SRC))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_DATA_SRC, "DATA_SRC", PERF_OUTPUT_DATA_SRC))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(WEIGHT) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT",
|
||||
PERF_OUTPUT_WEIGHT))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_WEIGHT, "WEIGHT", PERF_OUTPUT_WEIGHT))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(SYM) &&
|
||||
!(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
|
||||
!(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
|
||||
pr_err("Display of symbols requested but neither sample IP nor "
|
||||
"sample address\navailable. Hence, no addresses to convert "
|
||||
"to symbols.\n");
|
||||
|
|
@ -441,7 +432,7 @@ static int perf_evsel__check_attr(struct evsel *evsel,
|
|||
return -EINVAL;
|
||||
}
|
||||
if (PRINT_FIELD(DSO) &&
|
||||
!(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
|
||||
!(evsel->core.attr.sample_type & (PERF_SAMPLE_IP|PERF_SAMPLE_ADDR))) {
|
||||
pr_err("Display of DSO requested but no address to convert.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -458,33 +449,27 @@ static int perf_evsel__check_attr(struct evsel *evsel,
|
|||
return -EINVAL;
|
||||
}
|
||||
if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID",
|
||||
PERF_OUTPUT_TID|PERF_OUTPUT_PID))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", PERF_OUTPUT_TID|PERF_OUTPUT_PID))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(TIME) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME",
|
||||
PERF_OUTPUT_TIME))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", PERF_OUTPUT_TIME))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(CPU) &&
|
||||
perf_evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU",
|
||||
PERF_OUTPUT_CPU, allow_user_set))
|
||||
evsel__do_check_stype(evsel, PERF_SAMPLE_CPU, "CPU", PERF_OUTPUT_CPU, allow_user_set))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(IREGS) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
|
||||
PERF_OUTPUT_IREGS))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS", PERF_OUTPUT_IREGS))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(UREGS) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS",
|
||||
PERF_OUTPUT_UREGS))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", PERF_OUTPUT_UREGS))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(PHYS_ADDR) &&
|
||||
perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR",
|
||||
PERF_OUTPUT_PHYS_ADDR))
|
||||
evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", PERF_OUTPUT_PHYS_ADDR))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
|
@ -604,8 +589,6 @@ static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask,
|
|||
printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r), val);
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
return printed;
|
||||
}
|
||||
|
||||
|
|
@ -1714,7 +1697,7 @@ static int perf_evlist__max_name_len(struct evlist *evlist)
|
|||
int max = 0;
|
||||
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
int len = strlen(perf_evsel__name(evsel));
|
||||
int len = strlen(evsel__name(evsel));
|
||||
|
||||
max = MAX(len, max);
|
||||
}
|
||||
|
|
@ -1888,7 +1871,7 @@ static void process_event(struct perf_script *script,
|
|||
fprintf(fp, "%10" PRIu64 " ", sample->period);
|
||||
|
||||
if (PRINT_FIELD(EVNAME)) {
|
||||
const char *evname = perf_evsel__name(evsel);
|
||||
const char *evname = evsel__name(evsel);
|
||||
|
||||
if (!script->name_width)
|
||||
script->name_width = perf_evlist__max_name_len(script->session->evlist);
|
||||
|
|
@ -1950,7 +1933,7 @@ static void process_event(struct perf_script *script,
|
|||
else if (PRINT_FIELD(BRSTACKOFF))
|
||||
perf_sample__fprintf_brstackoff(sample, thread, attr, fp);
|
||||
|
||||
if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
|
||||
if (evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT))
|
||||
perf_sample__fprintf_bpf_output(sample, fp);
|
||||
perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
|
||||
|
||||
|
|
@ -1979,7 +1962,7 @@ static struct scripting_ops *scripting_ops;
|
|||
static void __process_stat(struct evsel *counter, u64 tstamp)
|
||||
{
|
||||
int nthreads = perf_thread_map__nr(counter->core.threads);
|
||||
int ncpus = perf_evsel__nr_cpus(counter);
|
||||
int ncpus = evsel__nr_cpus(counter);
|
||||
int cpu, thread;
|
||||
static int header_printed;
|
||||
|
||||
|
|
@ -2005,7 +1988,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
|
|||
counts->ena,
|
||||
counts->run,
|
||||
tstamp,
|
||||
perf_evsel__name(counter));
|
||||
evsel__name(counter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2977,7 +2960,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
|
|||
|
||||
match = 0;
|
||||
evlist__for_each_entry(session->evlist, pos) {
|
||||
if (!strcmp(perf_evsel__name(pos), evname)) {
|
||||
if (!strcmp(evsel__name(pos), evname)) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,9 +238,8 @@ static int write_stat_round_event(u64 tm, u64 type)
|
|||
|
||||
#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,
|
||||
struct perf_counts_values *count)
|
||||
static int evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
|
||||
struct perf_counts_values *count)
|
||||
{
|
||||
struct perf_sample_id *sid = SID(counter, cpu, thread);
|
||||
|
||||
|
|
@ -259,7 +258,7 @@ static int read_single_counter(struct evsel *counter, int cpu,
|
|||
count->val = val;
|
||||
return 0;
|
||||
}
|
||||
return perf_evsel__read_counter(counter, cpu, thread);
|
||||
return evsel__read_counter(counter, cpu, thread);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -284,7 +283,7 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
|
|||
|
||||
/*
|
||||
* The leader's group read loads data into its group members
|
||||
* (via perf_evsel__read_counter()) and sets their count->loaded.
|
||||
* (via evsel__read_counter()) and sets their count->loaded.
|
||||
*/
|
||||
if (!perf_counts__is_loaded(counter->counts, cpu, thread) &&
|
||||
read_single_counter(counter, cpu, thread, rs)) {
|
||||
|
|
@ -297,7 +296,7 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
|
|||
perf_counts__set_loaded(counter->counts, cpu, thread, false);
|
||||
|
||||
if (STAT_RECORD) {
|
||||
if (perf_evsel__write_stat_event(counter, cpu, thread, count)) {
|
||||
if (evsel__write_stat_event(counter, cpu, thread, count)) {
|
||||
pr_err("failed to write stat event\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -306,7 +305,7 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
|
|||
if (verbose > 1) {
|
||||
fprintf(stat_config.output,
|
||||
"%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
|
||||
perf_evsel__name(counter),
|
||||
evsel__name(counter),
|
||||
cpu,
|
||||
count->val, count->ena, count->run);
|
||||
}
|
||||
|
|
@ -359,6 +358,7 @@ static void process_interval(void)
|
|||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
diff_timespec(&rs, &ts, &ref_time);
|
||||
|
||||
perf_stat__reset_shadow_per_stat(&rt_stat);
|
||||
read_counters(&rs);
|
||||
|
||||
if (STAT_RECORD) {
|
||||
|
|
@ -409,7 +409,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *inf
|
|||
workload_exec_errno = info->si_value.sival_int;
|
||||
}
|
||||
|
||||
static bool perf_evsel__should_store_id(struct evsel *counter)
|
||||
static bool evsel__should_store_id(struct evsel *counter)
|
||||
{
|
||||
return STAT_RECORD || counter->core.attr.read_format & PERF_FORMAT_ID;
|
||||
}
|
||||
|
|
@ -454,7 +454,7 @@ static enum counter_recovery stat_handle_error(struct evsel *counter)
|
|||
errno == ENXIO) {
|
||||
if (verbose > 0)
|
||||
ui__warning("%s event is not supported by the kernel.\n",
|
||||
perf_evsel__name(counter));
|
||||
evsel__name(counter));
|
||||
counter->supported = false;
|
||||
/*
|
||||
* errored is a sticky flag that means one of the counter's
|
||||
|
|
@ -465,7 +465,7 @@ static enum counter_recovery stat_handle_error(struct evsel *counter)
|
|||
if ((counter->leader != counter) ||
|
||||
!(counter->leader->core.nr_members > 1))
|
||||
return COUNTER_SKIP;
|
||||
} else if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
|
||||
} else if (evsel__fallback(counter, errno, msg, sizeof(msg))) {
|
||||
if (verbose > 0)
|
||||
ui__warning("%s\n", msg);
|
||||
return COUNTER_RETRY;
|
||||
|
|
@ -483,8 +483,7 @@ static enum counter_recovery stat_handle_error(struct evsel *counter)
|
|||
}
|
||||
}
|
||||
|
||||
perf_evsel__open_strerror(counter, &target,
|
||||
errno, msg, sizeof(msg));
|
||||
evsel__open_strerror(counter, &target, errno, msg, sizeof(msg));
|
||||
ui__error("%s\n", msg);
|
||||
|
||||
if (child_pid != -1)
|
||||
|
|
@ -604,7 +603,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
|
|||
if (!counter->reset_group)
|
||||
continue;
|
||||
try_again_reset:
|
||||
pr_debug2("reopening weak %s\n", perf_evsel__name(counter));
|
||||
pr_debug2("reopening weak %s\n", evsel__name(counter));
|
||||
if (create_perf_stat_counter(counter, &stat_config, &target,
|
||||
counter->cpu_iter - 1) < 0) {
|
||||
|
||||
|
|
@ -635,14 +634,14 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
|
|||
if (l > stat_config.unit_width)
|
||||
stat_config.unit_width = l;
|
||||
|
||||
if (perf_evsel__should_store_id(counter) &&
|
||||
perf_evsel__store_ids(counter, evsel_list))
|
||||
if (evsel__should_store_id(counter) &&
|
||||
evsel__store_ids(counter, evsel_list))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (perf_evlist__apply_filters(evsel_list, &counter)) {
|
||||
pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
|
||||
counter->filter, perf_evsel__name(counter), errno,
|
||||
counter->filter, evsel__name(counter), errno,
|
||||
str_error_r(errno, msg, sizeof(msg)));
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -579,8 +579,8 @@ process_sample_cpu_idle(struct timechart *tchart __maybe_unused,
|
|||
struct perf_sample *sample,
|
||||
const char *backtrace __maybe_unused)
|
||||
{
|
||||
u32 state = perf_evsel__intval(evsel, sample, "state");
|
||||
u32 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
|
||||
u32 state = evsel__intval(evsel, sample, "state");
|
||||
u32 cpu_id = evsel__intval(evsel, sample, "cpu_id");
|
||||
|
||||
if (state == (u32)PWR_EVENT_EXIT)
|
||||
c_state_end(tchart, cpu_id, sample->time);
|
||||
|
|
@ -595,8 +595,8 @@ process_sample_cpu_frequency(struct timechart *tchart,
|
|||
struct perf_sample *sample,
|
||||
const char *backtrace __maybe_unused)
|
||||
{
|
||||
u32 state = perf_evsel__intval(evsel, sample, "state");
|
||||
u32 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
|
||||
u32 state = evsel__intval(evsel, sample, "state");
|
||||
u32 cpu_id = evsel__intval(evsel, sample, "cpu_id");
|
||||
|
||||
p_state_change(tchart, cpu_id, sample->time, state);
|
||||
return 0;
|
||||
|
|
@ -608,9 +608,9 @@ process_sample_sched_wakeup(struct timechart *tchart,
|
|||
struct perf_sample *sample,
|
||||
const char *backtrace)
|
||||
{
|
||||
u8 flags = perf_evsel__intval(evsel, sample, "common_flags");
|
||||
int waker = perf_evsel__intval(evsel, sample, "common_pid");
|
||||
int wakee = perf_evsel__intval(evsel, sample, "pid");
|
||||
u8 flags = evsel__intval(evsel, sample, "common_flags");
|
||||
int waker = evsel__intval(evsel, sample, "common_pid");
|
||||
int wakee = evsel__intval(evsel, sample, "pid");
|
||||
|
||||
sched_wakeup(tchart, sample->cpu, sample->time, waker, wakee, flags, backtrace);
|
||||
return 0;
|
||||
|
|
@ -622,9 +622,9 @@ process_sample_sched_switch(struct timechart *tchart,
|
|||
struct perf_sample *sample,
|
||||
const char *backtrace)
|
||||
{
|
||||
int prev_pid = perf_evsel__intval(evsel, sample, "prev_pid");
|
||||
int next_pid = perf_evsel__intval(evsel, sample, "next_pid");
|
||||
u64 prev_state = perf_evsel__intval(evsel, sample, "prev_state");
|
||||
int prev_pid = evsel__intval(evsel, sample, "prev_pid");
|
||||
int next_pid = evsel__intval(evsel, sample, "next_pid");
|
||||
u64 prev_state = evsel__intval(evsel, sample, "prev_state");
|
||||
|
||||
sched_switch(tchart, sample->cpu, sample->time, prev_pid, next_pid,
|
||||
prev_state, backtrace);
|
||||
|
|
@ -638,8 +638,8 @@ process_sample_power_start(struct timechart *tchart __maybe_unused,
|
|||
struct perf_sample *sample,
|
||||
const char *backtrace __maybe_unused)
|
||||
{
|
||||
u64 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
|
||||
u64 value = perf_evsel__intval(evsel, sample, "value");
|
||||
u64 cpu_id = evsel__intval(evsel, sample, "cpu_id");
|
||||
u64 value = evsel__intval(evsel, sample, "value");
|
||||
|
||||
c_state_start(cpu_id, sample->time, value);
|
||||
return 0;
|
||||
|
|
@ -661,8 +661,8 @@ process_sample_power_frequency(struct timechart *tchart,
|
|||
struct perf_sample *sample,
|
||||
const char *backtrace __maybe_unused)
|
||||
{
|
||||
u64 cpu_id = perf_evsel__intval(evsel, sample, "cpu_id");
|
||||
u64 value = perf_evsel__intval(evsel, sample, "value");
|
||||
u64 cpu_id = evsel__intval(evsel, sample, "cpu_id");
|
||||
u64 value = evsel__intval(evsel, sample, "value");
|
||||
|
||||
p_state_change(tchart, cpu_id, sample->time, value);
|
||||
return 0;
|
||||
|
|
@ -843,7 +843,7 @@ process_enter_read(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long fd = perf_evsel__intval(evsel, sample, "fd");
|
||||
long fd = evsel__intval(evsel, sample, "fd");
|
||||
return pid_begin_io_sample(tchart, sample->tid, IOTYPE_READ,
|
||||
sample->time, fd);
|
||||
}
|
||||
|
|
@ -853,7 +853,7 @@ process_exit_read(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long ret = perf_evsel__intval(evsel, sample, "ret");
|
||||
long ret = evsel__intval(evsel, sample, "ret");
|
||||
return pid_end_io_sample(tchart, sample->tid, IOTYPE_READ,
|
||||
sample->time, ret);
|
||||
}
|
||||
|
|
@ -863,7 +863,7 @@ process_enter_write(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long fd = perf_evsel__intval(evsel, sample, "fd");
|
||||
long fd = evsel__intval(evsel, sample, "fd");
|
||||
return pid_begin_io_sample(tchart, sample->tid, IOTYPE_WRITE,
|
||||
sample->time, fd);
|
||||
}
|
||||
|
|
@ -873,7 +873,7 @@ process_exit_write(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long ret = perf_evsel__intval(evsel, sample, "ret");
|
||||
long ret = evsel__intval(evsel, sample, "ret");
|
||||
return pid_end_io_sample(tchart, sample->tid, IOTYPE_WRITE,
|
||||
sample->time, ret);
|
||||
}
|
||||
|
|
@ -883,7 +883,7 @@ process_enter_sync(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long fd = perf_evsel__intval(evsel, sample, "fd");
|
||||
long fd = evsel__intval(evsel, sample, "fd");
|
||||
return pid_begin_io_sample(tchart, sample->tid, IOTYPE_SYNC,
|
||||
sample->time, fd);
|
||||
}
|
||||
|
|
@ -893,7 +893,7 @@ process_exit_sync(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long ret = perf_evsel__intval(evsel, sample, "ret");
|
||||
long ret = evsel__intval(evsel, sample, "ret");
|
||||
return pid_end_io_sample(tchart, sample->tid, IOTYPE_SYNC,
|
||||
sample->time, ret);
|
||||
}
|
||||
|
|
@ -903,7 +903,7 @@ process_enter_tx(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long fd = perf_evsel__intval(evsel, sample, "fd");
|
||||
long fd = evsel__intval(evsel, sample, "fd");
|
||||
return pid_begin_io_sample(tchart, sample->tid, IOTYPE_TX,
|
||||
sample->time, fd);
|
||||
}
|
||||
|
|
@ -913,7 +913,7 @@ process_exit_tx(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long ret = perf_evsel__intval(evsel, sample, "ret");
|
||||
long ret = evsel__intval(evsel, sample, "ret");
|
||||
return pid_end_io_sample(tchart, sample->tid, IOTYPE_TX,
|
||||
sample->time, ret);
|
||||
}
|
||||
|
|
@ -923,7 +923,7 @@ process_enter_rx(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long fd = perf_evsel__intval(evsel, sample, "fd");
|
||||
long fd = evsel__intval(evsel, sample, "fd");
|
||||
return pid_begin_io_sample(tchart, sample->tid, IOTYPE_RX,
|
||||
sample->time, fd);
|
||||
}
|
||||
|
|
@ -933,7 +933,7 @@ process_exit_rx(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long ret = perf_evsel__intval(evsel, sample, "ret");
|
||||
long ret = evsel__intval(evsel, sample, "ret");
|
||||
return pid_end_io_sample(tchart, sample->tid, IOTYPE_RX,
|
||||
sample->time, ret);
|
||||
}
|
||||
|
|
@ -943,7 +943,7 @@ process_enter_poll(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long fd = perf_evsel__intval(evsel, sample, "fd");
|
||||
long fd = evsel__intval(evsel, sample, "fd");
|
||||
return pid_begin_io_sample(tchart, sample->tid, IOTYPE_POLL,
|
||||
sample->time, fd);
|
||||
}
|
||||
|
|
@ -953,7 +953,7 @@ process_exit_poll(struct timechart *tchart,
|
|||
struct evsel *evsel,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
long ret = perf_evsel__intval(evsel, sample, "ret");
|
||||
long ret = evsel__intval(evsel, sample, "ret");
|
||||
return pid_end_io_sample(tchart, sample->tid, IOTYPE_POLL,
|
||||
sample->time, ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ static void perf_top__show_details(struct perf_top *top)
|
|||
if (notes->src == NULL)
|
||||
goto out_unlock;
|
||||
|
||||
printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name);
|
||||
printf("Showing %s for %s\n", evsel__name(top->sym_evsel), symbol->name);
|
||||
printf(" Events Pcnt (>=%d%%)\n", top->annotation_opts.min_pcnt);
|
||||
|
||||
more = symbol__annotate_printf(&he->ms, top->sym_evsel, &top->annotation_opts);
|
||||
|
|
@ -298,8 +298,7 @@ static void perf_top__resort_hists(struct perf_top *t)
|
|||
hists__collapse_resort(hists, NULL);
|
||||
|
||||
/* Non-group events are considered as leader */
|
||||
if (symbol_conf.event_group &&
|
||||
!perf_evsel__is_group_leader(pos)) {
|
||||
if (symbol_conf.event_group && !evsel__is_group_leader(pos)) {
|
||||
struct hists *leader_hists = evsel__hists(pos->leader);
|
||||
|
||||
hists__match(leader_hists, hists);
|
||||
|
|
@ -442,7 +441,7 @@ static void perf_top__print_mapped_keys(struct perf_top *top)
|
|||
fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries);
|
||||
|
||||
if (top->evlist->core.nr_entries > 1)
|
||||
fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel));
|
||||
fprintf(stdout, "\t[E] active event counter. \t(%s)\n", evsel__name(top->sym_evsel));
|
||||
|
||||
fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter);
|
||||
|
||||
|
|
@ -529,13 +528,13 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
|||
fprintf(stderr, "\nAvailable events:");
|
||||
|
||||
evlist__for_each_entry(top->evlist, top->sym_evsel)
|
||||
fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel));
|
||||
fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, evsel__name(top->sym_evsel));
|
||||
|
||||
prompt_integer(&counter, "Enter details event counter");
|
||||
|
||||
if (counter >= top->evlist->core.nr_entries) {
|
||||
top->sym_evsel = evlist__first(top->evlist);
|
||||
fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel));
|
||||
fprintf(stderr, "Sorry, no such event, using %s.\n", evsel__name(top->sym_evsel));
|
||||
sleep(1);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1046,14 +1045,13 @@ static int perf_top__start_counters(struct perf_top *top)
|
|||
perf_top_overwrite_fallback(top, counter))
|
||||
goto try_again;
|
||||
|
||||
if (perf_evsel__fallback(counter, errno, msg, sizeof(msg))) {
|
||||
if (evsel__fallback(counter, errno, msg, sizeof(msg))) {
|
||||
if (verbose > 0)
|
||||
ui__warning("%s\n", msg);
|
||||
goto try_again;
|
||||
}
|
||||
|
||||
perf_evsel__open_strerror(counter, &opts->target,
|
||||
errno, msg, sizeof(msg));
|
||||
evsel__open_strerror(counter, &opts->target, errno, msg, sizeof(msg));
|
||||
ui__error("%s\n", msg);
|
||||
goto out_err;
|
||||
}
|
||||
|
|
@ -1580,7 +1578,6 @@ int cmd_top(int argc, const char **argv)
|
|||
OPTS_EVSWITCH(&top.evswitch),
|
||||
OPT_END()
|
||||
};
|
||||
struct evlist *sb_evlist = NULL;
|
||||
const char * const top_usage[] = {
|
||||
"perf top [<options>]",
|
||||
NULL
|
||||
|
|
@ -1743,10 +1740,21 @@ int cmd_top(int argc, const char **argv)
|
|||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
if (!top.record_opts.no_bpf_event)
|
||||
bpf_event__add_sb_event(&sb_evlist, &perf_env);
|
||||
if (!top.record_opts.no_bpf_event) {
|
||||
top.sb_evlist = evlist__new();
|
||||
|
||||
if (perf_evlist__start_sb_thread(sb_evlist, target)) {
|
||||
if (top.sb_evlist == NULL) {
|
||||
pr_err("Couldn't create side band evlist.\n.");
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
if (evlist__add_bpf_sb_event(top.sb_evlist, &perf_env)) {
|
||||
pr_err("Couldn't ask for PERF_RECORD_BPF_EVENT side band events.\n.");
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
}
|
||||
|
||||
if (perf_evlist__start_sb_thread(top.sb_evlist, target)) {
|
||||
pr_debug("Couldn't start the BPF side band thread:\nBPF programs starting from now on won't be annotatable\n");
|
||||
opts->no_bpf_event = true;
|
||||
}
|
||||
|
|
@ -1754,7 +1762,7 @@ int cmd_top(int argc, const char **argv)
|
|||
status = __cmd_top(&top);
|
||||
|
||||
if (!opts->no_bpf_event)
|
||||
perf_evlist__stop_sb_thread(sb_evlist);
|
||||
perf_evlist__stop_sb_thread(top.sb_evlist);
|
||||
|
||||
out_delete_evlist:
|
||||
evlist__delete(top.evlist);
|
||||
|
|
|
|||
|
|
@ -366,11 +366,9 @@ static struct syscall_arg_fmt *evsel__syscall_arg_fmt(struct evsel *evsel)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int perf_evsel__init_tp_uint_field(struct evsel *evsel,
|
||||
struct tp_field *field,
|
||||
const char *name)
|
||||
static int evsel__init_tp_uint_field(struct evsel *evsel, struct tp_field *field, const char *name)
|
||||
{
|
||||
struct tep_format_field *format_field = perf_evsel__field(evsel, name);
|
||||
struct tep_format_field *format_field = evsel__field(evsel, name);
|
||||
|
||||
if (format_field == NULL)
|
||||
return -1;
|
||||
|
|
@ -380,13 +378,11 @@ static int perf_evsel__init_tp_uint_field(struct evsel *evsel,
|
|||
|
||||
#define perf_evsel__init_sc_tp_uint_field(evsel, name) \
|
||||
({ struct syscall_tp *sc = __evsel__syscall_tp(evsel);\
|
||||
perf_evsel__init_tp_uint_field(evsel, &sc->name, #name); })
|
||||
evsel__init_tp_uint_field(evsel, &sc->name, #name); })
|
||||
|
||||
static int perf_evsel__init_tp_ptr_field(struct evsel *evsel,
|
||||
struct tp_field *field,
|
||||
const char *name)
|
||||
static int evsel__init_tp_ptr_field(struct evsel *evsel, struct tp_field *field, const char *name)
|
||||
{
|
||||
struct tep_format_field *format_field = perf_evsel__field(evsel, name);
|
||||
struct tep_format_field *format_field = evsel__field(evsel, name);
|
||||
|
||||
if (format_field == NULL)
|
||||
return -1;
|
||||
|
|
@ -396,7 +392,7 @@ static int perf_evsel__init_tp_ptr_field(struct evsel *evsel,
|
|||
|
||||
#define perf_evsel__init_sc_tp_ptr_field(evsel, name) \
|
||||
({ struct syscall_tp *sc = __evsel__syscall_tp(evsel);\
|
||||
perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); })
|
||||
evsel__init_tp_ptr_field(evsel, &sc->name, #name); })
|
||||
|
||||
static void evsel__delete_priv(struct evsel *evsel)
|
||||
{
|
||||
|
|
@ -404,13 +400,13 @@ static void evsel__delete_priv(struct evsel *evsel)
|
|||
evsel__delete(evsel);
|
||||
}
|
||||
|
||||
static int perf_evsel__init_syscall_tp(struct evsel *evsel)
|
||||
static int evsel__init_syscall_tp(struct evsel *evsel)
|
||||
{
|
||||
struct syscall_tp *sc = evsel__syscall_tp(evsel);
|
||||
|
||||
if (sc != NULL) {
|
||||
if (perf_evsel__init_tp_uint_field(evsel, &sc->id, "__syscall_nr") &&
|
||||
perf_evsel__init_tp_uint_field(evsel, &sc->id, "nr"))
|
||||
if (evsel__init_tp_uint_field(evsel, &sc->id, "__syscall_nr") &&
|
||||
evsel__init_tp_uint_field(evsel, &sc->id, "nr"))
|
||||
return -ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -418,14 +414,14 @@ static int perf_evsel__init_syscall_tp(struct evsel *evsel)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int perf_evsel__init_augmented_syscall_tp(struct evsel *evsel, struct evsel *tp)
|
||||
static int evsel__init_augmented_syscall_tp(struct evsel *evsel, struct evsel *tp)
|
||||
{
|
||||
struct syscall_tp *sc = evsel__syscall_tp(evsel);
|
||||
|
||||
if (sc != NULL) {
|
||||
struct tep_format_field *syscall_id = perf_evsel__field(tp, "id");
|
||||
struct tep_format_field *syscall_id = evsel__field(tp, "id");
|
||||
if (syscall_id == NULL)
|
||||
syscall_id = perf_evsel__field(tp, "__syscall_nr");
|
||||
syscall_id = evsel__field(tp, "__syscall_nr");
|
||||
if (syscall_id == NULL ||
|
||||
__tp_field__init_uint(&sc->id, syscall_id->size, syscall_id->offset, evsel->needs_swap))
|
||||
return -EINVAL;
|
||||
|
|
@ -436,21 +432,21 @@ static int perf_evsel__init_augmented_syscall_tp(struct evsel *evsel, struct evs
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int perf_evsel__init_augmented_syscall_tp_args(struct evsel *evsel)
|
||||
static int evsel__init_augmented_syscall_tp_args(struct evsel *evsel)
|
||||
{
|
||||
struct syscall_tp *sc = __evsel__syscall_tp(evsel);
|
||||
|
||||
return __tp_field__init_ptr(&sc->args, sc->id.offset + sizeof(u64));
|
||||
}
|
||||
|
||||
static int perf_evsel__init_augmented_syscall_tp_ret(struct evsel *evsel)
|
||||
static int evsel__init_augmented_syscall_tp_ret(struct evsel *evsel)
|
||||
{
|
||||
struct syscall_tp *sc = __evsel__syscall_tp(evsel);
|
||||
|
||||
return __tp_field__init_uint(&sc->ret, sizeof(u64), sc->id.offset + sizeof(u64), evsel->needs_swap);
|
||||
}
|
||||
|
||||
static int perf_evsel__init_raw_syscall_tp(struct evsel *evsel, void *handler)
|
||||
static int evsel__init_raw_syscall_tp(struct evsel *evsel, void *handler)
|
||||
{
|
||||
if (evsel__syscall_tp(evsel) != NULL) {
|
||||
if (perf_evsel__init_sc_tp_uint_field(evsel, id))
|
||||
|
|
@ -474,7 +470,7 @@ static struct evsel *perf_evsel__raw_syscall_newtp(const char *direction, void *
|
|||
if (IS_ERR(evsel))
|
||||
return NULL;
|
||||
|
||||
if (perf_evsel__init_raw_syscall_tp(evsel, handler))
|
||||
if (evsel__init_raw_syscall_tp(evsel, handler))
|
||||
goto out_delete;
|
||||
|
||||
return evsel;
|
||||
|
|
@ -1801,7 +1797,7 @@ static int trace__read_syscall_info(struct trace *trace, int id)
|
|||
return syscall__set_arg_fmts(sc);
|
||||
}
|
||||
|
||||
static int perf_evsel__init_tp_arg_scnprintf(struct evsel *evsel)
|
||||
static int evsel__init_tp_arg_scnprintf(struct evsel *evsel)
|
||||
{
|
||||
struct syscall_arg_fmt *fmt = evsel__syscall_arg_fmt(evsel);
|
||||
|
||||
|
|
@ -2074,7 +2070,7 @@ static struct syscall *trace__syscall_info(struct trace *trace,
|
|||
if (verbose > 1) {
|
||||
static u64 n;
|
||||
fprintf(trace->output, "Invalid syscall %d id, skipping (%s, %" PRIu64 ") ...\n",
|
||||
id, perf_evsel__name(evsel), ++n);
|
||||
id, evsel__name(evsel), ++n);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2206,7 +2202,7 @@ static int trace__fprintf_sample(struct trace *trace, struct evsel *evsel,
|
|||
double ts = (double)sample->time / NSEC_PER_MSEC;
|
||||
|
||||
printed += fprintf(trace->output, "%22s %10.3f %s %d/%d [%d]\n",
|
||||
perf_evsel__name(evsel), ts,
|
||||
evsel__name(evsel), ts,
|
||||
thread__comm_str(thread),
|
||||
sample->pid, sample->tid, sample->cpu);
|
||||
}
|
||||
|
|
@ -2382,7 +2378,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam
|
|||
|
||||
static const char *errno_to_name(struct evsel *evsel, int err)
|
||||
{
|
||||
struct perf_env *env = perf_evsel__env(evsel);
|
||||
struct perf_env *env = evsel__env(evsel);
|
||||
const char *arch_name = perf_env__arch(env);
|
||||
|
||||
return arch_syscalls__strerrno(arch_name, err);
|
||||
|
|
@ -2513,7 +2509,7 @@ errno_print: {
|
|||
if (callchain_ret > 0)
|
||||
trace__fprintf_callchain(trace, sample);
|
||||
else if (callchain_ret < 0)
|
||||
pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
|
||||
pr_err("Problem processing %s callchain, skipping...\n", evsel__name(evsel));
|
||||
out:
|
||||
ttrace->entry_pending = false;
|
||||
err = 0;
|
||||
|
|
@ -2531,7 +2527,7 @@ static int trace__vfs_getname(struct trace *trace, struct evsel *evsel,
|
|||
size_t filename_len, entry_str_len, to_move;
|
||||
ssize_t remaining_space;
|
||||
char *pos;
|
||||
const char *filename = perf_evsel__rawptr(evsel, sample, "pathname");
|
||||
const char *filename = evsel__rawptr(evsel, sample, "pathname");
|
||||
|
||||
if (!thread)
|
||||
goto out;
|
||||
|
|
@ -2587,7 +2583,7 @@ static int trace__sched_stat_runtime(struct trace *trace, struct evsel *evsel,
|
|||
union perf_event *event __maybe_unused,
|
||||
struct perf_sample *sample)
|
||||
{
|
||||
u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
|
||||
u64 runtime = evsel__intval(evsel, sample, "runtime");
|
||||
double runtime_ms = (double)runtime / NSEC_PER_MSEC;
|
||||
struct thread *thread = machine__findnew_thread(trace->host,
|
||||
sample->pid,
|
||||
|
|
@ -2606,10 +2602,10 @@ static int trace__sched_stat_runtime(struct trace *trace, struct evsel *evsel,
|
|||
out_dump:
|
||||
fprintf(trace->output, "%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n",
|
||||
evsel->name,
|
||||
perf_evsel__strval(evsel, sample, "comm"),
|
||||
(pid_t)perf_evsel__intval(evsel, sample, "pid"),
|
||||
evsel__strval(evsel, sample, "comm"),
|
||||
(pid_t)evsel__intval(evsel, sample, "pid"),
|
||||
runtime,
|
||||
perf_evsel__intval(evsel, sample, "vruntime"));
|
||||
evsel__intval(evsel, sample, "vruntime"));
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
|
|
@ -2774,7 +2770,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
|
|||
|
||||
fprintf(trace->output, "%s(", evsel->name);
|
||||
|
||||
if (perf_evsel__is_bpf_output(evsel)) {
|
||||
if (evsel__is_bpf_output(evsel)) {
|
||||
bpf_output__fprintf(trace, sample);
|
||||
} else if (evsel->tp_format) {
|
||||
if (strncmp(evsel->tp_format->name, "sys_enter_", 10) ||
|
||||
|
|
@ -2795,7 +2791,7 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel,
|
|||
if (callchain_ret > 0)
|
||||
trace__fprintf_callchain(trace, sample);
|
||||
else if (callchain_ret < 0)
|
||||
pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
|
||||
pr_err("Problem processing %s callchain, skipping...\n", evsel__name(evsel));
|
||||
|
||||
++trace->nr_events_printed;
|
||||
|
||||
|
|
@ -2890,7 +2886,7 @@ static int trace__pgfault(struct trace *trace,
|
|||
if (callchain_ret > 0)
|
||||
trace__fprintf_callchain(trace, sample);
|
||||
else if (callchain_ret < 0)
|
||||
pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
|
||||
pr_err("Problem processing %s callchain, skipping...\n", evsel__name(evsel));
|
||||
|
||||
++trace->nr_events_printed;
|
||||
out:
|
||||
|
|
@ -3032,10 +3028,10 @@ static bool evlist__add_vfs_getname(struct evlist *evlist)
|
|||
}
|
||||
|
||||
evlist__for_each_entry_safe(evlist, evsel, tmp) {
|
||||
if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname"))
|
||||
if (!strstarts(evsel__name(evsel), "probe:vfs_getname"))
|
||||
continue;
|
||||
|
||||
if (perf_evsel__field(evsel, "pathname")) {
|
||||
if (evsel__field(evsel, "pathname")) {
|
||||
evsel->handler = trace__vfs_getname;
|
||||
found = true;
|
||||
continue;
|
||||
|
|
@ -3093,7 +3089,7 @@ static void trace__handle_event(struct trace *trace, union perf_event *event, st
|
|||
if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT &&
|
||||
sample->raw_data == NULL) {
|
||||
fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
|
||||
perf_evsel__name(evsel), sample->tid,
|
||||
evsel__name(evsel), sample->tid,
|
||||
sample->cpu, sample->raw_size);
|
||||
} else {
|
||||
tracepoint_handler handler = evsel->handler;
|
||||
|
|
@ -3124,8 +3120,8 @@ static int trace__add_syscall_newtp(struct trace *trace)
|
|||
if (perf_evsel__init_sc_tp_uint_field(sys_exit, ret))
|
||||
goto out_delete_sys_exit;
|
||||
|
||||
perf_evsel__config_callchain(sys_enter, &trace->opts, &callchain_param);
|
||||
perf_evsel__config_callchain(sys_exit, &trace->opts, &callchain_param);
|
||||
evsel__config_callchain(sys_enter, &trace->opts, &callchain_param);
|
||||
evsel__config_callchain(sys_exit, &trace->opts, &callchain_param);
|
||||
|
||||
evlist__add(evlist, sys_enter);
|
||||
evlist__add(evlist, sys_exit);
|
||||
|
|
@ -3164,10 +3160,9 @@ static int trace__set_ev_qualifier_tp_filter(struct trace *trace)
|
|||
if (filter == NULL)
|
||||
goto out_enomem;
|
||||
|
||||
if (!perf_evsel__append_tp_filter(trace->syscalls.events.sys_enter,
|
||||
filter)) {
|
||||
if (!evsel__append_tp_filter(trace->syscalls.events.sys_enter, filter)) {
|
||||
sys_exit = trace->syscalls.events.sys_exit;
|
||||
err = perf_evsel__append_tp_filter(sys_exit, filter);
|
||||
err = evsel__append_tp_filter(sys_exit, filter);
|
||||
}
|
||||
|
||||
free(filter);
|
||||
|
|
@ -3695,7 +3690,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe,
|
|||
return __trace__deliver_event(trace, event->event);
|
||||
}
|
||||
|
||||
static struct syscall_arg_fmt *perf_evsel__syscall_arg_fmt(struct evsel *evsel, char *arg)
|
||||
static struct syscall_arg_fmt *evsel__find_syscall_arg_fmt_by_name(struct evsel *evsel, char *arg)
|
||||
{
|
||||
struct tep_format_field *field;
|
||||
struct syscall_arg_fmt *fmt = __evsel__syscall_arg_fmt(evsel);
|
||||
|
|
@ -3750,7 +3745,7 @@ static int trace__expand_filter(struct trace *trace __maybe_unused, struct evsel
|
|||
|
||||
scnprintf(arg, sizeof(arg), "%.*s", left_size, left);
|
||||
|
||||
fmt = perf_evsel__syscall_arg_fmt(evsel, arg);
|
||||
fmt = evsel__find_syscall_arg_fmt_by_name(evsel, arg);
|
||||
if (fmt == NULL) {
|
||||
pr_err("\"%s\" not found in \"%s\", can't set filter \"%s\"\n",
|
||||
arg, evsel->name, evsel->filter);
|
||||
|
|
@ -3801,7 +3796,7 @@ static int trace__expand_filter(struct trace *trace __maybe_unused, struct evsel
|
|||
|
||||
if (new_filter != evsel->filter) {
|
||||
pr_debug("New filter for %s: %s\n", evsel->name, new_filter);
|
||||
perf_evsel__set_filter(evsel, new_filter);
|
||||
evsel__set_filter(evsel, new_filter);
|
||||
free(new_filter);
|
||||
}
|
||||
|
||||
|
|
@ -3849,7 +3844,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
pgfault_maj = perf_evsel__new_pgfault(PERF_COUNT_SW_PAGE_FAULTS_MAJ);
|
||||
if (pgfault_maj == NULL)
|
||||
goto out_error_mem;
|
||||
perf_evsel__config_callchain(pgfault_maj, &trace->opts, &callchain_param);
|
||||
evsel__config_callchain(pgfault_maj, &trace->opts, &callchain_param);
|
||||
evlist__add(evlist, pgfault_maj);
|
||||
}
|
||||
|
||||
|
|
@ -3857,7 +3852,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
pgfault_min = perf_evsel__new_pgfault(PERF_COUNT_SW_PAGE_FAULTS_MIN);
|
||||
if (pgfault_min == NULL)
|
||||
goto out_error_mem;
|
||||
perf_evsel__config_callchain(pgfault_min, &trace->opts, &callchain_param);
|
||||
evsel__config_callchain(pgfault_min, &trace->opts, &callchain_param);
|
||||
evlist__add(evlist, pgfault_min);
|
||||
}
|
||||
|
||||
|
|
@ -4108,7 +4103,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
out_error_apply_filters:
|
||||
fprintf(trace->output,
|
||||
"Failed to set filter \"%s\" on event %s with %d (%s)\n",
|
||||
evsel->filter, perf_evsel__name(evsel), errno,
|
||||
evsel->filter, evsel__name(evsel), errno,
|
||||
str_error_r(errno, errbuf, sizeof(errbuf)));
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
|
@ -4179,7 +4174,7 @@ static int trace__replay(struct trace *trace)
|
|||
"syscalls:sys_enter");
|
||||
|
||||
if (evsel &&
|
||||
(perf_evsel__init_raw_syscall_tp(evsel, trace__sys_enter) < 0 ||
|
||||
(evsel__init_raw_syscall_tp(evsel, trace__sys_enter) < 0 ||
|
||||
perf_evsel__init_sc_tp_ptr_field(evsel, args))) {
|
||||
pr_err("Error during initialize raw_syscalls:sys_enter event\n");
|
||||
goto out;
|
||||
|
|
@ -4191,7 +4186,7 @@ static int trace__replay(struct trace *trace)
|
|||
evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
|
||||
"syscalls:sys_exit");
|
||||
if (evsel &&
|
||||
(perf_evsel__init_raw_syscall_tp(evsel, trace__sys_exit) < 0 ||
|
||||
(evsel__init_raw_syscall_tp(evsel, trace__sys_exit) < 0 ||
|
||||
perf_evsel__init_sc_tp_uint_field(evsel, ret))) {
|
||||
pr_err("Error during initialize raw_syscalls:sys_exit event\n");
|
||||
goto out;
|
||||
|
|
@ -4471,11 +4466,11 @@ static int evlist__set_syscall_tp_fields(struct evlist *evlist)
|
|||
continue;
|
||||
|
||||
if (strcmp(evsel->tp_format->system, "syscalls")) {
|
||||
perf_evsel__init_tp_arg_scnprintf(evsel);
|
||||
evsel__init_tp_arg_scnprintf(evsel);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (perf_evsel__init_syscall_tp(evsel))
|
||||
if (evsel__init_syscall_tp(evsel))
|
||||
return -1;
|
||||
|
||||
if (!strncmp(evsel->tp_format->name, "sys_enter_", 10)) {
|
||||
|
|
@ -4989,7 +4984,7 @@ int cmd_trace(int argc, const char **argv)
|
|||
*/
|
||||
if (trace.syscalls.events.augmented) {
|
||||
evlist__for_each_entry(trace.evlist, evsel) {
|
||||
bool raw_syscalls_sys_exit = strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_exit") == 0;
|
||||
bool raw_syscalls_sys_exit = strcmp(evsel__name(evsel), "raw_syscalls:sys_exit") == 0;
|
||||
|
||||
if (raw_syscalls_sys_exit) {
|
||||
trace.raw_augmented_syscalls = true;
|
||||
|
|
@ -4997,10 +4992,10 @@ int cmd_trace(int argc, const char **argv)
|
|||
}
|
||||
|
||||
if (trace.syscalls.events.augmented->priv == NULL &&
|
||||
strstr(perf_evsel__name(evsel), "syscalls:sys_enter")) {
|
||||
strstr(evsel__name(evsel), "syscalls:sys_enter")) {
|
||||
struct evsel *augmented = trace.syscalls.events.augmented;
|
||||
if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) ||
|
||||
perf_evsel__init_augmented_syscall_tp_args(augmented))
|
||||
if (evsel__init_augmented_syscall_tp(augmented, evsel) ||
|
||||
evsel__init_augmented_syscall_tp_args(augmented))
|
||||
goto out;
|
||||
/*
|
||||
* Augmented is __augmented_syscalls__ BPF_OUTPUT event
|
||||
|
|
@ -5014,16 +5009,16 @@ int cmd_trace(int argc, const char **argv)
|
|||
* as not to filter it, then we'll handle it just like we would
|
||||
* for the BPF_OUTPUT one:
|
||||
*/
|
||||
if (perf_evsel__init_augmented_syscall_tp(evsel, evsel) ||
|
||||
perf_evsel__init_augmented_syscall_tp_args(evsel))
|
||||
if (evsel__init_augmented_syscall_tp(evsel, evsel) ||
|
||||
evsel__init_augmented_syscall_tp_args(evsel))
|
||||
goto out;
|
||||
evsel->handler = trace__sys_enter;
|
||||
}
|
||||
|
||||
if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) {
|
||||
if (strstarts(evsel__name(evsel), "syscalls:sys_exit_")) {
|
||||
struct syscall_tp *sc;
|
||||
init_augmented_syscall_tp:
|
||||
if (perf_evsel__init_augmented_syscall_tp(evsel, evsel))
|
||||
if (evsel__init_augmented_syscall_tp(evsel, evsel))
|
||||
goto out;
|
||||
sc = __evsel__syscall_tp(evsel);
|
||||
/*
|
||||
|
|
@ -5047,7 +5042,7 @@ int cmd_trace(int argc, const char **argv)
|
|||
*/
|
||||
if (trace.raw_augmented_syscalls)
|
||||
trace.raw_augmented_syscalls_args_size = (6 + 1) * sizeof(long) + sc->id.offset;
|
||||
perf_evsel__init_augmented_syscall_tp_ret(evsel);
|
||||
evsel__init_augmented_syscall_tp_ret(evsel);
|
||||
evsel->handler = trace__sys_exit;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19
tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json
Normal file
19
tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
[
|
||||
{
|
||||
"MetricExpr": "(hv_24x7@PM_MCS01_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_RD_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_RD_DISP_PORT23\\,chip\\=?@)",
|
||||
"MetricName": "Memory_RD_BW_Chip",
|
||||
"MetricGroup": "Memory_BW",
|
||||
"ScaleUnit": "1.6e-2MB"
|
||||
},
|
||||
{
|
||||
"MetricExpr": "(hv_24x7@PM_MCS01_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS01_128B_WR_DISP_PORT23\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT01\\,chip\\=?@ + hv_24x7@PM_MCS23_128B_WR_DISP_PORT23\\,chip\\=?@ )",
|
||||
"MetricName": "Memory_WR_BW_Chip",
|
||||
"MetricGroup": "Memory_BW",
|
||||
"ScaleUnit": "1.6e-2MB"
|
||||
},
|
||||
{
|
||||
"MetricExpr": "(hv_24x7@PM_PB_CYC\\,chip\\=?@ )",
|
||||
"MetricName": "PowerBUS_Frequency",
|
||||
"ScaleUnit": "2.5e-7GHz"
|
||||
}
|
||||
]
|
||||
|
|
@ -26,7 +26,7 @@ struct pmu_event {
|
|||
* Map a CPU to its table of PMU events. The CPU is identified by the
|
||||
* cpuid field, which is an arch-specific identifier for the CPU.
|
||||
* The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
|
||||
* must match the get_cpustr() in tools/perf/arch/xxx/util/header.c)
|
||||
* must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
|
||||
*
|
||||
* The cpuid can contain any character other than the comma.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
#!/usr/bin/sh
|
||||
#!/bin/bash
|
||||
perf record -g "$@"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#!/usr/bin/sh
|
||||
#!/bin/bash
|
||||
# description: create flame graphs
|
||||
perf script -s "$PERF_EXEC_PATH"/scripts/python/flamegraph.py -- "$@"
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ perf-y += mem2node.o
|
|||
perf-y += maps.o
|
||||
perf-y += time-utils-test.o
|
||||
perf-y += genelf.o
|
||||
perf-y += api-io.o
|
||||
|
||||
$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
|
||||
$(call rule_mkdir)
|
||||
|
|
|
|||
304
tools/perf/tests/api-io.c
Normal file
304
tools/perf/tests/api-io.c
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "tests.h"
|
||||
#include <api/io.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define TEMPL "/tmp/perf-test-XXXXXX"
|
||||
|
||||
#define EXPECT_EQUAL(val, expected) \
|
||||
do { \
|
||||
if (val != expected) { \
|
||||
pr_debug("%s:%d: %d != %d\n", \
|
||||
__FILE__, __LINE__, val, expected); \
|
||||
ret = -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_EQUAL64(val, expected) \
|
||||
do { \
|
||||
if (val != expected) { \
|
||||
pr_debug("%s:%d: %lld != %lld\n", \
|
||||
__FILE__, __LINE__, val, expected); \
|
||||
ret = -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int make_test_file(char path[PATH_MAX], const char *contents)
|
||||
{
|
||||
ssize_t contents_len = strlen(contents);
|
||||
int fd;
|
||||
|
||||
strcpy(path, TEMPL);
|
||||
fd = mkstemp(path);
|
||||
if (fd < 0) {
|
||||
pr_debug("mkstemp failed");
|
||||
return -1;
|
||||
}
|
||||
if (write(fd, contents, contents_len) < contents_len) {
|
||||
pr_debug("short write");
|
||||
close(fd);
|
||||
unlink(path);
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setup_test(char path[PATH_MAX], const char *contents,
|
||||
size_t buf_size, struct io *io)
|
||||
{
|
||||
if (make_test_file(path, contents))
|
||||
return -1;
|
||||
|
||||
io->fd = open(path, O_RDONLY);
|
||||
if (io->fd < 0) {
|
||||
pr_debug("Failed to open '%s'\n", path);
|
||||
unlink(path);
|
||||
return -1;
|
||||
}
|
||||
io->buf = malloc(buf_size);
|
||||
if (io->buf == NULL) {
|
||||
pr_debug("Failed to allocate memory");
|
||||
close(io->fd);
|
||||
unlink(path);
|
||||
return -1;
|
||||
}
|
||||
io__init(io, io->fd, io->buf, buf_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cleanup_test(char path[PATH_MAX], struct io *io)
|
||||
{
|
||||
free(io->buf);
|
||||
close(io->fd);
|
||||
unlink(path);
|
||||
}
|
||||
|
||||
static int do_test_get_char(const char *test_string, size_t buf_size)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct io io;
|
||||
int ch, ret = 0;
|
||||
size_t i;
|
||||
|
||||
if (setup_test(path, test_string, buf_size, &io))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < strlen(test_string); i++) {
|
||||
ch = io__get_char(&io);
|
||||
|
||||
EXPECT_EQUAL(ch, test_string[i]);
|
||||
EXPECT_EQUAL(io.eof, false);
|
||||
}
|
||||
ch = io__get_char(&io);
|
||||
EXPECT_EQUAL(ch, -1);
|
||||
EXPECT_EQUAL(io.eof, true);
|
||||
|
||||
cleanup_test(path, &io);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_get_char(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
size_t j;
|
||||
|
||||
static const char *const test_strings[] = {
|
||||
"12345678abcdef90",
|
||||
"a\nb\nc\nd\n",
|
||||
"\a\b\t\v\f\r",
|
||||
};
|
||||
for (i = 0; i <= 10; i++) {
|
||||
for (j = 0; j < ARRAY_SIZE(test_strings); j++) {
|
||||
if (do_test_get_char(test_strings[j], 1 << i))
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_test_get_hex(const char *test_string,
|
||||
__u64 val1, int ch1,
|
||||
__u64 val2, int ch2,
|
||||
__u64 val3, int ch3,
|
||||
bool end_eof)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct io io;
|
||||
int ch, ret = 0;
|
||||
__u64 hex;
|
||||
|
||||
if (setup_test(path, test_string, 4, &io))
|
||||
return -1;
|
||||
|
||||
ch = io__get_hex(&io, &hex);
|
||||
EXPECT_EQUAL64(hex, val1);
|
||||
EXPECT_EQUAL(ch, ch1);
|
||||
|
||||
ch = io__get_hex(&io, &hex);
|
||||
EXPECT_EQUAL64(hex, val2);
|
||||
EXPECT_EQUAL(ch, ch2);
|
||||
|
||||
ch = io__get_hex(&io, &hex);
|
||||
EXPECT_EQUAL64(hex, val3);
|
||||
EXPECT_EQUAL(ch, ch3);
|
||||
|
||||
EXPECT_EQUAL(io.eof, end_eof);
|
||||
|
||||
cleanup_test(path, &io);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_get_hex(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (do_test_get_hex("12345678abcdef90",
|
||||
0x12345678abcdef90, -1,
|
||||
0, -1,
|
||||
0, -1,
|
||||
true))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_hex("1\n2\n3\n",
|
||||
1, '\n',
|
||||
2, '\n',
|
||||
3, '\n',
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_hex("12345678ABCDEF90;a;b",
|
||||
0x12345678abcdef90, ';',
|
||||
0xa, ';',
|
||||
0xb, -1,
|
||||
true))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_hex("0x1x2x",
|
||||
0, 'x',
|
||||
1, 'x',
|
||||
2, 'x',
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_hex("x1x",
|
||||
0, -2,
|
||||
1, 'x',
|
||||
0, -1,
|
||||
true))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_hex("10000000000000000000000000000abcdefgh99i",
|
||||
0xabcdef, 'g',
|
||||
0, -2,
|
||||
0x99, 'i',
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_test_get_dec(const char *test_string,
|
||||
__u64 val1, int ch1,
|
||||
__u64 val2, int ch2,
|
||||
__u64 val3, int ch3,
|
||||
bool end_eof)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
struct io io;
|
||||
int ch, ret = 0;
|
||||
__u64 dec;
|
||||
|
||||
if (setup_test(path, test_string, 4, &io))
|
||||
return -1;
|
||||
|
||||
ch = io__get_dec(&io, &dec);
|
||||
EXPECT_EQUAL64(dec, val1);
|
||||
EXPECT_EQUAL(ch, ch1);
|
||||
|
||||
ch = io__get_dec(&io, &dec);
|
||||
EXPECT_EQUAL64(dec, val2);
|
||||
EXPECT_EQUAL(ch, ch2);
|
||||
|
||||
ch = io__get_dec(&io, &dec);
|
||||
EXPECT_EQUAL64(dec, val3);
|
||||
EXPECT_EQUAL(ch, ch3);
|
||||
|
||||
EXPECT_EQUAL(io.eof, end_eof);
|
||||
|
||||
cleanup_test(path, &io);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int test_get_dec(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (do_test_get_dec("12345678abcdef90",
|
||||
12345678, 'a',
|
||||
0, -2,
|
||||
0, -2,
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_dec("1\n2\n3\n",
|
||||
1, '\n',
|
||||
2, '\n',
|
||||
3, '\n',
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_dec("12345678;1;2",
|
||||
12345678, ';',
|
||||
1, ';',
|
||||
2, -1,
|
||||
true))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_dec("0x1x2x",
|
||||
0, 'x',
|
||||
1, 'x',
|
||||
2, 'x',
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_dec("x1x",
|
||||
0, -2,
|
||||
1, 'x',
|
||||
0, -1,
|
||||
true))
|
||||
ret = -1;
|
||||
|
||||
if (do_test_get_dec("10000000000000000000000000000000000000000000000000000000000123456789ab99c",
|
||||
123456789, 'a',
|
||||
0, -2,
|
||||
99, 'c',
|
||||
false))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int test__api_io(struct test *test __maybe_unused,
|
||||
int subtest __maybe_unused)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (test_get_char())
|
||||
ret = TEST_FAIL;
|
||||
if (test_get_hex())
|
||||
ret = TEST_FAIL;
|
||||
if (test_get_dec())
|
||||
ret = TEST_FAIL;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -309,6 +309,10 @@ static struct test generic_tests[] = {
|
|||
.desc = "Test jit_write_elf",
|
||||
.func = test__jit_write_elf,
|
||||
},
|
||||
{
|
||||
.desc = "Test api io",
|
||||
.func = test__api_io,
|
||||
},
|
||||
{
|
||||
.desc = "maps__merge_in",
|
||||
.func = test__maps__merge_in,
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ static int attach__current_disabled(struct evlist *evlist)
|
|||
|
||||
evsel->core.attr.disabled = 1;
|
||||
|
||||
err = perf_evsel__open_per_thread(evsel, threads);
|
||||
err = evsel__open_per_thread(evsel, threads);
|
||||
if (err) {
|
||||
pr_debug("Failed to open event cpu-clock:u\n");
|
||||
return err;
|
||||
|
|
@ -96,7 +96,7 @@ static int attach__current_enabled(struct evlist *evlist)
|
|||
return -1;
|
||||
}
|
||||
|
||||
err = perf_evsel__open_per_thread(evsel, threads);
|
||||
err = evsel__open_per_thread(evsel, threads);
|
||||
|
||||
perf_thread_map__put(threads);
|
||||
return err == 0 ? TEST_OK : TEST_FAIL;
|
||||
|
|
@ -125,7 +125,7 @@ static int attach__cpu_disabled(struct evlist *evlist)
|
|||
|
||||
evsel->core.attr.disabled = 1;
|
||||
|
||||
err = perf_evsel__open_per_cpu(evsel, cpus, -1);
|
||||
err = evsel__open_per_cpu(evsel, cpus, -1);
|
||||
if (err) {
|
||||
if (err == -EACCES)
|
||||
return TEST_SKIP;
|
||||
|
|
@ -152,7 +152,7 @@ static int attach__cpu_enabled(struct evlist *evlist)
|
|||
return -1;
|
||||
}
|
||||
|
||||
err = perf_evsel__open_per_cpu(evsel, cpus, -1);
|
||||
err = evsel__open_per_cpu(evsel, cpus, -1);
|
||||
if (err == -EACCES)
|
||||
return TEST_SKIP;
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu
|
|||
TEST_ASSERT_VAL("failed to synthesize attr update scale",
|
||||
!perf_event__synthesize_event_update_scale(NULL, evsel, process_event_scale));
|
||||
|
||||
tmp.name = perf_evsel__name(evsel);
|
||||
tmp.name = evsel__name(evsel);
|
||||
|
||||
TEST_ASSERT_VAL("failed to synthesize attr update name",
|
||||
!perf_event__synthesize_event_update_name(&tmp.tool, evsel, process_event_name));
|
||||
|
|
|
|||
|
|
@ -20,12 +20,11 @@ static int perf_evsel__roundtrip_cache_name_test(void)
|
|||
for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
|
||||
for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
|
||||
/* skip invalid cache type */
|
||||
if (!perf_evsel__is_cache_op_valid(type, op))
|
||||
if (!evsel__is_cache_op_valid(type, op))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
|
||||
__perf_evsel__hw_cache_type_op_res_name(type, op, i,
|
||||
name, sizeof(name));
|
||||
__evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
|
||||
err = parse_events(evlist, name, NULL);
|
||||
if (err)
|
||||
ret = err;
|
||||
|
|
@ -39,23 +38,22 @@ static int perf_evsel__roundtrip_cache_name_test(void)
|
|||
for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
|
||||
for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
|
||||
/* skip invalid cache type */
|
||||
if (!perf_evsel__is_cache_op_valid(type, op))
|
||||
if (!evsel__is_cache_op_valid(type, op))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
|
||||
__perf_evsel__hw_cache_type_op_res_name(type, op, i,
|
||||
name, sizeof(name));
|
||||
__evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
|
||||
if (evsel->idx != idx)
|
||||
continue;
|
||||
|
||||
++idx;
|
||||
|
||||
if (strcmp(perf_evsel__name(evsel), name)) {
|
||||
pr_debug("%s != %s\n", perf_evsel__name(evsel), name);
|
||||
if (strcmp(evsel__name(evsel), name)) {
|
||||
pr_debug("%s != %s\n", evsel__name(evsel), name);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -84,9 +82,9 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names)
|
|||
|
||||
err = 0;
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) {
|
||||
if (strcmp(evsel__name(evsel), names[evsel->idx])) {
|
||||
--err;
|
||||
pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]);
|
||||
pr_debug("%s != %s\n", evsel__name(evsel), names[evsel->idx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
static int perf_evsel__test_field(struct evsel *evsel, const char *name,
|
||||
int size, bool should_be_signed)
|
||||
{
|
||||
struct tep_format_field *field = perf_evsel__field(evsel, name);
|
||||
struct tep_format_field *field = evsel__field(evsel, name);
|
||||
int is_signed;
|
||||
int ret = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2)
|
|||
{
|
||||
double val;
|
||||
|
||||
if (expr__parse(&val, ctx, e))
|
||||
if (expr__parse(&val, ctx, e, 1))
|
||||
TEST_ASSERT_VAL("parse test failed", 0);
|
||||
TEST_ASSERT_VAL("unexpected value", val == val2);
|
||||
return 0;
|
||||
|
|
@ -44,21 +44,29 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused)
|
|||
return ret;
|
||||
|
||||
p = "FOO/0";
|
||||
ret = expr__parse(&val, &ctx, p);
|
||||
ret = expr__parse(&val, &ctx, p, 1);
|
||||
TEST_ASSERT_VAL("division by zero", ret == -1);
|
||||
|
||||
p = "BAR/";
|
||||
ret = expr__parse(&val, &ctx, p);
|
||||
ret = expr__parse(&val, &ctx, p, 1);
|
||||
TEST_ASSERT_VAL("missing operand", ret == -1);
|
||||
|
||||
TEST_ASSERT_VAL("find other",
|
||||
expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other) == 0);
|
||||
expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", &other, &num_other, 1) == 0);
|
||||
TEST_ASSERT_VAL("find other", num_other == 3);
|
||||
TEST_ASSERT_VAL("find other", !strcmp(other[0], "BAR"));
|
||||
TEST_ASSERT_VAL("find other", !strcmp(other[1], "BAZ"));
|
||||
TEST_ASSERT_VAL("find other", !strcmp(other[2], "BOZO"));
|
||||
TEST_ASSERT_VAL("find other", other[3] == NULL);
|
||||
|
||||
TEST_ASSERT_VAL("find other",
|
||||
expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@", NULL,
|
||||
&other, &num_other, 3) == 0);
|
||||
TEST_ASSERT_VAL("find other", num_other == 2);
|
||||
TEST_ASSERT_VAL("find other", !strcmp(other[0], "EVENT1,param=3/"));
|
||||
TEST_ASSERT_VAL("find other", !strcmp(other[1], "EVENT2,param=3/"));
|
||||
TEST_ASSERT_VAL("find other", other[2] == NULL);
|
||||
|
||||
for (i = 0; i < num_other; i++)
|
||||
zfree(&other[i]);
|
||||
free((void *)other);
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ static int test1(struct evsel *evsel, struct machine *machine)
|
|||
|
||||
symbol_conf.use_callchain = false;
|
||||
symbol_conf.cumulate_callchain = false;
|
||||
perf_evsel__reset_sample_bit(evsel, CALLCHAIN);
|
||||
evsel__reset_sample_bit(evsel, CALLCHAIN);
|
||||
|
||||
setup_sorting(NULL);
|
||||
callchain_register_param(&callchain_param);
|
||||
|
|
@ -427,7 +427,7 @@ static int test2(struct evsel *evsel, struct machine *machine)
|
|||
|
||||
symbol_conf.use_callchain = true;
|
||||
symbol_conf.cumulate_callchain = false;
|
||||
perf_evsel__set_sample_bit(evsel, CALLCHAIN);
|
||||
evsel__set_sample_bit(evsel, CALLCHAIN);
|
||||
|
||||
setup_sorting(NULL);
|
||||
callchain_register_param(&callchain_param);
|
||||
|
|
@ -485,7 +485,7 @@ static int test3(struct evsel *evsel, struct machine *machine)
|
|||
|
||||
symbol_conf.use_callchain = false;
|
||||
symbol_conf.cumulate_callchain = true;
|
||||
perf_evsel__reset_sample_bit(evsel, CALLCHAIN);
|
||||
evsel__reset_sample_bit(evsel, CALLCHAIN);
|
||||
|
||||
setup_sorting(NULL);
|
||||
callchain_register_param(&callchain_param);
|
||||
|
|
@ -669,7 +669,7 @@ static int test4(struct evsel *evsel, struct machine *machine)
|
|||
|
||||
symbol_conf.use_callchain = true;
|
||||
symbol_conf.cumulate_callchain = true;
|
||||
perf_evsel__set_sample_bit(evsel, CALLCHAIN);
|
||||
evsel__set_sample_bit(evsel, CALLCHAIN);
|
||||
|
||||
setup_sorting(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
|
|||
}
|
||||
|
||||
evsels[i]->core.attr.wakeup_events = 1;
|
||||
perf_evsel__set_sample_id(evsels[i], false);
|
||||
evsel__set_sample_id(evsels[i], false);
|
||||
|
||||
evlist__add(evlist, evsels[i]);
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
|
|||
if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
|
||||
pr_debug("expected %d %s events, got %d\n",
|
||||
expected_nr_events[evsel->idx],
|
||||
perf_evsel__name(evsel), nr_events[evsel->idx]);
|
||||
evsel__name(evsel), nr_events[evsel->idx]);
|
||||
err = -1;
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,15 +103,15 @@ int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int
|
|||
if (cpus->map[cpu] >= CPU_SETSIZE)
|
||||
continue;
|
||||
|
||||
if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
|
||||
pr_debug("perf_evsel__read_on_cpu\n");
|
||||
if (evsel__read_on_cpu(evsel, cpu, 0) < 0) {
|
||||
pr_debug("evsel__read_on_cpu\n");
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
expected = nr_openat_calls + cpu;
|
||||
if (perf_counts(evsel->counts, cpu, 0)->val != expected) {
|
||||
pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
|
||||
pr_debug("evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
|
||||
expected, cpus->map[cpu], perf_counts(evsel->counts, cpu, 0)->val);
|
||||
err = -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest
|
|||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
perf_evsel__config(evsel, &opts, NULL);
|
||||
evsel__config(evsel, &opts, NULL);
|
||||
|
||||
perf_thread_map__set_pid(evlist->core.threads, 0, getpid());
|
||||
|
||||
|
|
@ -108,13 +108,13 @@ int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest
|
|||
continue;
|
||||
}
|
||||
|
||||
err = perf_evsel__parse_sample(evsel, event, &sample);
|
||||
err = evsel__parse_sample(evsel, event, &sample);
|
||||
if (err) {
|
||||
pr_debug("Can't parse sample, err = %d\n", err);
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
tp_flags = perf_evsel__intval(evsel, &sample, "flags");
|
||||
tp_flags = evsel__intval(evsel, &sample, "flags");
|
||||
|
||||
if (flags != tp_flags) {
|
||||
pr_debug("%s: Expected flags=%#x, got %#x\n",
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __m
|
|||
goto out_thread_map_delete;
|
||||
}
|
||||
|
||||
if (perf_evsel__open_per_thread(evsel, threads) < 0) {
|
||||
if (evsel__open_per_thread(evsel, threads) < 0) {
|
||||
pr_debug("failed to open counter: %s, "
|
||||
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
|
||||
str_error_r(errno, sbuf, sizeof(sbuf)));
|
||||
|
|
@ -46,13 +46,13 @@ int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __m
|
|||
close(fd);
|
||||
}
|
||||
|
||||
if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
|
||||
pr_debug("perf_evsel__read_on_cpu\n");
|
||||
if (evsel__read_on_cpu(evsel, 0, 0) < 0) {
|
||||
pr_debug("evsel__read_on_cpu\n");
|
||||
goto out_close_fd;
|
||||
}
|
||||
|
||||
if (perf_counts(evsel->counts, 0, 0)->val != nr_openat_calls) {
|
||||
pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
|
||||
pr_debug("evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
|
||||
nr_openat_calls, perf_counts(evsel->counts, 0, 0)->val);
|
||||
goto out_close_fd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ static int test__checkevent_breakpoint_modifier(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong name",
|
||||
!strcmp(perf_evsel__name(evsel), "mem:0:u"));
|
||||
!strcmp(evsel__name(evsel), "mem:0:u"));
|
||||
|
||||
return test__checkevent_breakpoint(evlist);
|
||||
}
|
||||
|
|
@ -385,7 +385,7 @@ static int test__checkevent_breakpoint_x_modifier(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong name",
|
||||
!strcmp(perf_evsel__name(evsel), "mem:0:x:k"));
|
||||
!strcmp(evsel__name(evsel), "mem:0:x:k"));
|
||||
|
||||
return test__checkevent_breakpoint_x(evlist);
|
||||
}
|
||||
|
|
@ -399,7 +399,7 @@ static int test__checkevent_breakpoint_r_modifier(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->core.attr.exclude_hv);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong name",
|
||||
!strcmp(perf_evsel__name(evsel), "mem:0:r:hp"));
|
||||
!strcmp(evsel__name(evsel), "mem:0:r:hp"));
|
||||
|
||||
return test__checkevent_breakpoint_r(evlist);
|
||||
}
|
||||
|
|
@ -413,7 +413,7 @@ static int test__checkevent_breakpoint_w_modifier(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong name",
|
||||
!strcmp(perf_evsel__name(evsel), "mem:0:w:up"));
|
||||
!strcmp(evsel__name(evsel), "mem:0:w:up"));
|
||||
|
||||
return test__checkevent_breakpoint_w(evlist);
|
||||
}
|
||||
|
|
@ -427,7 +427,7 @@ static int test__checkevent_breakpoint_rw_modifier(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude_hv", evsel->core.attr.exclude_hv);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong name",
|
||||
!strcmp(perf_evsel__name(evsel), "mem:0:rw:kp"));
|
||||
!strcmp(evsel__name(evsel), "mem:0:rw:kp"));
|
||||
|
||||
return test__checkevent_breakpoint_rw(evlist);
|
||||
}
|
||||
|
|
@ -468,7 +468,7 @@ static int test__checkevent_list(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
|
||||
/* syscalls:sys_enter_openat:k */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong sample_type",
|
||||
PERF_TP_SAMPLE_TYPE == evsel->core.attr.sample_type);
|
||||
|
|
@ -479,7 +479,7 @@ static int test__checkevent_list(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
|
||||
/* 1:1:hp */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", 1 == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config);
|
||||
TEST_ASSERT_VAL("wrong exclude_user", evsel->core.attr.exclude_user);
|
||||
|
|
@ -498,15 +498,15 @@ static int test__checkevent_pmu_name(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config", 1 == evsel->core.attr.config);
|
||||
TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava"));
|
||||
TEST_ASSERT_VAL("wrong name", !strcmp(evsel__name(evsel), "krava"));
|
||||
|
||||
/* cpu/config=2/u" */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config", 2 == evsel->core.attr.config);
|
||||
TEST_ASSERT_VAL("wrong name",
|
||||
!strcmp(perf_evsel__name(evsel), "cpu/config=2/u"));
|
||||
!strcmp(evsel__name(evsel), "cpu/config=2/u"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -529,7 +529,7 @@ static int test__checkevent_pmu_partial_time_callgraph(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong time", !(PERF_SAMPLE_TIME & evsel->core.attr.sample_type));
|
||||
|
||||
/* cpu/config=2,call-graph=no,time=0,period=2000/ */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config", 2 == evsel->core.attr.config);
|
||||
/*
|
||||
|
|
@ -577,7 +577,7 @@ static int test__checkevent_pmu_events_mix(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned);
|
||||
|
||||
/* cpu/pmu-event/u*/
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong exclude_user",
|
||||
|
|
@ -652,13 +652,13 @@ static int test__group1(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* cycles:upp */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
|
||||
|
|
@ -670,7 +670,7 @@ static int test__group1(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 2);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
return 0;
|
||||
|
|
@ -694,13 +694,13 @@ static int test__group2(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* cache-references + :u modifier */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_REFERENCES == evsel->core.attr.config);
|
||||
|
|
@ -711,11 +711,11 @@ static int test__group2(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* cycles:k */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
|
||||
|
|
@ -725,7 +725,7 @@ static int test__group2(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
return 0;
|
||||
|
|
@ -750,15 +750,15 @@ static int test__group3(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong group name",
|
||||
!strcmp(leader->group_name, "group1"));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* group1 cycles:kppp */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
|
||||
|
|
@ -771,11 +771,11 @@ static int test__group3(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 3);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* group2 cycles + G modifier */
|
||||
evsel = leader = perf_evsel__next(evsel);
|
||||
evsel = leader = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
|
||||
|
|
@ -785,15 +785,15 @@ static int test__group3(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong group name",
|
||||
!strcmp(leader->group_name, "group2"));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* group2 1:3 + G modifier */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", 1 == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config", 3 == evsel->core.attr.config);
|
||||
TEST_ASSERT_VAL("wrong exclude_user", !evsel->core.attr.exclude_user);
|
||||
|
|
@ -803,11 +803,11 @@ static int test__group3(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* instructions:u */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config);
|
||||
|
|
@ -817,7 +817,7 @@ static int test__group3(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", !evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
return 0;
|
||||
|
|
@ -843,13 +843,13 @@ static int test__group4(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 1);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* instructions:kp + p */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config);
|
||||
|
|
@ -861,7 +861,7 @@ static int test__group4(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", evsel->core.attr.precise_ip == 2);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
return 0;
|
||||
|
|
@ -886,13 +886,13 @@ static int test__group5(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* instructions + G */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config);
|
||||
|
|
@ -903,11 +903,11 @@ static int test__group5(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* cycles:G */
|
||||
evsel = leader = perf_evsel__next(evsel);
|
||||
evsel = leader = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
|
||||
|
|
@ -918,13 +918,13 @@ static int test__group5(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
|
||||
|
||||
/* instructions:G */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_INSTRUCTIONS == evsel->core.attr.config);
|
||||
|
|
@ -935,10 +935,10 @@ static int test__group5(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
|
||||
/* cycles */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CPU_CYCLES == evsel->core.attr.config);
|
||||
|
|
@ -948,7 +948,7 @@ static int test__group5(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong exclude guest", evsel->core.attr.exclude_guest);
|
||||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -972,12 +972,12 @@ static int test__group_gh1(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
|
||||
/* cache-misses:G + :H group modifier */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -988,7 +988,7 @@ static int test__group_gh1(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1012,12 +1012,12 @@ static int test__group_gh2(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
|
||||
/* cache-misses:H + :G group modifier */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -1028,7 +1028,7 @@ static int test__group_gh2(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1052,12 +1052,12 @@ static int test__group_gh3(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
|
||||
/* cache-misses:H + :u group modifier */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -1068,7 +1068,7 @@ static int test__group_gh3(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1092,12 +1092,12 @@ static int test__group_gh4(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
||||
TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong leader", evsel__is_group_leader(evsel));
|
||||
TEST_ASSERT_VAL("wrong core.nr_members", evsel->core.nr_members == 2);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 0);
|
||||
|
||||
/* cache-misses:H + :uG group modifier */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -1108,7 +1108,7 @@ static int test__group_gh4(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong exclude host", !evsel->core.attr.exclude_host);
|
||||
TEST_ASSERT_VAL("wrong precise_ip", !evsel->core.attr.precise_ip);
|
||||
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
||||
TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
|
||||
TEST_ASSERT_VAL("wrong group_idx", evsel__group_idx(evsel) == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1135,7 +1135,7 @@ static int test__leader_sample1(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
|
||||
|
||||
/* cache-misses - not sampling */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -1149,7 +1149,7 @@ static int test__leader_sample1(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
|
||||
|
||||
/* branch-misses - not sampling */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -1188,7 +1188,7 @@ static int test__leader_sample2(struct evlist *evlist __maybe_unused)
|
|||
TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
|
||||
|
||||
/* branch-misses - not sampling */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config);
|
||||
|
|
@ -1234,14 +1234,14 @@ static int test__pinned_group(struct evlist *evlist)
|
|||
TEST_ASSERT_VAL("wrong pinned", evsel->core.attr.pinned);
|
||||
|
||||
/* cache-misses - can not be pinned, but will go on with the leader */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->core.attr.type);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_CACHE_MISSES == evsel->core.attr.config);
|
||||
TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned);
|
||||
|
||||
/* branch-misses - ditto */
|
||||
evsel = perf_evsel__next(evsel);
|
||||
evsel = evsel__next(evsel);
|
||||
TEST_ASSERT_VAL("wrong config",
|
||||
PERF_COUNT_HW_BRANCH_MISSES == evsel->core.attr.config);
|
||||
TEST_ASSERT_VAL("wrong pinned", !evsel->core.attr.pinned);
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unus
|
|||
* Config the evsels, setting attr->comm on the first one, etc.
|
||||
*/
|
||||
evsel = evlist__first(evlist);
|
||||
perf_evsel__set_sample_bit(evsel, CPU);
|
||||
perf_evsel__set_sample_bit(evsel, TID);
|
||||
perf_evsel__set_sample_bit(evsel, TIME);
|
||||
evsel__set_sample_bit(evsel, CPU);
|
||||
evsel__set_sample_bit(evsel, TID);
|
||||
evsel__set_sample_bit(evsel, TIME);
|
||||
perf_evlist__config(evlist, &opts, NULL);
|
||||
|
||||
err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
|
||||
|
|
|
|||
|
|
@ -296,12 +296,12 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
evsel.sample_size = __perf_evsel__sample_size(sample_type);
|
||||
evsel.sample_size = __evsel__sample_size(sample_type);
|
||||
|
||||
err = perf_evsel__parse_sample(&evsel, event, &sample_out);
|
||||
err = evsel__parse_sample(&evsel, event, &sample_out);
|
||||
if (err) {
|
||||
pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
|
||||
"perf_evsel__parse_sample", sample_type, err);
|
||||
"evsel__parse_sample", sample_type, err);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,8 +135,8 @@ static int process_sample_event(struct evlist *evlist,
|
|||
|
||||
evsel = perf_evlist__id2evsel(evlist, sample.id);
|
||||
if (evsel == switch_tracking->switch_evsel) {
|
||||
next_tid = perf_evsel__intval(evsel, &sample, "next_pid");
|
||||
prev_tid = perf_evsel__intval(evsel, &sample, "prev_pid");
|
||||
next_tid = evsel__intval(evsel, &sample, "next_pid");
|
||||
prev_tid = evsel__intval(evsel, &sample, "prev_pid");
|
||||
cpu = sample.cpu;
|
||||
pr_debug3("sched_switch: cpu: %d prev_tid %d next_tid %d\n",
|
||||
cpu, prev_tid, next_tid);
|
||||
|
|
@ -394,8 +394,8 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
|
|||
|
||||
switch_evsel = evlist__last(evlist);
|
||||
|
||||
perf_evsel__set_sample_bit(switch_evsel, CPU);
|
||||
perf_evsel__set_sample_bit(switch_evsel, TIME);
|
||||
evsel__set_sample_bit(switch_evsel, CPU);
|
||||
evsel__set_sample_bit(switch_evsel, TIME);
|
||||
|
||||
switch_evsel->core.system_wide = true;
|
||||
switch_evsel->no_aux_samples = true;
|
||||
|
|
@ -412,8 +412,8 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
|
|||
goto out_err;
|
||||
}
|
||||
|
||||
perf_evsel__set_sample_bit(cycles_evsel, CPU);
|
||||
perf_evsel__set_sample_bit(cycles_evsel, TIME);
|
||||
evsel__set_sample_bit(cycles_evsel, CPU);
|
||||
evsel__set_sample_bit(cycles_evsel, TIME);
|
||||
|
||||
/* Fourth event */
|
||||
err = parse_events(evlist, "dummy:u", NULL);
|
||||
|
|
@ -429,7 +429,7 @@ int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_
|
|||
tracking_evsel->core.attr.freq = 0;
|
||||
tracking_evsel->core.attr.sample_period = 1;
|
||||
|
||||
perf_evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
evsel__set_sample_bit(tracking_evsel, TIME);
|
||||
|
||||
/* Config events */
|
||||
perf_evlist__config(evlist, &opts, NULL);
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ int test__mem2node(struct test *t, int subtest);
|
|||
int test__maps__merge_in(struct test *t, int subtest);
|
||||
int test__time_utils(struct test *t, int subtest);
|
||||
int test__jit_write_elf(struct test *test, int subtest);
|
||||
int test__api_io(struct test *test, int subtest);
|
||||
|
||||
bool test__bp_signal_is_supported(void);
|
||||
bool test__bp_account_is_supported(void);
|
||||
|
|
|
|||
|
|
@ -33,10 +33,8 @@ static int session_write_header(char *path)
|
|||
{
|
||||
struct perf_session *session;
|
||||
struct perf_data data = {
|
||||
.file = {
|
||||
.path = path,
|
||||
},
|
||||
.mode = PERF_DATA_MODE_WRITE,
|
||||
.path = path,
|
||||
.mode = PERF_DATA_MODE_WRITE,
|
||||
};
|
||||
|
||||
session = perf_session__new(&data, false, NULL);
|
||||
|
|
@ -63,10 +61,8 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
|
|||
{
|
||||
struct perf_session *session;
|
||||
struct perf_data data = {
|
||||
.file = {
|
||||
.path = path,
|
||||
},
|
||||
.mode = PERF_DATA_MODE_READ,
|
||||
.path = path,
|
||||
.mode = PERF_DATA_MODE_READ,
|
||||
};
|
||||
int i;
|
||||
|
||||
|
|
|
|||
|
|
@ -3416,7 +3416,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
|
|||
struct hists *hists = evsel__hists(evsel);
|
||||
bool current_entry = ui_browser__is_current_entry(browser, row);
|
||||
unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
|
||||
const char *ev_name = perf_evsel__name(evsel);
|
||||
const char *ev_name = evsel__name(evsel);
|
||||
char bf[256], unit;
|
||||
const char *warn = " ";
|
||||
size_t printed;
|
||||
|
|
@ -3424,10 +3424,10 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
|
|||
ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
|
||||
HE_COLORSET_NORMAL);
|
||||
|
||||
if (perf_evsel__is_group_event(evsel)) {
|
||||
if (evsel__is_group_event(evsel)) {
|
||||
struct evsel *pos;
|
||||
|
||||
ev_name = perf_evsel__group_name(evsel);
|
||||
ev_name = evsel__group_name(evsel);
|
||||
|
||||
for_each_group_member(pos, evsel) {
|
||||
struct hists *pos_hists = evsel__hists(pos);
|
||||
|
|
@ -3512,13 +3512,13 @@ static int perf_evsel_menu__run(struct evsel_menu *menu,
|
|||
if (pos->core.node.next == &evlist->core.entries)
|
||||
pos = evlist__first(evlist);
|
||||
else
|
||||
pos = perf_evsel__next(pos);
|
||||
pos = evsel__next(pos);
|
||||
goto browse_hists;
|
||||
case K_UNTAB:
|
||||
if (pos->core.node.prev == &evlist->core.entries)
|
||||
pos = evlist__last(evlist);
|
||||
else
|
||||
pos = perf_evsel__prev(pos);
|
||||
pos = evsel__prev(pos);
|
||||
goto browse_hists;
|
||||
case K_SWITCH_INPUT_DATA:
|
||||
case K_RELOAD:
|
||||
|
|
@ -3554,7 +3554,7 @@ static bool filter_group_entries(struct ui_browser *browser __maybe_unused,
|
|||
{
|
||||
struct evsel *evsel = list_entry(entry, struct evsel, core.node);
|
||||
|
||||
if (symbol_conf.event_group && !perf_evsel__is_group_leader(evsel))
|
||||
if (symbol_conf.event_group && !evsel__is_group_leader(evsel))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -3587,7 +3587,7 @@ static int __perf_evlist__tui_browse_hists(struct evlist *evlist,
|
|||
ui_helpline__push("Press ESC to exit");
|
||||
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
const char *ev_name = perf_evsel__name(pos);
|
||||
const char *ev_name = evsel__name(pos);
|
||||
size_t line_len = strlen(ev_name) + 7;
|
||||
|
||||
if (menu.b.width < line_len)
|
||||
|
|
@ -3622,7 +3622,7 @@ int perf_evlist__tui_browse_hists(struct evlist *evlist, const char *help,
|
|||
|
||||
nr_entries = 0;
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (perf_evsel__is_group_leader(pos))
|
||||
if (evsel__is_group_leader(pos))
|
||||
nr_entries++;
|
||||
}
|
||||
|
||||
|
|
@ -3640,7 +3640,7 @@ static int block_hists_browser__title(struct hist_browser *browser, char *bf,
|
|||
size_t size)
|
||||
{
|
||||
struct hists *hists = evsel__hists(browser->block_evsel);
|
||||
const char *evname = perf_evsel__name(browser->block_evsel);
|
||||
const char *evname = evsel__name(browser->block_evsel);
|
||||
unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
|
||||
int ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct map_symbol *ms,
|
|||
|
||||
gtk_list_store_append(store, &iter);
|
||||
|
||||
if (perf_evsel__is_group_event(evsel)) {
|
||||
if (evsel__is_group_event(evsel)) {
|
||||
for (i = 0; i < evsel->core.nr_members; i++) {
|
||||
ret += perf_gtk__get_percent(s + ret,
|
||||
sizeof(s) - ret,
|
||||
|
|
|
|||
|
|
@ -635,18 +635,18 @@ int perf_evlist__gtk_browse_hists(struct evlist *evlist,
|
|||
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
const char *evname = perf_evsel__name(pos);
|
||||
const char *evname = evsel__name(pos);
|
||||
GtkWidget *scrolled_window;
|
||||
GtkWidget *tab_label;
|
||||
char buf[512];
|
||||
size_t size = sizeof(buf);
|
||||
|
||||
if (symbol_conf.event_group) {
|
||||
if (!perf_evsel__is_group_leader(pos))
|
||||
if (!evsel__is_group_leader(pos))
|
||||
continue;
|
||||
|
||||
if (pos->core.nr_members > 1) {
|
||||
perf_evsel__group_desc(pos, buf, size);
|
||||
evsel__group_desc(pos, buf, size);
|
||||
evname = buf;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,12 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
|
|||
} else
|
||||
ret = hpp__call_print_fn(hpp, print_fn, fmt, len, get_field(he));
|
||||
|
||||
if (perf_evsel__is_group_event(evsel)) {
|
||||
if (evsel__is_group_event(evsel)) {
|
||||
int prev_idx, idx_delta;
|
||||
struct hist_entry *pair;
|
||||
int nr_members = evsel->core.nr_members;
|
||||
|
||||
prev_idx = perf_evsel__group_idx(evsel);
|
||||
prev_idx = evsel__group_idx(evsel);
|
||||
|
||||
list_for_each_entry(pair, &he->pairs.head, pairs.node) {
|
||||
u64 period = get_field(pair);
|
||||
|
|
@ -58,7 +58,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
|
|||
continue;
|
||||
|
||||
evsel = hists_to_evsel(pair->hists);
|
||||
idx_delta = perf_evsel__group_idx(evsel) - prev_idx - 1;
|
||||
idx_delta = evsel__group_idx(evsel) - prev_idx - 1;
|
||||
|
||||
while (idx_delta--) {
|
||||
/*
|
||||
|
|
@ -82,7 +82,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
|
|||
len, period);
|
||||
}
|
||||
|
||||
prev_idx = perf_evsel__group_idx(evsel);
|
||||
prev_idx = evsel__group_idx(evsel);
|
||||
}
|
||||
|
||||
idx_delta = nr_members - prev_idx - 1;
|
||||
|
|
@ -164,12 +164,12 @@ static int hist_entry__new_pair(struct hist_entry *a, struct hist_entry *b,
|
|||
|
||||
list_for_each_entry(pair, &a->pairs.head, pairs.node) {
|
||||
struct evsel *evsel = hists_to_evsel(pair->hists);
|
||||
fa[perf_evsel__group_idx(evsel)] = get_field(pair);
|
||||
fa[evsel__group_idx(evsel)] = get_field(pair);
|
||||
}
|
||||
|
||||
list_for_each_entry(pair, &b->pairs.head, pairs.node) {
|
||||
struct evsel *evsel = hists_to_evsel(pair->hists);
|
||||
fb[perf_evsel__group_idx(evsel)] = get_field(pair);
|
||||
fb[evsel__group_idx(evsel)] = get_field(pair);
|
||||
}
|
||||
|
||||
*fields_a = fa;
|
||||
|
|
@ -190,7 +190,7 @@ static int __hpp__group_sort_idx(struct hist_entry *a, struct hist_entry *b,
|
|||
int cmp, nr_members, ret, i;
|
||||
|
||||
cmp = field_cmp(get_field(a), get_field(b));
|
||||
if (!perf_evsel__is_group_event(evsel))
|
||||
if (!evsel__is_group_event(evsel))
|
||||
return cmp;
|
||||
|
||||
nr_members = evsel->core.nr_members;
|
||||
|
|
@ -240,7 +240,7 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b,
|
|||
return ret;
|
||||
|
||||
evsel = hists_to_evsel(a->hists);
|
||||
if (!perf_evsel__is_group_event(evsel))
|
||||
if (!evsel__is_group_event(evsel))
|
||||
return ret;
|
||||
|
||||
nr_members = evsel->core.nr_members;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ perf-y += db-export.o
|
|||
perf-y += env.o
|
||||
perf-y += event.o
|
||||
perf-y += evlist.o
|
||||
perf-y += sideband_evlist.o
|
||||
perf-y += evsel.o
|
||||
perf-y += evsel_fprintf.o
|
||||
perf-y += perf_event_attr_fprintf.o
|
||||
|
|
@ -88,6 +89,7 @@ perf-y += counts.o
|
|||
perf-y += stat.o
|
||||
perf-y += stat-shadow.o
|
||||
perf-y += stat-display.o
|
||||
perf-y += perf_api_probe.o
|
||||
perf-y += record.o
|
||||
perf-y += srcline.o
|
||||
perf-y += srccode.o
|
||||
|
|
|
|||
|
|
@ -1191,7 +1191,7 @@ static struct disasm_line *disasm_line__new(struct annotate_args *args)
|
|||
struct disasm_line *dl = NULL;
|
||||
int nr = 1;
|
||||
|
||||
if (perf_evsel__is_group_event(args->evsel))
|
||||
if (evsel__is_group_event(args->evsel))
|
||||
nr = args->evsel->core.nr_members;
|
||||
|
||||
dl = zalloc(disasm_line_size(nr));
|
||||
|
|
@ -1437,7 +1437,7 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start
|
|||
if (queue)
|
||||
return -1;
|
||||
|
||||
if (perf_evsel__is_group_event(evsel))
|
||||
if (evsel__is_group_event(evsel))
|
||||
width *= evsel->core.nr_members;
|
||||
|
||||
if (!*al->line)
|
||||
|
|
@ -2156,7 +2156,7 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel,
|
|||
.evsel = evsel,
|
||||
.options = options,
|
||||
};
|
||||
struct perf_env *env = perf_evsel__env(evsel);
|
||||
struct perf_env *env = evsel__env(evsel);
|
||||
const char *arch_name = perf_env__arch(env);
|
||||
struct arch *arch;
|
||||
int err;
|
||||
|
|
@ -2344,7 +2344,7 @@ int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel,
|
|||
struct dso *dso = map->dso;
|
||||
char *filename;
|
||||
const char *d_filename;
|
||||
const char *evsel_name = perf_evsel__name(evsel);
|
||||
const char *evsel_name = evsel__name(evsel);
|
||||
struct annotation *notes = symbol__annotation(sym);
|
||||
struct sym_hist *h = annotation__histogram(notes, evsel->idx);
|
||||
struct annotation_line *pos, *queue = NULL;
|
||||
|
|
@ -2368,9 +2368,9 @@ int symbol__annotate_printf(struct map_symbol *ms, struct evsel *evsel,
|
|||
|
||||
len = symbol__size(sym);
|
||||
|
||||
if (perf_evsel__is_group_event(evsel)) {
|
||||
if (evsel__is_group_event(evsel)) {
|
||||
width *= evsel->core.nr_members;
|
||||
perf_evsel__group_desc(evsel, buf, sizeof(buf));
|
||||
evsel__group_desc(evsel, buf, sizeof(buf));
|
||||
evsel_name = buf;
|
||||
}
|
||||
|
||||
|
|
@ -2505,7 +2505,7 @@ static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp,
|
|||
int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel,
|
||||
struct annotation_options *opts)
|
||||
{
|
||||
const char *ev_name = perf_evsel__name(evsel);
|
||||
const char *ev_name = evsel__name(evsel);
|
||||
char buf[1024];
|
||||
char *filename;
|
||||
int err = -1;
|
||||
|
|
@ -2518,8 +2518,8 @@ int map_symbol__annotation_dump(struct map_symbol *ms, struct evsel *evsel,
|
|||
if (fp == NULL)
|
||||
goto out_free_filename;
|
||||
|
||||
if (perf_evsel__is_group_event(evsel)) {
|
||||
perf_evsel__group_desc(evsel, buf, sizeof(buf));
|
||||
if (evsel__is_group_event(evsel)) {
|
||||
evsel__group_desc(evsel, buf, sizeof(buf));
|
||||
ev_name = buf;
|
||||
}
|
||||
|
||||
|
|
@ -3064,7 +3064,7 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
|
|||
if (notes->offsets == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
if (perf_evsel__is_group_event(evsel))
|
||||
if (evsel__is_group_event(evsel))
|
||||
nr_pcnt = evsel->core.nr_members;
|
||||
|
||||
err = symbol__annotate(ms, evsel, options, parch);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "evsel.h"
|
||||
#include "evsel_config.h"
|
||||
#include "symbol.h"
|
||||
#include "util/perf_api_probe.h"
|
||||
#include "util/synthetic-events.h"
|
||||
#include "thread_map.h"
|
||||
#include "asm/bug.h"
|
||||
|
|
@ -69,7 +70,7 @@ static int perf_evlist__regroup(struct evlist *evlist,
|
|||
struct evsel *evsel;
|
||||
bool grp;
|
||||
|
||||
if (!perf_evsel__is_group_leader(leader))
|
||||
if (!evsel__is_group_leader(leader))
|
||||
return -EINVAL;
|
||||
|
||||
grp = false;
|
||||
|
|
@ -684,8 +685,8 @@ static int auxtrace_validate_aux_sample_size(struct evlist *evlist,
|
|||
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
sz = evsel->core.attr.aux_sample_size;
|
||||
if (perf_evsel__is_group_leader(evsel)) {
|
||||
has_aux_leader = perf_evsel__is_aux_event(evsel);
|
||||
if (evsel__is_group_leader(evsel)) {
|
||||
has_aux_leader = evsel__is_aux_event(evsel);
|
||||
if (sz) {
|
||||
if (has_aux_leader)
|
||||
pr_err("Cannot add AUX area sampling to an AUX area event\n");
|
||||
|
|
@ -704,10 +705,10 @@ static int auxtrace_validate_aux_sample_size(struct evlist *evlist,
|
|||
pr_err("Cannot add AUX area sampling because group leader is not an AUX area event\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
perf_evsel__set_sample_bit(evsel, AUX);
|
||||
evsel__set_sample_bit(evsel, AUX);
|
||||
opts->auxtrace_sample_mode = true;
|
||||
} else {
|
||||
perf_evsel__reset_sample_bit(evsel, AUX);
|
||||
evsel__reset_sample_bit(evsel, AUX);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -758,8 +759,8 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr,
|
|||
|
||||
/* Set aux_sample_size based on --aux-sample option */
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (perf_evsel__is_group_leader(evsel)) {
|
||||
has_aux_leader = perf_evsel__is_aux_event(evsel);
|
||||
if (evsel__is_group_leader(evsel)) {
|
||||
has_aux_leader = evsel__is_aux_event(evsel);
|
||||
} else if (has_aux_leader) {
|
||||
evsel->core.attr.aux_sample_size = sz;
|
||||
}
|
||||
|
|
@ -768,7 +769,7 @@ int auxtrace_parse_sample_options(struct auxtrace_record *itr,
|
|||
aux_evsel = NULL;
|
||||
/* Override with aux_sample_size from config term */
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (perf_evsel__is_aux_event(evsel))
|
||||
if (evsel__is_aux_event(evsel))
|
||||
aux_evsel = evsel;
|
||||
term = perf_evsel__get_config_term(evsel, AUX_SAMPLE_SIZE);
|
||||
if (term) {
|
||||
|
|
@ -1246,7 +1247,7 @@ static void unleader_auxtrace(struct perf_session *session)
|
|||
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (auxtrace__evsel_is_auxtrace(session, evsel) &&
|
||||
perf_evsel__is_group_leader(evsel)) {
|
||||
evsel__is_group_leader(evsel)) {
|
||||
unleader_evsel(session->evlist, evsel);
|
||||
}
|
||||
}
|
||||
|
|
@ -1463,8 +1464,12 @@ int itrace_parse_synth_opts(const struct option *opt, const char *str,
|
|||
synth_opts->callchain_sz = val;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
case 'l':
|
||||
synth_opts->last_branch = true;
|
||||
if (p[-1] == 'L')
|
||||
synth_opts->add_last_branch = true;
|
||||
else
|
||||
synth_opts->last_branch = true;
|
||||
synth_opts->last_branch_sz =
|
||||
PERF_ITRACE_DEFAULT_LAST_BRANCH_SZ;
|
||||
while (*p == ' ' || *p == ',')
|
||||
|
|
@ -2517,7 +2522,7 @@ static int parse_addr_filter(struct evsel *evsel, const char *filter,
|
|||
goto out_exit;
|
||||
}
|
||||
|
||||
if (perf_evsel__append_addr_filter(evsel, new_filter)) {
|
||||
if (evsel__append_addr_filter(evsel, new_filter)) {
|
||||
err = -ENOMEM;
|
||||
goto out_exit;
|
||||
}
|
||||
|
|
@ -2535,9 +2540,9 @@ static int parse_addr_filter(struct evsel *evsel, const char *filter,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int perf_evsel__nr_addr_filter(struct evsel *evsel)
|
||||
static int evsel__nr_addr_filter(struct evsel *evsel)
|
||||
{
|
||||
struct perf_pmu *pmu = perf_evsel__find_pmu(evsel);
|
||||
struct perf_pmu *pmu = evsel__find_pmu(evsel);
|
||||
int nr_addr_filters = 0;
|
||||
|
||||
if (!pmu)
|
||||
|
|
@ -2556,7 +2561,7 @@ int auxtrace_parse_filters(struct evlist *evlist)
|
|||
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
filter = evsel->filter;
|
||||
max_nr = perf_evsel__nr_addr_filter(evsel);
|
||||
max_nr = evsel__nr_addr_filter(evsel);
|
||||
if (!filter || !max_nr)
|
||||
continue;
|
||||
evsel->filter = NULL;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ enum itrace_period_type {
|
|||
* @add_callchain: add callchain to existing event records
|
||||
* @thread_stack: feed branches to the thread_stack
|
||||
* @last_branch: add branch context to 'instruction' events
|
||||
* @add_last_branch: add branch context to existing event records
|
||||
* @callchain_sz: maximum callchain size
|
||||
* @last_branch_sz: branch context size
|
||||
* @period: 'instructions' events period
|
||||
|
|
@ -105,6 +106,7 @@ struct itrace_synth_opts {
|
|||
bool add_callchain;
|
||||
bool thread_stack;
|
||||
bool last_branch;
|
||||
bool add_last_branch;
|
||||
unsigned int callchain_sz;
|
||||
unsigned int last_branch_sz;
|
||||
unsigned long long period;
|
||||
|
|
|
|||
|
|
@ -509,8 +509,7 @@ static int bpf_event__sb_cb(union perf_event *event, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bpf_event__add_sb_event(struct evlist **evlist,
|
||||
struct perf_env *env)
|
||||
int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env)
|
||||
{
|
||||
struct perf_event_attr attr = {
|
||||
.type = PERF_TYPE_SOFTWARE,
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ struct btf_node {
|
|||
#ifdef HAVE_LIBBPF_SUPPORT
|
||||
int machine__process_bpf(struct machine *machine, union perf_event *event,
|
||||
struct perf_sample *sample);
|
||||
int bpf_event__add_sb_event(struct evlist **evlist,
|
||||
struct perf_env *env);
|
||||
int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env);
|
||||
void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
|
||||
struct perf_env *env,
|
||||
FILE *fp);
|
||||
|
|
@ -46,8 +45,8 @@ static inline int machine__process_bpf(struct machine *machine __maybe_unused,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int bpf_event__add_sb_event(struct evlist **evlist __maybe_unused,
|
||||
struct perf_env *env __maybe_unused)
|
||||
static inline int evlist__add_bpf_sb_event(struct evlist *evlist __maybe_unused,
|
||||
struct perf_env *env __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1430,7 +1430,7 @@ apply_config_evsel_for_key(const char *name, int map_fd, void *pkey,
|
|||
return -BPF_LOADER_ERRNO__OBJCONF_MAP_EVTINH;
|
||||
}
|
||||
|
||||
if (perf_evsel__is_bpf_output(evsel))
|
||||
if (evsel__is_bpf_output(evsel))
|
||||
check_pass = true;
|
||||
if (attr->type == PERF_TYPE_RAW)
|
||||
check_pass = true;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ static int add_cgroup(struct evlist *evlist, const char *str)
|
|||
|
||||
static void cgroup__delete(struct cgroup *cgroup)
|
||||
{
|
||||
close(cgroup->fd);
|
||||
if (cgroup->fd >= 0)
|
||||
close(cgroup->fd);
|
||||
zfree(&cgroup->name);
|
||||
free(cgroup);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ int __weak sched_getcpu(void)
|
|||
|
||||
static int perf_flag_probe(void)
|
||||
{
|
||||
/* use 'safest' configuration as used in perf_evsel__fallback() */
|
||||
/* use 'safest' configuration as used in evsel__fallback() */
|
||||
struct perf_event_attr attr = {
|
||||
.type = PERF_TYPE_SOFTWARE,
|
||||
.config = PERF_COUNT_SW_CPU_CLOCK,
|
||||
|
|
|
|||
|
|
@ -564,6 +564,8 @@ static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
|
|||
resp = cs_etm_decoder__set_tid(etmq, packet_queue,
|
||||
elem, trace_chan_id);
|
||||
break;
|
||||
/* Unused packet types */
|
||||
case OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH:
|
||||
case OCSD_GEN_TRC_ELEM_ADDR_NACC:
|
||||
case OCSD_GEN_TRC_ELEM_CYCLE_COUNT:
|
||||
case OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN:
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ struct cs_etm_queue {
|
|||
struct cs_etm_traceid_queue **traceid_queues;
|
||||
};
|
||||
|
||||
/* RB tree for quick conversion between traceID and metadata pointers */
|
||||
static struct intlist *traceid_list;
|
||||
|
||||
static int cs_etm__update_queues(struct cs_etm_auxtrace *etm);
|
||||
static int cs_etm__process_queues(struct cs_etm_auxtrace *etm);
|
||||
static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm,
|
||||
|
|
|
|||
|
|
@ -114,9 +114,6 @@ enum cs_etm_isa {
|
|||
CS_ETM_ISA_T32,
|
||||
};
|
||||
|
||||
/* RB tree for quick conversion between traceID and metadata pointers */
|
||||
struct intlist *traceid_list;
|
||||
|
||||
struct cs_etm_queue;
|
||||
|
||||
struct cs_etm_packet {
|
||||
|
|
|
|||
|
|
@ -835,7 +835,7 @@ static int process_sample_event(struct perf_tool *tool,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (perf_evsel__is_bpf_output(evsel)) {
|
||||
if (evsel__is_bpf_output(evsel)) {
|
||||
ret = add_bpf_output_values(event_class, event, sample);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
|
@ -1155,7 +1155,7 @@ static int add_event(struct ctf_writer *cw, struct evsel *evsel)
|
|||
{
|
||||
struct bt_ctf_event_class *event_class;
|
||||
struct evsel_priv *priv;
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
const char *name = evsel__name(evsel);
|
||||
int ret;
|
||||
|
||||
pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type);
|
||||
|
|
@ -1174,7 +1174,7 @@ static int add_event(struct ctf_writer *cw, struct evsel *evsel)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (perf_evsel__is_bpf_output(evsel)) {
|
||||
if (evsel__is_bpf_output(evsel)) {
|
||||
ret = add_bpf_output_types(cw, event_class);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -626,7 +626,7 @@ int machine__resolve(struct machine *machine, struct addr_location *al,
|
|||
ret = strlist__has_entry(symbol_conf.sym_list,
|
||||
al->sym->name);
|
||||
}
|
||||
if (!(ret && al->sym)) {
|
||||
if (!ret && al->sym) {
|
||||
snprintf(al_addr_str, sz, "0x%"PRIx64,
|
||||
al->map->unmap_ip(al->map, al->sym->start));
|
||||
ret = strlist__has_entry(symbol_conf.sym_list,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "asm/bug.h"
|
||||
#include "bpf-event.h"
|
||||
#include "util/string2.h"
|
||||
#include "util/perf_api_probe.h"
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
|
|
@ -118,7 +119,7 @@ static void perf_evlist__update_id_pos(struct evlist *evlist)
|
|||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
perf_evsel__calc_id_pos(evsel);
|
||||
evsel__calc_id_pos(evsel);
|
||||
|
||||
perf_evlist__set_id_pos(evlist);
|
||||
}
|
||||
|
|
@ -390,14 +391,14 @@ void evlist__disable(struct evlist *evlist)
|
|||
evlist__for_each_entry(evlist, pos) {
|
||||
if (evsel__cpu_iter_skip(pos, cpu))
|
||||
continue;
|
||||
if (pos->disabled || !perf_evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
if (pos->disabled || !evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
continue;
|
||||
evsel__disable_cpu(pos, pos->cpu_iter - 1);
|
||||
}
|
||||
}
|
||||
affinity__cleanup(&affinity);
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (!perf_evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
if (!evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
continue;
|
||||
pos->disabled = true;
|
||||
}
|
||||
|
|
@ -420,14 +421,14 @@ void evlist__enable(struct evlist *evlist)
|
|||
evlist__for_each_entry(evlist, pos) {
|
||||
if (evsel__cpu_iter_skip(pos, cpu))
|
||||
continue;
|
||||
if (!perf_evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
if (!evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
continue;
|
||||
evsel__enable_cpu(pos, pos->cpu_iter - 1);
|
||||
}
|
||||
}
|
||||
affinity__cleanup(&affinity);
|
||||
evlist__for_each_entry(evlist, pos) {
|
||||
if (!perf_evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
if (!evsel__is_group_leader(pos) || !pos->core.fd)
|
||||
continue;
|
||||
pos->disabled = false;
|
||||
}
|
||||
|
|
@ -947,7 +948,7 @@ void __perf_evlist__set_sample_bit(struct evlist *evlist,
|
|||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
__perf_evsel__set_sample_bit(evsel, bit);
|
||||
__evsel__set_sample_bit(evsel, bit);
|
||||
}
|
||||
|
||||
void __perf_evlist__reset_sample_bit(struct evlist *evlist,
|
||||
|
|
@ -956,7 +957,7 @@ void __perf_evlist__reset_sample_bit(struct evlist *evlist,
|
|||
struct evsel *evsel;
|
||||
|
||||
evlist__for_each_entry(evlist, evsel)
|
||||
__perf_evsel__reset_sample_bit(evsel, bit);
|
||||
__evsel__reset_sample_bit(evsel, bit);
|
||||
}
|
||||
|
||||
int perf_evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel)
|
||||
|
|
@ -994,7 +995,7 @@ int perf_evlist__set_tp_filter(struct evlist *evlist, const char *filter)
|
|||
if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
|
||||
continue;
|
||||
|
||||
err = perf_evsel__set_filter(evsel, filter);
|
||||
err = evsel__set_filter(evsel, filter);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
|
@ -1014,7 +1015,7 @@ int perf_evlist__append_tp_filter(struct evlist *evlist, const char *filter)
|
|||
if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
|
||||
continue;
|
||||
|
||||
err = perf_evsel__append_tp_filter(evsel, filter);
|
||||
err = evsel__append_tp_filter(evsel, filter);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
|
@ -1438,7 +1439,7 @@ int perf_evlist__parse_sample(struct evlist *evlist, union perf_event *event,
|
|||
|
||||
if (!evsel)
|
||||
return -EFAULT;
|
||||
return perf_evsel__parse_sample(evsel, event, sample);
|
||||
return evsel__parse_sample(evsel, event, sample);
|
||||
}
|
||||
|
||||
int perf_evlist__parse_sample_timestamp(struct evlist *evlist,
|
||||
|
|
@ -1449,7 +1450,7 @@ int perf_evlist__parse_sample_timestamp(struct evlist *evlist,
|
|||
|
||||
if (!evsel)
|
||||
return -EFAULT;
|
||||
return perf_evsel__parse_sample_timestamp(evsel, event, timestamp);
|
||||
return evsel__parse_sample_timestamp(evsel, event, timestamp);
|
||||
}
|
||||
|
||||
int perf_evlist__strerror_open(struct evlist *evlist,
|
||||
|
|
@ -1703,133 +1704,3 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list,
|
|||
}
|
||||
return leader;
|
||||
}
|
||||
|
||||
int perf_evlist__add_sb_event(struct evlist **evlist,
|
||||
struct perf_event_attr *attr,
|
||||
perf_evsel__sb_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct evsel *evsel;
|
||||
bool new_evlist = (*evlist) == NULL;
|
||||
|
||||
if (*evlist == NULL)
|
||||
*evlist = evlist__new();
|
||||
if (*evlist == NULL)
|
||||
return -1;
|
||||
|
||||
if (!attr->sample_id_all) {
|
||||
pr_warning("enabling sample_id_all for all side band events\n");
|
||||
attr->sample_id_all = 1;
|
||||
}
|
||||
|
||||
evsel = perf_evsel__new_idx(attr, (*evlist)->core.nr_entries);
|
||||
if (!evsel)
|
||||
goto out_err;
|
||||
|
||||
evsel->side_band.cb = cb;
|
||||
evsel->side_band.data = data;
|
||||
evlist__add(*evlist, evsel);
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
if (new_evlist) {
|
||||
evlist__delete(*evlist);
|
||||
*evlist = NULL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void *perf_evlist__poll_thread(void *arg)
|
||||
{
|
||||
struct evlist *evlist = arg;
|
||||
bool draining = false;
|
||||
int i, done = 0;
|
||||
/*
|
||||
* In order to read symbols from other namespaces perf to needs to call
|
||||
* setns(2). This isn't permitted if the struct_fs has multiple users.
|
||||
* unshare(2) the fs so that we may continue to setns into namespaces
|
||||
* that we're observing when, for instance, reading the build-ids at
|
||||
* the end of a 'perf record' session.
|
||||
*/
|
||||
unshare(CLONE_FS);
|
||||
|
||||
while (!done) {
|
||||
bool got_data = false;
|
||||
|
||||
if (evlist->thread.done)
|
||||
draining = true;
|
||||
|
||||
if (!draining)
|
||||
evlist__poll(evlist, 1000);
|
||||
|
||||
for (i = 0; i < evlist->core.nr_mmaps; i++) {
|
||||
struct mmap *map = &evlist->mmap[i];
|
||||
union perf_event *event;
|
||||
|
||||
if (perf_mmap__read_init(&map->core))
|
||||
continue;
|
||||
while ((event = perf_mmap__read_event(&map->core)) != NULL) {
|
||||
struct evsel *evsel = perf_evlist__event2evsel(evlist, event);
|
||||
|
||||
if (evsel && evsel->side_band.cb)
|
||||
evsel->side_band.cb(event, evsel->side_band.data);
|
||||
else
|
||||
pr_warning("cannot locate proper evsel for the side band event\n");
|
||||
|
||||
perf_mmap__consume(&map->core);
|
||||
got_data = true;
|
||||
}
|
||||
perf_mmap__read_done(&map->core);
|
||||
}
|
||||
|
||||
if (draining && !got_data)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int perf_evlist__start_sb_thread(struct evlist *evlist,
|
||||
struct target *target)
|
||||
{
|
||||
struct evsel *counter;
|
||||
|
||||
if (!evlist)
|
||||
return 0;
|
||||
|
||||
if (perf_evlist__create_maps(evlist, target))
|
||||
goto out_delete_evlist;
|
||||
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
if (evsel__open(counter, evlist->core.cpus,
|
||||
evlist->core.threads) < 0)
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
if (evlist__mmap(evlist, UINT_MAX))
|
||||
goto out_delete_evlist;
|
||||
|
||||
evlist__for_each_entry(evlist, counter) {
|
||||
if (evsel__enable(counter))
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
evlist->thread.done = 0;
|
||||
if (pthread_create(&evlist->thread.th, NULL, perf_evlist__poll_thread, evlist))
|
||||
goto out_delete_evlist;
|
||||
|
||||
return 0;
|
||||
|
||||
out_delete_evlist:
|
||||
evlist__delete(evlist);
|
||||
evlist = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void perf_evlist__stop_sb_thread(struct evlist *evlist)
|
||||
{
|
||||
if (!evlist)
|
||||
return;
|
||||
evlist->thread.done = 1;
|
||||
pthread_join(evlist->thread.th, NULL);
|
||||
evlist__delete(evlist);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,10 +107,11 @@ int __perf_evlist__add_default_attrs(struct evlist *evlist,
|
|||
|
||||
int perf_evlist__add_dummy(struct evlist *evlist);
|
||||
|
||||
int perf_evlist__add_sb_event(struct evlist **evlist,
|
||||
int perf_evlist__add_sb_event(struct evlist *evlist,
|
||||
struct perf_event_attr *attr,
|
||||
perf_evsel__sb_cb_t cb,
|
||||
evsel__sb_cb_t cb,
|
||||
void *data);
|
||||
void evlist__set_cb(struct evlist *evlist, evsel__sb_cb_t cb, void *data);
|
||||
int perf_evlist__start_sb_thread(struct evlist *evlist,
|
||||
struct target *target);
|
||||
void perf_evlist__stop_sb_thread(struct evlist *evlist);
|
||||
|
|
@ -173,10 +174,6 @@ void evlist__close(struct evlist *evlist);
|
|||
struct callchain_param;
|
||||
|
||||
void perf_evlist__set_id_pos(struct evlist *evlist);
|
||||
bool perf_can_sample_identifier(void);
|
||||
bool perf_can_record_switch_events(void);
|
||||
bool perf_can_record_cpu_wide(void);
|
||||
bool perf_can_aux_sample(void);
|
||||
void perf_evlist__config(struct evlist *evlist, struct record_opts *opts,
|
||||
struct callchain_param *callchain);
|
||||
int record_opts__config(struct record_opts *opts);
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ int perf_evsel__object_config(size_t object_size,
|
|||
|
||||
#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y))
|
||||
|
||||
int __perf_evsel__sample_size(u64 sample_type)
|
||||
int __evsel__sample_size(u64 sample_type)
|
||||
{
|
||||
u64 mask = sample_type & PERF_SAMPLE_MASK;
|
||||
int size = 0;
|
||||
|
|
@ -178,53 +178,53 @@ static int __perf_evsel__calc_is_pos(u64 sample_type)
|
|||
return idx;
|
||||
}
|
||||
|
||||
void perf_evsel__calc_id_pos(struct evsel *evsel)
|
||||
void evsel__calc_id_pos(struct evsel *evsel)
|
||||
{
|
||||
evsel->id_pos = __perf_evsel__calc_id_pos(evsel->core.attr.sample_type);
|
||||
evsel->is_pos = __perf_evsel__calc_is_pos(evsel->core.attr.sample_type);
|
||||
}
|
||||
|
||||
void __perf_evsel__set_sample_bit(struct evsel *evsel,
|
||||
void __evsel__set_sample_bit(struct evsel *evsel,
|
||||
enum perf_event_sample_format bit)
|
||||
{
|
||||
if (!(evsel->core.attr.sample_type & bit)) {
|
||||
evsel->core.attr.sample_type |= bit;
|
||||
evsel->sample_size += sizeof(u64);
|
||||
perf_evsel__calc_id_pos(evsel);
|
||||
evsel__calc_id_pos(evsel);
|
||||
}
|
||||
}
|
||||
|
||||
void __perf_evsel__reset_sample_bit(struct evsel *evsel,
|
||||
void __evsel__reset_sample_bit(struct evsel *evsel,
|
||||
enum perf_event_sample_format bit)
|
||||
{
|
||||
if (evsel->core.attr.sample_type & bit) {
|
||||
evsel->core.attr.sample_type &= ~bit;
|
||||
evsel->sample_size -= sizeof(u64);
|
||||
perf_evsel__calc_id_pos(evsel);
|
||||
evsel__calc_id_pos(evsel);
|
||||
}
|
||||
}
|
||||
|
||||
void perf_evsel__set_sample_id(struct evsel *evsel,
|
||||
void evsel__set_sample_id(struct evsel *evsel,
|
||||
bool can_sample_identifier)
|
||||
{
|
||||
if (can_sample_identifier) {
|
||||
perf_evsel__reset_sample_bit(evsel, ID);
|
||||
perf_evsel__set_sample_bit(evsel, IDENTIFIER);
|
||||
evsel__reset_sample_bit(evsel, ID);
|
||||
evsel__set_sample_bit(evsel, IDENTIFIER);
|
||||
} else {
|
||||
perf_evsel__set_sample_bit(evsel, ID);
|
||||
evsel__set_sample_bit(evsel, ID);
|
||||
}
|
||||
evsel->core.attr.read_format |= PERF_FORMAT_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* perf_evsel__is_function_event - Return whether given evsel is a function
|
||||
* evsel__is_function_event - Return whether given evsel is a function
|
||||
* trace event
|
||||
*
|
||||
* @evsel - evsel selector to be tested
|
||||
*
|
||||
* Return %true if event is function trace event
|
||||
*/
|
||||
bool perf_evsel__is_function_event(struct evsel *evsel)
|
||||
bool evsel__is_function_event(struct evsel *evsel)
|
||||
{
|
||||
#define FUNCTION_EVENT "ftrace:function"
|
||||
|
||||
|
|
@ -249,8 +249,8 @@ void evsel__init(struct evsel *evsel,
|
|||
evsel->bpf_fd = -1;
|
||||
INIT_LIST_HEAD(&evsel->config_terms);
|
||||
perf_evsel__object.init(evsel);
|
||||
evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
|
||||
perf_evsel__calc_id_pos(evsel);
|
||||
evsel->sample_size = __evsel__sample_size(attr->sample_type);
|
||||
evsel__calc_id_pos(evsel);
|
||||
evsel->cmdline_group_boundary = false;
|
||||
evsel->metric_expr = NULL;
|
||||
evsel->metric_name = NULL;
|
||||
|
|
@ -267,13 +267,13 @@ struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
|
|||
return NULL;
|
||||
evsel__init(evsel, attr, idx);
|
||||
|
||||
if (perf_evsel__is_bpf_output(evsel)) {
|
||||
if (evsel__is_bpf_output(evsel)) {
|
||||
evsel->core.attr.sample_type |= (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
|
||||
PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD),
|
||||
evsel->core.attr.sample_period = 1;
|
||||
}
|
||||
|
||||
if (perf_evsel__is_clock(evsel)) {
|
||||
if (evsel__is_clock(evsel)) {
|
||||
/*
|
||||
* The evsel->unit points to static alias->unit
|
||||
* so it's ok to use static string in here.
|
||||
|
|
@ -385,7 +385,7 @@ const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
|
|||
"ref-cycles",
|
||||
};
|
||||
|
||||
static const char *__perf_evsel__hw_name(u64 config)
|
||||
static const char *__evsel__hw_name(u64 config)
|
||||
{
|
||||
if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config])
|
||||
return perf_evsel__hw_names[config];
|
||||
|
|
@ -429,9 +429,9 @@ static int perf_evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int perf_evsel__hw_name(struct evsel *evsel, char *bf, size_t size)
|
||||
static int evsel__hw_name(struct evsel *evsel, char *bf, size_t size)
|
||||
{
|
||||
int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->core.attr.config));
|
||||
int r = scnprintf(bf, size, "%s", __evsel__hw_name(evsel->core.attr.config));
|
||||
return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
|
||||
}
|
||||
|
||||
|
|
@ -448,20 +448,20 @@ const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = {
|
|||
"dummy",
|
||||
};
|
||||
|
||||
static const char *__perf_evsel__sw_name(u64 config)
|
||||
static const char *__evsel__sw_name(u64 config)
|
||||
{
|
||||
if (config < PERF_COUNT_SW_MAX && perf_evsel__sw_names[config])
|
||||
return perf_evsel__sw_names[config];
|
||||
return "unknown-software";
|
||||
}
|
||||
|
||||
static int perf_evsel__sw_name(struct evsel *evsel, char *bf, size_t size)
|
||||
static int evsel__sw_name(struct evsel *evsel, char *bf, size_t size)
|
||||
{
|
||||
int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->core.attr.config));
|
||||
int r = scnprintf(bf, size, "%s", __evsel__sw_name(evsel->core.attr.config));
|
||||
return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
|
||||
}
|
||||
|
||||
static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type)
|
||||
static int __evsel__bp_name(char *bf, size_t size, u64 addr, u64 type)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
|
@ -479,10 +479,10 @@ static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int perf_evsel__bp_name(struct evsel *evsel, char *bf, size_t size)
|
||||
static int evsel__bp_name(struct evsel *evsel, char *bf, size_t size)
|
||||
{
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type);
|
||||
int r = __evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type);
|
||||
return r + perf_evsel__add_modifiers(evsel, bf + r, size - r);
|
||||
}
|
||||
|
||||
|
|
@ -531,7 +531,7 @@ static unsigned long perf_evsel__hw_cache_stat[C(MAX)] = {
|
|||
[C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
|
||||
};
|
||||
|
||||
bool perf_evsel__is_cache_op_valid(u8 type, u8 op)
|
||||
bool evsel__is_cache_op_valid(u8 type, u8 op)
|
||||
{
|
||||
if (perf_evsel__hw_cache_stat[type] & COP(op))
|
||||
return true; /* valid */
|
||||
|
|
@ -539,8 +539,7 @@ bool perf_evsel__is_cache_op_valid(u8 type, u8 op)
|
|||
return false; /* invalid */
|
||||
}
|
||||
|
||||
int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
|
||||
char *bf, size_t size)
|
||||
int __evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size)
|
||||
{
|
||||
if (result) {
|
||||
return scnprintf(bf, size, "%s-%s-%s", perf_evsel__hw_cache[type][0],
|
||||
|
|
@ -552,7 +551,7 @@ int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
|
|||
perf_evsel__hw_cache_op[op][1]);
|
||||
}
|
||||
|
||||
static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size)
|
||||
static int __evsel__hw_cache_name(u64 config, char *bf, size_t size)
|
||||
{
|
||||
u8 op, result, type = (config >> 0) & 0xff;
|
||||
const char *err = "unknown-ext-hardware-cache-type";
|
||||
|
|
@ -571,33 +570,33 @@ static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size)
|
|||
goto out_err;
|
||||
|
||||
err = "invalid-cache";
|
||||
if (!perf_evsel__is_cache_op_valid(type, op))
|
||||
if (!evsel__is_cache_op_valid(type, op))
|
||||
goto out_err;
|
||||
|
||||
return __perf_evsel__hw_cache_type_op_res_name(type, op, result, bf, size);
|
||||
return __evsel__hw_cache_type_op_res_name(type, op, result, bf, size);
|
||||
out_err:
|
||||
return scnprintf(bf, size, "%s", err);
|
||||
}
|
||||
|
||||
static int perf_evsel__hw_cache_name(struct evsel *evsel, char *bf, size_t size)
|
||||
static int evsel__hw_cache_name(struct evsel *evsel, char *bf, size_t size)
|
||||
{
|
||||
int ret = __perf_evsel__hw_cache_name(evsel->core.attr.config, bf, size);
|
||||
int ret = __evsel__hw_cache_name(evsel->core.attr.config, bf, size);
|
||||
return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
|
||||
}
|
||||
|
||||
static int perf_evsel__raw_name(struct evsel *evsel, char *bf, size_t size)
|
||||
static int evsel__raw_name(struct evsel *evsel, char *bf, size_t size)
|
||||
{
|
||||
int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->core.attr.config);
|
||||
return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret);
|
||||
}
|
||||
|
||||
static int perf_evsel__tool_name(char *bf, size_t size)
|
||||
static int evsel__tool_name(char *bf, size_t size)
|
||||
{
|
||||
int ret = scnprintf(bf, size, "duration_time");
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *perf_evsel__name(struct evsel *evsel)
|
||||
const char *evsel__name(struct evsel *evsel)
|
||||
{
|
||||
char bf[128];
|
||||
|
||||
|
|
@ -609,22 +608,22 @@ const char *perf_evsel__name(struct evsel *evsel)
|
|||
|
||||
switch (evsel->core.attr.type) {
|
||||
case PERF_TYPE_RAW:
|
||||
perf_evsel__raw_name(evsel, bf, sizeof(bf));
|
||||
evsel__raw_name(evsel, bf, sizeof(bf));
|
||||
break;
|
||||
|
||||
case PERF_TYPE_HARDWARE:
|
||||
perf_evsel__hw_name(evsel, bf, sizeof(bf));
|
||||
evsel__hw_name(evsel, bf, sizeof(bf));
|
||||
break;
|
||||
|
||||
case PERF_TYPE_HW_CACHE:
|
||||
perf_evsel__hw_cache_name(evsel, bf, sizeof(bf));
|
||||
evsel__hw_cache_name(evsel, bf, sizeof(bf));
|
||||
break;
|
||||
|
||||
case PERF_TYPE_SOFTWARE:
|
||||
if (evsel->tool_event)
|
||||
perf_evsel__tool_name(bf, sizeof(bf));
|
||||
evsel__tool_name(bf, sizeof(bf));
|
||||
else
|
||||
perf_evsel__sw_name(evsel, bf, sizeof(bf));
|
||||
evsel__sw_name(evsel, bf, sizeof(bf));
|
||||
break;
|
||||
|
||||
case PERF_TYPE_TRACEPOINT:
|
||||
|
|
@ -632,7 +631,7 @@ const char *perf_evsel__name(struct evsel *evsel)
|
|||
break;
|
||||
|
||||
case PERF_TYPE_BREAKPOINT:
|
||||
perf_evsel__bp_name(evsel, bf, sizeof(bf));
|
||||
evsel__bp_name(evsel, bf, sizeof(bf));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -649,7 +648,7 @@ const char *perf_evsel__name(struct evsel *evsel)
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
const char *perf_evsel__group_name(struct evsel *evsel)
|
||||
const char *evsel__group_name(struct evsel *evsel)
|
||||
{
|
||||
return evsel->group_name ?: "anon group";
|
||||
}
|
||||
|
|
@ -664,21 +663,19 @@ const char *perf_evsel__group_name(struct evsel *evsel)
|
|||
* For record -e 'cycles,instructions' and report --group
|
||||
* 'cycles:u, instructions:u'
|
||||
*/
|
||||
int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size)
|
||||
int evsel__group_desc(struct evsel *evsel, char *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
struct evsel *pos;
|
||||
const char *group_name = perf_evsel__group_name(evsel);
|
||||
const char *group_name = evsel__group_name(evsel);
|
||||
|
||||
if (!evsel->forced_leader)
|
||||
ret = scnprintf(buf, size, "%s { ", group_name);
|
||||
|
||||
ret += scnprintf(buf + ret, size - ret, "%s",
|
||||
perf_evsel__name(evsel));
|
||||
ret += scnprintf(buf + ret, size - ret, "%s", evsel__name(evsel));
|
||||
|
||||
for_each_group_member(pos, evsel)
|
||||
ret += scnprintf(buf + ret, size - ret, ", %s",
|
||||
perf_evsel__name(pos));
|
||||
ret += scnprintf(buf + ret, size - ret, ", %s", evsel__name(pos));
|
||||
|
||||
if (!evsel->forced_leader)
|
||||
ret += scnprintf(buf + ret, size - ret, " }");
|
||||
|
|
@ -686,14 +683,13 @@ int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void __perf_evsel__config_callchain(struct evsel *evsel,
|
||||
struct record_opts *opts,
|
||||
struct callchain_param *param)
|
||||
static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *opts,
|
||||
struct callchain_param *param)
|
||||
{
|
||||
bool function = perf_evsel__is_function_event(evsel);
|
||||
bool function = evsel__is_function_event(evsel);
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
|
||||
perf_evsel__set_sample_bit(evsel, CALLCHAIN);
|
||||
evsel__set_sample_bit(evsel, CALLCHAIN);
|
||||
|
||||
attr->sample_max_stack = param->max_stack;
|
||||
|
||||
|
|
@ -708,7 +704,7 @@ static void __perf_evsel__config_callchain(struct evsel *evsel,
|
|||
"to get user callchain information. "
|
||||
"Falling back to framepointers.\n");
|
||||
} else {
|
||||
perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
|
||||
evsel__set_sample_bit(evsel, BRANCH_STACK);
|
||||
attr->branch_sample_type = PERF_SAMPLE_BRANCH_USER |
|
||||
PERF_SAMPLE_BRANCH_CALL_STACK |
|
||||
PERF_SAMPLE_BRANCH_NO_CYCLES |
|
||||
|
|
@ -722,8 +718,8 @@ static void __perf_evsel__config_callchain(struct evsel *evsel,
|
|||
|
||||
if (param->record_mode == CALLCHAIN_DWARF) {
|
||||
if (!function) {
|
||||
perf_evsel__set_sample_bit(evsel, REGS_USER);
|
||||
perf_evsel__set_sample_bit(evsel, STACK_USER);
|
||||
evsel__set_sample_bit(evsel, REGS_USER);
|
||||
evsel__set_sample_bit(evsel, STACK_USER);
|
||||
if (opts->sample_user_regs && DWARF_MINIMAL_REGS != PERF_REGS_MASK) {
|
||||
attr->sample_regs_user |= DWARF_MINIMAL_REGS;
|
||||
pr_warning("WARNING: The use of --call-graph=dwarf may require all the user registers, "
|
||||
|
|
@ -746,12 +742,11 @@ static void __perf_evsel__config_callchain(struct evsel *evsel,
|
|||
}
|
||||
}
|
||||
|
||||
void perf_evsel__config_callchain(struct evsel *evsel,
|
||||
struct record_opts *opts,
|
||||
struct callchain_param *param)
|
||||
void evsel__config_callchain(struct evsel *evsel, struct record_opts *opts,
|
||||
struct callchain_param *param)
|
||||
{
|
||||
if (param->enabled)
|
||||
return __perf_evsel__config_callchain(evsel, opts, param);
|
||||
return __evsel__config_callchain(evsel, opts, param);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -760,16 +755,16 @@ perf_evsel__reset_callgraph(struct evsel *evsel,
|
|||
{
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
|
||||
perf_evsel__reset_sample_bit(evsel, CALLCHAIN);
|
||||
evsel__reset_sample_bit(evsel, CALLCHAIN);
|
||||
if (param->record_mode == CALLCHAIN_LBR) {
|
||||
perf_evsel__reset_sample_bit(evsel, BRANCH_STACK);
|
||||
evsel__reset_sample_bit(evsel, BRANCH_STACK);
|
||||
attr->branch_sample_type &= ~(PERF_SAMPLE_BRANCH_USER |
|
||||
PERF_SAMPLE_BRANCH_CALL_STACK |
|
||||
PERF_SAMPLE_BRANCH_HW_INDEX);
|
||||
}
|
||||
if (param->record_mode == CALLCHAIN_DWARF) {
|
||||
perf_evsel__reset_sample_bit(evsel, REGS_USER);
|
||||
perf_evsel__reset_sample_bit(evsel, STACK_USER);
|
||||
evsel__reset_sample_bit(evsel, REGS_USER);
|
||||
evsel__reset_sample_bit(evsel, STACK_USER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -793,32 +788,32 @@ static void apply_config_terms(struct evsel *evsel,
|
|||
if (!(term->weak && opts->user_interval != ULLONG_MAX)) {
|
||||
attr->sample_period = term->val.period;
|
||||
attr->freq = 0;
|
||||
perf_evsel__reset_sample_bit(evsel, PERIOD);
|
||||
evsel__reset_sample_bit(evsel, PERIOD);
|
||||
}
|
||||
break;
|
||||
case PERF_EVSEL__CONFIG_TERM_FREQ:
|
||||
if (!(term->weak && opts->user_freq != UINT_MAX)) {
|
||||
attr->sample_freq = term->val.freq;
|
||||
attr->freq = 1;
|
||||
perf_evsel__set_sample_bit(evsel, PERIOD);
|
||||
evsel__set_sample_bit(evsel, PERIOD);
|
||||
}
|
||||
break;
|
||||
case PERF_EVSEL__CONFIG_TERM_TIME:
|
||||
if (term->val.time)
|
||||
perf_evsel__set_sample_bit(evsel, TIME);
|
||||
evsel__set_sample_bit(evsel, TIME);
|
||||
else
|
||||
perf_evsel__reset_sample_bit(evsel, TIME);
|
||||
evsel__reset_sample_bit(evsel, TIME);
|
||||
break;
|
||||
case PERF_EVSEL__CONFIG_TERM_CALLGRAPH:
|
||||
callgraph_buf = term->val.str;
|
||||
break;
|
||||
case PERF_EVSEL__CONFIG_TERM_BRANCH:
|
||||
if (term->val.str && strcmp(term->val.str, "no")) {
|
||||
perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
|
||||
evsel__set_sample_bit(evsel, BRANCH_STACK);
|
||||
parse_branch_str(term->val.str,
|
||||
&attr->branch_sample_type);
|
||||
} else
|
||||
perf_evsel__reset_sample_bit(evsel, BRANCH_STACK);
|
||||
evsel__reset_sample_bit(evsel, BRANCH_STACK);
|
||||
break;
|
||||
case PERF_EVSEL__CONFIG_TERM_STACK_USER:
|
||||
dump_size = term->val.stack_user;
|
||||
|
|
@ -832,7 +827,7 @@ static void apply_config_terms(struct evsel *evsel,
|
|||
case PERF_EVSEL__CONFIG_TERM_INHERIT:
|
||||
/*
|
||||
* attr->inherit should has already been set by
|
||||
* perf_evsel__config. If user explicitly set
|
||||
* evsel__config. If user explicitly set
|
||||
* inherit using config terms, override global
|
||||
* opt->no_inherit setting.
|
||||
*/
|
||||
|
|
@ -897,11 +892,11 @@ static void apply_config_terms(struct evsel *evsel,
|
|||
/* set perf-event callgraph */
|
||||
if (param.enabled) {
|
||||
if (sample_address) {
|
||||
perf_evsel__set_sample_bit(evsel, ADDR);
|
||||
perf_evsel__set_sample_bit(evsel, DATA_SRC);
|
||||
evsel__set_sample_bit(evsel, ADDR);
|
||||
evsel__set_sample_bit(evsel, DATA_SRC);
|
||||
evsel->core.attr.mmap_data = track;
|
||||
}
|
||||
perf_evsel__config_callchain(evsel, opts, ¶m);
|
||||
evsel__config_callchain(evsel, opts, ¶m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -953,8 +948,8 @@ struct perf_evsel_config_term *__perf_evsel__get_config_term(struct evsel *evsel
|
|||
* enable/disable events specifically, as there's no
|
||||
* initial traced exec call.
|
||||
*/
|
||||
void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
||||
struct callchain_param *callchain)
|
||||
void evsel__config(struct evsel *evsel, struct record_opts *opts,
|
||||
struct callchain_param *callchain)
|
||||
{
|
||||
struct evsel *leader = evsel->leader;
|
||||
struct perf_event_attr *attr = &evsel->core.attr;
|
||||
|
|
@ -965,17 +960,17 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
attr->inherit = !opts->no_inherit;
|
||||
attr->write_backward = opts->overwrite ? 1 : 0;
|
||||
|
||||
perf_evsel__set_sample_bit(evsel, IP);
|
||||
perf_evsel__set_sample_bit(evsel, TID);
|
||||
evsel__set_sample_bit(evsel, IP);
|
||||
evsel__set_sample_bit(evsel, TID);
|
||||
|
||||
if (evsel->sample_read) {
|
||||
perf_evsel__set_sample_bit(evsel, READ);
|
||||
evsel__set_sample_bit(evsel, READ);
|
||||
|
||||
/*
|
||||
* We need ID even in case of single event, because
|
||||
* PERF_SAMPLE_READ process ID specific data.
|
||||
*/
|
||||
perf_evsel__set_sample_id(evsel, false);
|
||||
evsel__set_sample_id(evsel, false);
|
||||
|
||||
/*
|
||||
* Apply group format only if we belong to group
|
||||
|
|
@ -994,7 +989,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
if (!attr->sample_period || (opts->user_freq != UINT_MAX ||
|
||||
opts->user_interval != ULLONG_MAX)) {
|
||||
if (opts->freq) {
|
||||
perf_evsel__set_sample_bit(evsel, PERIOD);
|
||||
evsel__set_sample_bit(evsel, PERIOD);
|
||||
attr->freq = 1;
|
||||
attr->sample_freq = opts->freq;
|
||||
} else {
|
||||
|
|
@ -1014,7 +1009,7 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
}
|
||||
|
||||
if (opts->sample_address) {
|
||||
perf_evsel__set_sample_bit(evsel, ADDR);
|
||||
evsel__set_sample_bit(evsel, ADDR);
|
||||
attr->mmap_data = track;
|
||||
}
|
||||
|
||||
|
|
@ -1023,24 +1018,24 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
* event, due to issues with page faults while tracing page
|
||||
* fault handler and its overall trickiness nature.
|
||||
*/
|
||||
if (perf_evsel__is_function_event(evsel))
|
||||
if (evsel__is_function_event(evsel))
|
||||
evsel->core.attr.exclude_callchain_user = 1;
|
||||
|
||||
if (callchain && callchain->enabled && !evsel->no_aux_samples)
|
||||
perf_evsel__config_callchain(evsel, opts, callchain);
|
||||
evsel__config_callchain(evsel, opts, callchain);
|
||||
|
||||
if (opts->sample_intr_regs) {
|
||||
attr->sample_regs_intr = opts->sample_intr_regs;
|
||||
perf_evsel__set_sample_bit(evsel, REGS_INTR);
|
||||
evsel__set_sample_bit(evsel, REGS_INTR);
|
||||
}
|
||||
|
||||
if (opts->sample_user_regs) {
|
||||
attr->sample_regs_user |= opts->sample_user_regs;
|
||||
perf_evsel__set_sample_bit(evsel, REGS_USER);
|
||||
evsel__set_sample_bit(evsel, REGS_USER);
|
||||
}
|
||||
|
||||
if (target__has_cpu(&opts->target) || opts->sample_cpu)
|
||||
perf_evsel__set_sample_bit(evsel, CPU);
|
||||
evsel__set_sample_bit(evsel, CPU);
|
||||
|
||||
/*
|
||||
* When the user explicitly disabled time don't force it here.
|
||||
|
|
@ -1049,31 +1044,31 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
(!perf_missing_features.sample_id_all &&
|
||||
(!opts->no_inherit || target__has_cpu(&opts->target) || per_cpu ||
|
||||
opts->sample_time_set)))
|
||||
perf_evsel__set_sample_bit(evsel, TIME);
|
||||
evsel__set_sample_bit(evsel, TIME);
|
||||
|
||||
if (opts->raw_samples && !evsel->no_aux_samples) {
|
||||
perf_evsel__set_sample_bit(evsel, TIME);
|
||||
perf_evsel__set_sample_bit(evsel, RAW);
|
||||
perf_evsel__set_sample_bit(evsel, CPU);
|
||||
evsel__set_sample_bit(evsel, TIME);
|
||||
evsel__set_sample_bit(evsel, RAW);
|
||||
evsel__set_sample_bit(evsel, CPU);
|
||||
}
|
||||
|
||||
if (opts->sample_address)
|
||||
perf_evsel__set_sample_bit(evsel, DATA_SRC);
|
||||
evsel__set_sample_bit(evsel, DATA_SRC);
|
||||
|
||||
if (opts->sample_phys_addr)
|
||||
perf_evsel__set_sample_bit(evsel, PHYS_ADDR);
|
||||
evsel__set_sample_bit(evsel, PHYS_ADDR);
|
||||
|
||||
if (opts->no_buffering) {
|
||||
attr->watermark = 0;
|
||||
attr->wakeup_events = 1;
|
||||
}
|
||||
if (opts->branch_stack && !evsel->no_aux_samples) {
|
||||
perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
|
||||
evsel__set_sample_bit(evsel, BRANCH_STACK);
|
||||
attr->branch_sample_type = opts->branch_stack;
|
||||
}
|
||||
|
||||
if (opts->sample_weight)
|
||||
perf_evsel__set_sample_bit(evsel, WEIGHT);
|
||||
evsel__set_sample_bit(evsel, WEIGHT);
|
||||
|
||||
attr->task = track;
|
||||
attr->mmap = track;
|
||||
|
|
@ -1087,14 +1082,14 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
|
||||
if (opts->record_cgroup) {
|
||||
attr->cgroup = track && !perf_missing_features.cgroup;
|
||||
perf_evsel__set_sample_bit(evsel, CGROUP);
|
||||
evsel__set_sample_bit(evsel, CGROUP);
|
||||
}
|
||||
|
||||
if (opts->record_switch_events)
|
||||
attr->context_switch = track;
|
||||
|
||||
if (opts->sample_transaction)
|
||||
perf_evsel__set_sample_bit(evsel, TRANSACTION);
|
||||
evsel__set_sample_bit(evsel, TRANSACTION);
|
||||
|
||||
if (opts->running_time) {
|
||||
evsel->core.attr.read_format |=
|
||||
|
|
@ -1108,15 +1103,15 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
* Disabling only independent events or group leaders,
|
||||
* keeping group members enabled.
|
||||
*/
|
||||
if (perf_evsel__is_group_leader(evsel))
|
||||
if (evsel__is_group_leader(evsel))
|
||||
attr->disabled = 1;
|
||||
|
||||
/*
|
||||
* Setting enable_on_exec for independent events and
|
||||
* group leaders for traced executed by perf.
|
||||
*/
|
||||
if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel) &&
|
||||
!opts->initial_delay)
|
||||
if (target__none(&opts->target) && evsel__is_group_leader(evsel) &&
|
||||
!opts->initial_delay)
|
||||
attr->enable_on_exec = 1;
|
||||
|
||||
if (evsel->immediate) {
|
||||
|
|
@ -1157,9 +1152,9 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
/* The --period option takes the precedence. */
|
||||
if (opts->period_set) {
|
||||
if (opts->period)
|
||||
perf_evsel__set_sample_bit(evsel, PERIOD);
|
||||
evsel__set_sample_bit(evsel, PERIOD);
|
||||
else
|
||||
perf_evsel__reset_sample_bit(evsel, PERIOD);
|
||||
evsel__reset_sample_bit(evsel, PERIOD);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1168,10 +1163,10 @@ void perf_evsel__config(struct evsel *evsel, struct record_opts *opts,
|
|||
* if BRANCH_STACK bit is set.
|
||||
*/
|
||||
if (opts->initial_delay && is_dummy_event(evsel))
|
||||
perf_evsel__reset_sample_bit(evsel, BRANCH_STACK);
|
||||
evsel__reset_sample_bit(evsel, BRANCH_STACK);
|
||||
}
|
||||
|
||||
int perf_evsel__set_filter(struct evsel *evsel, const char *filter)
|
||||
int evsel__set_filter(struct evsel *evsel, const char *filter)
|
||||
{
|
||||
char *new_filter = strdup(filter);
|
||||
|
||||
|
|
@ -1184,13 +1179,12 @@ int perf_evsel__set_filter(struct evsel *evsel, const char *filter)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int perf_evsel__append_filter(struct evsel *evsel,
|
||||
const char *fmt, const char *filter)
|
||||
static int evsel__append_filter(struct evsel *evsel, const char *fmt, const char *filter)
|
||||
{
|
||||
char *new_filter;
|
||||
|
||||
if (evsel->filter == NULL)
|
||||
return perf_evsel__set_filter(evsel, filter);
|
||||
return evsel__set_filter(evsel, filter);
|
||||
|
||||
if (asprintf(&new_filter, fmt, evsel->filter, filter) > 0) {
|
||||
free(evsel->filter);
|
||||
|
|
@ -1201,14 +1195,14 @@ static int perf_evsel__append_filter(struct evsel *evsel,
|
|||
return -1;
|
||||
}
|
||||
|
||||
int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter)
|
||||
int evsel__append_tp_filter(struct evsel *evsel, const char *filter)
|
||||
{
|
||||
return perf_evsel__append_filter(evsel, "(%s) && (%s)", filter);
|
||||
return evsel__append_filter(evsel, "(%s) && (%s)", filter);
|
||||
}
|
||||
|
||||
int perf_evsel__append_addr_filter(struct evsel *evsel, const char *filter)
|
||||
int evsel__append_addr_filter(struct evsel *evsel, const char *filter)
|
||||
{
|
||||
return perf_evsel__append_filter(evsel, "%s,%s", filter);
|
||||
return evsel__append_filter(evsel, "%s,%s", filter);
|
||||
}
|
||||
|
||||
/* Caller has to clear disabled after going through all CPUs. */
|
||||
|
|
@ -1259,7 +1253,7 @@ static void perf_evsel__free_config_terms(struct evsel *evsel)
|
|||
}
|
||||
}
|
||||
|
||||
void perf_evsel__exit(struct evsel *evsel)
|
||||
void evsel__exit(struct evsel *evsel)
|
||||
{
|
||||
assert(list_empty(&evsel->core.node));
|
||||
assert(evsel->evlist == NULL);
|
||||
|
|
@ -1279,12 +1273,12 @@ void perf_evsel__exit(struct evsel *evsel)
|
|||
|
||||
void evsel__delete(struct evsel *evsel)
|
||||
{
|
||||
perf_evsel__exit(evsel);
|
||||
evsel__exit(evsel);
|
||||
free(evsel);
|
||||
}
|
||||
|
||||
void perf_evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
|
||||
struct perf_counts_values *count)
|
||||
void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
|
||||
struct perf_counts_values *count)
|
||||
{
|
||||
struct perf_counts_values tmp;
|
||||
|
||||
|
|
@ -1323,8 +1317,7 @@ void perf_counts_values__scale(struct perf_counts_values *count,
|
|||
*pscaled = scaled;
|
||||
}
|
||||
|
||||
static int
|
||||
perf_evsel__read_one(struct evsel *evsel, int cpu, int thread)
|
||||
static int evsel__read_one(struct evsel *evsel, int cpu, int thread)
|
||||
{
|
||||
struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread);
|
||||
|
||||
|
|
@ -1384,8 +1377,7 @@ perf_evsel__process_group_data(struct evsel *leader,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
perf_evsel__read_group(struct evsel *leader, int cpu, int thread)
|
||||
static int evsel__read_group(struct evsel *leader, int cpu, int thread)
|
||||
{
|
||||
struct perf_stat_evsel *ps = leader->stats;
|
||||
u64 read_format = leader->core.attr.read_format;
|
||||
|
|
@ -1395,7 +1387,7 @@ perf_evsel__read_group(struct evsel *leader, int cpu, int thread)
|
|||
if (!(read_format & PERF_FORMAT_ID))
|
||||
return -EINVAL;
|
||||
|
||||
if (!perf_evsel__is_group_leader(leader))
|
||||
if (!evsel__is_group_leader(leader))
|
||||
return -EINVAL;
|
||||
|
||||
if (!data) {
|
||||
|
|
@ -1415,18 +1407,17 @@ perf_evsel__read_group(struct evsel *leader, int cpu, int thread)
|
|||
return perf_evsel__process_group_data(leader, cpu, thread, data);
|
||||
}
|
||||
|
||||
int perf_evsel__read_counter(struct evsel *evsel, int cpu, int thread)
|
||||
int evsel__read_counter(struct evsel *evsel, int cpu, int thread)
|
||||
{
|
||||
u64 read_format = evsel->core.attr.read_format;
|
||||
|
||||
if (read_format & PERF_FORMAT_GROUP)
|
||||
return perf_evsel__read_group(evsel, cpu, thread);
|
||||
else
|
||||
return perf_evsel__read_one(evsel, cpu, thread);
|
||||
return evsel__read_group(evsel, cpu, thread);
|
||||
|
||||
return evsel__read_one(evsel, cpu, thread);
|
||||
}
|
||||
|
||||
int __perf_evsel__read_on_cpu(struct evsel *evsel,
|
||||
int cpu, int thread, bool scale)
|
||||
int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale)
|
||||
{
|
||||
struct perf_counts_values count;
|
||||
size_t nv = scale ? 3 : 1;
|
||||
|
|
@ -1440,7 +1431,7 @@ int __perf_evsel__read_on_cpu(struct evsel *evsel,
|
|||
if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) <= 0)
|
||||
return -errno;
|
||||
|
||||
perf_evsel__compute_deltas(evsel, cpu, thread, &count);
|
||||
evsel__compute_deltas(evsel, cpu, thread, &count);
|
||||
perf_counts_values__scale(&count, scale, NULL);
|
||||
*perf_counts(evsel->counts, cpu, thread) = count;
|
||||
return 0;
|
||||
|
|
@ -1451,7 +1442,7 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread)
|
|||
struct evsel *leader = evsel->leader;
|
||||
int fd;
|
||||
|
||||
if (perf_evsel__is_group_leader(evsel))
|
||||
if (evsel__is_group_leader(evsel))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
|
|
@ -1730,8 +1721,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
|
|||
|
||||
/*
|
||||
* If we succeeded but had to kill clockid, fail and
|
||||
* have perf_evsel__open_strerror() print us a nice
|
||||
* error.
|
||||
* have evsel__open_strerror() print us a nice error.
|
||||
*/
|
||||
if (perf_missing_features.clockid ||
|
||||
perf_missing_features.clockid_wrong) {
|
||||
|
|
@ -1835,7 +1825,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
|
|||
} else if (!perf_missing_features.group_read &&
|
||||
evsel->core.attr.inherit &&
|
||||
(evsel->core.attr.read_format & PERF_FORMAT_GROUP) &&
|
||||
perf_evsel__is_group_leader(evsel)) {
|
||||
evsel__is_group_leader(evsel)) {
|
||||
perf_missing_features.group_read = true;
|
||||
pr_debug2_peo("switching off group read\n");
|
||||
goto fallback_missing_features;
|
||||
|
|
@ -1869,9 +1859,7 @@ void evsel__close(struct evsel *evsel)
|
|||
perf_evsel__free_id(&evsel->core);
|
||||
}
|
||||
|
||||
int perf_evsel__open_per_cpu(struct evsel *evsel,
|
||||
struct perf_cpu_map *cpus,
|
||||
int cpu)
|
||||
int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu)
|
||||
{
|
||||
if (cpu == -1)
|
||||
return evsel__open_cpu(evsel, cpus, NULL, 0,
|
||||
|
|
@ -1880,8 +1868,7 @@ int perf_evsel__open_per_cpu(struct evsel *evsel,
|
|||
return evsel__open_cpu(evsel, cpus, NULL, cpu, cpu + 1);
|
||||
}
|
||||
|
||||
int perf_evsel__open_per_thread(struct evsel *evsel,
|
||||
struct perf_thread_map *threads)
|
||||
int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads)
|
||||
{
|
||||
return evsel__open(evsel, NULL, threads);
|
||||
}
|
||||
|
|
@ -1976,8 +1963,8 @@ perf_event__check_size(union perf_event *event, unsigned int sample_size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event,
|
||||
struct perf_sample *data)
|
||||
int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
|
||||
struct perf_sample *data)
|
||||
{
|
||||
u64 type = evsel->core.attr.sample_type;
|
||||
bool swapped = evsel->needs_swap;
|
||||
|
|
@ -2171,7 +2158,7 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event,
|
|||
return -EFAULT;
|
||||
|
||||
sz = data->branch_stack->nr * sizeof(struct branch_entry);
|
||||
if (perf_evsel__has_branch_hw_idx(evsel))
|
||||
if (evsel__has_branch_hw_idx(evsel))
|
||||
sz += sizeof(u64);
|
||||
else
|
||||
data->no_hw_idx = true;
|
||||
|
|
@ -2279,9 +2266,8 @@ int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int perf_evsel__parse_sample_timestamp(struct evsel *evsel,
|
||||
union perf_event *event,
|
||||
u64 *timestamp)
|
||||
int evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event,
|
||||
u64 *timestamp)
|
||||
{
|
||||
u64 type = evsel->core.attr.sample_type;
|
||||
const __u64 *array;
|
||||
|
|
@ -2323,15 +2309,14 @@ int perf_evsel__parse_sample_timestamp(struct evsel *evsel,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name)
|
||||
struct tep_format_field *evsel__field(struct evsel *evsel, const char *name)
|
||||
{
|
||||
return tep_find_field(evsel->tp_format, name);
|
||||
}
|
||||
|
||||
void *perf_evsel__rawptr(struct evsel *evsel, struct perf_sample *sample,
|
||||
const char *name)
|
||||
void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name)
|
||||
{
|
||||
struct tep_format_field *field = perf_evsel__field(evsel, name);
|
||||
struct tep_format_field *field = evsel__field(evsel, name);
|
||||
int offset;
|
||||
|
||||
if (!field)
|
||||
|
|
@ -2386,10 +2371,9 @@ u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sam
|
|||
return 0;
|
||||
}
|
||||
|
||||
u64 perf_evsel__intval(struct evsel *evsel, struct perf_sample *sample,
|
||||
const char *name)
|
||||
u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name)
|
||||
{
|
||||
struct tep_format_field *field = perf_evsel__field(evsel, name);
|
||||
struct tep_format_field *field = evsel__field(evsel, name);
|
||||
|
||||
if (!field)
|
||||
return 0;
|
||||
|
|
@ -2397,8 +2381,7 @@ u64 perf_evsel__intval(struct evsel *evsel, struct perf_sample *sample,
|
|||
return field ? format_field__intval(field, sample, evsel->needs_swap) : 0;
|
||||
}
|
||||
|
||||
bool perf_evsel__fallback(struct evsel *evsel, int err,
|
||||
char *msg, size_t msgsize)
|
||||
bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize)
|
||||
{
|
||||
int paranoid;
|
||||
|
||||
|
|
@ -2423,7 +2406,7 @@ bool perf_evsel__fallback(struct evsel *evsel, int err,
|
|||
return true;
|
||||
} else if (err == EACCES && !evsel->core.attr.exclude_kernel &&
|
||||
(paranoid = perf_event_paranoid()) > 1) {
|
||||
const char *name = perf_evsel__name(evsel);
|
||||
const char *name = evsel__name(evsel);
|
||||
char *new_name;
|
||||
const char *sep = ":";
|
||||
|
||||
|
|
@ -2490,8 +2473,8 @@ static bool find_process(const char *name)
|
|||
return ret ? false : true;
|
||||
}
|
||||
|
||||
int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
|
||||
int err, char *msg, size_t size)
|
||||
int evsel__open_strerror(struct evsel *evsel, struct target *target,
|
||||
int err, char *msg, size_t size)
|
||||
{
|
||||
char sbuf[STRERR_BUFSIZE];
|
||||
int printed = 0;
|
||||
|
|
@ -2501,8 +2484,7 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
|
|||
case EACCES:
|
||||
if (err == EPERM)
|
||||
printed = scnprintf(msg, size,
|
||||
"No permission to enable %s event.\n\n",
|
||||
perf_evsel__name(evsel));
|
||||
"No permission to enable %s event.\n\n", evsel__name(evsel));
|
||||
|
||||
return scnprintf(msg + printed, size - printed,
|
||||
"You may not have permission to collect %sstats.\n\n"
|
||||
|
|
@ -2521,8 +2503,7 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
|
|||
target->system_wide ? "system-wide " : "",
|
||||
perf_event_paranoid());
|
||||
case ENOENT:
|
||||
return scnprintf(msg, size, "The %s event is not supported.",
|
||||
perf_evsel__name(evsel));
|
||||
return scnprintf(msg, size, "The %s event is not supported.", evsel__name(evsel));
|
||||
case EMFILE:
|
||||
return scnprintf(msg, size, "%s",
|
||||
"Too many events are opened.\n"
|
||||
|
|
@ -2546,7 +2527,7 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
|
|||
if (evsel->core.attr.sample_period != 0)
|
||||
return scnprintf(msg, size,
|
||||
"%s: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat'",
|
||||
perf_evsel__name(evsel));
|
||||
evsel__name(evsel));
|
||||
if (evsel->core.attr.precise_ip)
|
||||
return scnprintf(msg, size, "%s",
|
||||
"\'precise\' request may not be supported. Try removing 'p' modifier.");
|
||||
|
|
@ -2579,11 +2560,10 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
|
|||
return scnprintf(msg, size,
|
||||
"The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
|
||||
"/bin/dmesg | grep -i perf may provide additional information.\n",
|
||||
err, str_error_r(err, sbuf, sizeof(sbuf)),
|
||||
perf_evsel__name(evsel));
|
||||
err, str_error_r(err, sbuf, sizeof(sbuf)), evsel__name(evsel));
|
||||
}
|
||||
|
||||
struct perf_env *perf_evsel__env(struct evsel *evsel)
|
||||
struct perf_env *evsel__env(struct evsel *evsel)
|
||||
{
|
||||
if (evsel && evsel->evlist)
|
||||
return evsel->evlist->env;
|
||||
|
|
@ -2608,7 +2588,7 @@ static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist)
|
||||
int evsel__store_ids(struct evsel *evsel, struct evlist *evlist)
|
||||
{
|
||||
struct perf_cpu_map *cpus = evsel->core.cpus;
|
||||
struct perf_thread_map *threads = evsel->core.threads;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ struct perf_counts;
|
|||
struct perf_stat_evsel;
|
||||
union perf_event;
|
||||
|
||||
typedef int (perf_evsel__sb_cb_t)(union perf_event *event, void *data);
|
||||
typedef int (evsel__sb_cb_t)(union perf_event *event, void *data);
|
||||
|
||||
enum perf_tool_event {
|
||||
PERF_TOOL_NONE = 0,
|
||||
|
|
@ -101,8 +101,8 @@ struct evsel {
|
|||
int cpu_iter;
|
||||
const char *pmu_name;
|
||||
struct {
|
||||
perf_evsel__sb_cb_t *cb;
|
||||
void *data;
|
||||
evsel__sb_cb_t *cb;
|
||||
void *data;
|
||||
} side_band;
|
||||
/*
|
||||
* For reporting purposes, an evsel sample can have a callchain
|
||||
|
|
@ -143,7 +143,7 @@ static inline struct perf_cpu_map *evsel__cpus(struct evsel *evsel)
|
|||
return perf_evsel__cpus(&evsel->core);
|
||||
}
|
||||
|
||||
static inline int perf_evsel__nr_cpus(struct evsel *evsel)
|
||||
static inline int evsel__nr_cpus(struct evsel *evsel)
|
||||
{
|
||||
return evsel__cpus(evsel)->nr;
|
||||
}
|
||||
|
|
@ -151,15 +151,15 @@ static inline int perf_evsel__nr_cpus(struct evsel *evsel)
|
|||
void perf_counts_values__scale(struct perf_counts_values *count,
|
||||
bool scale, s8 *pscaled);
|
||||
|
||||
void perf_evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
|
||||
struct perf_counts_values *count);
|
||||
void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
|
||||
struct perf_counts_values *count);
|
||||
|
||||
int perf_evsel__object_config(size_t object_size,
|
||||
int (*init)(struct evsel *evsel),
|
||||
void (*fini)(struct evsel *evsel));
|
||||
|
||||
struct perf_pmu *perf_evsel__find_pmu(struct evsel *evsel);
|
||||
bool perf_evsel__is_aux_event(struct evsel *evsel);
|
||||
struct perf_pmu *evsel__find_pmu(struct evsel *evsel);
|
||||
bool evsel__is_aux_event(struct evsel *evsel);
|
||||
|
||||
struct evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx);
|
||||
|
||||
|
|
@ -183,22 +183,20 @@ struct evsel *perf_evsel__new_cycles(bool precise);
|
|||
struct tep_event *event_format__new(const char *sys, const char *name);
|
||||
|
||||
void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx);
|
||||
void perf_evsel__exit(struct evsel *evsel);
|
||||
void evsel__exit(struct evsel *evsel);
|
||||
void evsel__delete(struct evsel *evsel);
|
||||
|
||||
struct callchain_param;
|
||||
|
||||
void perf_evsel__config(struct evsel *evsel,
|
||||
struct record_opts *opts,
|
||||
struct callchain_param *callchain);
|
||||
void perf_evsel__config_callchain(struct evsel *evsel,
|
||||
struct record_opts *opts,
|
||||
struct callchain_param *callchain);
|
||||
void evsel__config(struct evsel *evsel, struct record_opts *opts,
|
||||
struct callchain_param *callchain);
|
||||
void evsel__config_callchain(struct evsel *evsel, struct record_opts *opts,
|
||||
struct callchain_param *callchain);
|
||||
|
||||
int __perf_evsel__sample_size(u64 sample_type);
|
||||
void perf_evsel__calc_id_pos(struct evsel *evsel);
|
||||
int __evsel__sample_size(u64 sample_type);
|
||||
void evsel__calc_id_pos(struct evsel *evsel);
|
||||
|
||||
bool perf_evsel__is_cache_op_valid(u8 type, u8 op);
|
||||
bool evsel__is_cache_op_valid(u8 type, u8 op);
|
||||
|
||||
#define PERF_EVSEL__MAX_ALIASES 8
|
||||
|
||||
|
|
@ -210,177 +208,153 @@ extern const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX]
|
|||
[PERF_EVSEL__MAX_ALIASES];
|
||||
extern const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX];
|
||||
extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX];
|
||||
int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
|
||||
char *bf, size_t size);
|
||||
const char *perf_evsel__name(struct evsel *evsel);
|
||||
int __evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, char *bf, size_t size);
|
||||
const char *evsel__name(struct evsel *evsel);
|
||||
|
||||
const char *perf_evsel__group_name(struct evsel *evsel);
|
||||
int perf_evsel__group_desc(struct evsel *evsel, char *buf, size_t size);
|
||||
const char *evsel__group_name(struct evsel *evsel);
|
||||
int evsel__group_desc(struct evsel *evsel, char *buf, size_t size);
|
||||
|
||||
void __perf_evsel__set_sample_bit(struct evsel *evsel,
|
||||
enum perf_event_sample_format bit);
|
||||
void __perf_evsel__reset_sample_bit(struct evsel *evsel,
|
||||
enum perf_event_sample_format bit);
|
||||
void __evsel__set_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit);
|
||||
void __evsel__reset_sample_bit(struct evsel *evsel, enum perf_event_sample_format bit);
|
||||
|
||||
#define perf_evsel__set_sample_bit(evsel, bit) \
|
||||
__perf_evsel__set_sample_bit(evsel, PERF_SAMPLE_##bit)
|
||||
#define evsel__set_sample_bit(evsel, bit) \
|
||||
__evsel__set_sample_bit(evsel, PERF_SAMPLE_##bit)
|
||||
|
||||
#define perf_evsel__reset_sample_bit(evsel, bit) \
|
||||
__perf_evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit)
|
||||
#define evsel__reset_sample_bit(evsel, bit) \
|
||||
__evsel__reset_sample_bit(evsel, PERF_SAMPLE_##bit)
|
||||
|
||||
void perf_evsel__set_sample_id(struct evsel *evsel,
|
||||
bool use_sample_identifier);
|
||||
void evsel__set_sample_id(struct evsel *evsel, bool use_sample_identifier);
|
||||
|
||||
int perf_evsel__set_filter(struct evsel *evsel, const char *filter);
|
||||
int perf_evsel__append_tp_filter(struct evsel *evsel, const char *filter);
|
||||
int perf_evsel__append_addr_filter(struct evsel *evsel,
|
||||
const char *filter);
|
||||
int evsel__set_filter(struct evsel *evsel, const char *filter);
|
||||
int evsel__append_tp_filter(struct evsel *evsel, const char *filter);
|
||||
int evsel__append_addr_filter(struct evsel *evsel, const char *filter);
|
||||
int evsel__enable_cpu(struct evsel *evsel, int cpu);
|
||||
int evsel__enable(struct evsel *evsel);
|
||||
int evsel__disable(struct evsel *evsel);
|
||||
int evsel__disable_cpu(struct evsel *evsel, int cpu);
|
||||
|
||||
int perf_evsel__open_per_cpu(struct evsel *evsel,
|
||||
struct perf_cpu_map *cpus,
|
||||
int cpu);
|
||||
int perf_evsel__open_per_thread(struct evsel *evsel,
|
||||
struct perf_thread_map *threads);
|
||||
int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu);
|
||||
int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads);
|
||||
int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus,
|
||||
struct perf_thread_map *threads);
|
||||
void evsel__close(struct evsel *evsel);
|
||||
|
||||
struct perf_sample;
|
||||
|
||||
void *perf_evsel__rawptr(struct evsel *evsel, struct perf_sample *sample,
|
||||
const char *name);
|
||||
u64 perf_evsel__intval(struct evsel *evsel, struct perf_sample *sample,
|
||||
const char *name);
|
||||
void *evsel__rawptr(struct evsel *evsel, struct perf_sample *sample, const char *name);
|
||||
u64 evsel__intval(struct evsel *evsel, struct perf_sample *sample, const char *name);
|
||||
|
||||
static inline char *perf_evsel__strval(struct evsel *evsel,
|
||||
struct perf_sample *sample,
|
||||
const char *name)
|
||||
static inline char *evsel__strval(struct evsel *evsel, struct perf_sample *sample, const char *name)
|
||||
{
|
||||
return perf_evsel__rawptr(evsel, sample, name);
|
||||
return evsel__rawptr(evsel, sample, name);
|
||||
}
|
||||
|
||||
struct tep_format_field;
|
||||
|
||||
u64 format_field__intval(struct tep_format_field *field, struct perf_sample *sample, bool needs_swap);
|
||||
|
||||
struct tep_format_field *perf_evsel__field(struct evsel *evsel, const char *name);
|
||||
struct tep_format_field *evsel__field(struct evsel *evsel, const char *name);
|
||||
|
||||
#define perf_evsel__match(evsel, t, c) \
|
||||
#define evsel__match(evsel, t, c) \
|
||||
(evsel->core.attr.type == PERF_TYPE_##t && \
|
||||
evsel->core.attr.config == PERF_COUNT_##c)
|
||||
|
||||
static inline bool perf_evsel__match2(struct evsel *e1,
|
||||
struct evsel *e2)
|
||||
static inline bool evsel__match2(struct evsel *e1, struct evsel *e2)
|
||||
{
|
||||
return (e1->core.attr.type == e2->core.attr.type) &&
|
||||
(e1->core.attr.config == e2->core.attr.config);
|
||||
}
|
||||
|
||||
#define perf_evsel__cmp(a, b) \
|
||||
((a) && \
|
||||
(b) && \
|
||||
(a)->core.attr.type == (b)->core.attr.type && \
|
||||
(a)->core.attr.config == (b)->core.attr.config)
|
||||
int evsel__read_counter(struct evsel *evsel, int cpu, int thread);
|
||||
|
||||
int perf_evsel__read_counter(struct evsel *evsel, int cpu, int thread);
|
||||
|
||||
int __perf_evsel__read_on_cpu(struct evsel *evsel,
|
||||
int cpu, int thread, bool scale);
|
||||
int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale);
|
||||
|
||||
/**
|
||||
* perf_evsel__read_on_cpu - Read out the results on a CPU and thread
|
||||
* evsel__read_on_cpu - Read out the results on a CPU and thread
|
||||
*
|
||||
* @evsel - event selector to read value
|
||||
* @cpu - CPU of interest
|
||||
* @thread - thread of interest
|
||||
*/
|
||||
static inline int perf_evsel__read_on_cpu(struct evsel *evsel,
|
||||
int cpu, int thread)
|
||||
static inline int evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread)
|
||||
{
|
||||
return __perf_evsel__read_on_cpu(evsel, cpu, thread, false);
|
||||
return __evsel__read_on_cpu(evsel, cpu, thread, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* perf_evsel__read_on_cpu_scaled - Read out the results on a CPU and thread, scaled
|
||||
* evsel__read_on_cpu_scaled - Read out the results on a CPU and thread, scaled
|
||||
*
|
||||
* @evsel - event selector to read value
|
||||
* @cpu - CPU of interest
|
||||
* @thread - thread of interest
|
||||
*/
|
||||
static inline int perf_evsel__read_on_cpu_scaled(struct evsel *evsel,
|
||||
int cpu, int thread)
|
||||
static inline int evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu, int thread)
|
||||
{
|
||||
return __perf_evsel__read_on_cpu(evsel, cpu, thread, true);
|
||||
return __evsel__read_on_cpu(evsel, cpu, thread, true);
|
||||
}
|
||||
|
||||
int perf_evsel__parse_sample(struct evsel *evsel, union perf_event *event,
|
||||
struct perf_sample *sample);
|
||||
int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
|
||||
struct perf_sample *sample);
|
||||
|
||||
int perf_evsel__parse_sample_timestamp(struct evsel *evsel,
|
||||
union perf_event *event,
|
||||
u64 *timestamp);
|
||||
int evsel__parse_sample_timestamp(struct evsel *evsel, union perf_event *event,
|
||||
u64 *timestamp);
|
||||
|
||||
static inline struct evsel *perf_evsel__next(struct evsel *evsel)
|
||||
static inline struct evsel *evsel__next(struct evsel *evsel)
|
||||
{
|
||||
return list_entry(evsel->core.node.next, struct evsel, core.node);
|
||||
}
|
||||
|
||||
static inline struct evsel *perf_evsel__prev(struct evsel *evsel)
|
||||
static inline struct evsel *evsel__prev(struct evsel *evsel)
|
||||
{
|
||||
return list_entry(evsel->core.node.prev, struct evsel, core.node);
|
||||
}
|
||||
|
||||
/**
|
||||
* perf_evsel__is_group_leader - Return whether given evsel is a leader event
|
||||
* evsel__is_group_leader - Return whether given evsel is a leader event
|
||||
*
|
||||
* @evsel - evsel selector to be tested
|
||||
*
|
||||
* Return %true if @evsel is a group leader or a stand-alone event
|
||||
*/
|
||||
static inline bool perf_evsel__is_group_leader(const struct evsel *evsel)
|
||||
static inline bool evsel__is_group_leader(const struct evsel *evsel)
|
||||
{
|
||||
return evsel->leader == evsel;
|
||||
}
|
||||
|
||||
/**
|
||||
* perf_evsel__is_group_event - Return whether given evsel is a group event
|
||||
* evsel__is_group_event - Return whether given evsel is a group event
|
||||
*
|
||||
* @evsel - evsel selector to be tested
|
||||
*
|
||||
* Return %true iff event group view is enabled and @evsel is a actual group
|
||||
* leader which has other members in the group
|
||||
*/
|
||||
static inline bool perf_evsel__is_group_event(struct evsel *evsel)
|
||||
static inline bool evsel__is_group_event(struct evsel *evsel)
|
||||
{
|
||||
if (!symbol_conf.event_group)
|
||||
return false;
|
||||
|
||||
return perf_evsel__is_group_leader(evsel) && evsel->core.nr_members > 1;
|
||||
return evsel__is_group_leader(evsel) && evsel->core.nr_members > 1;
|
||||
}
|
||||
|
||||
bool perf_evsel__is_function_event(struct evsel *evsel);
|
||||
bool evsel__is_function_event(struct evsel *evsel);
|
||||
|
||||
static inline bool perf_evsel__is_bpf_output(struct evsel *evsel)
|
||||
static inline bool evsel__is_bpf_output(struct evsel *evsel)
|
||||
{
|
||||
return perf_evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT);
|
||||
return evsel__match(evsel, SOFTWARE, SW_BPF_OUTPUT);
|
||||
}
|
||||
|
||||
static inline bool perf_evsel__is_clock(struct evsel *evsel)
|
||||
static inline bool evsel__is_clock(struct evsel *evsel)
|
||||
{
|
||||
return perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
|
||||
perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK);
|
||||
return evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
|
||||
evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK);
|
||||
}
|
||||
|
||||
bool perf_evsel__fallback(struct evsel *evsel, int err,
|
||||
char *msg, size_t msgsize);
|
||||
int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
|
||||
int err, char *msg, size_t size);
|
||||
bool evsel__fallback(struct evsel *evsel, int err, char *msg, size_t msgsize);
|
||||
int evsel__open_strerror(struct evsel *evsel, struct target *target,
|
||||
int err, char *msg, size_t size);
|
||||
|
||||
static inline int perf_evsel__group_idx(struct evsel *evsel)
|
||||
static inline int evsel__group_idx(struct evsel *evsel)
|
||||
{
|
||||
return evsel->idx - evsel->leader->idx;
|
||||
}
|
||||
|
|
@ -397,12 +371,12 @@ for ((_evsel) = _leader; \
|
|||
(_evsel) && (_evsel)->leader == (_leader); \
|
||||
(_evsel) = list_entry((_evsel)->core.node.next, struct evsel, core.node))
|
||||
|
||||
static inline bool perf_evsel__has_branch_callstack(const struct evsel *evsel)
|
||||
static inline bool evsel__has_branch_callstack(const struct evsel *evsel)
|
||||
{
|
||||
return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK;
|
||||
}
|
||||
|
||||
static inline bool perf_evsel__has_branch_hw_idx(const struct evsel *evsel)
|
||||
static inline bool evsel__has_branch_hw_idx(const struct evsel *evsel)
|
||||
{
|
||||
return evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
|
||||
}
|
||||
|
|
@ -417,7 +391,17 @@ static inline bool evsel__has_callchain(const struct evsel *evsel)
|
|||
evsel->synth_sample_type & PERF_SAMPLE_CALLCHAIN;
|
||||
}
|
||||
|
||||
struct perf_env *perf_evsel__env(struct evsel *evsel);
|
||||
static inline bool evsel__has_br_stack(const struct evsel *evsel)
|
||||
{
|
||||
/*
|
||||
* For reporting purposes, an evsel sample can have a recorded branch
|
||||
* stack or a branch stack synthesized from AUX area data.
|
||||
*/
|
||||
return evsel->core.attr.sample_type & PERF_SAMPLE_BRANCH_STACK ||
|
||||
evsel->synth_sample_type & PERF_SAMPLE_BRANCH_STACK;
|
||||
}
|
||||
|
||||
int perf_evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
|
||||
struct perf_env *evsel__env(struct evsel *evsel);
|
||||
|
||||
int evsel__store_ids(struct evsel *evsel, struct evlist *evlist);
|
||||
#endif /* __PERF_EVSEL_H */
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
/*
|
||||
* The 'struct perf_evsel_config_term' is used to pass event
|
||||
* specific configuration data to perf_evsel__config routine.
|
||||
* specific configuration data to evsel__config routine.
|
||||
* It is allocated within event parsing and attached to
|
||||
* perf_evsel::config_terms list head.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,22 +44,22 @@ int perf_evsel__fprintf(struct evsel *evsel,
|
|||
if (details->event_group) {
|
||||
struct evsel *pos;
|
||||
|
||||
if (!perf_evsel__is_group_leader(evsel))
|
||||
if (!evsel__is_group_leader(evsel))
|
||||
return 0;
|
||||
|
||||
if (evsel->core.nr_members > 1)
|
||||
printed += fprintf(fp, "%s{", evsel->group_name ?: "");
|
||||
|
||||
printed += fprintf(fp, "%s", perf_evsel__name(evsel));
|
||||
printed += fprintf(fp, "%s", evsel__name(evsel));
|
||||
for_each_group_member(pos, evsel)
|
||||
printed += fprintf(fp, ",%s", perf_evsel__name(pos));
|
||||
printed += fprintf(fp, ",%s", evsel__name(pos));
|
||||
|
||||
if (evsel->core.nr_members > 1)
|
||||
printed += fprintf(fp, "}");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printed += fprintf(fp, "%s", perf_evsel__name(evsel));
|
||||
printed += fprintf(fp, "%s", evsel__name(evsel));
|
||||
|
||||
if (details->verbose) {
|
||||
printed += perf_event_attr__fprintf(fp, &evsel->core.attr,
|
||||
|
|
|
|||
|
|
@ -27,10 +27,11 @@ void expr__ctx_init(struct expr_parse_ctx *ctx)
|
|||
|
||||
static int
|
||||
__expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
||||
int start)
|
||||
int start, int runtime)
|
||||
{
|
||||
struct expr_scanner_ctx scanner_ctx = {
|
||||
.start_token = start,
|
||||
.runtime = runtime,
|
||||
};
|
||||
YY_BUFFER_STATE buffer;
|
||||
void *scanner;
|
||||
|
|
@ -54,9 +55,9 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr)
|
||||
int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr, int runtime)
|
||||
{
|
||||
return __expr__parse(final_val, ctx, expr, EXPR_PARSE) ? -1 : 0;
|
||||
return __expr__parse(final_val, ctx, expr, EXPR_PARSE, runtime) ? -1 : 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -74,13 +75,13 @@ already_seen(const char *val, const char *one, const char **other,
|
|||
}
|
||||
|
||||
int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
int *num_other)
|
||||
int *num_other, int runtime)
|
||||
{
|
||||
int err, i = 0, j = 0;
|
||||
struct expr_parse_ctx ctx;
|
||||
|
||||
expr__ctx_init(&ctx);
|
||||
err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER);
|
||||
err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER, runtime);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@ struct expr_parse_ctx {
|
|||
|
||||
struct expr_scanner_ctx {
|
||||
int start_token;
|
||||
int runtime;
|
||||
};
|
||||
|
||||
void expr__ctx_init(struct expr_parse_ctx *ctx);
|
||||
void expr__add_id(struct expr_parse_ctx *ctx, const char *id, double val);
|
||||
int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr);
|
||||
int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr, int runtime);
|
||||
int expr__find_other(const char *expr, const char *one, const char ***other,
|
||||
int *num_other);
|
||||
int *num_other, int runtime);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ static int value(yyscan_t scanner, int base)
|
|||
* Allow @ instead of / to be able to specify pmu/event/ without
|
||||
* conflicts with normal division.
|
||||
*/
|
||||
static char *normalize(char *str)
|
||||
static char *normalize(char *str, int runtime)
|
||||
{
|
||||
char *ret = str;
|
||||
char *dst = str;
|
||||
|
|
@ -45,6 +45,19 @@ static char *normalize(char *str)
|
|||
*dst++ = '/';
|
||||
else if (*str == '\\')
|
||||
*dst++ = *++str;
|
||||
else if (*str == '?') {
|
||||
char *paramval;
|
||||
int i = 0;
|
||||
int size = asprintf(¶mval, "%d", runtime);
|
||||
|
||||
if (size < 0)
|
||||
*dst++ = '0';
|
||||
else {
|
||||
while (i < size)
|
||||
*dst++ = paramval[i++];
|
||||
free(paramval);
|
||||
}
|
||||
}
|
||||
else
|
||||
*dst++ = *str;
|
||||
str++;
|
||||
|
|
@ -54,16 +67,16 @@ static char *normalize(char *str)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int str(yyscan_t scanner, int token)
|
||||
static int str(yyscan_t scanner, int token, int runtime)
|
||||
{
|
||||
YYSTYPE *yylval = expr_get_lval(scanner);
|
||||
char *text = expr_get_text(scanner);
|
||||
|
||||
yylval->str = normalize(strdup(text));
|
||||
yylval->str = normalize(strdup(text), runtime);
|
||||
if (!yylval->str)
|
||||
return EXPR_ERROR;
|
||||
|
||||
yylval->str = normalize(yylval->str);
|
||||
yylval->str = normalize(yylval->str, runtime);
|
||||
return token;
|
||||
}
|
||||
%}
|
||||
|
|
@ -72,8 +85,8 @@ number [0-9]+
|
|||
|
||||
sch [-,=]
|
||||
spec \\{sch}
|
||||
sym [0-9a-zA-Z_\.:@]+
|
||||
symbol {spec}*{sym}*{spec}*{sym}*
|
||||
sym [0-9a-zA-Z_\.:@?]+
|
||||
symbol {spec}*{sym}*{spec}*{sym}*{spec}*{sym}
|
||||
|
||||
%%
|
||||
struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
|
||||
|
|
@ -93,7 +106,7 @@ if { return IF; }
|
|||
else { return ELSE; }
|
||||
#smt_on { return SMT_ON; }
|
||||
{number} { return value(yyscanner, 10); }
|
||||
{symbol} { return str(yyscanner, ID); }
|
||||
{symbol} { return str(yyscanner, ID, sctx->runtime); }
|
||||
"|" { return '|'; }
|
||||
"^" { return '^'; }
|
||||
"&" { return '&'; }
|
||||
|
|
|
|||
|
|
@ -525,7 +525,7 @@ static int write_event_desc(struct feat_fd *ff,
|
|||
/*
|
||||
* write event string as passed on cmdline
|
||||
*/
|
||||
ret = do_write_string(ff, perf_evsel__name(evsel));
|
||||
ret = do_write_string(ff, evsel__name(evsel));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/*
|
||||
|
|
@ -783,8 +783,7 @@ static int write_group_desc(struct feat_fd *ff,
|
|||
return ret;
|
||||
|
||||
evlist__for_each_entry(evlist, evsel) {
|
||||
if (perf_evsel__is_group_leader(evsel) &&
|
||||
evsel->core.nr_members > 1) {
|
||||
if (evsel__is_group_leader(evsel) && evsel->core.nr_members > 1) {
|
||||
const char *name = evsel->group_name ?: "{anon_group}";
|
||||
u32 leader_idx = evsel->idx;
|
||||
u32 nr_members = evsel->core.nr_members;
|
||||
|
|
@ -1907,14 +1906,12 @@ static void print_group_desc(struct feat_fd *ff, FILE *fp)
|
|||
session = container_of(ff->ph, struct perf_session, header);
|
||||
|
||||
evlist__for_each_entry(session->evlist, evsel) {
|
||||
if (perf_evsel__is_group_leader(evsel) &&
|
||||
evsel->core.nr_members > 1) {
|
||||
fprintf(fp, "# group: %s{%s", evsel->group_name ?: "",
|
||||
perf_evsel__name(evsel));
|
||||
if (evsel__is_group_leader(evsel) && evsel->core.nr_members > 1) {
|
||||
fprintf(fp, "# group: %s{%s", evsel->group_name ?: "", evsel__name(evsel));
|
||||
|
||||
nr = evsel->core.nr_members - 1;
|
||||
} else if (nr) {
|
||||
fprintf(fp, ",%s", perf_evsel__name(evsel));
|
||||
fprintf(fp, ",%s", evsel__name(evsel));
|
||||
|
||||
if (--nr == 0)
|
||||
fprintf(fp, "}\n");
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user