All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: Rob Herring <robh@kernel.org>
Cc: Will Deacon <will@kernel.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Jiri Olsa <jolsa@redhat.com>, LKML <linux-kernel@vger.kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Namhyung Kim <namhyung@kernel.org>,
	Raphael Gault <raphael.gault@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Jonathan Cameron <Jonathan.Cameron@huawei.com>,
	Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Subject: Re: [PATCH v2 5/9] libperf: Add support for user space counter access
Date: Thu, 3 Sep 2020 22:51:08 -0700	[thread overview]
Message-ID: <CAP-5=fUYsNZNM-s8auc5RVwQ-oqEnG10uBVhorns5aU29OAYXw@mail.gmail.com> (raw)
In-Reply-To: <CAL_JsqLUZ+iejO0WyqivPfkZ+Wk_VC-fw260ScqGk1r=PnUZbA@mail.gmail.com>

On Wed, Sep 2, 2020 at 12:48 PM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, Sep 2, 2020 at 12:07 PM Ian Rogers <irogers@google.com> wrote:
> >
> > On Fri, Aug 28, 2020 at 1:56 PM Rob Herring <robh@kernel.org> wrote:
> > >
> > > x86 and arm64 can both support direct access of event counters in
> > > userspace. The access sequence is less than trivial and currently exists
> > > in perf test code (tools/perf/arch/x86/tests/rdpmc.c) with copies in
> > > projects such as PAPI and libpfm4.
> > >
> > > In order to support usersapce access, an event must be mmapped. While
> > > there's already mmap support for evlist, the usecase is a bit different
> > > than the self monitoring with userspace access. So let's add a new
> > > perf_evsel__mmap() function to mmap an evsel. This allows implementing
> > > userspace access as a fastpath for perf_evsel__read().
> > >
> > > The mmapped address is returned by perf_evsel__mmap() primarily for
> > > users/tests to check if userspace access is enabled.
> > >
> > > Signed-off-by: Rob Herring <robh@kernel.org>
> > > ---
>
> > > +int perf_mmap__read_self(struct perf_mmap *map, struct perf_counts_values *count)
> > > +{
> > > +       struct perf_event_mmap_page *pc = map->base;
> > > +       u32 seq, idx, time_mult = 0, time_shift = 0;
> > > +       u64 cnt, cyc = 0, time_offset = 0, time_cycles = 0, time_mask = ~0ULL;
> > > +
> > > +       BUG_ON(!pc);
> > > +
> > > +       if (!pc->cap_user_rdpmc)
> > > +               return -1;
> > > +
> > > +       do {
> > > +               seq = READ_ONCE(pc->lock);
> > > +               barrier();
> > > +
> > > +               count->ena = READ_ONCE(pc->time_enabled);
> > > +               count->run = READ_ONCE(pc->time_running);
> > > +
> > > +               if (pc->cap_user_time && count->ena != count->run) {
> > > +                       cyc = read_timestamp();
> > > +                       time_mult = READ_ONCE(pc->time_mult);
> > > +                       time_shift = READ_ONCE(pc->time_shift);
> > > +                       time_offset = READ_ONCE(pc->time_offset);
> > > +
> > > +                       if (pc->cap_user_time_short) {
> > > +                               time_cycles = READ_ONCE(pc->time_cycles);
> > > +                               time_mask = READ_ONCE(pc->time_mask);
> > > +                       }
> > > +               }
> > > +
> > > +               idx = READ_ONCE(pc->index);
> > > +               cnt = READ_ONCE(pc->offset);
> > > +               if (pc->cap_user_rdpmc && idx) {
> > > +                       u64 evcnt = read_perf_counter(idx - 1);
> > > +                       u16 width = READ_ONCE(pc->pmc_width);
> > > +
> > > +                       evcnt <<= 64 - width;
> > > +                       evcnt >>= 64 - width;
> > > +                       cnt += evcnt;
> > > +               } else
> > > +                       return -1;
> > > +
> > > +               barrier();
> > > +       } while (READ_ONCE(pc->lock) != seq);
> > > +
> > > +       if (count->ena != count->run) {
> >
> > There's an existing bug here that I tried to resolve in this patch:
> > https://lore.kernel.org/lkml/CAP-5=fVRdqvswtyQMg5cB+ntTGda+SAYskjTQednEH-AeZo13g@mail.gmail.com/
> > Due to multiplexing, enabled may be > 0 but run == 0 and the divide
> > below can end up with divide by zero.
>
> Yeah, I saw that, but didn't try to also fix that issue here.
>
> > I like the idea of this code being in a library, there's an intent
> > that the perf_event.h and test code be copy-paste-able, but there is
> > some pre-existing divergence. It would be nice if this code could be
> > closer to the sample code in both the test and perf_event.h.
>
> The only way we get and keep all the versions of the code aligned is
> removing the other copies. We should just remove the code comment from
> perf_event.h IMO. If rdpmc.c is going to stick around given some
> resistance to removing it, then perhaps it should be converted to use
> libperf. At that point it could also be arch independent. Though I
> don't like the idea of having the same test twice.

This makes sense to me, perhaps others could comment. Given the
cleaned up API fixing or deleting tools/perf/arch/x86/tests/rdpmc.c is
desirable (as your patch set does). I wondered if we could do Jiri's
suggestion to run the lib/perf tests with perf test. One way would be
to have shell script wrapper in tools/perf/tests/shell. It's not clear
how to make a dependency from a shell script there and tests built
elsewhere in the tree though.

> > As per the change above, I think running and enabled times need to be
> > out arguments.
>
> They are now in this version.

Sorry, my mistake. I'd missed that.

Thanks,
Ian

> Rob

WARNING: multiple messages have this Message-ID (diff)
From: Ian Rogers <irogers@google.com>
To: Rob Herring <robh@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
	Will Deacon <will@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Catalin Marinas <catalin.marinas@arm.com>,
	LKML <linux-kernel@vger.kernel.org>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Raphael Gault <raphael.gault@arm.com>,
	Ingo Molnar <mingo@redhat.com>,
	Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>,
	Jonathan Cameron <Jonathan.Cameron@huawei.com>,
	Namhyung Kim <namhyung@kernel.org>, Jiri Olsa <jolsa@redhat.com>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v2 5/9] libperf: Add support for user space counter access
Date: Thu, 3 Sep 2020 22:51:08 -0700	[thread overview]
Message-ID: <CAP-5=fUYsNZNM-s8auc5RVwQ-oqEnG10uBVhorns5aU29OAYXw@mail.gmail.com> (raw)
In-Reply-To: <CAL_JsqLUZ+iejO0WyqivPfkZ+Wk_VC-fw260ScqGk1r=PnUZbA@mail.gmail.com>

On Wed, Sep 2, 2020 at 12:48 PM Rob Herring <robh@kernel.org> wrote:
>
> On Wed, Sep 2, 2020 at 12:07 PM Ian Rogers <irogers@google.com> wrote:
> >
> > On Fri, Aug 28, 2020 at 1:56 PM Rob Herring <robh@kernel.org> wrote:
> > >
> > > x86 and arm64 can both support direct access of event counters in
> > > userspace. The access sequence is less than trivial and currently exists
> > > in perf test code (tools/perf/arch/x86/tests/rdpmc.c) with copies in
> > > projects such as PAPI and libpfm4.
> > >
> > > In order to support usersapce access, an event must be mmapped. While
> > > there's already mmap support for evlist, the usecase is a bit different
> > > than the self monitoring with userspace access. So let's add a new
> > > perf_evsel__mmap() function to mmap an evsel. This allows implementing
> > > userspace access as a fastpath for perf_evsel__read().
> > >
> > > The mmapped address is returned by perf_evsel__mmap() primarily for
> > > users/tests to check if userspace access is enabled.
> > >
> > > Signed-off-by: Rob Herring <robh@kernel.org>
> > > ---
>
> > > +int perf_mmap__read_self(struct perf_mmap *map, struct perf_counts_values *count)
> > > +{
> > > +       struct perf_event_mmap_page *pc = map->base;
> > > +       u32 seq, idx, time_mult = 0, time_shift = 0;
> > > +       u64 cnt, cyc = 0, time_offset = 0, time_cycles = 0, time_mask = ~0ULL;
> > > +
> > > +       BUG_ON(!pc);
> > > +
> > > +       if (!pc->cap_user_rdpmc)
> > > +               return -1;
> > > +
> > > +       do {
> > > +               seq = READ_ONCE(pc->lock);
> > > +               barrier();
> > > +
> > > +               count->ena = READ_ONCE(pc->time_enabled);
> > > +               count->run = READ_ONCE(pc->time_running);
> > > +
> > > +               if (pc->cap_user_time && count->ena != count->run) {
> > > +                       cyc = read_timestamp();
> > > +                       time_mult = READ_ONCE(pc->time_mult);
> > > +                       time_shift = READ_ONCE(pc->time_shift);
> > > +                       time_offset = READ_ONCE(pc->time_offset);
> > > +
> > > +                       if (pc->cap_user_time_short) {
> > > +                               time_cycles = READ_ONCE(pc->time_cycles);
> > > +                               time_mask = READ_ONCE(pc->time_mask);
> > > +                       }
> > > +               }
> > > +
> > > +               idx = READ_ONCE(pc->index);
> > > +               cnt = READ_ONCE(pc->offset);
> > > +               if (pc->cap_user_rdpmc && idx) {
> > > +                       u64 evcnt = read_perf_counter(idx - 1);
> > > +                       u16 width = READ_ONCE(pc->pmc_width);
> > > +
> > > +                       evcnt <<= 64 - width;
> > > +                       evcnt >>= 64 - width;
> > > +                       cnt += evcnt;
> > > +               } else
> > > +                       return -1;
> > > +
> > > +               barrier();
> > > +       } while (READ_ONCE(pc->lock) != seq);
> > > +
> > > +       if (count->ena != count->run) {
> >
> > There's an existing bug here that I tried to resolve in this patch:
> > https://lore.kernel.org/lkml/CAP-5=fVRdqvswtyQMg5cB+ntTGda+SAYskjTQednEH-AeZo13g@mail.gmail.com/
> > Due to multiplexing, enabled may be > 0 but run == 0 and the divide
> > below can end up with divide by zero.
>
> Yeah, I saw that, but didn't try to also fix that issue here.
>
> > I like the idea of this code being in a library, there's an intent
> > that the perf_event.h and test code be copy-paste-able, but there is
> > some pre-existing divergence. It would be nice if this code could be
> > closer to the sample code in both the test and perf_event.h.
>
> The only way we get and keep all the versions of the code aligned is
> removing the other copies. We should just remove the code comment from
> perf_event.h IMO. If rdpmc.c is going to stick around given some
> resistance to removing it, then perhaps it should be converted to use
> libperf. At that point it could also be arch independent. Though I
> don't like the idea of having the same test twice.

This makes sense to me, perhaps others could comment. Given the
cleaned up API fixing or deleting tools/perf/arch/x86/tests/rdpmc.c is
desirable (as your patch set does). I wondered if we could do Jiri's
suggestion to run the lib/perf tests with perf test. One way would be
to have shell script wrapper in tools/perf/tests/shell. It's not clear
how to make a dependency from a shell script there and tests built
elsewhere in the tree though.

> > As per the change above, I think running and enabled times need to be
> > out arguments.
>
> They are now in this version.

Sorry, my mistake. I'd missed that.

Thanks,
Ian

> Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-09-04  5:51 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-28 20:56 [PATCH v2 0/9] libperf and arm64 userspace counter access support Rob Herring
2020-08-28 20:56 ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 1/9] arm64: pmu: Add hook to handle pmu-related undefined instructions Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 2/9] arm64: pmu: Add function implementation to update event index in userpage Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 3/9] arm64: perf: Enable pmu counter direct access for perf event on armv8 Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 4/9] tools/include: Add an initial math64.h Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 5/9] libperf: Add support for user space counter access Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-31  9:11   ` Jiri Olsa
2020-08-31  9:11     ` Jiri Olsa
2020-09-02 16:58     ` Rob Herring
2020-09-02 16:58       ` Rob Herring
2020-08-31  9:11   ` Jiri Olsa
2020-08-31  9:11     ` Jiri Olsa
2020-09-02 17:01     ` Rob Herring
2020-09-02 17:01       ` Rob Herring
2020-09-02 18:07   ` Ian Rogers
2020-09-02 18:07     ` Ian Rogers
2020-09-02 19:48     ` Rob Herring
2020-09-02 19:48       ` Rob Herring
2020-09-04  5:51       ` Ian Rogers [this message]
2020-09-04  5:51         ` Ian Rogers
2020-08-28 20:56 ` [PATCH v2 6/9] libperf: Add arm64 support to perf_mmap__read_self() Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 7/9] perf: arm64: Add test for userspace counter access on heterogeneous systems Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 8/9] Documentation: arm64: Document PMU counters access from userspace Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-28 20:56 ` [PATCH v2 9/9] perf: Remove x86 specific rdpmc test Rob Herring
2020-08-28 20:56   ` Rob Herring
2020-08-31  9:11   ` Jiri Olsa
2020-08-31  9:11     ` Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAP-5=fUYsNZNM-s8auc5RVwQ-oqEnG10uBVhorns5aU29OAYXw@mail.gmail.com' \
    --to=irogers@google.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=acme@kernel.org \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=catalin.marinas@arm.com \
    --cc=honnappa.nagarahalli@arm.com \
    --cc=jolsa@redhat.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=raphael.gault@arm.com \
    --cc=robh@kernel.org \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.