Commit e28ee123 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf arm-spe/cs-etm: Directly iterate CPU maps

Rather than iterate all CPUs and see if they are in CPU maps, directly
iterate the CPU map. Similarly make use of the intersect function
taking care for when "any" CPU is specified. Switch
perf_cpu_map__has_any_cpu_or_is_empty() to more appropriate
alternatives.
Reviewed-by: default avatarJames Clark <james.clark@arm.com>
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
Cc: Andrew Jones <ajones@ventanamicro.com>
Cc: André Almeida <andrealmeid@igalia.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Atish Patra <atishp@rivosinc.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Darren Hart <dvhart@infradead.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Steinar H. Gunderson <sesse@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: Yang Li <yang.lee@linux.alibaba.com>
Cc: Yanteng Si <siyanteng@loongson.cn>
Link: https://lore.kernel.org/r/20240202234057.2085863-4-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent dcd45b37
...@@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr, ...@@ -197,38 +197,37 @@ static int cs_etm_validate_timestamp(struct auxtrace_record *itr,
static int cs_etm_validate_config(struct auxtrace_record *itr, static int cs_etm_validate_config(struct auxtrace_record *itr,
struct evsel *evsel) struct evsel *evsel)
{ {
int i, err = -EINVAL; int idx, err = 0;
struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus; struct perf_cpu_map *event_cpus = evsel->evlist->core.user_requested_cpus;
struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus(); struct perf_cpu_map *intersect_cpus;
struct perf_cpu cpu;
/* Set option of each CPU we have */
for (i = 0; i < cpu__max_cpu().cpu; i++) {
struct perf_cpu cpu = { .cpu = i, };
/* /*
* In per-cpu case, do the validation for CPUs to work with. * Set option of each CPU we have. In per-cpu case, do the validation
* In per-thread case, the CPU map is empty. Since the traced * for CPUs to work with. In per-thread case, the CPU map has the "any"
* program can run on any CPUs in this case, thus don't skip * CPU value. Since the traced program can run on any CPUs in this case,
* validation. * thus don't skip validation.
*/ */
if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus) && if (!perf_cpu_map__has_any_cpu(event_cpus)) {
!perf_cpu_map__has(event_cpus, cpu)) struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
continue;
if (!perf_cpu_map__has(online_cpus, cpu)) intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
continue; perf_cpu_map__put(online_cpus);
} else {
intersect_cpus = perf_cpu_map__new_online_cpus();
}
err = cs_etm_validate_context_id(itr, evsel, i); perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
err = cs_etm_validate_context_id(itr, evsel, cpu.cpu);
if (err) if (err)
goto out; break;
err = cs_etm_validate_timestamp(itr, evsel, i);
err = cs_etm_validate_timestamp(itr, evsel, cpu.cpu);
if (err) if (err)
goto out; break;
} }
err = 0; perf_cpu_map__put(intersect_cpus);
out:
perf_cpu_map__put(online_cpus);
return err; return err;
} }
...@@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, ...@@ -435,7 +434,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
* Also the case of per-cpu mmaps, need the contextID in order to be notified * Also the case of per-cpu mmaps, need the contextID in order to be notified
* when a context switch happened. * when a context switch happened.
*/ */
if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) { if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
"timestamp", 1); "timestamp", 1);
evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel,
...@@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, ...@@ -461,7 +460,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
evsel->core.attr.sample_period = 1; evsel->core.attr.sample_period = 1;
/* In per-cpu case, always need the time of mmap events etc */ /* In per-cpu case, always need the time of mmap events etc */
if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus))
evsel__set_sample_bit(evsel, TIME); evsel__set_sample_bit(evsel, TIME);
err = cs_etm_validate_config(itr, cs_etm_evsel); err = cs_etm_validate_config(itr, cs_etm_evsel);
...@@ -533,45 +532,31 @@ static size_t ...@@ -533,45 +532,31 @@ static size_t
cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
struct evlist *evlist __maybe_unused) struct evlist *evlist __maybe_unused)
{ {
int i; int idx;
int etmv3 = 0, etmv4 = 0, ete = 0; int etmv3 = 0, etmv4 = 0, ete = 0;
struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus; struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus;
struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus(); struct perf_cpu_map *intersect_cpus;
struct perf_cpu cpu;
/* cpu map is not empty, we have specific CPUs to work with */
if (!perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) {
for (i = 0; i < cpu__max_cpu().cpu; i++) {
struct perf_cpu cpu = { .cpu = i, };
if (!perf_cpu_map__has(event_cpus, cpu) || if (!perf_cpu_map__has_any_cpu(event_cpus)) {
!perf_cpu_map__has(online_cpus, cpu)) /* cpu map is not "any" CPU , we have specific CPUs to work with */
continue; struct perf_cpu_map *online_cpus = perf_cpu_map__new_online_cpus();
if (cs_etm_is_ete(itr, i)) intersect_cpus = perf_cpu_map__intersect(event_cpus, online_cpus);
ete++; perf_cpu_map__put(online_cpus);
else if (cs_etm_is_etmv4(itr, i))
etmv4++;
else
etmv3++;
}
} else { } else {
/* get configuration for all CPUs in the system */ /* Event can be "any" CPU so count all online CPUs. */
for (i = 0; i < cpu__max_cpu().cpu; i++) { intersect_cpus = perf_cpu_map__new_online_cpus();
struct perf_cpu cpu = { .cpu = i, }; }
perf_cpu_map__for_each_cpu_skip_any(cpu, idx, intersect_cpus) {
if (!perf_cpu_map__has(online_cpus, cpu)) if (cs_etm_is_ete(itr, cpu.cpu))
continue;
if (cs_etm_is_ete(itr, i))
ete++; ete++;
else if (cs_etm_is_etmv4(itr, i)) else if (cs_etm_is_etmv4(itr, cpu.cpu))
etmv4++; etmv4++;
else else
etmv3++; etmv3++;
} }
} perf_cpu_map__put(intersect_cpus);
perf_cpu_map__put(online_cpus);
return (CS_ETM_HEADER_SIZE + return (CS_ETM_HEADER_SIZE +
(ete * CS_ETE_PRIV_SIZE) + (ete * CS_ETE_PRIV_SIZE) +
...@@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr, ...@@ -813,16 +798,15 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
if (!session->evlist->core.nr_mmaps) if (!session->evlist->core.nr_mmaps)
return -EINVAL; return -EINVAL;
/* If the cpu_map is empty all online CPUs are involved */ /* If the cpu_map has the "any" CPU all online CPUs are involved */
if (perf_cpu_map__has_any_cpu_or_is_empty(event_cpus)) { if (perf_cpu_map__has_any_cpu(event_cpus)) {
cpu_map = online_cpus; cpu_map = online_cpus;
} else { } else {
/* Make sure all specified CPUs are online */ /* Make sure all specified CPUs are online */
for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) { struct perf_cpu cpu;
struct perf_cpu cpu = { .cpu = i, };
if (perf_cpu_map__has(event_cpus, cpu) && perf_cpu_map__for_each_cpu(cpu, i, event_cpus) {
!perf_cpu_map__has(online_cpus, cpu)) if (!perf_cpu_map__has(online_cpus, cpu))
return -EINVAL; return -EINVAL;
} }
......
...@@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, ...@@ -232,7 +232,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
* In the case of per-cpu mmaps, sample CPU for AUX event; * In the case of per-cpu mmaps, sample CPU for AUX event;
* also enable the timestamp tracing for samples correlation. * also enable the timestamp tracing for samples correlation.
*/ */
if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) { if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
evsel__set_sample_bit(arm_spe_evsel, CPU); evsel__set_sample_bit(arm_spe_evsel, CPU);
evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel, evsel__set_config_if_unset(arm_spe_pmu, arm_spe_evsel,
"ts_enable", 1); "ts_enable", 1);
...@@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, ...@@ -265,7 +265,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
tracking_evsel->core.attr.sample_period = 1; tracking_evsel->core.attr.sample_period = 1;
/* In per-cpu case, always need the time of mmap events etc */ /* In per-cpu case, always need the time of mmap events etc */
if (!perf_cpu_map__has_any_cpu_or_is_empty(cpus)) { if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) {
evsel__set_sample_bit(tracking_evsel, TIME); evsel__set_sample_bit(tracking_evsel, TIME);
evsel__set_sample_bit(tracking_evsel, CPU); evsel__set_sample_bit(tracking_evsel, CPU);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment