From: Patryk Wlazlyn <patryk.wlazlyn@linux.intel.com>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
rafael.j.wysocki@intel.com, len.brown@intel.com,
artem.bityutskiy@linux.intel.com, dave.hansen@linux.intel.com,
patryk.wlazlyn@linux.intel.com
Subject: [PATCH v3 1/3] x86/smp: Allow calling mwait_play_dead with arbitrary hint
Date: Fri, 8 Nov 2024 13:29:07 +0100 [thread overview]
Message-ID: <20241108122909.763663-2-patryk.wlazlyn@linux.intel.com> (raw)
In-Reply-To: <20241108122909.763663-1-patryk.wlazlyn@linux.intel.com>
The current implementation for looking up the mwait hint for the deepest
cstate depends on them to be continuous in range [0, NUM_SUBSTATES-1].
While that is correct on most Intel x86 platforms, it is not documented
and may not result in reaching the most optimized idle state on some of
them.
For example Intel's Sierra Forest report two C6 substates in cpuid leaf 5:
C6S (hint 0x22)
C6SP (hint 0x23)
Hints 0x20 and 0x21 are skipped entirely, causing the current
implementation to compute the wrong hint, when looking for the deepest
cstate for offlined CPU to enter. As a result, package with an offlined
CPU can never reach PC6.
Allow the idle driver to call mwait_play_dead() code with the forced
mwait hint, skipping the cpuid based computation.
Signed-off-by: Patryk Wlazlyn <patryk.wlazlyn@linux.intel.com>
---
arch/x86/include/asm/smp.h | 6 ++++++
arch/x86/kernel/smpboot.c | 25 ++++++++++++++++++-------
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index ca073f40698f..fbd275d6661a 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -114,6 +114,7 @@ void wbinvd_on_cpu(int cpu);
int wbinvd_on_all_cpus(void);
void smp_kick_mwait_play_dead(void);
+int mwait_play_dead_with_hint(unsigned long hint);
void native_smp_send_reschedule(int cpu);
void native_send_call_func_ipi(const struct cpumask *mask);
@@ -164,6 +165,11 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu)
{
return (struct cpumask *)cpumask_of(0);
}
+
+static inline int mwait_play_dead_with_hint(unsigned long eax_hint)
+{
+ return 1;
+}
#endif /* CONFIG_SMP */
#ifdef CONFIG_DEBUG_NMI_SELFTEST
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 0c35207320cb..44c40781bad6 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1270,13 +1270,14 @@ void play_dead_common(void)
local_irq_disable();
}
+int mwait_play_dead_with_hint(unsigned long eax_hint);
+
/*
* We need to flush the caches before going to sleep, lest we have
* dirty data in our caches when we come back up.
*/
-static inline void mwait_play_dead(void)
+static inline int mwait_play_dead(void)
{
- struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
unsigned int eax, ebx, ecx, edx;
unsigned int highest_cstate = 0;
unsigned int highest_subcstate = 0;
@@ -1284,13 +1285,13 @@ static inline void mwait_play_dead(void)
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
- return;
+ return 1;
if (!this_cpu_has(X86_FEATURE_MWAIT))
- return;
+ return 1;
if (!this_cpu_has(X86_FEATURE_CLFLUSH))
- return;
+ return 1;
if (__this_cpu_read(cpu_info.cpuid_level) < CPUID_MWAIT_LEAF)
- return;
+ return 1;
eax = CPUID_MWAIT_LEAF;
ecx = 0;
@@ -1314,6 +1315,13 @@ static inline void mwait_play_dead(void)
(highest_subcstate - 1);
}
+ return mwait_play_dead_with_hint(eax);
+}
+
+int mwait_play_dead_with_hint(unsigned long eax_hint)
+{
+ struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
+
/* Set up state for the kexec() hack below */
md->status = CPUDEAD_MWAIT_WAIT;
md->control = CPUDEAD_MWAIT_WAIT;
@@ -1333,7 +1341,7 @@ static inline void mwait_play_dead(void)
mb();
__monitor(md, 0, 0);
mb();
- __mwait(eax, 0);
+ __mwait(eax_hint, 0);
if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) {
/*
@@ -1353,6 +1361,9 @@ static inline void mwait_play_dead(void)
native_halt();
}
}
+
+ /* Never reached */
+ return 0;
}
/*
--
2.47.0
next prev parent reply other threads:[~2024-11-08 12:29 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-08 12:29 [PATCH v3 0/3] SRF: Fix offline CPU preventing pc6 entry Patryk Wlazlyn
2024-11-08 12:29 ` Patryk Wlazlyn [this message]
2024-11-08 16:03 ` [PATCH v3 1/3] x86/smp: Allow calling mwait_play_dead with arbitrary hint Dave Hansen
2024-11-12 10:54 ` Patryk Wlazlyn
2024-11-08 12:29 ` [PATCH v3 2/3] x86/smp native_play_dead: Prefer cpuidle_play_dead() over mwait_play_dead() Patryk Wlazlyn
2024-11-08 16:14 ` Dave Hansen
2024-11-12 10:55 ` Patryk Wlazlyn
2024-11-12 11:47 ` Peter Zijlstra
2024-11-12 12:03 ` Rafael J. Wysocki
2024-11-12 12:18 ` Peter Zijlstra
2024-11-12 12:30 ` Rafael J. Wysocki
2024-11-12 12:38 ` Rafael J. Wysocki
2024-11-12 13:49 ` Peter Zijlstra
2024-11-12 14:56 ` Rafael J. Wysocki
2024-11-12 15:08 ` Peter Zijlstra
2024-11-12 16:24 ` Rafael J. Wysocki
2024-11-12 12:44 ` Artem Bityutskiy
2024-11-12 14:01 ` Peter Zijlstra
2024-11-14 12:03 ` Peter Zijlstra
2024-11-15 1:21 ` Thomas Gleixner
2024-11-15 10:07 ` Peter Zijlstra
2024-11-15 15:37 ` Thomas Gleixner
2024-11-12 13:23 ` Rafael J. Wysocki
2024-11-12 14:56 ` Peter Zijlstra
2024-11-12 15:00 ` Rafael J. Wysocki
2024-11-13 11:41 ` Gautham R. Shenoy
2024-11-13 16:14 ` Dave Hansen
2024-11-14 5:06 ` Gautham R. Shenoy
2024-11-13 16:22 ` Peter Zijlstra
2024-11-13 16:27 ` Wysocki, Rafael J
2024-11-14 11:58 ` Rafael J. Wysocki
2024-11-14 12:17 ` Peter Zijlstra
2024-11-14 17:36 ` Gautham R. Shenoy
2024-11-14 17:58 ` Rafael J. Wysocki
2024-11-14 11:58 ` Peter Zijlstra
2024-11-14 17:24 ` Gautham R. Shenoy
2024-11-15 10:11 ` Peter Zijlstra
2024-11-25 5:45 ` Gautham R. Shenoy
2024-11-08 12:29 ` [PATCH v3 3/3] intel_idle: Provide enter_dead() handler for SRF Patryk Wlazlyn
2024-11-08 16:21 ` Dave Hansen
2024-11-12 10:57 ` Patryk Wlazlyn
2024-11-12 11:28 ` Rafael J. Wysocki
2024-11-12 16:07 ` Dave Hansen
2024-11-12 19:17 ` Thomas Gleixner
2024-11-12 19:43 ` Rafael J. Wysocki
2024-11-08 22:12 ` kernel test robot
2024-11-08 16:22 ` [PATCH v3 0/3] SRF: Fix offline CPU preventing pc6 entry Dave Hansen
2024-11-12 11:45 ` Peter Zijlstra
2024-11-12 15:43 ` Patryk Wlazlyn
2024-11-13 1:19 ` Thomas Gleixner
2024-11-14 17:13 ` Patryk Wlazlyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241108122909.763663-2-patryk.wlazlyn@linux.intel.com \
--to=patryk.wlazlyn@linux.intel.com \
--cc=artem.bityutskiy@linux.intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=len.brown@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rafael.j.wysocki@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®