Re: [PATCH V2 2/6] perf/x86/intel/pebs: Fix PEBS timestamps overwritten
From: Namhyung Kim
Date: Tue Oct 11 2022 - 14:21:32 EST
Hello,
On Thu, Sep 1, 2022 at 6:10 AM <kan.liang@xxxxxxxxxxxxxxx> wrote:
>
> From: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>
>
> The PEBS TSC-based timestamps do not appear correctly in the final
> perf.data output file from perf record.
>
> The data->time field setup by PEBS in the setup_pebs_fixed_sample_data()
> is later overwritten by perf_events generic code in
> perf_prepare_sample(). There is an ordering problem.
>
> Set the sample flags when the data->time is updated by PEBS.
> The data->time field will not be overwritten anymore.
I have a report that it breaks the symbolization of samples.
It seems time is not in sync between perf_clock and PEBS.
One thing I noticed is that the system has a config option
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y.
Looking at the code, it seems sched_clock is doing some
adjustments in that case. So I'm not sure if it'd work well
on those systems.
Thoughts?
Thanks,
Namhyung
>
> Reported-by: Andreas Kogler <andreas.kogler.0x@xxxxxxxxx>
> Reported-by: Stephane Eranian <eranian@xxxxxxxxxx>
> Signed-off-by: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>
> ---
> arch/x86/events/intel/ds.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
> index de1f55d51784..01cbe26225c2 100644
> --- a/arch/x86/events/intel/ds.c
> +++ b/arch/x86/events/intel/ds.c
> @@ -1643,8 +1643,10 @@ static void setup_pebs_fixed_sample_data(struct perf_event *event,
> * We can only do this for the default trace clock.
> */
> if (x86_pmu.intel_cap.pebs_format >= 3 &&
> - event->attr.use_clockid == 0)
> + event->attr.use_clockid == 0) {
> data->time = native_sched_clock_from_tsc(pebs->tsc);
> + data->sample_flags |= PERF_SAMPLE_TIME;
> + }
>
> if (has_branch_stack(event))
> data->br_stack = &cpuc->lbr_stack;
> @@ -1705,8 +1707,10 @@ static void setup_pebs_adaptive_sample_data(struct perf_event *event,
> perf_sample_data_init(data, 0, event->hw.last_period);
> data->period = event->hw.last_period;
>
> - if (event->attr.use_clockid == 0)
> + if (event->attr.use_clockid == 0) {
> data->time = native_sched_clock_from_tsc(basic->tsc);
> + data->sample_flags |= PERF_SAMPLE_TIME;
> + }
>
> /*
> * We must however always use iregs for the unwinder to stay sane; the
> --
> 2.35.1
>