Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131883993
D1441.id3003.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D1441.id3003.diff
View Options
Index: sys/amd64/amd64/machdep.c
===================================================================
--- sys/amd64/amd64/machdep.c
+++ sys/amd64/amd64/machdep.c
@@ -839,7 +839,7 @@
}
/* 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);
Index: sys/dev/acpica/acpi_cpu.c
===================================================================
--- sys/dev/acpica/acpi_cpu.c
+++ sys/dev/acpica/acpi_cpu.c
@@ -85,6 +85,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
device_get_unit(sc->cpu_dev), i));
continue;
} else
- cpu_can_deep_sleep = 1;
+ cpu_deepest_sleep = 3;
break;
}
@@ -993,7 +1002,9 @@
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;
Index: sys/i386/i386/machdep.c
===================================================================
--- sys/i386/i386/machdep.c
+++ sys/i386/i386/machdep.c
@@ -1423,7 +1423,7 @@
#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);
Index: sys/kern/kern_clocksource.c
===================================================================
--- sys/kern/kern_clocksource.c
+++ sys/kern/kern_clocksource.c
@@ -59,8 +59,9 @@
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 @@
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 @@
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);
Index: sys/kern/kern_tc.c
===================================================================
--- sys/kern/kern_tc.c
+++ sys/kern/kern_tc.c
@@ -1330,10 +1330,10 @@
/* 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;
Index: sys/sys/systm.h
===================================================================
--- sys/sys/systm.h
+++ sys/sys/systm.h
@@ -289,8 +289,9 @@
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);
Index: sys/sys/timetc.h
===================================================================
--- sys/sys/timetc.h
+++ sys/sys/timetc.h
@@ -58,7 +58,7 @@
* 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.
Index: sys/x86/x86/tsc.c
===================================================================
--- sys/x86/x86/tsc.c
+++ sys/x86/x86/tsc.c
@@ -581,16 +581,16 @@
}
/*
- * 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;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 12, 11:09 PM (8 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23645100
Default Alt Text
D1441.id3003.diff (7 KB)
Attached To
Mode
D1441: Handle the TSC sometimes stopping on older Intel CPUs with C2 by disabling both C2 and C3 if the TSC is used as the timecounter on these CPUs.
Attached
Detach File
Event Timeline
Log In to Comment