1 |
From e400ad8b7e6a1b9102123c6240289a811501f7d9 Mon Sep 17 00:00:00 2001 |
2 |
From: Dave Hansen <dave.hansen@intel.com> |
3 |
Date: Thu, 22 Sep 2022 11:47:45 -0700 |
4 |
Subject: [PATCH] ACPI: processor idle: Practically limit "Dummy wait" |
5 |
workaround to old Intel systems |
6 |
|
7 |
Old, circa 2002 chipsets have a bug: they don't go idle when they are |
8 |
supposed to. So, a workaround was added to slow the CPU down and |
9 |
ensure that the CPU waits a bit for the chipset to actually go idle. |
10 |
This workaround is ancient and has been in place in some form since |
11 |
the original kernel ACPI implementation. |
12 |
|
13 |
But, this workaround is very painful on modern systems. The "inl()" |
14 |
can take thousands of cycles (see Link: for some more detailed |
15 |
numbers and some fun kernel archaeology). |
16 |
|
17 |
First and foremost, modern systems should not be using this code. |
18 |
Typical Intel systems have not used it in over a decade because it is |
19 |
horribly inferior to MWAIT-based idle. |
20 |
|
21 |
Despite this, people do seem to be tripping over this workaround on |
22 |
AMD system today. |
23 |
|
24 |
Limit the "dummy wait" workaround to Intel systems. Keep Modern AMD |
25 |
systems from tripping over the workaround. Remotely modern Intel |
26 |
systems use intel_idle instead of this code and will, in practice, |
27 |
remain unaffected by the dummy wait. |
28 |
|
29 |
Reported-by: K Prateek Nayak <kprateek.nayak@amd.com> |
30 |
Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
31 |
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> |
32 |
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com> |
33 |
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> |
34 |
Link: https://lore.kernel.org/all/20220921063638.2489-1-kprateek.nayak@amd.com/ |
35 |
Link: https://lkml.kernel.org/r/20220922184745.3252932-1-dave.hansen@intel.com |
36 |
--- |
37 |
drivers/acpi/processor_idle.c | 23 ++++++++++++++++++++--- |
38 |
1 file changed, 20 insertions(+), 3 deletions(-) |
39 |
|
40 |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c |
41 |
index 16a1663d02d4..9f40917c49ef 100644 |
42 |
--- a/drivers/acpi/processor_idle.c |
43 |
+++ b/drivers/acpi/processor_idle.c |
44 |
@@ -531,10 +531,27 @@ static void wait_for_freeze(void) |
45 |
/* No delay is needed if we are in guest */ |
46 |
if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
47 |
return; |
48 |
+ /* |
49 |
+ * Modern (>=Nehalem) Intel systems use ACPI via intel_idle, |
50 |
+ * not this code. Assume that any Intel systems using this |
51 |
+ * are ancient and may need the dummy wait. This also assumes |
52 |
+ * that the motivating chipset issue was Intel-only. |
53 |
+ */ |
54 |
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
55 |
+ return; |
56 |
#endif |
57 |
- /* Dummy wait op - must do something useless after P_LVL2 read |
58 |
- because chipsets cannot guarantee that STPCLK# signal |
59 |
- gets asserted in time to freeze execution properly. */ |
60 |
+ /* |
61 |
+ * Dummy wait op - must do something useless after P_LVL2 read |
62 |
+ * because chipsets cannot guarantee that STPCLK# signal gets |
63 |
+ * asserted in time to freeze execution properly |
64 |
+ * |
65 |
+ * This workaround has been in place since the original ACPI |
66 |
+ * implementation was merged, circa 2002. |
67 |
+ * |
68 |
+ * If a profile is pointing to this instruction, please first |
69 |
+ * consider moving your system to a more modern idle |
70 |
+ * mechanism. |
71 |
+ */ |
72 |
inl(acpi_gbl_FADT.xpm_timer_block.address); |
73 |
} |
74 |
|
75 |
-- |
76 |
2.37.3 |
77 |
|