From nobody Sat Nov 30 04:35:11 2024 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE26D1C230F for ; Thu, 12 Sep 2024 19:04:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726167848; cv=none; b=TbIT8PQ2wkGVthHJGQuZWB6HezJZSByPFQXoIn2qTj5DT8g9KnFzPXzSATwX18KISofFzlVscoOF+TaaTB23tQjMMUX2WtF0wNIMTtPk2snoUq2sBgEOw0BtjIpPR1n6QNr7mVDU6LcUvy3d0eID09QNRaU7NgM9ePYxnxhAwgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726167848; c=relaxed/simple; bh=TTIjCYxP53lHBDp2SF08jsCX5D/qc73CFDZaIm095c0=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=H87izZ3msUyUNdIZBA7Hq0oZPxWc8f6DAYn8rK7ZB7HRcy0HW0a43vnoipHpOAq9vf6M/6cykRMgVR5DCKw4q5xIsr4y0R4Q3IkfQjlEDHKbUaEDoBkM9RImKCF8PA6G+nhS5dfbvL+2+tmRqxLy4zwKMTf8JigyHdB05e8Tzao= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fi7HFSmT; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fi7HFSmT" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6d3e062dbeeso20864867b3.0 for ; Thu, 12 Sep 2024 12:04:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1726167846; x=1726772646; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=6jIvOGb3G7M9uAjA6lvLhCc81s2AI2IMSCiiBY2eqtE=; b=fi7HFSmTKr8LuDk62bYTv5aLmMPIZdaxABmeVBHYLexh38vYXRrJACkZSFQery5X7W kZrQLKrzZZ0CeiJ2lYZ8GfQgUefBJmlzSO/9Dokyu2qNwEkktySbWkSQ12S0q05DL0bQ Hrj1Rj7H3XPi0IlgqgQdpzQ0u4wLYeaVI+iv56ULVMm115NtEX3hg9e4BVye5j3aTA2E ocvaLkYc58Mxjdd2o9MhliidSAUjQ8t00NQtbk/P+nGiVa6ZU92sEsbO3rKAvtXAjqpD f+AAeg/pBtOdn6ZEOq00nJvgMnh/mzWhIzDNavVi+PC7XEwmnshMTjUtTivf0PfEKZkR w+Cw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726167846; x=1726772646; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6jIvOGb3G7M9uAjA6lvLhCc81s2AI2IMSCiiBY2eqtE=; b=hhBwjumL6mbQrOJi/woLqpAvIuQKOJ3lzwn0szbrvau8rfDI7jWjSh+Qg1EeghKNQZ Fs7bszM/jdwBWLY2NnxIDWGL7xN36wBaYtx/nsHNOzjJOGbCAPpzQ5L/2nQOM5EL99Lo LP3ki50BRPRsPGmrcmTUyG81EefoLGI97xkvUB2MK1n9zFrDjy10Iw3Q7tjgAmzAqHg0 UIHry0h0KRXvxqhGHc5b/gt5+NHmGeb4vVJYhuYHvf0zuoYIi2RnBP8mzXIsNy0Y8Hz7 ndgOQgS612h+zH/Y36CCHN+pcmk61TM5M2hxhn/7ZbEWO8BF9981EjXWyJBuC4x8C6e2 hiBg== X-Forwarded-Encrypted: i=1; AJvYcCWtad3QeZ88i3EPIxo6hJRP+ZLQL0k9gldgiBcVlxNd/m4HwL79vTbb3Kxp6xG37fNyUKZ/zNkqKliFVs4=@vger.kernel.org X-Gm-Message-State: AOJu0YycCNXWeBCWjXF3rDX6m6Y+QLun0DzDfiMC72951TKJh91dAxyk zsDnGlXvt1sukHHtwTcB9S+RiP+X6l5rCsCQ2Eka7miB8jd9Ad39KwFZQ0cnMNFn/IhahLqPtpM dZwCc9Q== X-Google-Smtp-Source: AGHT+IF7haVn28lDdEjpyTvp9F1KQfVVD/Td0eI6oNlSn0fEyOoqG3BkKHLDOsvbaLbXpHgiZ78n2sjns68N X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:cf0e:7a99:e672:3862]) (user=irogers job=sendgmr) by 2002:a81:a883:0:b0:6d3:e7e6:8462 with SMTP id 00721157ae682-6db952f5ee5mr2188327b3.1.1726167845806; Thu, 12 Sep 2024 12:04:05 -0700 (PDT) Date: Thu, 12 Sep 2024 12:03:34 -0700 In-Reply-To: <20240912190341.919229-1-irogers@google.com> Message-Id: <20240912190341.919229-8-irogers@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240912190341.919229-1-irogers@google.com> X-Mailer: git-send-email 2.46.0.662.g92d0881bb0-goog Subject: [PATCH v2 07/13] perf tool_pmu: Move expr literals to tool_pmu From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Ravi Bangoria , Weilin Wang , Jing Zhang , Xu Yang , Sandipan Das , Benjamin Gray , Athira Jajeev , Howard Chu , Dominique Martinet , Yang Jihong , Colin Ian King , Veronika Molnarova , "Dr. David Alan Gilbert" , Oliver Upton , Changbin Du , Ze Gao , Andi Kleen , "=?UTF-8?q?Cl=C3=A9ment=20Le=20Goffic?=" , Sun Haiyong , Junhao He , Tiezhu Yang , Yicong Yang , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, linux-arm-kernel@lists.infradead.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the expr literals like "#smt_on" as tool events, this allows stat events to give the values. On my laptop with hyperthreading enabled: ``` $ perf stat -e "has_pmem,num_cores,num_cpus,num_cpus_online,num_dies,num_pa= ckages,smt_on,system_tsc_freq" true Performance counter stats for 'true': 0 has_pmem 8 num_cores 16 num_cpus 16 num_cpus_online 1 num_dies 1 num_packages 1 smt_on 2,496,000,000 system_tsc_freq 0.001113637 seconds time elapsed 0.001218000 seconds user 0.000000000 seconds sys ``` And with hyperthreading disabled: ``` $ perf stat -e "has_pmem,num_cores,num_cpus,num_cpus_online,num_dies,num_pa= ckages,smt_on,system_tsc_freq" true Performance counter stats for 'true': 0 has_pmem 8 num_cores 16 num_cpus 8 num_cpus_online 1 num_dies 1 num_packages 0 smt_on 2,496,000,000 system_tsc_freq 0.000802115 seconds time elapsed 0.000000000 seconds user 0.000806000 seconds sys ``` As zero matters for these values, in stat-display should_skip_zero_counter only skip the zero value if it is not the first aggregation index. The tool event implementations are used in expr but not evaluated as events for simplicity. Also core_wide isn't made a tool event as it requires command line parameters. Signed-off-by: Ian Rogers --- tools/perf/arch/arm64/util/pmu.c | 5 +- tools/perf/arch/x86/util/tsc.c | 18 ++-- tools/perf/util/expr.c | 93 +++----------------- tools/perf/util/pmu.c | 5 -- tools/perf/util/pmu.h | 1 - tools/perf/util/stat-display.c | 8 +- tools/perf/util/stat-shadow.c | 11 ++- tools/perf/util/tool_pmu.c | 146 ++++++++++++++++++++++++++++++- tools/perf/util/tool_pmu.h | 19 +++- tools/perf/util/tsc.h | 2 +- 10 files changed, 201 insertions(+), 107 deletions(-) diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/= pmu.c index 2a4eab2d160e..a0964b191fcb 100644 --- a/tools/perf/arch/arm64/util/pmu.c +++ b/tools/perf/arch/arm64/util/pmu.c @@ -5,6 +5,7 @@ #include "../../../util/header.h" #include "../../../util/pmu.h" #include "../../../util/pmus.h" +#include "../../../util/tool_pmu.h" #include #include =20 @@ -24,7 +25,7 @@ const struct pmu_metrics_table *pmu_metrics_table__find(v= oid) return NULL; } =20 -double perf_pmu__cpu_slots_per_cycle(void) +u64 tool_pmu__cpu_slots_per_cycle(void) { char path[PATH_MAX]; unsigned long long slots =3D 0; @@ -41,5 +42,5 @@ double perf_pmu__cpu_slots_per_cycle(void) filename__read_ull(path, &slots); } =20 - return slots ? (double)slots : NAN; + return slots; } diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index e2d6cfe21057..3a439e4b12d2 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -24,9 +24,9 @@ u64 rdtsc(void) * ... * will return 3000000000. */ -static double cpuinfo_tsc_freq(void) +static u64 cpuinfo_tsc_freq(void) { - double result =3D 0; + u64 result =3D 0; FILE *cpuinfo; char *line =3D NULL; size_t len =3D 0; @@ -34,20 +34,22 @@ static double cpuinfo_tsc_freq(void) cpuinfo =3D fopen("/proc/cpuinfo", "r"); if (!cpuinfo) { pr_err("Failed to read /proc/cpuinfo for TSC frequency\n"); - return NAN; + return 0; } while (getline(&line, &len, cpuinfo) > 0) { if (!strncmp(line, "model name", 10)) { char *pos =3D strstr(line + 11, " @ "); + double float_result; =20 - if (pos && sscanf(pos, " @ %lfGHz", &result) =3D=3D 1) { - result *=3D 1000000000; + if (pos && sscanf(pos, " @ %lfGHz", &float_result) =3D=3D 1) { + float_result *=3D 1000000000; + result =3D (u64)float_result; goto out; } } } out: - if (fpclassify(result) =3D=3D FP_ZERO) + if (result =3D=3D 0) pr_err("Failed to find TSC frequency in /proc/cpuinfo\n"); =20 free(line); @@ -55,7 +57,7 @@ static double cpuinfo_tsc_freq(void) return result; } =20 -double arch_get_tsc_freq(void) +u64 arch_get_tsc_freq(void) { unsigned int a, b, c, d, lvl; static bool cached; @@ -86,6 +88,6 @@ double arch_get_tsc_freq(void) return tsc; } =20 - tsc =3D (double)c * (double)b / (double)a; + tsc =3D (u64)c * (u64)b / (u64)a; return tsc; } diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index b2536a59c44e..5e3732bc2fa5 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -5,25 +5,22 @@ #include #include #include "metricgroup.h" -#include "cpumap.h" -#include "cputopo.h" #include "debug.h" #include "evlist.h" #include "expr.h" +#include "pmu.h" +#include "smt.h" +#include "tool_pmu.h" #include #include #include "util/hashmap.h" #include "util/header.h" #include "util/pmu.h" -#include "smt.h" -#include "tsc.h" -#include #include #include #include #include #include -#include "pmu.h" =20 struct expr_id_data { union { @@ -393,90 +390,26 @@ double expr_id_data__source_count(const struct expr_i= d_data *data) return data->val.source_count; } =20 -#if !defined(__i386__) && !defined(__x86_64__) -double arch_get_tsc_freq(void) -{ - return 0.0; -} -#endif - -static double has_pmem(void) -{ - static bool has_pmem, cached; - const char *sysfs =3D sysfs__mountpoint(); - char path[PATH_MAX]; - - if (!cached) { - snprintf(path, sizeof(path), "%s/firmware/acpi/tables/NFIT", sysfs); - has_pmem =3D access(path, F_OK) =3D=3D 0; - cached =3D true; - } - return has_pmem ? 1.0 : 0.0; -} - double expr__get_literal(const char *literal, const struct expr_scanner_ct= x *ctx) { - const struct cpu_topology *topology; double result =3D NAN; + enum tool_pmu_event ev =3D tool_pmu__str_to_event(literal + 1); =20 - if (!strcmp("#num_cpus", literal)) { - result =3D cpu__max_present_cpu().cpu; - goto out; - } - if (!strcmp("#num_cpus_online", literal)) { - struct perf_cpu_map *online =3D cpu_map__online(); - - if (online) - result =3D perf_cpu_map__nr(online); - goto out; - } + if (ev !=3D TOOL_PMU__EVENT_NONE) { + u64 count; =20 - if (!strcasecmp("#system_tsc_freq", literal)) { - result =3D arch_get_tsc_freq(); - goto out; - } + if (tool_pmu__read_event(ev, &count)) + result =3D count; + else + pr_err("Failure to read '%s'", literal); =20 - /* - * Assume that topology strings are consistent, such as CPUs "0-1" - * wouldn't be listed as "0,1", and so after deduplication the number of - * these strings gives an indication of the number of packages, dies, - * etc. - */ - if (!strcasecmp("#smt_on", literal)) { - result =3D smt_on() ? 1.0 : 0.0; - goto out; - } - if (!strcmp("#core_wide", literal)) { + } else if (!strcmp("#core_wide", literal)) { result =3D core_wide(ctx->system_wide, ctx->user_requested_cpu_list) ? 1.0 : 0.0; - goto out; - } - if (!strcmp("#num_packages", literal)) { - topology =3D online_topology(); - result =3D topology->package_cpus_lists; - goto out; - } - if (!strcmp("#num_dies", literal)) { - topology =3D online_topology(); - result =3D topology->die_cpus_lists; - goto out; - } - if (!strcmp("#num_cores", literal)) { - topology =3D online_topology(); - result =3D topology->core_cpus_lists; - goto out; - } - if (!strcmp("#slots", literal)) { - result =3D perf_pmu__cpu_slots_per_cycle(); - goto out; - } - if (!strcmp("#has_pmem", literal)) { - result =3D has_pmem(); - goto out; + } else { + pr_err("Unrecognized literal '%s'", literal); } =20 - pr_err("Unrecognized literal '%s'", literal); -out: pr_debug2("literal: %s =3D %f\n", literal, result); return result; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d6310fa1b8bd..9cb7a4e5e7d4 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -2250,11 +2250,6 @@ bool perf_pmu__match(const struct perf_pmu *pmu, con= st char *tok) (need_fnmatch && !fnmatch(tok, name, 0)); } =20 -double __weak perf_pmu__cpu_slots_per_cycle(void) -{ - return NAN; -} - int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size) { const char *sysfs =3D sysfs__mountpoint(); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 880a8dc661b7..c4ca359d4215 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -271,7 +271,6 @@ void perf_pmu__warn_invalid_formats(struct perf_pmu *pm= u); =20 bool perf_pmu__match(const struct perf_pmu *pmu, const char *tok); =20 -double perf_pmu__cpu_slots_per_cycle(void); int perf_pmu__event_source_devices_scnprintf(char *pathname, size_t size); int perf_pmu__pathname_scnprintf(char *buf, size_t size, const char *pmu_name, const char *filename); diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index a82a8ec79b39..ad8baf33fdba 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -951,8 +951,12 @@ static bool should_skip_zero_counter(struct perf_stat_= config *config, * Many tool events are only gathered on the first index, skip other * zero values. */ - if (evsel__is_tool(counter)) - return true; + if (evsel__is_tool(counter)) { + struct aggr_cpu_id own_id =3D + config->aggr_get_id(config, (struct perf_cpu){ .cpu =3D 0 }); + + return !aggr_cpu_id__equal(id, &own_id); + } =20 /* * Skip value 0 when it's an uncore event and the given aggr id diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index e56969d1e39d..aa367c667926 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -400,8 +400,17 @@ static int prepare_metric(const struct metric_expr *me= xp, case TOOL_PMU__EVENT_MAX: pr_err("Invalid tool event 'max'"); abort(); + case TOOL_PMU__EVENT_HAS_PMEM: + case TOOL_PMU__EVENT_NUM_CORES: + case TOOL_PMU__EVENT_NUM_CPUS: + case TOOL_PMU__EVENT_NUM_CPUS_ONLINE: + case TOOL_PMU__EVENT_NUM_DIES: + case TOOL_PMU__EVENT_NUM_PACKAGES: + case TOOL_PMU__EVENT_SLOTS: + case TOOL_PMU__EVENT_SMT_ON: + case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: default: - pr_err("Unknown tool event '%s'", evsel__name(metric_events[i])); + pr_err("Unexpected tool event '%s'", evsel__name(metric_events[i])); abort(); } val =3D avg_stats(stats) * scale; diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index b8116c5c7250..3768c6a42ff6 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -1,11 +1,16 @@ // SPDX-License-Identifier: GPL-2.0-only #include "cgroup.h" #include "counts.h" +#include "cputopo.h" #include "evsel.h" #include "pmu.h" #include "print-events.h" +#include "smt.h" #include "time-utils.h" #include "tool_pmu.h" +#include "tsc.h" +#include +#include #include #include #include @@ -17,6 +22,15 @@ static const char *const tool_pmu__event_names[TOOL_PMU_= _EVENT_MAX] =3D { "duration_time", "user_time", "system_time", + "has_pmem", + "num_cores", + "num_cpus", + "num_cpus_online", + "num_dies", + "num_packages", + "slots", + "smt_on", + "system_tsc_freq", }; =20 =20 @@ -33,8 +47,14 @@ enum tool_pmu_event tool_pmu__str_to_event(const char *s= tr) int i; =20 tool_pmu__for_each_event(i) { - if (!strcasecmp(str, tool_pmu__event_names[i])) + if (!strcasecmp(str, tool_pmu__event_names[i])) { +#if !defined(__aarch64__) + /* The slots event should only appear on arm64. */ + if (i =3D=3D TOOL_PMU__EVENT_SLOTS) + return TOOL_PMU__EVENT_NONE; +#endif return i; + } } return TOOL_PMU__EVENT_NONE; } @@ -252,6 +272,9 @@ int evsel__tool_pmu_open(struct evsel *evsel, enum tool_pmu_event ev =3D evsel__tool_event(evsel); int pid =3D -1, idx =3D 0, thread =3D 0, nthreads, err =3D 0, old_errno; =20 + if (ev =3D=3D TOOL_PMU__EVENT_NUM_CPUS) + return 0; + if (ev =3D=3D TOOL_PMU__EVENT_DURATION_TIME) { if (evsel->core.attr.sample_period) /* no sampling */ return -EINVAL; @@ -330,16 +353,133 @@ int evsel__tool_pmu_open(struct evsel *evsel, return err; } =20 +#if !defined(__i386__) && !defined(__x86_64__) +u64 arch_get_tsc_freq(void) +{ + return 0; +} +#endif + +#if !defined(__aarch64__) +u64 tool_pmu__cpu_slots_per_cycle(void) +{ + return 0; +} +#endif + +static bool has_pmem(void) +{ + static bool has_pmem, cached; + const char *sysfs =3D sysfs__mountpoint(); + char path[PATH_MAX]; + + if (!cached) { + snprintf(path, sizeof(path), "%s/firmware/acpi/tables/NFIT", sysfs); + has_pmem =3D access(path, F_OK) =3D=3D 0; + cached =3D true; + } + return has_pmem; +} + +bool tool_pmu__read_event(enum tool_pmu_event ev, u64 *result) +{ + const struct cpu_topology *topology; + + switch (ev) { + case TOOL_PMU__EVENT_HAS_PMEM: + *result =3D has_pmem() ? 1 : 0; + return true; + + case TOOL_PMU__EVENT_NUM_CORES: + topology =3D online_topology(); + *result =3D topology->core_cpus_lists; + return true; + + case TOOL_PMU__EVENT_NUM_CPUS: + *result =3D cpu__max_present_cpu().cpu; + return true; + + case TOOL_PMU__EVENT_NUM_CPUS_ONLINE: { + struct perf_cpu_map *online =3D cpu_map__online(); + + if (online) { + *result =3D perf_cpu_map__nr(online); + return true; + } + return false; + } + case TOOL_PMU__EVENT_NUM_DIES: + topology =3D online_topology(); + *result =3D topology->die_cpus_lists; + return true; + + case TOOL_PMU__EVENT_NUM_PACKAGES: + topology =3D online_topology(); + *result =3D topology->package_cpus_lists; + return true; + + case TOOL_PMU__EVENT_SLOTS: + *result =3D tool_pmu__cpu_slots_per_cycle(); + return *result ? true : false; + + case TOOL_PMU__EVENT_SMT_ON: + *result =3D smt_on() ? 1 : 0; + return true; + + case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: + *result =3D arch_get_tsc_freq(); + return true; + + case TOOL_PMU__EVENT_NONE: + case TOOL_PMU__EVENT_DURATION_TIME: + case TOOL_PMU__EVENT_USER_TIME: + case TOOL_PMU__EVENT_SYSTEM_TIME: + case TOOL_PMU__EVENT_MAX: + default: + return false; + } +} + int evsel__tool_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread) { __u64 *start_time, cur_time, delta_start; + unsigned long val; int fd, err =3D 0; - struct perf_counts_values *count; + struct perf_counts_values *count, *old_count =3D NULL; bool adjust =3D false; + enum tool_pmu_event ev =3D evsel__tool_event(evsel); =20 count =3D perf_counts(evsel->counts, cpu_map_idx, thread); =20 - switch (evsel__tool_event(evsel)) { + switch (ev) { + case TOOL_PMU__EVENT_HAS_PMEM: + case TOOL_PMU__EVENT_NUM_CORES: + case TOOL_PMU__EVENT_NUM_CPUS: + case TOOL_PMU__EVENT_NUM_CPUS_ONLINE: + case TOOL_PMU__EVENT_NUM_DIES: + case TOOL_PMU__EVENT_NUM_PACKAGES: + case TOOL_PMU__EVENT_SLOTS: + case TOOL_PMU__EVENT_SMT_ON: + case TOOL_PMU__EVENT_SYSTEM_TSC_FREQ: + if (evsel->prev_raw_counts) + old_count =3D perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread); + val =3D 0; + if (cpu_map_idx =3D=3D 0 && thread =3D=3D 0) { + if (!tool_pmu__read_event(ev, &val)) { + count->lost++; + val =3D 0; + } + } + if (old_count) { + count->val =3D old_count->val + val; + count->run =3D old_count->run + 1; + count->ena =3D old_count->ena + 1; + } else { + count->val =3D val; + count->run++; + count->ena++; + } + return 0; case TOOL_PMU__EVENT_DURATION_TIME: /* * Pretend duration_time is only on the first CPU and thread, or diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h index b156645206c4..ecdf316525bb 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -10,9 +10,18 @@ struct print_callbacks; =20 enum tool_pmu_event { TOOL_PMU__EVENT_NONE =3D 0, - TOOL_PMU__EVENT_DURATION_TIME =3D 1, - TOOL_PMU__EVENT_USER_TIME =3D 2, - TOOL_PMU__EVENT_SYSTEM_TIME =3D 3, + TOOL_PMU__EVENT_DURATION_TIME, + TOOL_PMU__EVENT_USER_TIME, + TOOL_PMU__EVENT_SYSTEM_TIME, + TOOL_PMU__EVENT_HAS_PMEM, + TOOL_PMU__EVENT_NUM_CORES, + TOOL_PMU__EVENT_NUM_CPUS, + TOOL_PMU__EVENT_NUM_CPUS_ONLINE, + TOOL_PMU__EVENT_NUM_DIES, + TOOL_PMU__EVENT_NUM_PACKAGES, + TOOL_PMU__EVENT_SLOTS, + TOOL_PMU__EVENT_SMT_ON, + TOOL_PMU__EVENT_SYSTEM_TSC_FREQ, =20 TOOL_PMU__EVENT_MAX, }; @@ -31,9 +40,11 @@ int tool_pmu__config_terms(struct perf_event_attr *attr, struct parse_events_terms *terms, struct parse_events_error *err); int tool_pmu__for_each_event_cb(struct perf_pmu *pmu, void *state, pmu_eve= nt_callback cb); +bool tool_pmu__read_event(enum tool_pmu_event ev, u64 *result); =20 -bool perf_pmu__is_tool(const struct perf_pmu *pmu); +u64 tool_pmu__cpu_slots_per_cycle(void); =20 +bool perf_pmu__is_tool(const struct perf_pmu *pmu); =20 bool evsel__is_tool(const struct evsel *evsel); enum tool_pmu_event evsel__tool_event(const struct evsel *evsel); diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h index 88fd1c4c1cb8..57ce8449647f 100644 --- a/tools/perf/util/tsc.h +++ b/tools/perf/util/tsc.h @@ -25,7 +25,7 @@ int perf_read_tsc_conversion(const struct perf_event_mmap= _page *pc, u64 perf_time_to_tsc(u64 ns, struct perf_tsc_conversion *tc); u64 tsc_to_perf_time(u64 cyc, struct perf_tsc_conversion *tc); u64 rdtsc(void); -double arch_get_tsc_freq(void); +u64 arch_get_tsc_freq(void); =20 size_t perf_event__fprintf_time_conv(union perf_event *event, FILE *fp); =20 --=20 2.46.0.662.g92d0881bb0-goog