FreeBSD Bugzilla – Attachment 149826 Details for
Bug 192316
Invariant TSC gets misdetected on Intel Core 2 Duo processors, resulting in sluggish system behavior
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
only_disable_c2.patch
192316.patch (text/plain), 7.72 KB, created by
John Baldwin
on 2014-11-25 15:48:58 UTC
(
hide
)
Description:
only_disable_c2.patch
Filename:
MIME Type:
Creator:
John Baldwin
Created:
2014-11-25 15:48:58 UTC
Size:
7.72 KB
patch
obsolete
>diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c >index 95d67c0..bcfdac1 100644 >--- a/sys/amd64/amd64/machdep.c >+++ b/sys/amd64/amd64/machdep.c >@@ -839,7 +839,7 @@ cpu_idle(int busy) > } > > /* Apply AMD APIC timer C1E workaround. */ >- if (cpu_ident_amdc1e && cpu_disable_deep_sleep) { >+ if (cpu_ident_amdc1e && cpu_disable_c3_sleep) { > msr = rdmsr(MSR_AMDK8_IPM); > if (msr & AMDK8_CMPHALT) > wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT); >diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c >index 9350935..794aee2 100644 >--- a/sys/dev/acpica/acpi_cpu.c >+++ b/sys/dev/acpica/acpi_cpu.c >@@ -85,6 +85,7 @@ struct acpi_cpu_softc { > int cpu_prev_sleep;/* Last idle sleep duration. */ > int cpu_features; /* Child driver supported features. */ > /* Runtime state. */ >+ int cpu_non_c2; /* Index of lowest non-C2 state. */ > int cpu_non_c3; /* Index of lowest non-C3 state. */ > u_int cpu_cx_stats[MAX_CX_STATES];/* Cx usage history. */ > /* Values for sysctl. */ >@@ -668,8 +669,10 @@ acpi_cpu_generic_cx_probe(struct acpi_cpu_softc *sc) > cx_ptr->type = ACPI_STATE_C1; > cx_ptr->trans_lat = 0; > cx_ptr++; >+ sc->cpu_non_c2 = sc->cpu_cx_count; > sc->cpu_non_c3 = sc->cpu_cx_count; > sc->cpu_cx_count++; >+ cpu_deepest_sleep = 1; > > /* > * The spec says P_BLK must be 6 bytes long. However, some systems >@@ -695,6 +698,7 @@ acpi_cpu_generic_cx_probe(struct acpi_cpu_softc *sc) > cx_ptr++; > sc->cpu_non_c3 = sc->cpu_cx_count; > sc->cpu_cx_count++; >+ cpu_deepest_sleep = 2; > } > } > if (sc->cpu_p_blk_len < 6) >@@ -711,7 +715,7 @@ acpi_cpu_generic_cx_probe(struct acpi_cpu_softc *sc) > cx_ptr->trans_lat = AcpiGbl_FADT.C3Latency; > cx_ptr++; > sc->cpu_cx_count++; >- cpu_can_deep_sleep = 1; >+ cpu_deepest_sleep = 3; > } > } > } >@@ -757,6 +761,7 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) > count = MAX_CX_STATES; > } > >+ sc->cpu_non_c2 = 0; > sc->cpu_non_c3 = 0; > sc->cpu_cx_count = 0; > cx_ptr = sc->cpu_cx_states; >@@ -768,6 +773,7 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) > cx_ptr->type = ACPI_STATE_C0; > cx_ptr++; > sc->cpu_cx_count++; >+ cpu_deepest_sleep = 1; > > /* Set up all valid states. */ > for (i = 0; i < count; i++) { >@@ -788,6 +794,7 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) > /* This is the first C1 state. Use the reserved slot. */ > sc->cpu_cx_states[0] = *cx_ptr; > } else { >+ sc->cpu_non_c2 = sc->cpu_cx_count; > sc->cpu_non_c3 = sc->cpu_cx_count; > cx_ptr++; > sc->cpu_cx_count++; >@@ -795,6 +802,8 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) > continue; > case ACPI_STATE_C2: > sc->cpu_non_c3 = sc->cpu_cx_count; >+ if (cpu_deepest_sleep < 2) >+ cpu_deepest_sleep = 2; > break; > case ACPI_STATE_C3: > default: >@@ -804,7 +813,7 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) > device_get_unit(sc->cpu_dev), i)); > continue; > } else >- cpu_can_deep_sleep = 1; >+ cpu_deepest_sleep = 3; > break; > } > >@@ -993,7 +1002,9 @@ acpi_cpu_idle(sbintime_t sbt) > if (sbt >= 0 && us > (sbt >> 12)) > us = (sbt >> 12); > cx_next_idx = 0; >- if (cpu_disable_deep_sleep) >+ if (cpu_disable_c2_sleep) >+ i = min(sc->cpu_cx_lowest, sc->cpu_non_c2); >+ else if (cpu_disable_c3_sleep) > i = min(sc->cpu_cx_lowest, sc->cpu_non_c3); > else > i = sc->cpu_cx_lowest; >diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c >index 5ed5c54..4948f20 100644 >--- a/sys/i386/i386/machdep.c >+++ b/sys/i386/i386/machdep.c >@@ -1423,7 +1423,7 @@ cpu_idle(int busy) > > #ifndef XEN > /* Apply AMD APIC timer C1E workaround. */ >- if (cpu_ident_amdc1e && cpu_disable_deep_sleep) { >+ if (cpu_ident_amdc1e && cpu_disable_c3_sleep) { > msr = rdmsr(MSR_AMDK8_IPM); > if (msr & AMDK8_CMPHALT) > wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT); >diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c >index 092c818..6e50441 100644 >--- a/sys/kern/kern_clocksource.c >+++ b/sys/kern/kern_clocksource.c >@@ -59,8 +59,9 @@ __FBSDID("$FreeBSD$"); > cyclic_clock_func_t cyclic_clock_func = NULL; > #endif > >-int cpu_can_deep_sleep = 0; /* C3 state is available. */ >-int cpu_disable_deep_sleep = 0; /* Timer dies in C3. */ >+int cpu_deepest_sleep = 0; /* Deepest Cx state available. */ >+int cpu_disable_c2_sleep = 0; /* Timer dies in C2. */ >+int cpu_disable_c3_sleep = 0; /* Timer dies in C3. */ > > static void setuptimer(void); > static void loadtimer(sbintime_t now, int first); >@@ -627,7 +628,7 @@ cpu_initclocks_bsp(void) > else if (!periodic && (timer->et_flags & ET_FLAGS_ONESHOT) == 0) > periodic = 1; > if (timer->et_flags & ET_FLAGS_C3STOP) >- cpu_disable_deep_sleep++; >+ cpu_disable_c3_sleep++; > > /* > * We honor the requested 'hz' value. >@@ -928,9 +929,9 @@ sysctl_kern_eventtimer_timer(SYSCTL_HANDLER_ARGS) > configtimer(0); > et_free(timer); > if (et->et_flags & ET_FLAGS_C3STOP) >- cpu_disable_deep_sleep++; >+ cpu_disable_c3_sleep++; > if (timer->et_flags & ET_FLAGS_C3STOP) >- cpu_disable_deep_sleep--; >+ cpu_disable_c3_sleep--; > periodic = want_periodic; > timer = et; > et_init(timer, timercb, NULL, NULL); >diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c >index 78ceff2..7a6b4e6 100644 >--- a/sys/kern/kern_tc.c >+++ b/sys/kern/kern_tc.c >@@ -1330,10 +1330,10 @@ tc_windup(void) > /* Now is a good time to change timecounters. */ > if (th->th_counter != timecounter) { > #ifndef __arm__ >- if ((timecounter->tc_flags & TC_FLAGS_C3STOP) != 0) >- cpu_disable_deep_sleep++; >- if ((th->th_counter->tc_flags & TC_FLAGS_C3STOP) != 0) >- cpu_disable_deep_sleep--; >+ if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0) >+ cpu_disable_c2_sleep++; >+ if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0) >+ cpu_disable_c2_sleep--; > #endif > th->th_counter = timecounter; > th->th_offset_count = ncount; >diff --git a/sys/sys/systm.h b/sys/sys/systm.h >index f4eae57..4457414 100644 >--- a/sys/sys/systm.h >+++ b/sys/sys/systm.h >@@ -289,8 +289,9 @@ sbintime_t cpu_idleclock(void); > void cpu_activeclock(void); > void cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt); > void cpu_et_frequency(struct eventtimer *et, uint64_t newfreq); >-extern int cpu_can_deep_sleep; >-extern int cpu_disable_deep_sleep; >+extern int cpu_deepest_sleep; >+extern int cpu_disable_c2_sleep; >+extern int cpu_disable_c3_sleep; > > int cr_cansee(struct ucred *u1, struct ucred *u2); > int cr_canseesocket(struct ucred *cred, struct socket *so); >diff --git a/sys/sys/timetc.h b/sys/sys/timetc.h >index 48b962f..e68e327 100644 >--- a/sys/sys/timetc.h >+++ b/sys/sys/timetc.h >@@ -58,7 +58,7 @@ struct timecounter { > * means "only use at explicit request". > */ > u_int tc_flags; >-#define TC_FLAGS_C3STOP 1 /* Timer dies in C3. */ >+#define TC_FLAGS_C2STOP 1 /* Timer dies in C2+. */ > #define TC_FLAGS_SUSPEND_SAFE 2 /* > * Timer functional across > * suspend/resume. >diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c >index b78e3c9..4364df2 100644 >--- a/sys/x86/x86/tsc.c >+++ b/sys/x86/x86/tsc.c >@@ -581,16 +581,16 @@ init_TSC_tc(void) > } > > /* >- * We cannot use the TSC if it stops incrementing in deep sleep. >- * Currently only Intel CPUs are known for this problem unless >- * the invariant TSC bit is set. >+ * We cannot use the TSC if it stops incrementing while idle. >+ * Intel CPUs without a C-state invariant TSC can stop the TSC >+ * in either C2 or C3. > */ >- if (cpu_can_deep_sleep && cpu_vendor_id == CPU_VENDOR_INTEL && >+ if (cpu_deepest_sleep >= 2 && cpu_vendor_id == CPU_VENDOR_INTEL && > (amd_pminfo & AMDPM_TSC_INVARIANT) == 0) { > tsc_timecounter.tc_quality = -1000; >- tsc_timecounter.tc_flags |= TC_FLAGS_C3STOP; >+ tsc_timecounter.tc_flags |= TC_FLAGS_C2STOP; > if (bootverbose) >- printf("TSC timecounter disabled: C3 enabled.\n"); >+ printf("TSC timecounter disabled: C-states may halt it.\n"); > goto init; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 192316
:
145227
|
147407
|
148617
| 149826