Messages in this thread Patch in this message | | | Date | Wed, 27 Sep 2017 15:10:03 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH v6 1/4] sched/clock: interface to allow timestamps early in boot |
| |
On Wed, Sep 27, 2017 at 02:58:57PM +0200, Peter Zijlstra wrote: > (we're violating "notsc" in any case and really should kill that > option).
Something like so; in particular simple_udelay_calibrate() will issue RDTSC _way_ early, so there is absolutely no point in then pretending we can't use RDTSC for sched_clock.
---
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 796d96bb0821..1dd3849a42ca 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -37,13 +37,6 @@ EXPORT_SYMBOL(tsc_khz); */ static int __read_mostly tsc_unstable; -/* native_sched_clock() is called before tsc_init(), so - we must start with the TSC soft disabled to prevent - erroneous rdtsc usage on !boot_cpu_has(X86_FEATURE_TSC) processors */ -static int __read_mostly tsc_disabled = -1; - -static DEFINE_STATIC_KEY_FALSE(__use_tsc); - int tsc_clocksource_reliable; static u32 art_to_tsc_numerator; @@ -191,24 +184,7 @@ static void set_cyc2ns_scale(unsigned long khz, int cpu, unsigned long long tsc_ */ u64 native_sched_clock(void) { - if (static_branch_likely(&__use_tsc)) { - u64 tsc_now = rdtsc(); - - /* return the value in ns */ - return cycles_2_ns(tsc_now); - } - - /* - * Fall back to jiffies if there's no TSC available: - * ( But note that we still use it if the TSC is marked - * unstable. We do this because unlike Time Of Day, - * the scheduler clock tolerates small errors and it's - * very important for it to be as fast as the platform - * can achieve it. ) - */ - - /* No locking but a rare wrong value is not a big deal: */ - return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); + return cycles_2_ns(rdtsc()); } /* @@ -244,27 +220,6 @@ int check_tsc_unstable(void) } EXPORT_SYMBOL_GPL(check_tsc_unstable); -#ifdef CONFIG_X86_TSC -int __init notsc_setup(char *str) -{ - pr_warn("Kernel compiled with CONFIG_X86_TSC, cannot disable TSC completely\n"); - tsc_disabled = 1; - return 1; -} -#else -/* - * disable flag for tsc. Takes effect by clearing the TSC cpu flag - * in cpu/common.c - */ -int __init notsc_setup(char *str) -{ - setup_clear_cpu_cap(X86_FEATURE_TSC); - return 1; -} -#endif - -__setup("notsc", notsc_setup); - static int no_sched_irq_time; static int __init tsc_setup(char *str) @@ -1229,7 +1184,7 @@ static void tsc_refine_calibration_work(struct work_struct *work) static int __init init_tsc_clocksource(void) { - if (!boot_cpu_has(X86_FEATURE_TSC) || tsc_disabled > 0 || !tsc_khz) + if (!boot_cpu_has(X86_FEATURE_TSC) || !tsc_khz) return 0; if (tsc_clocksource_reliable) @@ -1311,14 +1266,6 @@ void __init tsc_init(void) set_cyc2ns_scale(tsc_khz, cpu, cyc); } - if (tsc_disabled > 0) - return; - - /* now allow native_sched_clock() to use rdtsc */ - - tsc_disabled = 0; - static_branch_enable(&__use_tsc); - if (!no_sched_irq_time) enable_sched_clock_irqtime(); @@ -1348,7 +1295,7 @@ unsigned long calibrate_delay_is_known(void) int sibling, cpu = smp_processor_id(); struct cpumask *mask = topology_core_cpumask(cpu); - if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC)) + if (!cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC)) return 0; if (!mask)
| |