tools/perf: Allow inherit + PERF_SAMPLE_READ when opening events

The "perf record" tool will now default to this new mode if the user
specifies a sampling group when not in system-wide mode, and when
"--no-inherit" is not specified.

This change updates evsel to allow the combination of inherit
and PERF_SAMPLE_READ.

A fallback is implemented for kernel versions where this feature is not
supported.

Signed-off-by: Ben Gainey <ben.gainey@arm.com>
Cc: james.clark@arm.com
Link: https://lore.kernel.org/r/20241001121505.1009685-3-ben.gainey@arm.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Ben Gainey 2024-10-01 13:15:05 +01:00 committed by Namhyung Kim
parent 80c281fca2
commit 90035d3cd8
10 changed files with 169 additions and 5 deletions

View file

@ -51,6 +51,8 @@ Following tests are defined (with perf commands):
perf record --call-graph fp kill (test-record-graph-fp-aarch64)
perf record -e '{cycles,instructions}' kill (test-record-group1)
perf record -e '{cycles/period=1/,instructions/period=2/}:S' kill (test-record-group2)
perf record -e '{cycles,cache-misses}:S' kill (test-record-group-sampling1)
perf record -c 10000 -e '{cycles,cache-misses}:S' kill (test-record-group-sampling2)
perf record -D kill (test-record-no-delay)
perf record -i kill (test-record-no-inherit)
perf record -n kill (test-record-no-samples)

View file

@ -18,5 +18,7 @@ sample_type=65927
mmap=0
comm=0
task=0
inherit=0
[event:system-wide-dummy]
inherit=0

View file

@ -19,7 +19,7 @@ sample_period=4000
sample_type=391
read_format=4|20
disabled=0
inherit=1
inherit=0
pinned=0
exclusive=0
exclude_user=0

View file

@ -2,6 +2,7 @@
command = record
args = --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
ret = 1
kernel_until = 6.12
[event-1:base-record]
fd=1
@ -18,7 +19,7 @@ group_fd=1
type=0
config=3
# default | PERF_SAMPLE_READ
# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD
sample_type=343
# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST

View file

@ -0,0 +1,50 @@
[config]
command = record
args = --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
ret = 1
kernel_since = 6.12
[event-1:base-record]
fd=1
group_fd=-1
# cycles
type=0
config=0
# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD
sample_type=343
# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
read_format=28|31
task=1
mmap=1
comm=1
enable_on_exec=1
disabled=1
# inherit is enabled for group sampling
inherit=1
[event-2:base-record]
fd=2
group_fd=1
# cache-misses
type=0
config=3
# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD
sample_type=343
# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
read_format=28|31
task=0
mmap=0
comm=0
enable_on_exec=0
disabled=0
freq=0
# inherit is enabled for group sampling
inherit=1

View file

@ -0,0 +1,61 @@
[config]
command = record
args = --no-bpf-event -c 10000 -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
ret = 1
kernel_since = 6.12
[event-1:base-record]
fd=1
group_fd=-1
# cycles
type=0
config=0
# default | PERF_SAMPLE_READ
sample_type=87
# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
read_format=28|31
task=1
mmap=1
comm=1
enable_on_exec=1
disabled=1
# inherit is enabled for group sampling
inherit=1
# sampling disabled
sample_freq=0
sample_period=10000
freq=0
write_backward=0
[event-2:base-record]
fd=2
group_fd=1
# cache-misses
type=0
config=3
# default | PERF_SAMPLE_READ
sample_type=87
# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING
read_format=28|31
task=0
mmap=0
comm=0
enable_on_exec=0
disabled=0
# inherit is enabled for group sampling
inherit=1
# sampling disabled
sample_freq=0
sample_period=0
freq=0
write_backward=0

View file

@ -2,6 +2,7 @@
command = record
args = --no-bpf-event -e '{cycles/period=1234000/,instructions/period=6789000/}:S' kill >/dev/null 2>&1
ret = 1
kernel_until = 6.12
[event-1:base-record]
fd=1

View file

@ -0,0 +1,31 @@
[config]
command = record
args = --no-bpf-event -e '{cycles/period=1234000/,instructions/period=6789000/}:S' kill >/dev/null 2>&1
ret = 1
kernel_since = 6.12
[event-1:base-record]
fd=1
group_fd=-1
config=0|1
sample_period=1234000
sample_type=87
read_format=28|31
disabled=1
inherit=1
freq=0
[event-2:base-record]
fd=2
group_fd=1
config=0|1
sample_period=6789000
sample_type=87
read_format=28|31
disabled=0
inherit=1
mmap=0
comm=0
freq=0
enable_on_exec=0
task=0

View file

@ -1148,7 +1148,7 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread;
attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
attr->inherit = !opts->no_inherit;
attr->inherit = target__has_cpu(&opts->target) ? 0 : !opts->no_inherit;
attr->write_backward = opts->overwrite ? 1 : 0;
attr->read_format = PERF_FORMAT_LOST;
@ -1170,7 +1170,15 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
*/
if (leader->core.nr_members > 1) {
attr->read_format |= PERF_FORMAT_GROUP;
attr->inherit = 0;
}
/*
* Inherit + SAMPLE_READ requires SAMPLE_TID in the read_format
*/
if (attr->inherit) {
evsel__set_sample_bit(evsel, TID);
evsel->core.attr.read_format |=
PERF_FORMAT_ID;
}
}
@ -2104,6 +2112,8 @@ static int __evsel__prepare_open(struct evsel *evsel, struct perf_cpu_map *cpus,
static void evsel__disable_missing_features(struct evsel *evsel)
{
if (perf_missing_features.inherit_sample_read)
evsel->core.attr.inherit = 0;
if (perf_missing_features.branch_counters)
evsel->core.attr.branch_sample_type &= ~PERF_SAMPLE_BRANCH_COUNTERS;
if (perf_missing_features.read_lost)
@ -2159,7 +2169,12 @@ bool evsel__detect_missing_features(struct evsel *evsel)
* Must probe features in the order they were added to the
* perf_event_attr interface.
*/
if (!perf_missing_features.branch_counters &&
if (!perf_missing_features.inherit_sample_read &&
evsel->core.attr.inherit && (evsel->core.attr.sample_type & PERF_SAMPLE_READ)) {
perf_missing_features.inherit_sample_read = true;
pr_debug2("Using PERF_SAMPLE_READ / :S modifier is not compatible with inherit, falling back to no-inherit.\n");
return true;
} else if (!perf_missing_features.branch_counters &&
(evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) {
perf_missing_features.branch_counters = true;
pr_debug2("switching off branch counters support\n");

View file

@ -221,6 +221,7 @@ struct perf_missing_features {
bool weight_struct;
bool read_lost;
bool branch_counters;
bool inherit_sample_read;
};
extern struct perf_missing_features perf_missing_features;