Thread (35 messages) 35 messages, 7 authors, 2021-10-11
STALE1708d REVIEWED: 1 (1M)

[RFC PATCH v1 09/20] arch: x86: Add TSC to ART translation

From: <hidden>
Date: 2021-08-24 16:48:46
Also in: lkml
Subsystem: the rest, x86 architecture (32-bit and 64-bit) · Maintainers: Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen

From: Lakshmi Sowjanya D <redacted>

Add a function to convert TSC(Time Stamp Capture) time to ART.

The Intel(R) PMC Timed I/O device uses ART to trigger output events.

The TSC to ART translation converts the TSC value yielded by
ktime_convert_real_to_system_counter() to ART. The conversion is
required to program the COMPV register that will be compared against
the art time to generate output events.

Co-developed-by: Christopher Hall <redacted>
Signed-off-by: Christopher Hall <redacted>
Signed-off-by: Tamal Saha <redacted>
Signed-off-by: Lakshmi Sowjanya D <redacted>
Reviewed-by: Mark Gross <mgross@linux.intel.com>
---
 arch/x86/include/asm/tsc.h |  3 +++
 arch/x86/kernel/tsc.c      | 35 ++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index a50b0102e5c1..f1de7ede3ec9 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -8,6 +8,8 @@
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
 
+struct system_counterval_t;
+
 /*
  * Standard way to access the cycle counter.
  */
@@ -29,6 +31,7 @@ static inline cycles_t get_cycles(void)
 }
 
 extern u64 read_art_time(void);
+extern int convert_tsc_to_art(const struct system_counterval_t *tsc, u64 *art);
 extern struct system_counterval_t convert_art_to_tsc(u64 art);
 extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
 
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index bbab6cf1a73b..040109228100 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1231,22 +1231,43 @@ int unsynchronized_tsc(void)
 }
 
 /*
- * Converts the current TSC to the current ART value using conversion
+ * Converts input TSC to the corresponding ART value using conversion
  * factors discovered by detect_art()
  */
-u64 read_art_time(void)
+int convert_tsc_to_art(const struct system_counterval_t *system_counter, u64 *art)
 {
-	u64 tsc, tmp, res, rem;
+	u64 tmp, res, rem;
+
+	if (system_counter->cs != art_related_clocksource)
+		return -EINVAL;
 
-	tsc = read_tsc(NULL) - art_to_tsc_offset;
-	rem = do_div(tsc, art_to_tsc_numerator);
+	res = system_counter->cycles - art_to_tsc_offset;
+	rem = do_div(res, art_to_tsc_numerator);
 
-	res = tsc * art_to_tsc_denominator;
+	*art = res * art_to_tsc_denominator;
 	tmp = rem * art_to_tsc_denominator;
 
 	do_div(tmp, art_to_tsc_numerator);
+	*art += tmp;
+
+	return 0;
+}
+EXPORT_SYMBOL(convert_tsc_to_art);
+
+/*
+ * Converts the current TSC to the current ART value using conversion
+ * factors discovered by detect_art()
+ */
+u64 read_art_time(void)
+{
+	struct system_counterval_t tsc;
+	u64 art = 0;
+
+	tsc.cs = art_related_clocksource;
+	tsc.cycles = read_tsc(NULL);
+	convert_tsc_to_art(&tsc, &art);
 
-	return res + tmp;
+	return art;
 }
 EXPORT_SYMBOL(read_art_time);
 
-- 
2.17.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help