Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp1358110ybj; Thu, 7 May 2020 22:41:24 -0700 (PDT) X-Google-Smtp-Source: APiQypLpMZV1YSr91RpMwPfXdDgs59qdsqfY5ltXZDLDxO61f4KzrkftBSNnW3JONYqDsFvzehJd X-Received: by 2002:a17:906:18e9:: with SMTP id e9mr457468ejf.140.1588916484600; Thu, 07 May 2020 22:41:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588916484; cv=none; d=google.com; s=arc-20160816; b=IVWfVbpuCeuTra9WSsdey7LrKW3Vcqy4OAdibnwDQ1zu071McAJvphEa5/VSiBScNn obmfuIhrZNzV5TG9P1y3z46R2acmsuNCeCw6eQZuvz/bxMH/2Jue6fqG0kfpP7gdw+SV VQzso/7elLlJY9GTx/RuwvdiBc5JTjxccnMccg4o/3HGP6r4ROTd+0h8cxnKEOs8u+qQ TBVmSHftwCxP/SP9giNtP8EIQ4JApaktmexwCAbPxNdd4IrXpYNnrKRTGpv36t+A3WoV M+DsUNdYOCJo6P71O0VTpaxCbW0vp6sZrvF+eSL3M3XqXUdjWE4siZ8maxy7IcV4hxxY 9fMg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:cc:to:from :subject:references:mime-version:message-id:in-reply-to:date :dkim-signature; bh=j2DWTKjCez9WaKW/YskFPCoMAe0qTcBQQHk9f6RNmbA=; b=Dm5Q6iw2W3/6CPj8f6hloagHSFrpqWnof/A/JR97rMPx/e7xuY6NOzG4O54jJZ+iEJ nyJ7VBhVkuUIoRnuyvyFSJ7QoRBaYXvCAN9KqxTWoD5q5el4RRZzICYXazADz25gaeVC 75yhC2ocgB8I0H3MZxNWGRST9ZkHeNwmvJY2y5ydgdGjs6iuTKqV0Ti4baLZt4ZeNAUY 9JDU/j6iY94KSJLxMDIhyrEYXEQ3HxhGOwnmip1vdacQxjzjD7awpoT7kwUpHb+Ccgok J0P89lwXeUTTxbv5F/HdMGEob9jNTtkc3aHdOffBO362c2Ny3OQyiFmlNhRMRyna7Ekg 3E4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=rqfdEfU+; 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=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n1si352725ejr.104.2020.05.07.22.41.01; Thu, 07 May 2020 22:41:24 -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; dkim=pass header.i=@google.com header.s=20161025 header.b=rqfdEfU+; 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=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726904AbgEHFgi (ORCPT + 99 others); Fri, 8 May 2020 01:36:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49278 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726797AbgEHFgg (ORCPT ); Fri, 8 May 2020 01:36:36 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE447C05BD43 for ; Thu, 7 May 2020 22:36:35 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id w15so745327ybp.16 for ; Thu, 07 May 2020 22:36:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc:content-transfer-encoding; bh=j2DWTKjCez9WaKW/YskFPCoMAe0qTcBQQHk9f6RNmbA=; b=rqfdEfU+rQ5dJRYkpZYYypFOiCKuj89t+WJ9zuiazNBoNEAzPeLBRmBMtTxGZSc9pH +WmJAq/KbgxI6wNSalCoir50LtGuYsHLIFwqHcp2BOIrxZcBSc3ZaYbmM4XMY1/qqbyM 0okalejqABrfqtuBkMCPM4bwxGNVY50i/+S5J38NPVZI33NLGF6xdQWyglvMDH09Mpua xvDMTo6qxaFOjjxaIeuy9mb1BnxpPu9L7AT+kJ0/1H0t0Jf/vL8Qu/p6eiEIYMYYa83w JcVQ4bDCD4whP1Ku3nSDNfyLWW0ssRyc5ZLsCDyaGEwzRZ7g3n4Ew/uIUPqNBOc99Nos epqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc:content-transfer-encoding; bh=j2DWTKjCez9WaKW/YskFPCoMAe0qTcBQQHk9f6RNmbA=; b=UdFbB9+1B0PcQ+t3RXHXp97e7qLizhNvHRfsON1RZzwNyFH/ylBnvO/wuKPuMHMjcH qAD0oHHbpQL9wTj1lYTaBZunPrxlZuS7WFUdXGDyo4P4ArKrQ65RrzrxiPCMAd+3VXWO dhnCoHSOXuUbI5R1VdgAoMNkiAcs5BeJw57wWiFv73sEycdxen8HA3zP/bHTEBqxCyXw hi8npGMpqUmobfeY40YEtOblwb09HQeNbOe+7QJgY14gbD03FVsKXxA4BFc9jkovCiPP J3ELxgCoTB5nBYO7oDTALf4RZdDim7tjdpxQmfhFauySZzf8sRtBQs2+Te2P141GYz3X dr1A== X-Gm-Message-State: AGi0PuapOqRNpFzOuSP8aTIhboVPjAbgKfE4gzPMRIiMTWUD3SfOZ5On 4yWsN9aHEpxpXQQ3cuGICeb/xN6+2L1K X-Received: by 2002:a5b:5c6:: with SMTP id w6mr1969712ybp.339.1588916195084; Thu, 07 May 2020 22:36:35 -0700 (PDT) Date: Thu, 7 May 2020 22:36:16 -0700 In-Reply-To: <20200508053629.210324-1-irogers@google.com> Message-Id: <20200508053629.210324-2-irogers@google.com> Mime-Version: 1.0 References: <20200508053629.210324-1-irogers@google.com> X-Mailer: git-send-email 2.26.2.645.ge9eca65c58-goog Subject: [RFC PATCH v3 01/14] perf parse-events: expand add PMU error/verbose messages From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , Kajol Jain , Andi Kleen , John Garry , Jin Yao , Kan Liang , Cong Wang , Kim Phillips , linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, linux-perf-users@vger.kernel.org, Vince Weaver , Stephane Eranian , Ian Rogers Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On a CPU like skylakex an uncore_iio_0 PMU may alias with uncore_iio_free_running_0. The latter PMU doesn't support fc_mask as a parameter and so pmu_config_term fails. Typically parse_events_add_pmu is called in a loop where if one alias succeeds errors are ignored, however, if multiple errors occur parse_events__handle_error will currently give a WARN_ONCE. This change removes the WARN_ONCE in parse_events__handle_error and makes it a pr_debug. It adds verbose messages to parse_events_add_pmu warning that non-fatal errors may occur, while giving details on the pmu and config terms for useful context. pmu_config_term is altered so the failing term and pmu are present in the case of the 'unknown term' error which makes spotting the free_running case more straightforward. Before: $ perf --debug verbose=3D3 stat -M llc_misses.pcie_read sleep 1 Using CPUID GenuineIntel-6-55-4 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cp= u.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_re= q_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cp= u.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_re= q_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 adding {unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_of_cpu.mem_= read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_req_of_cpu.m= em_read.part3}:W,{unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_o= f_cpu.mem_read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_re= q_of_cpu.mem_read.part3}:W intel_pt default config: tsc,mtc,mtc_period=3D3,psb_period=3D3,pt,branch WARNING: multiple event parsing errors ... Invalid event/parameter 'fc_mask' ... After: $ perf --debug verbose=3D3 stat -M llc_misses.pcie_read sleep 1 Using CPUID GenuineIntel-6-55-4 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cp= u.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_re= q_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cp= u.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_re= q_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 adding {unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_of_cpu.mem_= read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_req_of_cpu.m= em_read.part3}:W,{unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_o= f_cpu.mem_read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_re= q_of_cpu.mem_read.part3}:W intel_pt default config: tsc,mtc,mtc_period=3D3,psb_period=3D3,pt,branch Attempting to add event pmu 'uncore_iio_free_running_5' with 'unc_iio_data_= req_of_cpu.mem_read.part0,' that may result in non-fatal errors After aliases, add event pmu 'uncore_iio_free_running_5' with 'fc_mask,ch_m= ask,umask,event,' that may result in non-fatal errors Attempting to add event pmu 'uncore_iio_free_running_3' with 'unc_iio_data_= req_of_cpu.mem_read.part0,' that may result in non-fatal errors After aliases, add event pmu 'uncore_iio_free_running_3' with 'fc_mask,ch_m= ask,umask,event,' that may result in non-fatal errors Attempting to add event pmu 'uncore_iio_free_running_1' with 'unc_iio_data_= req_of_cpu.mem_read.part0,' that may result in non-fatal errors After aliases, add event pmu 'uncore_iio_free_running_1' with 'fc_mask,ch_m= ask,umask,event,' that may result in non-fatal errors Multiple errors dropping message: unknown term 'fc_mask' for pmu 'uncore_ii= o_free_running_3' (valid terms: event,umask,config,config1,config2,name,per= iod,percore) ... Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/intel-pt.c | 32 +++++++++++++++++----------- tools/perf/tests/pmu.c | 4 ++-- tools/perf/util/parse-events.c | 29 ++++++++++++++++++++++++- tools/perf/util/pmu.c | 33 ++++++++++++++++++----------- tools/perf/util/pmu.h | 2 +- 5 files changed, 72 insertions(+), 28 deletions(-) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util= /intel-pt.c index fd9e22d1e366..0fe401ad3347 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -59,7 +59,8 @@ struct intel_pt_recording { size_t priv_size; }; =20 -static int intel_pt_parse_terms_with_default(struct list_head *formats, +static int intel_pt_parse_terms_with_default(const char *pmu_name, + struct list_head *formats, const char *str, u64 *config) { @@ -78,7 +79,8 @@ static int intel_pt_parse_terms_with_default(struct list_= head *formats, goto out_free; =20 attr.config =3D *config; - err =3D perf_pmu__config_terms(formats, &attr, terms, true, NULL); + err =3D perf_pmu__config_terms(pmu_name, formats, &attr, terms, true, + NULL); if (err) goto out_free; =20 @@ -88,11 +90,12 @@ static int intel_pt_parse_terms_with_default(struct lis= t_head *formats, return err; } =20 -static int intel_pt_parse_terms(struct list_head *formats, const char *str= , - u64 *config) +static int intel_pt_parse_terms(const char *pmu_name, struct list_head *fo= rmats, + const char *str, u64 *config) { *config =3D 0; - return intel_pt_parse_terms_with_default(formats, str, config); + return intel_pt_parse_terms_with_default(pmu_name, formats, str, + config); } =20 static u64 intel_pt_masked_bits(u64 mask, u64 bits) @@ -229,7 +232,8 @@ static u64 intel_pt_default_config(struct perf_pmu *int= el_pt_pmu) =20 pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf); =20 - intel_pt_parse_terms(&intel_pt_pmu->format, buf, &config); + intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, buf, + &config); =20 return config; } @@ -337,13 +341,16 @@ static int intel_pt_info_fill(struct auxtrace_record = *itr, if (priv_size !=3D ptr->priv_size) return -EINVAL; =20 - intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit); - intel_pt_parse_terms(&intel_pt_pmu->format, "noretcomp", - &noretcomp_bit); - intel_pt_parse_terms(&intel_pt_pmu->format, "mtc", &mtc_bit); + intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, + "tsc", &tsc_bit); + intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, + "noretcomp", &noretcomp_bit); + intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, + "mtc", &mtc_bit); mtc_freq_bits =3D perf_pmu__format_bits(&intel_pt_pmu->format, "mtc_period"); - intel_pt_parse_terms(&intel_pt_pmu->format, "cyc", &cyc_bit); + intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, + "cyc", &cyc_bit); =20 intel_pt_tsc_ctc_ratio(&tsc_ctc_ratio_n, &tsc_ctc_ratio_d); =20 @@ -768,7 +775,8 @@ static int intel_pt_recording_options(struct auxtrace_r= ecord *itr, } } =20 - intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &tsc_bit); + intel_pt_parse_terms(intel_pt_pmu->name, &intel_pt_pmu->format, + "tsc", &tsc_bit); =20 if (opts->full_auxtrace && (intel_pt_evsel->core.attr.config & tsc_bit)) have_timing_info =3D true; diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index 74379ff1f7fa..5c11fe2b3040 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -156,8 +156,8 @@ int test__pmu(struct test *test __maybe_unused, int sub= test __maybe_unused) if (ret) break; =20 - ret =3D perf_pmu__config_terms(&formats, &attr, terms, - false, NULL); + ret =3D perf_pmu__config_terms("perf-pmu-test", &formats, &attr, + terms, false, NULL); if (ret) break; =20 diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.= c index e9464b04f149..0ebc0fd9385a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -204,7 +204,8 @@ void parse_events__handle_error(struct parse_events_err= or *err, int idx, err->help =3D help; break; default: - WARN_ONCE(1, "WARNING: multiple event parsing errors\n"); + pr_debug("Multiple errors dropping message: %s (%s)\n", + err->str, err->help); free(err->str); err->str =3D str; free(err->help); @@ -1422,6 +1423,19 @@ int parse_events_add_pmu(struct parse_events_state *= parse_state, bool use_uncore_alias; LIST_HEAD(config_terms); =20 + if (verbose > 1) { + fprintf(stderr, "Attempting to add event pmu '%s' with '", + name); + if (head_config) { + struct parse_events_term *term; + + list_for_each_entry(term, head_config, list) { + fprintf(stderr, "%s,", term->config); + } + } + fprintf(stderr, "' that may result in non-fatal errors\n"); + } + pmu =3D perf_pmu__find(name); if (!pmu) { char *err_str; @@ -1458,6 +1472,19 @@ int parse_events_add_pmu(struct parse_events_state *= parse_state, if (perf_pmu__check_alias(pmu, head_config, &info)) return -EINVAL; =20 + if (verbose > 1) { + fprintf(stderr, "After aliases, add event pmu '%s' with '", + name); + if (head_config) { + struct parse_events_term *term; + + list_for_each_entry(term, head_config, list) { + fprintf(stderr, "%s,", term->config); + } + } + fprintf(stderr, "' that may result in non-fatal errors\n"); + } + /* * Configure hardcoded terms first, no need to check * return value when called with fail =3D=3D 0 ;) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 92bd7fafcce6..71d0290b616a 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1056,7 +1056,8 @@ static char *pmu_formats_string(struct list_head *for= mats) * Setup one of config[12] attr members based on the * user input data - term parameter. */ -static int pmu_config_term(struct list_head *formats, +static int pmu_config_term(const char *pmu_name, + struct list_head *formats, struct perf_event_attr *attr, struct parse_events_term *term, struct list_head *head_terms, @@ -1082,16 +1083,24 @@ static int pmu_config_term(struct list_head *format= s, =20 format =3D pmu_find_format(formats, term->config); if (!format) { - if (verbose > 0) - printf("Invalid event/parameter '%s'\n", term->config); + char *pmu_term =3D pmu_formats_string(formats); + char *unknown_term; + char *help_msg; + + if (asprintf(&unknown_term, + "unknown term '%s' for pmu '%s'", + term->config, pmu_name) < 0) + unknown_term =3D strdup("unknown term"); + help_msg =3D parse_events_formats_error_string(pmu_term); if (err) { - char *pmu_term =3D pmu_formats_string(formats); - parse_events__handle_error(err, term->err_term, - strdup("unknown term"), - parse_events_formats_error_string(pmu_term)); - free(pmu_term); + unknown_term, + help_msg); + } else { + pr_debug("%s (%s)\n", unknown_term, help_msg); + free(unknown_term); } + free(pmu_term); return -EINVAL; } =20 @@ -1168,7 +1177,7 @@ static int pmu_config_term(struct list_head *formats, return 0; } =20 -int perf_pmu__config_terms(struct list_head *formats, +int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats= , struct perf_event_attr *attr, struct list_head *head_terms, bool zero, struct parse_events_error *err) @@ -1176,7 +1185,7 @@ int perf_pmu__config_terms(struct list_head *formats, struct parse_events_term *term; =20 list_for_each_entry(term, head_terms, list) { - if (pmu_config_term(formats, attr, term, head_terms, + if (pmu_config_term(pmu_name, formats, attr, term, head_terms, zero, err)) return -EINVAL; } @@ -1196,8 +1205,8 @@ int perf_pmu__config(struct perf_pmu *pmu, struct per= f_event_attr *attr, bool zero =3D !!pmu->default_config; =20 attr->type =3D pmu->type; - return perf_pmu__config_terms(&pmu->format, attr, head_terms, - zero, err); + return perf_pmu__config_terms(pmu->name, &pmu->format, attr, + head_terms, zero, err); } =20 static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index e119333e93ba..85e0c7f2515c 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -76,7 +76,7 @@ struct perf_pmu *perf_pmu__find_by_type(unsigned int type= ); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms, struct parse_events_error *error); -int perf_pmu__config_terms(struct list_head *formats, +int perf_pmu__config_terms(const char *pmu_name, struct list_head *formats= , struct perf_event_attr *attr, struct list_head *head_terms, bool zero, struct parse_events_error *error); --=20 2.26.2.645.ge9eca65c58-goog