Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp4946077rwd; Tue, 23 May 2023 15:21:46 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ61tuMw4k7EmAbl1FfUQHmbMwc2+g3hcAivzuNih9HCtysEKiGPa7LCtLPprtrIbq1xHFDs X-Received: by 2002:a05:6a00:b48:b0:636:f5f4:5308 with SMTP id p8-20020a056a000b4800b00636f5f45308mr792117pfo.7.1684880506201; Tue, 23 May 2023 15:21:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684880506; cv=none; d=google.com; s=arc-20160816; b=khIq9kEMQw9ITBnBSvNeRyCmWQ4HSwRA4TOnExmwTCnzzRBhTMot5QI2/ivqVehHJh /e1tZxRWtdQDgUHSGK+vx7ofWVOVS82h+SetgIxwZTB295at788r+VuheXbhYb1mJUNS WKAT/d6FURFW9YIJpSy9YfWrTCSi5O4A/L5SrvjAx7NNZSYChrVlNJfD3rHGIQvNyuHa jirtgECGwHeQZWHcRKkT1o+8VJvmuKkcSWjwBkomTR0LlckvhxgQTQWa9+u3mXd3WML9 U2H/UhGwXs1sghsh7bbr7jvcTfbWc8BG5aYaEGFUqpojAIo3Di8qm94HXVp8iGRU8oxX Slxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version; bh=53TNCQ+IulLSCZazo8snIqjkbzrCV9L/txKL+EaKMrE=; b=YBm1ZALLS74aDj3r2jaT/FLSpOQ8kGUZWzhpwzJskCCLZmKw70DDbRjCQxoHMfEGXf 5XtX4u1MuJl/yd8sdGquHTECF5XFdGpskaMgPqXhQbZHOGEf/sqSbB/mK8mzcKBMHMQN kroP/PoWMyWl7AkLMb2TppKL75nEnrEd2aQIX8C7HHAdkKWTNVOpTkstPr54v3Hnq+sq nCX5SPvTfcSJOromznb/HlwVxTEzTUSXObAEDg3BooaBJOezIXLFHzsd9mflvKmDZdF8 by8zMkZKrDWU1rhllwnV2G/WFsoy+zOGaBBHNKqwyw7Bv+5HewSq+h6gug2HZpgEl8pS 8Beg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a187-20020a6390c4000000b0053ef469281bsi1512422pge.474.2023.05.23.15.21.33; Tue, 23 May 2023 15:21:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236315AbjEWV7n convert rfc822-to-8bit (ORCPT + 99 others); Tue, 23 May 2023 17:59:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229961AbjEWV7m (ORCPT ); Tue, 23 May 2023 17:59:42 -0400 Received: from mail-yb1-f171.google.com (mail-yb1-f171.google.com [209.85.219.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D20E983; Tue, 23 May 2023 14:59:40 -0700 (PDT) Received: by mail-yb1-f171.google.com with SMTP id 3f1490d57ef6-ba827c74187so409577276.0; Tue, 23 May 2023 14:59:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684879180; x=1687471180; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JGjJxcn57lgCZWic9tKK0sWJnTgZ1s/472pT76ji6ok=; b=KQhIoL0YPlIejfe7jbC+sM2wiQe5cIhcsc8hkpOGH91/b7Y4aaVgQAVv7TmoiRAtw4 pto7OAWjqtYl2H6vufb+oiHRgPcyV352Wfwlt/PmxopDVid94uFyITsbuiEPnrMZ8ijQ fpJEjt9p7BRM1cI84Z7Ej8vyikcHPPBNbFNkz/A4Vm9GVdXCjv7QIxbMnsrHXTQh3ra3 erBMNzIlCA5jFOo3fFM5Q91AhQqECuN3wdsMh/iRIQW+tQNjvCIQfmcrK6yObJ4XECY5 9btJ3I7dgRDD7EejYEsi3F36hRpMf2qR6ZoiOuvzafdma0pKyka1sKm5Wn92ibxjHjpn 48Hw== X-Gm-Message-State: AC+VfDz4gmnMqcOPuLUt6Hl0dd1eTBCxVY1th/8XLrPg/8A6QoJFByfy I0dBHGThDAxYfvLkMxJwzauIc2W6Q5eBAp4CVlCOc8uW X-Received: by 2002:a25:a1c9:0:b0:ba8:61f8:8eed with SMTP id a67-20020a25a1c9000000b00ba861f88eedmr16329846ybi.0.1684879179617; Tue, 23 May 2023 14:59:39 -0700 (PDT) MIME-Version: 1.0 References: <20230522064330.189127-1-irogers@google.com> <20230522064330.189127-2-irogers@google.com> In-Reply-To: <20230522064330.189127-2-irogers@google.com> From: Namhyung Kim Date: Tue, 23 May 2023 14:59:28 -0700 Message-ID: Subject: Re: [PATCH v2 01/23] perf tools: Warn if no user requested CPUs match PMU's CPUs To: Ian Rogers Cc: Suzuki K Poulose , Mike Leach , Leo Yan , John Garry , Will Deacon , James Clark , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Adrian Hunter , Kajol Jain , Jing Zhang , Kan Liang , Zhengjun Xing , Ravi Bangoria , Madhavan Srinivasan , Athira Rajeev , Ming Wang , Huacai Chen , Sandipan Das , Dmitrii Dolgov <9erthalion6@gmail.com>, Sean Christopherson , Ali Saidi , Rob Herring , Thomas Richter , Kang Minchul , linux-kernel@vger.kernel.org, coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8BIT X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Ian, On Sun, May 21, 2023 at 11:43 PM Ian Rogers wrote: > > In commit 1d3351e631fc ("perf tools: Enable on a list of CPUs for hybrid") > perf on hybrid will warn if a user requested CPU doesn't match the PMU > of the given event but only for hybrid PMUs. Make the logic generic > for all PMUs and remove the hybrid logic. > > Warn if a CPU is requested that is offline for uncore events. Warn if > a CPU is requested for a core PMU, but the CPU isn't within the cpu > map of that PMU. > > For example on a 16 (0-15) CPU system: > ``` > $ perf stat -e imc_free_running/data_read/,cycles -C 16 true > WARNING: Requested CPU(s) '16' not supported by PMU 'uncore_imc_free_running_1' for event 'imc_free_running/data_read/' > WARNING: Requested CPU(s) '16' not supported by PMU 'uncore_imc_free_running_0' for event 'imc_free_running/data_read/' > WARNING: Requested CPU(s) '16' not supported by PMU 'cpu' for event 'cycles' > > Performance counter stats for 'CPU(s) 16': > > MiB imc_free_running/data_read/ > cycles > > 0.000570094 seconds time elapsed > ``` I'm ok with the warning changes, but it also removed the fixup logic for the hybrid PMUs to change the cpu map in the events. I'm not sure if it's your intention. If so, I think you'd better splitting it into a separate commit with some explanation. Thanks, Namhyung > > Signed-off-by: Ian Rogers > --- > tools/perf/builtin-record.c | 6 +-- > tools/perf/builtin-stat.c | 5 +-- > tools/perf/util/cpumap.h | 2 +- > tools/perf/util/evlist-hybrid.c | 74 --------------------------------- > tools/perf/util/evlist-hybrid.h | 1 - > tools/perf/util/evlist.c | 44 ++++++++++++++++++++ > tools/perf/util/evlist.h | 2 + > tools/perf/util/pmu.c | 33 --------------- > tools/perf/util/pmu.h | 4 -- > 9 files changed, 49 insertions(+), 122 deletions(-) > > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c > index ec0f2d5f189f..9d212236c75a 100644 > --- a/tools/perf/builtin-record.c > +++ b/tools/perf/builtin-record.c > @@ -4198,11 +4198,7 @@ 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__fix_hybrid_cpus(rec->evlist, rec->opts.target.cpu_list)) { > - pr_err("failed to use cpu list %s\n", > - rec->opts.target.cpu_list); > - goto out; > - } > + evlist__warn_user_requested_cpus(rec->evlist, rec->opts.target.cpu_list); > > rec->opts.target.hybrid = perf_pmu__has_hybrid(); > > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c > index bc45cee3f77c..612467216306 100644 > --- a/tools/perf/builtin-stat.c > +++ b/tools/perf/builtin-stat.c > @@ -2462,10 +2462,7 @@ int cmd_stat(int argc, const char **argv) > } > } > > - if (evlist__fix_hybrid_cpus(evsel_list, target.cpu_list)) { > - pr_err("failed to use cpu list %s\n", target.cpu_list); > - goto out; > - } > + evlist__warn_user_requested_cpus(evsel_list, target.cpu_list); > > target.hybrid = perf_pmu__has_hybrid(); > if (evlist__create_maps(evsel_list, &target) < 0) { > diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h > index e3426541e0aa..c1de993c083f 100644 > --- a/tools/perf/util/cpumap.h > +++ b/tools/perf/util/cpumap.h > @@ -59,7 +59,7 @@ struct perf_cpu cpu__max_present_cpu(void); > /** > * cpu_map__is_dummy - Events associated with a pid, rather than a CPU, use a single dummy map with an entry of -1. > */ > -static inline bool cpu_map__is_dummy(struct perf_cpu_map *cpus) > +static inline bool cpu_map__is_dummy(const struct perf_cpu_map *cpus) > { > return perf_cpu_map__nr(cpus) == 1 && perf_cpu_map__cpu(cpus, 0).cpu == -1; > } > diff --git a/tools/perf/util/evlist-hybrid.c b/tools/perf/util/evlist-hybrid.c > index 57f02beef023..db3f5fbdebe1 100644 > --- a/tools/perf/util/evlist-hybrid.c > +++ b/tools/perf/util/evlist-hybrid.c > @@ -86,77 +86,3 @@ bool evlist__has_hybrid(struct evlist *evlist) > > return false; > } > - > -int evlist__fix_hybrid_cpus(struct evlist *evlist, const char *cpu_list) > -{ > - struct perf_cpu_map *cpus; > - struct evsel *evsel, *tmp; > - struct perf_pmu *pmu; > - int ret, unmatched_count = 0, events_nr = 0; > - > - if (!perf_pmu__has_hybrid() || !cpu_list) > - return 0; > - > - cpus = perf_cpu_map__new(cpu_list); > - if (!cpus) > - return -1; > - > - /* > - * The evsels are created with hybrid pmu's cpus. But now we > - * need to check and adjust the cpus of evsel by cpu_list because > - * cpu_list may cause conflicts with cpus of evsel. For example, > - * cpus of evsel is cpu0-7, but the cpu_list is cpu6-8, we need > - * to adjust the cpus of evsel to cpu6-7. And then propatate maps > - * in evlist__create_maps(). > - */ > - evlist__for_each_entry_safe(evlist, tmp, evsel) { > - struct perf_cpu_map *matched_cpus, *unmatched_cpus; > - char buf1[128], buf2[128]; > - > - pmu = perf_pmu__find_hybrid_pmu(evsel->pmu_name); > - if (!pmu) > - continue; > - > - ret = perf_pmu__cpus_match(pmu, cpus, &matched_cpus, > - &unmatched_cpus); > - if (ret) > - goto out; > - > - events_nr++; > - > - if (perf_cpu_map__nr(matched_cpus) > 0 && > - (perf_cpu_map__nr(unmatched_cpus) > 0 || > - perf_cpu_map__nr(matched_cpus) < perf_cpu_map__nr(cpus) || > - perf_cpu_map__nr(matched_cpus) < perf_cpu_map__nr(pmu->cpus))) { > - perf_cpu_map__put(evsel->core.cpus); > - perf_cpu_map__put(evsel->core.own_cpus); > - evsel->core.cpus = perf_cpu_map__get(matched_cpus); > - evsel->core.own_cpus = perf_cpu_map__get(matched_cpus); > - > - if (perf_cpu_map__nr(unmatched_cpus) > 0) { > - cpu_map__snprint(matched_cpus, buf1, sizeof(buf1)); > - pr_warning("WARNING: use %s in '%s' for '%s', skip other cpus in list.\n", > - buf1, pmu->name, evsel->name); > - } > - } > - > - if (perf_cpu_map__nr(matched_cpus) == 0) { > - evlist__remove(evlist, evsel); > - evsel__delete(evsel); > - > - cpu_map__snprint(cpus, buf1, sizeof(buf1)); > - cpu_map__snprint(pmu->cpus, buf2, sizeof(buf2)); > - pr_warning("WARNING: %s isn't a '%s', please use a CPU list in the '%s' range (%s)\n", > - buf1, pmu->name, pmu->name, buf2); > - unmatched_count++; > - } > - > - perf_cpu_map__put(matched_cpus); > - perf_cpu_map__put(unmatched_cpus); > - } > - if (events_nr) > - ret = (unmatched_count == events_nr) ? -1 : 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 aacdb1b0f948..19f74b4c340a 100644 > --- a/tools/perf/util/evlist-hybrid.h > +++ b/tools/perf/util/evlist-hybrid.h > @@ -10,6 +10,5 @@ > 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__fix_hybrid_cpus(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 a0504316b06f..5d0d99127a90 100644 > --- a/tools/perf/util/evlist.c > +++ b/tools/perf/util/evlist.c > @@ -2465,3 +2465,47 @@ void evlist__check_mem_load_aux(struct evlist *evlist) > } > } > } > + > +/** > + * evlist__warn_user_requested_cpus() - Check each evsel against requested CPUs > + * and warn if the user CPU list is inapplicable for the event's PMUs > + * CPUs. Uncore PMUs list a CPU in sysfs, but this may be overwritten by a > + * user requested CPU and so any online CPU is applicable. Core PMUs handle > + * events on the CPUs in their list and otherwise the event isn't supported. > + * @evlist: The list of events being checked. > + * @cpu_list: The user provided list of CPUs. > + */ > +void evlist__warn_user_requested_cpus(struct evlist *evlist, const char *cpu_list) > +{ > + struct perf_cpu_map *user_requested_cpus; > + struct evsel *pos; > + > + if (!cpu_list) > + return; > + > + user_requested_cpus = perf_cpu_map__new(cpu_list); > + if (!user_requested_cpus) > + return; > + > + evlist__for_each_entry(evlist, pos) { > + const struct perf_cpu_map *to_test; > + struct perf_cpu cpu; > + int idx; > + bool warn = true; > + const struct perf_pmu *pmu = evsel__find_pmu(pos); > + > + to_test = pmu && pmu->is_uncore ? cpu_map__online() : evsel__cpus(pos); > + > + perf_cpu_map__for_each_cpu(cpu, idx, to_test) { > + if (perf_cpu_map__has(user_requested_cpus, cpu)) { > + warn = false; > + break; > + } > + } > + if (warn) { > + pr_warning("WARNING: Requested CPU(s) '%s' not supported by PMU '%s' for event '%s'\n", > + cpu_list, pmu ? pmu->name : "cpu", evsel__name(pos)); > + } > + } > + perf_cpu_map__put(user_requested_cpus); > +} > diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h > index e7e5540cc970..5e7ff44f3043 100644 > --- a/tools/perf/util/evlist.h > +++ b/tools/perf/util/evlist.h > @@ -447,4 +447,6 @@ struct evsel *evlist__find_evsel(struct evlist *evlist, int idx); > > int evlist__scnprintf_evsels(struct evlist *evlist, size_t size, char *bf); > void evlist__check_mem_load_aux(struct evlist *evlist); > +void evlist__warn_user_requested_cpus(struct evlist *evlist, const char *cpu_list); > + > #endif /* __PERF_EVLIST_H */ > diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c > index f4f0afbc391c..1e0be23d4dd7 100644 > --- a/tools/perf/util/pmu.c > +++ b/tools/perf/util/pmu.c > @@ -2038,39 +2038,6 @@ int perf_pmu__match(char *pattern, char *name, char *tok) > return 0; > } > > -int perf_pmu__cpus_match(struct perf_pmu *pmu, struct perf_cpu_map *cpus, > - struct perf_cpu_map **mcpus_ptr, > - struct perf_cpu_map **ucpus_ptr) > -{ > - struct perf_cpu_map *pmu_cpus = pmu->cpus; > - struct perf_cpu_map *matched_cpus, *unmatched_cpus; > - struct perf_cpu cpu; > - int i, matched_nr = 0, unmatched_nr = 0; > - > - matched_cpus = perf_cpu_map__default_new(); > - if (!matched_cpus) > - return -1; > - > - unmatched_cpus = perf_cpu_map__default_new(); > - if (!unmatched_cpus) { > - perf_cpu_map__put(matched_cpus); > - return -1; > - } > - > - perf_cpu_map__for_each_cpu(cpu, i, cpus) { > - if (!perf_cpu_map__has(pmu_cpus, cpu)) > - RC_CHK_ACCESS(unmatched_cpus)->map[unmatched_nr++] = cpu; > - else > - RC_CHK_ACCESS(matched_cpus)->map[matched_nr++] = cpu; > - } > - > - perf_cpu_map__set_nr(unmatched_cpus, unmatched_nr); > - perf_cpu_map__set_nr(matched_cpus, matched_nr); > - *mcpus_ptr = matched_cpus; > - *ucpus_ptr = unmatched_cpus; > - return 0; > -} > - > double __weak perf_pmu__cpu_slots_per_cycle(void) > { > return NAN; > diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h > index 0e0cb6283594..49033bb134f3 100644 > --- a/tools/perf/util/pmu.h > +++ b/tools/perf/util/pmu.h > @@ -257,10 +257,6 @@ void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu); > bool perf_pmu__has_hybrid(void); > int perf_pmu__match(char *pattern, char *name, char *tok); > > -int perf_pmu__cpus_match(struct perf_pmu *pmu, struct perf_cpu_map *cpus, > - struct perf_cpu_map **mcpus_ptr, > - struct perf_cpu_map **ucpus_ptr); > - > char *pmu_find_real_name(const char *name); > char *pmu_find_alias_name(const char *name); > double perf_pmu__cpu_slots_per_cycle(void); > -- > 2.40.1.698.g37aff9b760-goog >