All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>, Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Kajol Jain <kjain@linux.ibm.com>, Andi Kleen <ak@linux.intel.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Anshuman Khandual <anshuman.khandual@arm.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Rob Herring <robh@kernel.org>,
	Stephane Eranian <eranian@google.com>
Subject: Re: [PATCH v3 1/3] perf: Align user space counter reading with code
Date: Mon, 1 Aug 2022 09:17:55 -0300	[thread overview]
Message-ID: <YufEc1i32OOa+6u8@kernel.org> (raw)
In-Reply-To: <20220719223946.176299-2-irogers@google.com>

Em Tue, Jul 19, 2022 at 03:39:44PM -0700, Ian Rogers escreveu:
> Align the user space counter reading documentation with the code in
> perf_mmap__read_self. Previously the documentation was based on the perf
> rdpmc test, but now general purpose code is provided by libperf.

Peter, can you merge this so as not to make Linus raise eyebrows with me
processing things outside tools/perf/ when asking him to pull perf
userspace?

- Arnaldo
 
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
>  include/uapi/linux/perf_event.h       | 35 +++++++++++++++++----------
>  tools/include/uapi/linux/perf_event.h | 35 +++++++++++++++++----------
>  2 files changed, 44 insertions(+), 26 deletions(-)
> 
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index d37629dbad72..6826dabb7e03 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -538,9 +538,13 @@ struct perf_event_mmap_page {
>  	 *
>  	 *     if (pc->cap_usr_time && enabled != running) {
>  	 *       cyc = rdtsc();
> -	 *       time_offset = pc->time_offset;
>  	 *       time_mult   = pc->time_mult;
>  	 *       time_shift  = pc->time_shift;
> +	 *       time_offset = pc->time_offset;
> +	 *       if (pc->cap_user_time_short) {
> +	 *         time_cycles = pc->time_cycles;
> +	 *         time_mask = pc->time_mask;
> +	 *       }
>  	 *     }
>  	 *
>  	 *     index = pc->index;
> @@ -548,6 +552,9 @@ struct perf_event_mmap_page {
>  	 *     if (pc->cap_user_rdpmc && index) {
>  	 *       width = pc->pmc_width;
>  	 *       pmc = rdpmc(index - 1);
> +	 *       pmc <<= 64 - width;
> +	 *       pmc >>= 64 - width;
> +	 *       count += pmc;
>  	 *     }
>  	 *
>  	 *     barrier();
> @@ -590,25 +597,27 @@ struct perf_event_mmap_page {
>  	 * If cap_usr_time the below fields can be used to compute the time
>  	 * delta since time_enabled (in ns) using rdtsc or similar.
>  	 *
> -	 *   u64 quot, rem;
> -	 *   u64 delta;
> -	 *
> -	 *   quot = (cyc >> time_shift);
> -	 *   rem = cyc & (((u64)1 << time_shift) - 1);
> -	 *   delta = time_offset + quot * time_mult +
> -	 *              ((rem * time_mult) >> time_shift);
> +	 *   cyc = time_cycles + ((cyc - time_cycles) & time_mask);
> +	 *   delta = time_offset + mul_u64_u32_shr(cyc, time_mult, time_shift);
>  	 *
>  	 * Where time_offset,time_mult,time_shift and cyc are read in the
> -	 * seqcount loop described above. This delta can then be added to
> -	 * enabled and possible running (if index), improving the scaling:
> +	 * seqcount loop described above. mul_u64_u32_shr will compute:
> +	 *
> +	 *   (u64)(((unsigned __int128)cyc * time_mult) >> time_shift)
> +	 *
> +	 * This delta can then be added to enabled and possible running (if
> +	 * index) to improve the scaling. Due to event multiplexing, running
> +	 * may be zero and so care is needed to avoid division by zero.
>  	 *
>  	 *   enabled += delta;
>  	 *   if (index)
>  	 *     running += delta;
>  	 *
> -	 *   quot = count / running;
> -	 *   rem  = count % running;
> -	 *   count = quot * enabled + (rem * enabled) / running;
> +	 *   if (running != 0) {
> +	 *     quot = count / running;
> +	 *     rem  = count % running;
> +	 *     count = quot * enabled + (rem * enabled) / running;
> +	 *   }
>  	 */
>  	__u16	time_shift;
>  	__u32	time_mult;
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index d37629dbad72..6826dabb7e03 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -538,9 +538,13 @@ struct perf_event_mmap_page {
>  	 *
>  	 *     if (pc->cap_usr_time && enabled != running) {
>  	 *       cyc = rdtsc();
> -	 *       time_offset = pc->time_offset;
>  	 *       time_mult   = pc->time_mult;
>  	 *       time_shift  = pc->time_shift;
> +	 *       time_offset = pc->time_offset;
> +	 *       if (pc->cap_user_time_short) {
> +	 *         time_cycles = pc->time_cycles;
> +	 *         time_mask = pc->time_mask;
> +	 *       }
>  	 *     }
>  	 *
>  	 *     index = pc->index;
> @@ -548,6 +552,9 @@ struct perf_event_mmap_page {
>  	 *     if (pc->cap_user_rdpmc && index) {
>  	 *       width = pc->pmc_width;
>  	 *       pmc = rdpmc(index - 1);
> +	 *       pmc <<= 64 - width;
> +	 *       pmc >>= 64 - width;
> +	 *       count += pmc;
>  	 *     }
>  	 *
>  	 *     barrier();
> @@ -590,25 +597,27 @@ struct perf_event_mmap_page {
>  	 * If cap_usr_time the below fields can be used to compute the time
>  	 * delta since time_enabled (in ns) using rdtsc or similar.
>  	 *
> -	 *   u64 quot, rem;
> -	 *   u64 delta;
> -	 *
> -	 *   quot = (cyc >> time_shift);
> -	 *   rem = cyc & (((u64)1 << time_shift) - 1);
> -	 *   delta = time_offset + quot * time_mult +
> -	 *              ((rem * time_mult) >> time_shift);
> +	 *   cyc = time_cycles + ((cyc - time_cycles) & time_mask);
> +	 *   delta = time_offset + mul_u64_u32_shr(cyc, time_mult, time_shift);
>  	 *
>  	 * Where time_offset,time_mult,time_shift and cyc are read in the
> -	 * seqcount loop described above. This delta can then be added to
> -	 * enabled and possible running (if index), improving the scaling:
> +	 * seqcount loop described above. mul_u64_u32_shr will compute:
> +	 *
> +	 *   (u64)(((unsigned __int128)cyc * time_mult) >> time_shift)
> +	 *
> +	 * This delta can then be added to enabled and possible running (if
> +	 * index) to improve the scaling. Due to event multiplexing, running
> +	 * may be zero and so care is needed to avoid division by zero.
>  	 *
>  	 *   enabled += delta;
>  	 *   if (index)
>  	 *     running += delta;
>  	 *
> -	 *   quot = count / running;
> -	 *   rem  = count % running;
> -	 *   count = quot * enabled + (rem * enabled) / running;
> +	 *   if (running != 0) {
> +	 *     quot = count / running;
> +	 *     rem  = count % running;
> +	 *     count = quot * enabled + (rem * enabled) / running;
> +	 *   }
>  	 */
>  	__u16	time_shift;
>  	__u32	time_mult;
> -- 
> 2.37.0.170.g444d1eabd0-goog

-- 

- Arnaldo

  parent reply	other threads:[~2022-08-01 12:39 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-19 22:39 [PATCH v3 0/3] Tidy user rdpmc documentation and testing Ian Rogers
2022-07-19 22:39 ` [PATCH v3 1/3] perf: Align user space counter reading with code Ian Rogers
2022-07-19 23:05   ` Rob Herring
2022-07-20 15:06   ` Vince Weaver
2022-07-20 15:18     ` Ian Rogers
2022-08-04  8:49     ` Ingo Molnar
2022-08-01 12:17   ` Arnaldo Carvalho de Melo [this message]
2022-07-19 22:39 ` [PATCH v3 2/3] perf test: Remove x86 rdpmc test Ian Rogers
2022-08-01 12:19   ` Arnaldo Carvalho de Melo
2022-07-19 22:39 ` [PATCH v3 3/3] perf test: Add user space counter reading tests Ian Rogers
2022-07-20 14:57   ` Vince Weaver
2022-07-20 15:09     ` Ian Rogers
2022-08-01 12:23   ` Arnaldo Carvalho de Melo

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=YufEc1i32OOa+6u8@kernel.org \
    --to=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=anshuman.khandual@arm.com \
    --cc=eranian@google.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=kjain@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=robh@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.