Skip to content

Commit 351e1aa

Browse files
committed
Merge branch 'x86-timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 timer fixes from Thomas Gleixner: "Two commits which were missed to be sent during the merge window. - The TSC calibration fix turns out to be more urgent as recent Skylake-X systems seem to have massive trouble with calibration disturbance. This should go back into stable for that reason and it the risk of breakage is rather low. - Drop an unused define" * 'x86-timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/hpet: Remove unused FSEC_PER_NSEC define x86/tsc: Make calibration refinement more robust
2 parents f907bb4 + d999c0e commit 351e1aa

File tree

2 files changed

+16
-18
lines changed

2 files changed

+16
-18
lines changed

arch/x86/kernel/hpet.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121

2222
#define HPET_MASK CLOCKSOURCE_MASK(32)
2323

24-
/* FSEC = 10^-15
25-
NSEC = 10^-9 */
26-
#define FSEC_PER_NSEC 1000000L
27-
2824
#define HPET_DEV_USED_BIT 2
2925
#define HPET_DEV_USED (1 << HPET_DEV_USED_BIT)
3026
#define HPET_DEV_VALID 0x8

arch/x86/kernel/tsc.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,16 @@ static int __init tsc_setup(char *str)
297297

298298
__setup("tsc=", tsc_setup);
299299

300-
#define MAX_RETRIES 5
301-
#define SMI_TRESHOLD 50000
300+
#define MAX_RETRIES 5
301+
#define TSC_DEFAULT_THRESHOLD 0x20000
302302

303303
/*
304-
* Read TSC and the reference counters. Take care of SMI disturbance
304+
* Read TSC and the reference counters. Take care of any disturbances
305305
*/
306306
static u64 tsc_read_refs(u64 *p, int hpet)
307307
{
308308
u64 t1, t2;
309+
u64 thresh = tsc_khz ? tsc_khz >> 5 : TSC_DEFAULT_THRESHOLD;
309310
int i;
310311

311312
for (i = 0; i < MAX_RETRIES; i++) {
@@ -315,7 +316,7 @@ static u64 tsc_read_refs(u64 *p, int hpet)
315316
else
316317
*p = acpi_pm_read_early();
317318
t2 = get_cycles();
318-
if ((t2 - t1) < SMI_TRESHOLD)
319+
if ((t2 - t1) < thresh)
319320
return t2;
320321
}
321322
return ULLONG_MAX;
@@ -703,15 +704,15 @@ static unsigned long pit_hpet_ptimer_calibrate_cpu(void)
703704
* zero. In each wait loop iteration we read the TSC and check
704705
* the delta to the previous read. We keep track of the min
705706
* and max values of that delta. The delta is mostly defined
706-
* by the IO time of the PIT access, so we can detect when a
707-
* SMI/SMM disturbance happened between the two reads. If the
707+
* by the IO time of the PIT access, so we can detect when
708+
* any disturbance happened between the two reads. If the
708709
* maximum time is significantly larger than the minimum time,
709710
* then we discard the result and have another try.
710711
*
711712
* 2) Reference counter. If available we use the HPET or the
712713
* PMTIMER as a reference to check the sanity of that value.
713714
* We use separate TSC readouts and check inside of the
714-
* reference read for a SMI/SMM disturbance. We dicard
715+
* reference read for any possible disturbance. We dicard
715716
* disturbed values here as well. We do that around the PIT
716717
* calibration delay loop as we have to wait for a certain
717718
* amount of time anyway.
@@ -744,7 +745,7 @@ static unsigned long pit_hpet_ptimer_calibrate_cpu(void)
744745
if (ref1 == ref2)
745746
continue;
746747

747-
/* Check, whether the sampling was disturbed by an SMI */
748+
/* Check, whether the sampling was disturbed */
748749
if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX)
749750
continue;
750751

@@ -1268,7 +1269,7 @@ static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
12681269
*/
12691270
static void tsc_refine_calibration_work(struct work_struct *work)
12701271
{
1271-
static u64 tsc_start = -1, ref_start;
1272+
static u64 tsc_start = ULLONG_MAX, ref_start;
12721273
static int hpet;
12731274
u64 tsc_stop, ref_stop, delta;
12741275
unsigned long freq;
@@ -1283,14 +1284,15 @@ static void tsc_refine_calibration_work(struct work_struct *work)
12831284
* delayed the first time we expire. So set the workqueue
12841285
* again once we know timers are working.
12851286
*/
1286-
if (tsc_start == -1) {
1287+
if (tsc_start == ULLONG_MAX) {
1288+
restart:
12871289
/*
12881290
* Only set hpet once, to avoid mixing hardware
12891291
* if the hpet becomes enabled later.
12901292
*/
12911293
hpet = is_hpet_enabled();
1292-
schedule_delayed_work(&tsc_irqwork, HZ);
12931294
tsc_start = tsc_read_refs(&ref_start, hpet);
1295+
schedule_delayed_work(&tsc_irqwork, HZ);
12941296
return;
12951297
}
12961298

@@ -1300,9 +1302,9 @@ static void tsc_refine_calibration_work(struct work_struct *work)
13001302
if (ref_start == ref_stop)
13011303
goto out;
13021304

1303-
/* Check, whether the sampling was disturbed by an SMI */
1304-
if (tsc_start == ULLONG_MAX || tsc_stop == ULLONG_MAX)
1305-
goto out;
1305+
/* Check, whether the sampling was disturbed */
1306+
if (tsc_stop == ULLONG_MAX)
1307+
goto restart;
13061308

13071309
delta = tsc_stop - tsc_start;
13081310
delta *= 1000000LL;

0 commit comments

Comments
 (0)