From: "Liang, Kan" <kan.liang@linux.intel.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: mingo@redhat.com, linux-kernel@vger.kernel.org, acme@kernel.org,
tglx@linutronix.de, jolsa@redhat.com, eranian@google.com,
ak@linux.intel.com
Subject: Re: [PATCH V3 1/5] perf/x86/intel: fix event update for auto-reload
Date: Tue, 6 Feb 2018 12:58:23 -0500 [thread overview]
Message-ID: <ae4c7aff-da12-8cb3-4fac-4637ab001060@linux.intel.com> (raw)
In-Reply-To: <20180206150648.GK2249@hirez.programming.kicks-ass.net>
> With the exception of handling 'empty' buffers, I ended up with the
> below. Please try again.
>
There are two small errors. After fixing them, the patch works well.
> ---
> --- a/arch/x86/events/core.c
> +++ b/arch/x86/events/core.c
> @@ -1156,16 +1156,13 @@ int x86_perf_event_set_period(struct per
>
> per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
>
> - if (!(hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) ||
> - local64_read(&hwc->prev_count) != (u64)-left) {
> - /*
> - * The hw event starts counting from this event offset,
> - * mark it to be able to extra future deltas:
> - */
> - local64_set(&hwc->prev_count, (u64)-left);
> + /*
> + * The hw event starts counting from this event offset,
> + * mark it to be able to extra future deltas:
> + */
> + local64_set(&hwc->prev_count, (u64)-left);
>
> - wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
> - }
> + wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask);
>
> /*
> * Due to erratum on certan cpu we need
> --- a/arch/x86/events/intel/ds.c
> +++ b/arch/x86/events/intel/ds.c
> @@ -1306,17 +1306,89 @@ get_next_pebs_record_by_bit(void *base,
> return NULL;
> }
>
> +/*
> + * Special variant of intel_pmu_save_and_restart() for auto-reload.
> + */
> +static int
> +intel_pmu_save_and_restart_reload(struct perf_event *event, int count)
> +{
> + struct hw_perf_event *hwc = &event->hw;
> + int shift = 64 - x86_pmu.cntval_bits;
> + u64 period = hwc->sample_period;
> + u64 prev_raw_count, new_raw_count;
> + u64 delta;
> +
> + WARN_ON(!period);
> +
> + /*
> + * drain_pebs() only happens when the PMU is disabled.
> + */
> + WARN_ON(this_cpu_read(cpu_hw_events.enabled));
> +
> + prev_raw_count = local64_read(&hwc->prev_count);
> + rdpmcl(hwc->event_base_rdpmc, new_raw_count);
> + local64_set(&hwx->prev_count, new_raw_count);
Here is a typo. It should be &hwc->prev_count.
> +
> + /*
> + * Careful, not all hw sign-extends above the physical width
> + * of the counter.
> + */
> + delta = (new_raw_count << shift) - (prev_raw_count << shift);
> + delta >>= shift;
new_raw_count could be smaller than prev_raw_count.
The sign bit will be set. The delta>> could be wrong.
I think we can add a period here to prevent it.
+ delta = (period << shift) + (new_raw_count << shift) -
+ (prev_raw_count << shift);
+ delta >>= shift;
......
+ local64_add(delta + period * (count - 1), &event->count);
Thanks,
Kan
> +
> + /*
> + * Since the counter increments a negative counter value and
> + * overflows on the sign switch, giving the interval:
> + *
> + * [-period, 0]
> + *
> + * the difference between two consequtive reads is:
> + *
> + * A) value2 - value1;
> + * when no overflows have happened in between,
> + *
> + * B) (0 - value1) + (value2 - (-period));
> + * when one overflow happened in between,
> + *
> + * C) (0 - value1) + (n - 1) * (period) + (value2 - (-period));
> + * when @n overflows happened in between.
> + *
> + * Here A) is the obvious difference, B) is the extention to the
> + * discrete interval, where the first term is to the top of the
> + * interval and the second term is from the bottom of the next
> + * interval and 3) the extention to multiple intervals, where the
> + * middle term is the whole intervals covered.
> + *
> + * An equivalent of C, by reduction, is:
> + *
> + * value2 - value1 + n * period
> + */
> + local64_add(delta + period * count, &event->count);
> +
> + perf_event_update_userpage(event);
> +
> + return 0;
> +}
> +
> static void __intel_pmu_pebs_event(struct perf_event *event,
> struct pt_regs *iregs,
> void *base, void *top,
> int bit, int count)
> {
> + struct hw_perf_event *hwc = &event->hw;
> struct perf_sample_data data;
> struct pt_regs regs;
> void *at = get_next_pebs_record_by_bit(base, top, bit);
>
> - if (!intel_pmu_save_and_restart(event) &&
> - !(event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD))
> + if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) {
> + /*
> + * Now, auto-reload is only enabled in fixed period mode.
> + * The reload value is always hwc->sample_period.
> + * May need to change it, if auto-reload is enabled in
> + * freq mode later.
> + */
> + intel_pmu_save_and_restart_reload(event, count);
> + } else if (!intel_pmu_save_and_restart(event))
> return;
>
> while (count > 1) {
>
next prev parent reply other threads:[~2018-02-06 17:58 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-29 16:29 [PATCH V3 0/5] bugs fix for large PEBS mmap read and rdpmc read kan.liang
2018-01-29 16:29 ` [PATCH V3 1/5] perf/x86/intel: fix event update for auto-reload kan.liang
2018-02-06 15:06 ` Peter Zijlstra
2018-02-06 17:58 ` Liang, Kan [this message]
2018-02-09 14:09 ` Peter Zijlstra
2018-02-09 15:49 ` Liang, Kan
2018-02-10 14:09 ` Peter Zijlstra
2018-01-29 16:29 ` [PATCH V3 2/5] perf/x86: introduce read function for x86_pmu kan.liang
2018-01-29 16:29 ` [PATCH V3 3/5] perf/x86/intel/ds: introduce read function for large pebs kan.liang
2018-01-29 16:29 ` [PATCH V3 4/5] perf/x86/intel: fix pmu read for large PEBS kan.liang
2018-01-29 16:29 ` [PATCH V3 5/5] perf/x86: fix: disable userspace RDPMC usage " kan.liang
2018-01-30 9:16 ` [PATCH V3 0/5] bugs fix for large PEBS mmap read and rdpmc read Stephane Eranian
2018-01-30 13:39 ` Jiri Olsa
2018-01-30 14:59 ` Liang, Kan
2018-01-30 15:04 ` Jiri Olsa
2018-01-30 15:25 ` Liang, Kan
2018-01-30 16:36 ` Stephane Eranian
2018-01-30 16:48 ` Liang, Kan
2018-01-30 18:52 ` Jiri Olsa
2018-01-30 19:56 ` Stephane Eranian
2018-01-31 3:59 ` Andi Kleen
2018-01-31 9:15 ` Jiri Olsa
2018-01-31 13:15 ` Jiri Olsa
2018-01-31 15:15 ` Liang, Kan
2018-01-31 15:41 ` Jiri Olsa
2018-01-30 14:41 ` Liang, Kan
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=ae4c7aff-da12-8cb3-4fac-4637ab001060@linux.intel.com \
--to=kan.liang@linux.intel.com \
--cc=acme@kernel.org \
--cc=ak@linux.intel.com \
--cc=eranian@google.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
/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.