Page MenuHomeFreeBSD

D15551.diff
No OneTemporary

D15551.diff

Index: head/sys/amd64/include/clock.h
===================================================================
--- head/sys/amd64/include/clock.h
+++ head/sys/amd64/include/clock.h
@@ -34,6 +34,7 @@
void startrtclock(void);
void init_TSC(void);
+void resume_TSC(void);
#define HAS_TIMER_SPKR 1
int timer_spkr_acquire(void);
Index: head/sys/dev/acpica/acpi.c
===================================================================
--- head/sys/dev/acpica/acpi.c
+++ head/sys/dev/acpica/acpi.c
@@ -52,6 +52,7 @@
#include <sys/timetc.h>
#if defined(__i386__) || defined(__amd64__)
+#include <machine/clock.h>
#include <machine/pci_cfgreg.h>
#endif
#include <machine/resource.h>
@@ -3040,6 +3041,10 @@
if (slp_state >= ACPI_SS_SLP_PREP)
AcpiLeaveSleepState(state);
if (slp_state >= ACPI_SS_SLEPT) {
+#if defined(__i386__) || defined(__amd64__)
+ /* NB: we are still using ACPI timecounter at this point. */
+ resume_TSC();
+#endif
acpi_resync_clock(sc);
acpi_enable_fixed_events(sc);
}
Index: head/sys/i386/include/clock.h
===================================================================
--- head/sys/i386/include/clock.h
+++ head/sys/i386/include/clock.h
@@ -32,6 +32,7 @@
void startrtclock(void);
void timer_restore(void);
void init_TSC(void);
+void resume_TSC(void);
#define HAS_TIMER_SPKR 1
int timer_spkr_acquire(void);
Index: head/sys/x86/x86/tsc.c
===================================================================
--- head/sys/x86/x86/tsc.c
+++ head/sys/x86/x86/tsc.c
@@ -451,7 +451,7 @@
}
static int
-test_tsc(void)
+test_tsc(int adj_max_count)
{
uint64_t *data, *tsc;
u_int i, size, adj;
@@ -467,7 +467,7 @@
smp_tsc = 1; /* XXX */
smp_rendezvous(smp_no_rendezvous_barrier, comp_smp_tsc,
smp_no_rendezvous_barrier, data);
- if (!smp_tsc && adj < smp_tsc_adjust) {
+ if (!smp_tsc && adj < adj_max_count) {
adj++;
smp_rendezvous(smp_no_rendezvous_barrier, adj_smp_tsc,
smp_no_rendezvous_barrier, data);
@@ -512,7 +512,7 @@
* on uniprocessor kernel.
*/
static int
-test_tsc(void)
+test_tsc(int adj_max_count __unused)
{
return (0);
@@ -579,7 +579,7 @@
* environments, so it is set to a negative quality in those cases.
*/
if (mp_ncpus > 1)
- tsc_timecounter.tc_quality = test_tsc();
+ tsc_timecounter.tc_quality = test_tsc(smp_tsc_adjust);
else if (tsc_is_invariant)
tsc_timecounter.tc_quality = 1000;
max_freq >>= tsc_shift;
@@ -614,6 +614,30 @@
}
}
SYSINIT(tsc_tc, SI_SUB_SMP, SI_ORDER_ANY, init_TSC_tc, NULL);
+
+void
+resume_TSC(void)
+{
+ int quality;
+
+ /* If TSC was not good on boot, it is unlikely to become good now. */
+ if (tsc_timecounter.tc_quality < 0)
+ return;
+ /* Nothing to do with UP. */
+ if (mp_ncpus < 2)
+ return;
+
+ /*
+ * If TSC was good, a single synchronization should be enough,
+ * but honour smp_tsc_adjust if it's set.
+ */
+ quality = test_tsc(MAX(smp_tsc_adjust, 1));
+ if (quality != tsc_timecounter.tc_quality) {
+ printf("TSC timecounter quality changed: %d -> %d\n",
+ tsc_timecounter.tc_quality, quality);
+ tsc_timecounter.tc_quality = quality;
+ }
+}
/*
* When cpufreq levels change, find out about the (new) max frequency. We

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 3, 6:10 PM (15 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29173663
Default Alt Text
D15551.diff (3 KB)

Event Timeline