From patchwork Fri Aug 18 03:09:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kim Phillips X-Patchwork-Id: 9907463 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6765E602C8 for ; Fri, 18 Aug 2017 03:10:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A9B628BE3 for ; Fri, 18 Aug 2017 03:10:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4F50928BE8; Fri, 18 Aug 2017 03:10:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7FF8C28BE7 for ; Fri, 18 Aug 2017 03:09:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753891AbdHRDJp (ORCPT ); Thu, 17 Aug 2017 23:09:45 -0400 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:56872 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753345AbdHRDJo (ORCPT ); Thu, 17 Aug 2017 23:09:44 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6023680D; Thu, 17 Aug 2017 20:09:43 -0700 (PDT) Received: from dupont (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A98953F577; Thu, 17 Aug 2017 20:09:42 -0700 (PDT) Date: Thu, 17 Aug 2017 22:09:41 -0500 From: Kim Phillips To: David Howells Cc: , , , , , , , perf group , Will Deacon , Mark Rutland , Arnaldo Carvalho de Melo Subject: Re: [PATCH 06/27] Provide supplementary error message facility [ver #5] Message-Id: <20170817220941.8c6532b076bb0d8db60a6968@arm.com> In-Reply-To: <149745337097.10897.6533194783327792549.stgit@warthog.procyon.org.uk> References: <149745330648.10897.9605870130502083184.stgit@warthog.procyon.org.uk> <149745337097.10897.6533194783327792549.stgit@warthog.procyon.org.uk> Organization: Arm X-Mailer: Sylpheed 3.5.1 (GTK+ 2.24.31; x86_64-pc-linux-gnu) Mime-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Wed, 14 Jun 2017 16:16:11 +0100 David Howells wrote: > Provide a way for the kernel to pass supplementary error messages to > userspace. This will make it easier for userspace, particularly in > containers to find out what went wrong during mounts and automounts, but is > also made available to any other syscalls that want to use it. Hi all, I see patches 1-5 have already made it to Linus' master branch, but I can't determine the status of this particular patch. Assuming it's still under consideration, I'd like to attest to the significantly higher level of user experience improvement it can give perf users (see RFC below): Am I taking the right approach here by assuming this new error message facility is indeed eligible for upstream acceptance sometime soon? Thanks, Kim From da34ddaf1aa8c731f645c268a1caf17029caca8c Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 16 Aug 2017 17:56:40 -0500 Subject: [RFC] perf tool & spe driver: shot at prctl errmsging Example session: Lines beginning with "spe-pmu@" are new and specify what the PMU driver found wrong to the user in a much more precise manner: $ ./perf record -e arm_spe_0// -C 0-3 true Error: spe-pmu@0: no sample period, or less than minimum (256) PMU Hardware doesn't support sampling/overflow-interrupts. $ ./perf record -e arm_spe_0// -C 0-3 -c 1024 true [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.022 MB perf.data ] $ ./perf record -e arm_spe_0// -C 0-4 -c 1024 true Error: spe-pmu@0: not supported on CPU 4. Supported CPU list: 0-3 The arm_spe_0// event is not supported. $ ./perf record -e arm_spe_0/pa_enable=1/ -C 0-3 -c 1024 true Error: spe-pmu@0: physical address and/or context ID capture limited to privileged users $ sudo ./perf record -e arm_spe_0/pa_enable=1/ -C 0-3 -c 1024 true [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.071 MB perf.data ] $ Signed-off-by: Kim Phillips Cc: Will Deacon Cc: Mark Rutland Cc: Arnaldo Carvalho de Melo --- - patch available and rebased on top of linux-will.git/perf/spe's latest, here: http://www.linux-arm.org/git?p=linux-kp.git;a=shortlog;h=refs/heads/spe-prctl or git://linux-arm.org/linux-kp.git # spe-prctl branch drivers/perf/arm_spe_pmu.c | 46 ++++++++++++++++++++++++++++++++++++++-------- tools/perf/perf.c | 12 ++++++++++++ tools/perf/util/evsel.c | 14 +++++++++----- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index fef0a4834879..cb4db7dac929 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -23,11 +23,13 @@ #define DRVNAME PMUNAME "_pmu" #define pr_fmt(fmt) DRVNAME ": " fmt +#include #include #include #include #include #include +#include #include #include #include @@ -660,20 +662,30 @@ static int arm_spe_pmu_event_init(struct perf_event *event) u64 reg; struct perf_event_attr *attr = &event->attr; struct arm_spe_pmu *spe_pmu = to_spe_pmu(event->pmu); + const struct device *dev = &spe_pmu->pdev->dev; + const char *devname = dev_name(dev); /* This is, of course, deeply driver-specific */ if (attr->type != event->pmu->type) return -ENOENT; if (event->cpu >= 0 && - !cpumask_test_cpu(event->cpu, &spe_pmu->supported_cpus)) + !cpumask_test_cpu(event->cpu, &spe_pmu->supported_cpus)) { + errorf("%s: not supported on CPU %d. Supported CPU list: %*pbl\n", + devname, event->cpu, cpumask_pr_args(&spe_pmu->supported_cpus)); return -ENOENT; + } - if (arm_spe_event_to_pmsevfr(event) & PMSEVFR_EL1_RES0) + if (arm_spe_event_to_pmsevfr(event) & PMSEVFR_EL1_RES0) { + errorf("%s: unsupported Sampling Event Filter (PMSEVFR) value\n", + devname); return -EOPNOTSUPP; + } - if (attr->exclude_idle) + if (attr->exclude_idle) { + errorf("%s: Cannot exclude profiling when idle\n", devname); return -EOPNOTSUPP; + } /* * Feedback-directed frequency throttling doesn't work when we @@ -682,26 +694,44 @@ static int arm_spe_pmu_event_init(struct perf_event *event) * count to reflect that. Instead, force the user to specify a * sample period instead. */ - if (attr->freq) + if (attr->freq) { + errorf("%s: sample period must be specified\n", devname); return -EINVAL; + } + + if (!event->hw.sample_period || + event->hw.sample_period < spe_pmu->min_period) { + errorf("%s: no sample period, or less than minimum (%d)\n", + devname, spe_pmu->min_period); + return -EOPNOTSUPP; + } reg = arm_spe_event_to_pmsfcr(event); if ((reg & BIT(PMSFCR_EL1_FE_SHIFT)) && - !(spe_pmu->features & SPE_PMU_FEAT_FILT_EVT)) + !(spe_pmu->features & SPE_PMU_FEAT_FILT_EVT)) { + errorf("%s: unsupported filter (EVT)\n", devname); return -EOPNOTSUPP; + } if ((reg & BIT(PMSFCR_EL1_FT_SHIFT)) && - !(spe_pmu->features & SPE_PMU_FEAT_FILT_TYP)) + !(spe_pmu->features & SPE_PMU_FEAT_FILT_TYP)) { + errorf("%s: unsupported filter (TYP)\n", devname); return -EOPNOTSUPP; + } if ((reg & BIT(PMSFCR_EL1_FL_SHIFT)) && - !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT)) + !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT)) { + errorf("%s: unsupported filter (LAT)\n", devname); return -EOPNOTSUPP; + } reg = arm_spe_event_to_pmscr(event); if (!capable(CAP_SYS_ADMIN) && - (reg & (BIT(PMSCR_EL1_PA_SHIFT) | BIT(PMSCR_EL1_CX_SHIFT)))) + (reg & (BIT(PMSCR_EL1_PA_SHIFT) | BIT(PMSCR_EL1_CX_SHIFT)))) { + errorf("%s: physical address and/or context ID capture limited to privileged users\n", + devname); return -EACCES; + } return 0; } diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 628a5e412cb1..0d16dc5042ab 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -30,6 +30,13 @@ #include #include +#include +#include +#include + +#define PR_ERRMSG_ENABLE 48 +#define PR_ERRMSG_READ 49 + const char perf_usage_string[] = "perf [--version] [--help] [OPTIONS] COMMAND [ARGS]"; @@ -431,6 +438,11 @@ int main(int argc, const char **argv) char sbuf[STRERR_BUFSIZE]; int value; + if (prctl(PR_ERRMSG_ENABLE, 1) < 0) { + perror("prctl/en"); + exit(1); + } + /* libsubcmd init */ exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT); pager_init(PERF_PAGER_ENVIRONMENT); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d9899280a9ee..e997a361d1eb 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "asm/bug.h" #include "callchain.h" @@ -40,6 +41,9 @@ #include "sane_ctype.h" +#define PR_ERRMSG_ENABLE 48 +#define PR_ERRMSG_READ 49 + static struct { bool sample_id_all; bool exclude_guest; @@ -2518,19 +2522,19 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, int err, char *msg, size_t size) { char sbuf[STRERR_BUFSIZE]; - int printed = 0; - int n, perr; + int perr, printed = 0; + size_t n; do { errno = 0; n = prctl(PR_ERRMSG_READ, sbuf, sizeof(sbuf)); perr = errno; - if (n > 0) { - printed = scnprintf(msg, n + 1, "%s\n", sbuf); + if (n > 0 && n < size) { + sbuf[n] = 0; + printed = scnprintf(msg, size, "%s", sbuf); size -= printed; msg += printed; } - } while (perr == 0); switch (err) {