From nobody Thu Nov 28 12:36:17 2024 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0EA56188938; Tue, 1 Oct 2024 12:15:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727784948; cv=none; b=UfwEExSt3MKbWe2ojGrA4K5InnNHIqTa7n2byNtRPCxSi0D/baCTATxB96S6wokQAUHRLdrKAP+KKUIZivNx/amx1AZCsOpxRvq+ZFZJKC6XvUt6aTp53aLr/L7LORdenzcJFo+X17N06+aIJLaTreHKS1xSYPllOTpR1T7lZGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727784948; c=relaxed/simple; bh=HwDLj/H7orJxKlxbKhY5waYIeG+1lBz6C9eK5XxG0Yg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=roFOyndBBPKhlGRXKthUZECsX7YKVMUdxlq/11gajbqMNbxrl0sjAgbBt8Oo6cs4jbkIs51GLbxeYIaev6ctXZpkhxp7+4ZHjRIuM/C/IywqNNGuGMtcOXX2ktZr5ABVX69z07JLBm8Zhh8Q/MMNWczdD6+WYd2No/cp431tfmQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B98E0367; Tue, 1 Oct 2024 05:16:14 -0700 (PDT) Received: from e126817.cambridge.arm.com (e126817.cambridge.arm.com [10.2.3.5]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3961B3F58B; Tue, 1 Oct 2024 05:15:43 -0700 (PDT) From: Ben Gainey To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org Cc: james.clark@arm.com, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gainey Subject: [PATCH v12 1/2] tools/perf: Correctly calculate sample period for inherited SAMPLE_READ values Date: Tue, 1 Oct 2024 13:15:04 +0100 Message-ID: <20241001121505.1009685-2-ben.gainey@arm.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241001121505.1009685-1-ben.gainey@arm.com> References: <20241001121505.1009685-1-ben.gainey@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Sample period calculation in deliver_sample_value is updated to calculate the per-thread period delta for events that are inherit + PERF_SAMPLE_READ. When the sampling event has this configuration, the read_format.id is used with the tid from the sample to lookup the storage of the previously accumulated counter total before calculating the delta. All existing valid configurations where read_format.value represents some global value continue to use just the read_format.id to locate the storage of the previously accumulated total. perf_sample_id is modified to support tracking per-thread values, along with the existing global per-id values. In the per-thread case, values are stored in a hash by tid within the perf_sample_id, and are dynamically allocated as the number is not known ahead of time. Signed-off-by: Ben Gainey --- tools/lib/perf/evsel.c | 48 +++++++++++++++++++ tools/lib/perf/include/internal/evsel.h | 63 ++++++++++++++++++++++++- tools/perf/util/session.c | 28 +++++++---- 3 files changed, 128 insertions(+), 11 deletions(-) diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c index c07160953224..c475319e2e41 100644 --- a/tools/lib/perf/evsel.c +++ b/tools/lib/perf/evsel.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ void perf_evsel__init(struct perf_evsel *evsel, struct pe= rf_event_attr *attr, int idx) { INIT_LIST_HEAD(&evsel->node); + INIT_LIST_HEAD(&evsel->per_stream_periods); evsel->attr =3D *attr; evsel->idx =3D idx; evsel->leader =3D evsel; @@ -531,10 +533,56 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, in= t ncpus, int nthreads) =20 void perf_evsel__free_id(struct perf_evsel *evsel) { + struct perf_sample_id_period *pos, *n; + xyarray__delete(evsel->sample_id); evsel->sample_id =3D NULL; zfree(&evsel->id); evsel->ids =3D 0; + + perf_evsel_for_each_per_thread_period_safe(evsel, n, pos) { + list_del_init(&pos->node); + free(pos); + } +} + +bool perf_evsel__attr_has_per_thread_sample_period(struct perf_evsel *evse= l) +{ + return (evsel->attr.sample_type & PERF_SAMPLE_READ) && + (evsel->attr.sample_type & PERF_SAMPLE_TID) && + evsel->attr.inherit; +} + +u64 *perf_sample_id__get_period_storage(struct perf_sample_id *sid, u32 ti= d, bool per_thread) +{ + struct hlist_head *head; + struct perf_sample_id_period *res; + int hash; + + if (!per_thread) + return &sid->period; + + hash =3D hash_32(tid, PERF_SAMPLE_ID__HLIST_BITS); + head =3D &sid->periods[hash]; + + hlist_for_each_entry(res, head, hnode) + if (res->tid =3D=3D tid) + return &res->period; + + if (sid->evsel =3D=3D NULL) + return NULL; + + res =3D zalloc(sizeof(struct perf_sample_id_period)); + if (res =3D=3D NULL) + return NULL; + + INIT_LIST_HEAD(&res->node); + res->tid =3D tid; + + list_add_tail(&res->node, &sid->evsel->per_stream_periods); + hlist_add_head(&res->hnode, &sid->periods[hash]); + + return &res->period; } =20 void perf_counts_values__scale(struct perf_counts_values *count, diff --git a/tools/lib/perf/include/internal/evsel.h b/tools/lib/perf/inclu= de/internal/evsel.h index 5cd220a61962..ea78defa77d0 100644 --- a/tools/lib/perf/include/internal/evsel.h +++ b/tools/lib/perf/include/internal/evsel.h @@ -11,6 +11,32 @@ struct perf_thread_map; struct xyarray; =20 +/** + * The per-thread accumulated period storage node. + */ +struct perf_sample_id_period { + struct list_head node; + struct hlist_node hnode; + /* Holds total ID period value for PERF_SAMPLE_READ processing. */ + u64 period; + /* The TID that the values belongs to */ + u32 tid; +}; + +/** + * perf_evsel_for_each_per_thread_period_safe - safely iterate thru all the + * per_stream_periods + * @evlist:perf_evsel instance to iterate + * @item: struct perf_sample_id_period iterator + * @tmp: struct perf_sample_id_period temp iterator + */ +#define perf_evsel_for_each_per_thread_period_safe(evsel, tmp, item) \ + list_for_each_entry_safe(item, tmp, &(evsel)->per_stream_periods, node) + + +#define PERF_SAMPLE_ID__HLIST_BITS 4 +#define PERF_SAMPLE_ID__HLIST_SIZE (1 << PERF_SAMPLE_ID__HLIST_BITS) + /* * Per fd, to map back from PERF_SAMPLE_ID to evsel, only used when there = are * more than one entry in the evlist. @@ -34,8 +60,32 @@ struct perf_sample_id { pid_t machine_pid; struct perf_cpu vcpu; =20 - /* Holds total ID period value for PERF_SAMPLE_READ processing. */ - u64 period; + /* + * Per-thread, and global event counts are mutually exclusive: + * Whilst it is possible to combine events into a group with differing + * values of PERF_SAMPLE_READ, it is not valid to have inconsistent + * values for `inherit`. Therefore it is not possible to have a + * situation where a per-thread event is sampled as a global event; + * all !inherit groups are global, and all groups where the sampling + * event is inherit + PERF_SAMPLE_READ will be per-thread. Any event + * that is part of such a group that is inherit but not PERF_SAMPLE_READ + * will be read as per-thread. If such an event can also trigger a + * sample (such as with sample_period > 0) then it will not cause + * `read_format` to be included in its PERF_RECORD_SAMPLE, and + * therefore will not expose the per-thread group members as global. + */ + union { + /* + * Holds total ID period value for PERF_SAMPLE_READ processing + * (when period is not per-thread). + */ + u64 period; + /* + * Holds total ID period value for PERF_SAMPLE_READ processing + * (when period is per-thread). + */ + struct hlist_head periods[PERF_SAMPLE_ID__HLIST_SIZE]; + }; }; =20 struct perf_evsel { @@ -58,6 +108,10 @@ struct perf_evsel { u32 ids; struct perf_evsel *leader; =20 + /* For events where the read_format value is per-thread rather than + * global, stores the per-thread cumulative period */ + struct list_head per_stream_periods; + /* parse modifier helper */ int nr_members; /* @@ -88,4 +142,9 @@ int perf_evsel__apply_filter(struct perf_evsel *evsel, c= onst char *filter); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads= ); void perf_evsel__free_id(struct perf_evsel *evsel); =20 +bool perf_evsel__attr_has_per_thread_sample_period(struct perf_evsel *evse= l); + +u64 *perf_sample_id__get_period_storage(struct perf_sample_id *sid, u32 ti= d, + bool per_thread); + #endif /* __LIBPERF_INTERNAL_EVSEL_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index dbaf07bf6c5f..507e6cba9545 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1171,18 +1171,24 @@ static int deliver_sample_value(struct evlist *evli= st, union perf_event *event, struct perf_sample *sample, struct sample_read_value *v, - struct machine *machine) + struct machine *machine, + bool per_thread) { struct perf_sample_id *sid =3D evlist__id2sid(evlist, v->id); struct evsel *evsel; + u64 *storage =3D NULL; =20 if (sid) { + storage =3D perf_sample_id__get_period_storage(sid, sample->tid, per_thr= ead); + } + + if (storage) { sample->id =3D v->id; - sample->period =3D v->value - sid->period; - sid->period =3D v->value; + sample->period =3D v->value - *storage; + *storage =3D v->value; } =20 - if (!sid || sid->evsel =3D=3D NULL) { + if (!storage || sid->evsel =3D=3D NULL) { ++evlist->stats.nr_unknown_id; return 0; } @@ -1203,17 +1209,19 @@ static int deliver_sample_group(struct evlist *evli= st, union perf_event *event, struct perf_sample *sample, struct machine *machine, - u64 read_format) + u64 read_format, + bool per_thread) { int ret =3D -EINVAL; struct sample_read_value *v =3D sample->read.group.values; =20 if (tool->dont_split_sample_group) - return deliver_sample_value(evlist, tool, event, sample, v, machine); + return deliver_sample_value(evlist, tool, event, sample, v, machine, + per_thread); =20 sample_read_group__for_each(v, sample->read.group.nr, read_format) { ret =3D deliver_sample_value(evlist, tool, event, sample, v, - machine); + machine, per_thread); if (ret) break; } @@ -1228,6 +1236,7 @@ static int evlist__deliver_sample(struct evlist *evli= st, const struct perf_tool /* We know evsel !=3D NULL. */ u64 sample_type =3D evsel->core.attr.sample_type; u64 read_format =3D evsel->core.attr.read_format; + bool per_thread =3D perf_evsel__attr_has_per_thread_sample_period(&evsel-= >core); =20 /* Standard sample delivery. */ if (!(sample_type & PERF_SAMPLE_READ)) @@ -1236,10 +1245,11 @@ static int evlist__deliver_sample(struct evlist *ev= list, const struct perf_tool /* For PERF_SAMPLE_READ we have either single or group mode. */ if (read_format & PERF_FORMAT_GROUP) return deliver_sample_group(evlist, tool, event, sample, - machine, read_format); + machine, read_format, per_thread); else return deliver_sample_value(evlist, tool, event, sample, - &sample->read.one, machine); + &sample->read.one, machine, + per_thread); } =20 static int machines__deliver_event(struct machines *machines, --=20 2.46.1 From nobody Thu Nov 28 12:36:17 2024 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 212CD1C2438; Tue, 1 Oct 2024 12:15:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727784950; cv=none; b=RdXvhGzgWXhwrJ0z9n1fRJqui1x3r4JLNWTNkBSycfbSZ2FnQSEE/3D9mIa/nFFCUSf2ksTPJq3oxgX3fo5bAwnpp/MfcxE5pJMIseVfHo6s10IoSUCnARAL+Xe4oERu1bSe8Zmb+vxYY4GtdCXO4/mN9ExDNKKlZXNjVYbssls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727784950; c=relaxed/simple; bh=gCR3KLInBSs1V1xQ4gsZJMF6jcF6sqI3qnZobKenBfg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GItqXIMuy/B+CFd0F760P2+VubVROcjx5PoxYkIVAdMNfaRm+fPY0z2UGevAfbX/zxRB75JhzLWo4rzIlSuPS0t1jVpAHuuB2beyLDdNdgmi2dsdRHhJ4ehXDPEbso1CXnfqr+k3TMFP0yuMnQt4NwbwN+PuTeUFeRIRxjRq0/U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0B469DA7; Tue, 1 Oct 2024 05:16:17 -0700 (PDT) Received: from e126817.cambridge.arm.com (e126817.cambridge.arm.com [10.2.3.5]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7EE633F58B; Tue, 1 Oct 2024 05:15:45 -0700 (PDT) From: Ben Gainey To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org, namhyung@kernel.org Cc: james.clark@arm.com, mark.rutland@arm.com, alexander.shishkin@linux.intel.com, jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gainey Subject: [PATCH v12 2/2] tools/perf: Allow inherit + PERF_SAMPLE_READ when opening events Date: Tue, 1 Oct 2024 13:15:05 +0100 Message-ID: <20241001121505.1009685-3-ben.gainey@arm.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241001121505.1009685-1-ben.gainey@arm.com> References: <20241001121505.1009685-1-ben.gainey@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- tools/perf/tests/attr/README | 2 + tools/perf/tests/attr/test-record-C0 | 2 + tools/perf/tests/attr/test-record-dummy-C0 | 2 +- .../tests/attr/test-record-group-sampling | 3 +- .../tests/attr/test-record-group-sampling1 | 51 ++++++++++++++++ .../tests/attr/test-record-group-sampling2 | 61 +++++++++++++++++++ tools/perf/tests/attr/test-record-group2 | 1 + ...{test-record-group2 =3D> test-record-group3} | 10 +-- tools/perf/util/evsel.c | 21 ++++++- tools/perf/util/evsel.h | 1 + 10 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 tools/perf/tests/attr/test-record-group-sampling1 create mode 100644 tools/perf/tests/attr/test-record-group-sampling2 copy tools/perf/tests/attr/{test-record-group2 =3D> test-record-group3} (8= 1%) diff --git a/tools/perf/tests/attr/README b/tools/perf/tests/attr/README index 4066fec7180a..67c4ca76b85d 100644 --- a/tools/perf/tests/attr/README +++ b/tools/perf/tests/attr/README @@ -51,6 +51,8 @@ Following tests are defined (with perf commands): perf record --call-graph fp kill (test-record-graph-fp-aarc= h64) perf record -e '{cycles,instructions}' kill (test-record-group1) perf record -e '{cycles/period=3D1/,instructions/period=3D2/}:S' kill (t= est-record-group2) + perf record -e '{cycles,cache-misses}:S' kill (test-record-group-samplin= g1) + perf record -c 10000 -e '{cycles,cache-misses}:S' kill (test-record-grou= p-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) diff --git a/tools/perf/tests/attr/test-record-C0 b/tools/perf/tests/attr/t= est-record-C0 index 198e8429a1bf..1049ac8b52f2 100644 --- a/tools/perf/tests/attr/test-record-C0 +++ b/tools/perf/tests/attr/test-record-C0 @@ -18,5 +18,7 @@ sample_type=3D65927 mmap=3D0 comm=3D0 task=3D0 +inherit=3D0 =20 [event:system-wide-dummy] +inherit=3D0 diff --git a/tools/perf/tests/attr/test-record-dummy-C0 b/tools/perf/tests/= attr/test-record-dummy-C0 index 576ec48b3aaf..3050298bd614 100644 --- a/tools/perf/tests/attr/test-record-dummy-C0 +++ b/tools/perf/tests/attr/test-record-dummy-C0 @@ -19,7 +19,7 @@ sample_period=3D4000 sample_type=3D391 read_format=3D4|20 disabled=3D0 -inherit=3D1 +inherit=3D0 pinned=3D0 exclusive=3D0 exclude_user=3D0 diff --git a/tools/perf/tests/attr/test-record-group-sampling b/tools/perf/= tests/attr/test-record-group-sampling index 97e7e64a38f0..86a940d7895d 100644 --- a/tools/perf/tests/attr/test-record-group-sampling +++ b/tools/perf/tests/attr/test-record-group-sampling @@ -2,6 +2,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>= &1 ret =3D 1 +kernel_until =3D 6.12 =20 [event-1:base-record] fd=3D1 @@ -18,7 +19,7 @@ group_fd=3D1 type=3D0 config=3D3 =20 -# default | PERF_SAMPLE_READ +# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD sample_type=3D343 =20 # PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST diff --git a/tools/perf/tests/attr/test-record-group-sampling1 b/tools/perf= /tests/attr/test-record-group-sampling1 new file mode 100644 index 000000000000..e96a10627a46 --- /dev/null +++ b/tools/perf/tests/attr/test-record-group-sampling1 @@ -0,0 +1,51 @@ +[config] +command =3D record +args =3D --no-bpf-event -e '{cycles,cache-misses}:S' kill >/dev/null 2>= &1 +ret =3D 1 +kernel_since =3D 6.12 + +[event-1:base-record] +fd=3D1 +group_fd=3D-1 + +# cycles +type=3D0 +config=3D0 + +# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD +sample_type=3D343 + +# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOT= AL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING +read_format=3D28|31 +task=3D1 +mmap=3D1 +comm=3D1 +enable_on_exec=3D1 +disabled=3D1 + +# inherit is enabled for group sampling +inherit=3D1 + +[event-2:base-record] +fd=3D2 +group_fd=3D1 + +# cache-misses +type=3D0 +config=3D3 + +# default | PERF_SAMPLE_READ | PERF_SAMPLE_PERIOD +sample_type=3D343 + +# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOT= AL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING +read_format=3D28|31 +task=3D0 +mmap=3D0 +comm=3D0 +enable_on_exec=3D0 +disabled=3D0 +freq=3D0 + +# inherit is enabled for group sampling +inherit=3D1 + diff --git a/tools/perf/tests/attr/test-record-group-sampling2 b/tools/perf= /tests/attr/test-record-group-sampling2 new file mode 100644 index 000000000000..e0432244a0eb --- /dev/null +++ b/tools/perf/tests/attr/test-record-group-sampling2 @@ -0,0 +1,61 @@ +[config] +command =3D record +args =3D --no-bpf-event -c 10000 -e '{cycles,cache-misses}:S' kill >/de= v/null 2>&1 +ret =3D 1 +kernel_since =3D 6.12 + +[event-1:base-record] +fd=3D1 +group_fd=3D-1 + +# cycles +type=3D0 +config=3D0 + +# default | PERF_SAMPLE_READ +sample_type=3D87 + +# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOT= AL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING +read_format=3D28|31 +task=3D1 +mmap=3D1 +comm=3D1 +enable_on_exec=3D1 +disabled=3D1 + +# inherit is enabled for group sampling +inherit=3D1 + +# sampling disabled +sample_freq=3D0 +sample_period=3D10000 +freq=3D0 +write_backward=3D0 + +[event-2:base-record] +fd=3D2 +group_fd=3D1 + +# cache-misses +type=3D0 +config=3D3 + +# default | PERF_SAMPLE_READ +sample_type=3D87 + +# PERF_FORMAT_ID | PERF_FORMAT_GROUP | PERF_FORMAT_LOST | PERF_FORMAT_TOT= AL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING +read_format=3D28|31 +task=3D0 +mmap=3D0 +comm=3D0 +enable_on_exec=3D0 +disabled=3D0 + +# inherit is enabled for group sampling +inherit=3D1 + +# sampling disabled +sample_freq=3D0 +sample_period=3D0 +freq=3D0 +write_backward=3D0 diff --git a/tools/perf/tests/attr/test-record-group2 b/tools/perf/tests/at= tr/test-record-group2 index cebdaa8e64e4..891d41a7bddf 100644 --- a/tools/perf/tests/attr/test-record-group2 +++ b/tools/perf/tests/attr/test-record-group2 @@ -2,6 +2,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles/period=3D1234000/,instructions/peri= od=3D6789000/}:S' kill >/dev/null 2>&1 ret =3D 1 +kernel_until =3D 6.12 =20 [event-1:base-record] fd=3D1 diff --git a/tools/perf/tests/attr/test-record-group2 b/tools/perf/tests/at= tr/test-record-group3 similarity index 81% copy from tools/perf/tests/attr/test-record-group2 copy to tools/perf/tests/attr/test-record-group3 index cebdaa8e64e4..249be884959e 100644 --- a/tools/perf/tests/attr/test-record-group2 +++ b/tools/perf/tests/attr/test-record-group3 @@ -2,6 +2,7 @@ command =3D record args =3D --no-bpf-event -e '{cycles/period=3D1234000/,instructions/peri= od=3D6789000/}:S' kill >/dev/null 2>&1 ret =3D 1 +kernel_since =3D 6.12 =20 [event-1:base-record] fd=3D1 @@ -9,8 +10,9 @@ group_fd=3D-1 config=3D0|1 sample_period=3D1234000 sample_type=3D87 -read_format=3D12|28 -inherit=3D0 +read_format=3D28|31 +disabled=3D1 +inherit=3D1 freq=3D0 =20 [event-2:base-record] @@ -19,9 +21,9 @@ group_fd=3D1 config=3D0|1 sample_period=3D6789000 sample_type=3D87 -read_format=3D12|28 +read_format=3D28|31 disabled=3D0 -inherit=3D0 +inherit=3D1 mmap=3D0 comm=3D0 freq=3D0 diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index edfb376f0611..337d9091996d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1147,7 +1147,7 @@ void evsel__config(struct evsel *evsel, struct record= _opts *opts, bool per_cpu =3D opts->target.default_per_cpu && !opts->target.per_thread; =20 attr->sample_id_all =3D perf_missing_features.sample_id_all ? 0 : 1; - attr->inherit =3D !opts->no_inherit; + attr->inherit =3D target__has_cpu(&opts->target) ? 0 : !opts->no_inhe= rit; attr->write_backward =3D opts->overwrite ? 1 : 0; attr->read_format =3D PERF_FORMAT_LOST; =20 @@ -1169,7 +1169,15 @@ void evsel__config(struct evsel *evsel, struct recor= d_opts *opts, */ if (leader->core.nr_members > 1) { attr->read_format |=3D PERF_FORMAT_GROUP; - attr->inherit =3D 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 |=3D + PERF_FORMAT_ID; } } =20 @@ -2103,6 +2111,8 @@ static int __evsel__prepare_open(struct evsel *evsel,= struct perf_cpu_map *cpus, =20 static void evsel__disable_missing_features(struct evsel *evsel) { + if (perf_missing_features.inherit_sample_read) + evsel->core.attr.inherit =3D 0; if (perf_missing_features.branch_counters) evsel->core.attr.branch_sample_type &=3D ~PERF_SAMPLE_BRANCH_COUNTERS; if (perf_missing_features.read_lost) @@ -2158,7 +2168,12 @@ bool evsel__detect_missing_features(struct evsel *ev= sel) * 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_SAMP= LE_READ)) { + perf_missing_features.inherit_sample_read =3D true; + pr_debug2("Using PERF_SAMPLE_READ / :S modifier is not compatible with i= nherit, 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 =3D true; pr_debug2("switching off branch counters support\n"); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3e751ea769ac..bd08d94d3f8a 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -221,6 +221,7 @@ struct perf_missing_features { bool weight_struct; bool read_lost; bool branch_counters; + bool inherit_sample_read; }; =20 extern struct perf_missing_features perf_missing_features; --=20 2.46.1