public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perf/x86/intel/ds: Fix the conversion from TSC to perf time
@ 2023-01-23 17:20 kan.liang
  2023-01-23 20:39 ` Peter Zijlstra
  0 siblings, 1 reply; 3+ messages in thread
From: kan.liang @ 2023-01-23 17:20 UTC (permalink / raw)
  To: peterz, mingo, linux-kernel; +Cc: namhyung, eranian, ak, Kan Liang

From: Kan Liang <kan.liang@linux.intel.com>

The time order is incorrect when the TSC in a PEBS record is used.

 $perf record -e cycles:upp dd if=/dev/zero of=/dev/null
  count=10000
 $ perf script --show-task-events
       perf-exec     0     0.000000: PERF_RECORD_COMM: perf-exec:915/915
              dd   915   106.479872: PERF_RECORD_COMM exec: dd:915/915
              dd   915   106.483270: PERF_RECORD_EXIT(915:915):(914:914)
              dd   915   106.512429:          1 cycles:upp:
 ffffffff96c011b7 [unknown] ([unknown])
 ... ...

The perf time is from sched_clock_cpu(). The current PEBS code
unconditionally convert the TSC to native_sched_clock(). There is a
shift between the two clocks. If the TSC is stable, the shift is
consistent, __sched_clock_offset. If the TSC is unstable, the shift has
to be calculated at runtime.

The TSC unstable case seems to be some corner cases (e.g., due to broken
BIOS). This patch doesn't support the conversion when the TSC is
unstable. The TSC in a PEBS record will be dropped and fallback to the
software perf time provided by the generic code.

Fixes: 47a3aeb39e8d ("perf/x86/intel/pebs: Fix PEBS timestamps overwritten")
Reported-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/all/CAM9d7cgWDVAq8-11RbJ2uGfwkKD6fA-OMwOKDrNUrU_=8MgEjg@mail.gmail.com/
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
---
 arch/x86/events/intel/ds.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 183efa914b99..7980e92dec64 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -2,12 +2,14 @@
 #include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/slab.h>
+#include <linux/sched/clock.h>
 
 #include <asm/cpu_entry_area.h>
 #include <asm/perf_event.h>
 #include <asm/tlbflush.h>
 #include <asm/insn.h>
 #include <asm/io.h>
+#include <asm/timer.h>
 
 #include "../perf_event.h"
 
@@ -1568,6 +1570,28 @@ static u64 get_data_src(struct perf_event *event, u64 aux)
 	return val;
 }
 
+static void setup_pebs_time(struct perf_event *event,
+			    struct perf_sample_data *data,
+			    u64 tsc)
+{
+	/* Converting to a user-defined clock is not supported yet. */
+	if (event->attr.use_clockid != 0)
+		return;
+
+	/*
+	 * Converting the TSC to perf time is only supported,
+	 * when the TSC is stable.
+	 * The TSC unstable case seems to be some corner cases
+	 * (e.g., due to broken BIOS). Drop the PEBS TSC and
+	 * fall back to the SW time, see perf_event_clock().
+	 */
+	if (!using_native_sched_clock() || !sched_clock_stable())
+		return;
+
+	data->time = native_sched_clock_from_tsc(tsc) + __sched_clock_offset;
+	data->sample_flags |= PERF_SAMPLE_TIME;
+}
+
 #define PERF_SAMPLE_ADDR_TYPE	(PERF_SAMPLE_ADDR |		\
 				 PERF_SAMPLE_PHYS_ADDR |	\
 				 PERF_SAMPLE_DATA_PAGE_SIZE)
@@ -1715,11 +1739,8 @@ 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) {
-		data->time = native_sched_clock_from_tsc(pebs->tsc);
-		data->sample_flags |= PERF_SAMPLE_TIME;
-	}
+	if (x86_pmu.intel_cap.pebs_format >= 3)
+		setup_pebs_time(event, data, pebs->tsc);
 
 	if (has_branch_stack(event))
 		perf_sample_save_brstack(data, event, &cpuc->lbr_stack);
@@ -1781,10 +1802,7 @@ 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) {
-		data->time = native_sched_clock_from_tsc(basic->tsc);
-		data->sample_flags |= PERF_SAMPLE_TIME;
-	}
+	setup_pebs_time(event, data, basic->tsc);
 
 	/*
 	 * We must however always use iregs for the unwinder to stay sane; the
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] perf/x86/intel/ds: Fix the conversion from TSC to perf time
  2023-01-23 17:20 [PATCH] perf/x86/intel/ds: Fix the conversion from TSC to perf time kan.liang
@ 2023-01-23 20:39 ` Peter Zijlstra
  2023-01-23 21:34   ` Liang, Kan
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Zijlstra @ 2023-01-23 20:39 UTC (permalink / raw)
  To: kan.liang; +Cc: mingo, linux-kernel, namhyung, eranian, ak, Thomas Gleixner

On Mon, Jan 23, 2023 at 09:20:27AM -0800, kan.liang@linux.intel.com wrote:
> The TSC unstable case seems to be some corner cases (e.g., due to broken
> BIOS). This patch doesn't support the conversion when the TSC is
> unstable. The TSC in a PEBS record will be dropped and fallback to the
> software perf time provided by the generic code.

:-(

You're saying there's modern systems (PEBS timestamps are fairly new)
that trigger unstable TSC ?

What systems in specific have you observed this on -- we really need to
name and shame them, this is fully unacceptable.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] perf/x86/intel/ds: Fix the conversion from TSC to perf time
  2023-01-23 20:39 ` Peter Zijlstra
@ 2023-01-23 21:34   ` Liang, Kan
  0 siblings, 0 replies; 3+ messages in thread
From: Liang, Kan @ 2023-01-23 21:34 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: mingo, linux-kernel, namhyung, eranian, ak, Thomas Gleixner



On 2023-01-23 3:39 p.m., Peter Zijlstra wrote:
> On Mon, Jan 23, 2023 at 09:20:27AM -0800, kan.liang@linux.intel.com wrote:
>> The TSC unstable case seems to be some corner cases (e.g., due to broken
>> BIOS). This patch doesn't support the conversion when the TSC is
>> unstable. The TSC in a PEBS record will be dropped and fallback to the
>> software perf time provided by the generic code.
> 
> :-(
> 
> You're saying there's modern systems (PEBS timestamps are fairly new)
> that trigger unstable TSC ?
> 
> What systems in specific have you observed this on -- we really need to
> name and shame them, this is fully unacceptable.

No, I didn't observe any systems which trigger unstable TSC.

Here, I tried to explain the reason why the patch didn't support the
conversion when the TSC is unstable. Because it's a corner case and very
unlikely to happen.
The "broken BIOS" case is quoted from the __sched_clock_work(), which
shows that the broken BIOS may be a reason of unstable TSC.

Sorry for the confusion caused.

Let me rephrase this.
"This patch doesn't support the conversion when the TSC is unstable.
Because the TSC unstable case is a corner case and very unlikely to
happen. Even if it happens, the TSC in a PEBS record will be dropped and
fall back to the inaccurate software perf time provided by the generic
code as perf does it on the previous platforms."

Thanks,
Kan


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-01-23 21:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-23 17:20 [PATCH] perf/x86/intel/ds: Fix the conversion from TSC to perf time kan.liang
2023-01-23 20:39 ` Peter Zijlstra
2023-01-23 21:34   ` Liang, Kan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox