Messages in this thread | | | Date | Mon, 11 May 2020 11:25:19 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH v2 0/3] arm64: perf_event: Fix time offset prior to epoch |
| |
On Mon, May 11, 2020 at 11:22:00AM +0200, Peter Zijlstra wrote:
> (_completely_ untested) > > --- > arch/arm64/kernel/perf_event.c | 27 ++++++++++++++++++--------- > include/linux/sched_clock.h | 28 ++++++++++++++++++++++++++++ > kernel/time/sched_clock.c | 41 +++++++++++++---------------------------- > 3 files changed, 59 insertions(+), 37 deletions(-) > > diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c > index 4d7879484cec..81a49a916660 100644 > --- a/arch/arm64/kernel/perf_event.c > +++ b/arch/arm64/kernel/perf_event.c > @@ -1165,28 +1165,37 @@ device_initcall(armv8_pmu_driver_init) > void arch_perf_update_userpage(struct perf_event *event, > struct perf_event_mmap_page *userpg, u64 now) > { > - u32 freq; > - u32 shift; > + struct clock_read_data *rd; > + unsigned int seq; > > /* > * Internal timekeeping for enabled/running/stopped times > * is always computed with the sched_clock. > */ > - freq = arch_timer_get_rate(); > userpg->cap_user_time = 1; > + userpg->cap_user_time_zero = 1; > + > + do { > + rd = sched_clock_read_begin(&seq); > + > + userpg->time_mult = rd->mult; > + userpg->time_shift = rd->shift; > + userpg->time_offset = rd->epoch_ns;
^^^^^^^ wants to be time_zero
> + > + userpg->time_zero -= (rd->epoch_cyc * rd->shift) >> rd->shift; > + > + } while (sched_clock_read_retry(seq)); > + > + userpg->time_offset = userpf->time_zero - now; > > - clocks_calc_mult_shift(&userpg->time_mult, &shift, freq, > - NSEC_PER_SEC, 0);
And that ^^^ was complete crap.
> /* > * time_shift is not expected to be greater than 31 due to > * the original published conversion algorithm shifting a > * 32-bit value (now specifies a 64-bit value) - refer > * perf_event_mmap_page documentation in perf_event.h. > */ > - if (shift == 32) { > - shift = 31; > + if (userpg->time_shift == 32) { > + userpg->time_shift = 31; > userpg->time_mult >>= 1; > } > - userpg->time_shift = (u16)shift; > - userpg->time_offset = -now; > }
| |