Skip to content

Commit bd35c77

Browse files
Krzysztof PiecuchKAGA-KOKO
authored andcommitted
x86/tsc: Add tsc_early_khz command line parameter
Changing base clock frequency directly impacts TSC Hz but not CPUID.16h value. An overclocked CPU supporting CPUID.16h and with partial CPUID.15h support will set TSC KHZ according to "best guess" given by CPUID.16h relying on tsc_refine_calibration_work to give better numbers later. tsc_refine_calibration_work will refuse to do its work when the outcome is off the early TSC KHZ value by more than 1% which is certain to happen on an overclocked system. Fix this by adding a tsc_early_khz command line parameter that makes the kernel skip early TSC calibration and use the given value instead. This allows the user to provide the expected TSC frequency that is closer to reality than the one reported by the hardware, enabling tsc_refine_calibration_work to do meaningful error checking. [ tglx: Made the variable __initdata as it's only used on init and removed the error checking in the argument parser because kstrto*() only stores to the variable if the string is valid ] Signed-off-by: Krzysztof Piecuch <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/O2CpIOrqLZHgNRkfjRpz_LGqnc1ix_seNIiOCvHY4RHoulOVRo6kMXKuLOfBVTi0SMMevg6Go1uZ_cL9fLYtYdTRNH78ChaFaZyG3VAyYz8=@protonmail.com
1 parent cec5f26 commit bd35c77

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5067,6 +5067,12 @@
50675067
interruptions from clocksource watchdog are not
50685068
acceptable).
50695069

5070+
tsc_early_khz= [X86] Skip early TSC calibration and use the given
5071+
value instead. Useful when the early TSC frequency discovery
5072+
procedure is not reliable, such as on overclocked systems
5073+
with CPUID.16h support and partial CPUID.15h support.
5074+
Format: <unsigned int>
5075+
50705076
tsx= [X86] Control Transactional Synchronization
50715077
Extensions (TSX) feature in Intel processors that
50725078
support TSX control.

arch/x86/kernel/tsc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ EXPORT_SYMBOL(tsc_khz);
4141
* TSC can be unstable due to cpufreq or due to unsynced TSCs
4242
*/
4343
static int __read_mostly tsc_unstable;
44+
static unsigned int __initdata tsc_early_khz;
4445

4546
static DEFINE_STATIC_KEY_FALSE(__use_tsc);
4647

@@ -59,6 +60,12 @@ struct cyc2ns {
5960

6061
static DEFINE_PER_CPU_ALIGNED(struct cyc2ns, cyc2ns);
6162

63+
static int __init tsc_early_khz_setup(char *buf)
64+
{
65+
return kstrtouint(buf, 0, &tsc_early_khz);
66+
}
67+
early_param("tsc_early_khz", tsc_early_khz_setup);
68+
6269
__always_inline void cyc2ns_read_begin(struct cyc2ns_data *data)
6370
{
6471
int seq, idx;
@@ -1412,7 +1419,10 @@ static bool __init determine_cpu_tsc_frequencies(bool early)
14121419

14131420
if (early) {
14141421
cpu_khz = x86_platform.calibrate_cpu();
1415-
tsc_khz = x86_platform.calibrate_tsc();
1422+
if (tsc_early_khz)
1423+
tsc_khz = tsc_early_khz;
1424+
else
1425+
tsc_khz = x86_platform.calibrate_tsc();
14161426
} else {
14171427
/* We should not be here with non-native cpu calibration */
14181428
WARN_ON(x86_platform.calibrate_cpu != native_calibrate_cpu);

0 commit comments

Comments
 (0)