Messages in this thread Patch in this message | | | From | Feng Tang <> | Subject | [RFC 1/2] x86/tsc: add a timer to make sure tsc_adjust is always checked | Date | Tue, 30 Mar 2021 16:25:46 +0800 |
| |
Normally the tsc_sync will be checked every time system enters idle state, but there is still caveat that a system won't enter idle, either because it's too busy or configured purposely to not enter idle. Setup a periodic timer to make sure the check is always on.
Signed-off-by: Feng Tang <feng.tang@intel.com> --- arch/x86/kernel/tsc_sync.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 3d3c761..1ba3941 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -30,6 +30,7 @@ struct tsc_adjust { }; static DEFINE_PER_CPU(struct tsc_adjust, tsc_adjust); +static struct timer_list tsc_sync_check_timer; /* * TSC's on different sockets may be reset asynchronously. @@ -77,6 +78,43 @@ void tsc_verify_tsc_adjust(bool resume) } } +/* + * Normally the tsc_sync will be checked every time system enters idle state, + * but there is still caveat that a system won't enter idle, either because + * it's too busy or configured purposely to not enter idle. + * + * So setup a periodic timer to make sure the check is always on. + */ + +#define SYNC_CHECK_INTERVAL (HZ * 600) +static void tsc_sync_check_timer_fn(struct timer_list *unused) +{ + int next_cpu; + + tsc_verify_tsc_adjust(false); + + /* Loop to do the check for all onlined CPUs */ + next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask); + if (next_cpu >= nr_cpu_ids) + next_cpu = cpumask_first(cpu_online_mask); + + tsc_sync_check_timer.expires += SYNC_CHECK_INTERVAL; + add_timer_on(&tsc_sync_check_timer, next_cpu); +} + +static int __init start_sync_check_timer(void) +{ + if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST)) + return 0; + + timer_setup(&tsc_sync_check_timer, tsc_sync_check_timer_fn, 0); + tsc_sync_check_timer.expires = jiffies + SYNC_CHECK_INTERVAL; + add_timer(&tsc_sync_check_timer); + + return 0; +} +late_initcall(start_sync_check_timer); + static void tsc_sanitize_first_cpu(struct tsc_adjust *cur, s64 bootval, unsigned int cpu, bool bootcpu) { -- 2.7.4
| |