Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp188633pxj; Thu, 17 Jun 2021 00:03:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxWiIY0MUeTI+JVh+JBUhuGcYQSYsjlina52EMbQPRSTqvQpYQMkjIR1wEvcjGRhTQBhgdk X-Received: by 2002:a05:6602:2be3:: with SMTP id d3mr2648146ioy.54.1623913410584; Thu, 17 Jun 2021 00:03:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623913410; cv=none; d=google.com; s=arc-20160816; b=NVRafvg7ocKUflyYW0ptGnKis6200igeodRFQ4ELwb6b2SLmmRhIwunji45A7RKiqS gQAR0rWhpP2Zxg05e77x99pjsHBzAjpGMEHzndyLIuay8z16oAPLOjtmidfphAiBSzvT C4ffelxH1yZX+DMsKlgCCZkc1g8p+nilPl1Jhrol7sAChUmYer1e4rzZ0nspWGmDGBTq 9H/TLg0tVWQKOOymFz3FR5qvJLHAuVLVr9e6p7tFH57p34T3t1BrVPiB9xrp7SIb6ptO wL6/d3tZsl4D3ch3kOUtS04+xW9udfABQFdOyGUsOfatSKt7/6d9Fcs4BenreIgi4d2L ZfqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:message-id:date:subject:cc:to:from:ironport-sdr :ironport-sdr; bh=s7GN9qkjnYiBAYE9xzsw2G0l2/z/O8UeTEhG7XeWIvU=; b=MO3ydpuX6Eykb+XlWjYt/6nUkNWXC34nMWdF8pYuDH3PrHbJqPy/mjTv/8yLOseqLA zhmTLUKk52HWffWagNJ920K6Z5MbS2fzPXOSwe0aMa6vMlpPZBxxHGP6ujwL5OyhG/D2 uNfE4MiVXVT+jFCGqu0aK2+S5kBVp3yFUl/tM++BVqTVPb2i4hyhjHBcFk9V3ki4iIK4 L0Tp3GYtJLbhFhLtrjUWTPaw1o3r+gdfgkkH4hR2N2DC64hZphBNfWhUFCv0GyAsdMZi odKMr6ihQQ3KK/Cwk9TItTomK/0kEMSNDPM0I4k+yG0rMAEmezrEwgp2l+faY7g0y8Ry TjzA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q3si5216726ilu.88.2021.06.17.00.03.18; Thu, 17 Jun 2021 00:03:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229693AbhFQHDz (ORCPT + 99 others); Thu, 17 Jun 2021 03:03:55 -0400 Received: from mga18.intel.com ([134.134.136.126]:13853 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229580AbhFQHDy (ORCPT ); Thu, 17 Jun 2021 03:03:54 -0400 IronPort-SDR: TOAY1J5n09qSIwfDEZT3G2AvIeVCfkAjZlg95jIcIRVUwQfCKjzDkcO8HozBlgy/Sc+9phq/qJ 0eHyYkvj70lA== X-IronPort-AV: E=McAfee;i="6200,9189,10017"; a="193626443" X-IronPort-AV: E=Sophos;i="5.83,278,1616482800"; d="scan'208";a="193626443" Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2021 00:01:27 -0700 IronPort-SDR: ZcgPJKy4oUKavEkfM6it3kc2olRV4FPnFbI60Ni3LMwX6rpzyVtvsiCVyPX/mQ/LhMdGvjXJvr cG/jChFVPdCA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,278,1616482800"; d="scan'208";a="555118030" Received: from kbl-ppc.sh.intel.com ([10.239.159.163]) by fmsmga001.fm.intel.com with ESMTP; 17 Jun 2021 00:01:24 -0700 From: Jin Yao To: acme@kernel.org, jolsa@kernel.org, peterz@infradead.org, mingo@redhat.com, alexander.shishkin@linux.intel.com Cc: Linux-kernel@vger.kernel.org, ak@linux.intel.com, kan.liang@intel.com, yao.jin@intel.com, Jin Yao Subject: [PATCH] perf tools: Enable on a list of CPUs for hybrid Date: Thu, 17 Jun 2021 15:00:26 +0800 Message-Id: <20210617070026.14475-1-yao.jin@linux.intel.com> X-Mailer: git-send-email 2.17.1 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The perf-record and perf-stat have supported the option '-C/--cpus' to count or collect only on the list of CPUs provided. This option needs to be supported for hybrid as well. For hybrid support, it needs to check that the CPUs are available on hybrid PMU. On AlderLake, for example, 'cpu_core' has CPU0-CPU15, and 'cpu_atom' has CPU16-CPU23. Before: # perf stat -e cpu_core/cycles/ -C16 true Performance counter stats for 'CPU(s) 16': cpu_core/cycles/ The perf-stat silently returned "" without any helpful information. It should error out that CPU16 was not available on 'cpu_core'. After: # perf stat -e cpu_core/cycles/ -C16 true 'cpu_core' doesn't have cpu 16 failed to use cpu list 16 It also supports to count only on a given CPU. # perf stat -e cpu_core/cycles/ -C15 -vv true ------------------------------------------------------------ perf_event_attr: size 128 config 0x400000000 sample_type IDENTIFIER read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING disabled 1 inherit 1 exclude_guest 1 ------------------------------------------------------------ sys_perf_event_open: pid -1 cpu 15 group_fd -1 flags 0x8 = 3 cycles: 0: 103287 569776 569776 cycles: 103287 569776 569776 Performance counter stats for 'CPU(s) 15': 103,287 cpu_core/cycles/ 0.000566813 seconds time elapsed Collect the counts of 'cycles' on CPU15 (CPU15 is in 'cpu_core'). Signed-off-by: Jin Yao --- tools/perf/builtin-record.c | 6 +++++ tools/perf/builtin-stat.c | 5 ++++ tools/perf/util/evlist-hybrid.c | 43 +++++++++++++++++++++++++++++++++ tools/perf/util/evlist-hybrid.h | 1 + tools/perf/util/evlist.c | 1 + tools/perf/util/pmu.c | 23 ++++++++++++++++++ tools/perf/util/pmu.h | 3 +++ 7 files changed, 82 insertions(+) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index bc3dd379eb67..bd39d4260549 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2877,6 +2877,12 @@ int cmd_record(int argc, const char **argv) /* Enable ignoring missing threads when -u/-p option is defined. */ rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid; + if (evlist__use_cpu_list(rec->evlist, rec->opts.target.cpu_list)) { + pr_err("failed to use cpu list %s\n", + rec->opts.target.cpu_list); + goto out; + } + err = -ENOMEM; if (evlist__create_maps(rec->evlist, &rec->opts.target) < 0) usage_with_options(record_usage, record_options); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f9f74a514315..9c27c90d069f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2427,6 +2427,11 @@ int cmd_stat(int argc, const char **argv) if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) target.per_thread = true; + if (evlist__use_cpu_list(evsel_list, target.cpu_list)) { + pr_err("failed to use cpu list %s\n", target.cpu_list); + goto out; + } + if (evlist__create_maps(evsel_list, &target) < 0) { if (target__has_task(&target)) { pr_err("Problems finding threads of monitor\n"); diff --git a/tools/perf/util/evlist-hybrid.c b/tools/perf/util/evlist-hybrid.c index db3f5fbdebe1..e8fdd98aed3f 100644 --- a/tools/perf/util/evlist-hybrid.c +++ b/tools/perf/util/evlist-hybrid.c @@ -86,3 +86,46 @@ bool evlist__has_hybrid(struct evlist *evlist) return false; } + +int evlist__use_cpu_list(struct evlist *evlist, const char *cpu_list) +{ + struct perf_cpu_map *cpus; + struct evsel *evsel; + struct perf_pmu *pmu; + int ret; + + if (!perf_pmu__has_hybrid() || !cpu_list) + return 0; + + cpus = perf_cpu_map__new(cpu_list); + if (!cpus) + return -1; + + evlist__for_each_entry(evlist, evsel) { + bool exact_match; + + pmu = perf_pmu__find_hybrid_pmu(evsel->pmu_name); + if (!pmu) + continue; + + if (!perf_pmu__cpus_matched(pmu, cpus, &exact_match)) { + ret = -1; + goto out; + } + + if (!exact_match) { + /* + * Use the cpus in cpu_list. + */ + perf_cpu_map__put(evsel->core.cpus); + perf_cpu_map__put(evsel->core.own_cpus); + evsel->core.cpus = perf_cpu_map__get(cpus); + evsel->core.own_cpus = perf_cpu_map__get(cpus); + } + } + + ret = 0; +out: + perf_cpu_map__put(cpus); + return ret; +} diff --git a/tools/perf/util/evlist-hybrid.h b/tools/perf/util/evlist-hybrid.h index 19f74b4c340a..f33a4e8443a1 100644 --- a/tools/perf/util/evlist-hybrid.h +++ b/tools/perf/util/evlist-hybrid.h @@ -10,5 +10,6 @@ int evlist__add_default_hybrid(struct evlist *evlist, bool precise); void evlist__warn_hybrid_group(struct evlist *evlist); bool evlist__has_hybrid(struct evlist *evlist); +int evlist__use_cpu_list(struct evlist *evlist, const char *cpu_list); #endif /* __PERF_EVLIST_HYBRID_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 6ba9664089bd..e8a0f95f7f47 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -27,6 +27,7 @@ #include "util/perf_api_probe.h" #include "util/evsel_fprintf.h" #include "util/evlist-hybrid.h" +#include "util/pmu.h" #include #include #include diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 88c8ecdc60b0..0e3a19a6736d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1872,3 +1872,26 @@ bool perf_pmu__has_hybrid(void) return !list_empty(&perf_pmu__hybrid_pmus); } + +bool perf_pmu__cpus_matched(struct perf_pmu *pmu, struct perf_cpu_map *cpus, + bool *exact_match) +{ + struct perf_cpu_map *pmu_cpus = pmu->cpus; + int cpu; + + *exact_match = false; + + for (int i = 0; i < cpus->nr; i++) { + cpu = perf_cpu_map__idx(pmu_cpus, cpus->map[i]); + if (cpu == -1) { + pr_err("'%s' doesn't have cpu %d\n", + pmu->name, cpus->map[i]); + return false; + } + } + + if (cpus->nr == pmu_cpus->nr) + *exact_match = true; + + return true; +} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index a790ef758171..1cca48e02b5d 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -11,6 +11,7 @@ #include "pmu-events/pmu-events.h" struct evsel_config_term; +struct perf_cpu_map; enum { PERF_PMU_FORMAT_VALUE_CONFIG, @@ -133,5 +134,7 @@ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, char *name); bool perf_pmu__has_hybrid(void); +bool perf_pmu__cpus_matched(struct perf_pmu *pmu, struct perf_cpu_map *cpus, + bool *exact_match); #endif /* __PMU_H */ -- 2.17.1