diff mbox series

[v2,15/17] x86/cpu/intel: Bound the non-architectural constant_tsc model checks

Message ID 20250211194407.2577252-16-sohil.mehta@intel.com (mailing list archive)
State New
Headers show
Series Prepare for new Intel Family numbers | expand

Commit Message

Sohil Mehta Feb. 11, 2025, 7:44 p.m. UTC
Constant TSC has been architectural on Intel CPUs for a while. Supported
CPUs use the architectural Invariant TSC bit in CPUID.80000007. A
Family-model check is not required for these CPUs.

Prevent unnecessary confusion but restricting the model specific checks
to CPUs that need it and moving it closer to the architectural check.

Invariant TSC was likely introduced around the Nehalam timeframe on the
Xeon side and Saltwell timeframe on the Atom side.  Due to interspersed
model numbers extend the non-architectural capability setting until
Ivybridge to be safe.

Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>

---

v2: No change.

---
 arch/x86/kernel/cpu/intel.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Dave Hansen Feb. 11, 2025, 9:41 p.m. UTC | #1
On 2/11/25 11:44, Sohil Mehta wrote:
> Constant TSC has been architectural on Intel CPUs for a while. Supported
> CPUs use the architectural Invariant TSC bit in CPUID.80000007. A
> Family-model check is not required for these CPUs.
> 
> Prevent unnecessary confusion but restricting the model specific checks
> to CPUs that need it and moving it closer to the architectural check.
> 
> Invariant TSC was likely introduced around the Nehalam timeframe on the
> Xeon side and Saltwell timeframe on the Atom side.  Due to interspersed
> model numbers extend the non-architectural capability setting until
> Ivybridge to be safe.

How about:

X86_FEATURE_CONSTANT_TSC is a Linux-defined, synthesized feature flag.
It is used across several vendors. Intel CPUs will set the feature when
the architectural CPUID.80000007.EDX[1] bit is set. There are also some
Intel CPUs that have the X86_FEATURE_CONSTANT_TSC behavior but don't
enumerate it with the architectural bit.  Those currently have a model
range check.

Today, virtually all of the CPUs that have the CPUID bit *also* match
the "model >= 0x0e" check. This is confusing. Instead of an open-ended
check, pick some models (INTEL_IVYBRIDGE and P4_WILLAMETTE) as the end
of goofy CPUs that should enumerate the bit but don't.  These models are
relatively arbitrary but conservative pick for this.

This makes it obvious that later CPUs (like family 18+) no longer need
to synthesize X86_FEATURE_CONSTANT_TSC.


> +	/* Some older CPUs have invariant TSC but may not report it architecturally via 8000_0007 */
> +	if ((c->x86_vfm >= INTEL_P4_PRESCOTT && c->x86_vfm <= INTEL_P4_WILLAMETTE) ||
> +	    (c->x86_vfm >= INTEL_CORE_YONAH && c->x86_vfm <= INTEL_IVYBRIDGE))
> +		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);

Please do vertically align this too.

Would it make logical sense to do:

        if (c->x86_power & (1 << 8)) {
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
                set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
        } else if ((c->x86_vfm >= INTEL_P4_PRESCOTT ...

?

That would make it *totally* clear that it's an either/or situation.  Right?
Sohil Mehta Feb. 12, 2025, 12:45 a.m. UTC | #2
On 2/11/2025 1:41 PM, Dave Hansen wrote:
> On 2/11/25 11:44, Sohil Mehta wrote:
>> Constant TSC has been architectural on Intel CPUs for a while. Supported
>> CPUs use the architectural Invariant TSC bit in CPUID.80000007. A
>> Family-model check is not required for these CPUs.
>>
>> Prevent unnecessary confusion but restricting the model specific checks
>> to CPUs that need it and moving it closer to the architectural check.
>>
>> Invariant TSC was likely introduced around the Nehalam timeframe on the
>> Xeon side and Saltwell timeframe on the Atom side.  Due to interspersed
>> model numbers extend the non-architectural capability setting until
>> Ivybridge to be safe.
> 
> How about:
> 
> X86_FEATURE_CONSTANT_TSC is a Linux-defined, synthesized feature flag.
> It is used across several vendors. Intel CPUs will set the feature when
> the architectural CPUID.80000007.EDX[1] bit is set. There are also some
> Intel CPUs that have the X86_FEATURE_CONSTANT_TSC behavior but don't
> enumerate it with the architectural bit.  Those currently have a model
> range check.
> 
> Today, virtually all of the CPUs that have the CPUID bit *also* match
> the "model >= 0x0e" check. This is confusing. Instead of an open-ended
> check, pick some models (INTEL_IVYBRIDGE and P4_WILLAMETTE) as the end
> of goofy CPUs that should enumerate the bit but don't.  These models are
> relatively arbitrary but conservative pick for this.
> 
> This makes it obvious that later CPUs (like family 18+) no longer need
> to synthesize X86_FEATURE_CONSTANT_TSC.
> 

Looks much better.

>> +	/* Some older CPUs have invariant TSC but may not report it architecturally via 8000_0007 */
>> +	if ((c->x86_vfm >= INTEL_P4_PRESCOTT && c->x86_vfm <= INTEL_P4_WILLAMETTE) ||
>> +	    (c->x86_vfm >= INTEL_CORE_YONAH && c->x86_vfm <= INTEL_IVYBRIDGE))
>> +		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
> 
> Please do vertically align this too.
> 
> Would it make logical sense to do:
> 
>         if (c->x86_power & (1 << 8)) {
>                 set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
>                 set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
>         } else if ((c->x86_vfm >= INTEL_P4_PRESCOTT ...
> 
> ?
> 
> That would make it *totally* clear that it's an either/or situation.  Right?
> 

Yup, will change it.

>
diff mbox series

Patch

diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 1b01ef4dfda2..ab195dcea50b 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -210,10 +210,6 @@  static void early_init_intel(struct cpuinfo_x86 *c)
 {
 	u64 misc_enable;
 
-	if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
-		(c->x86 == 0x6 && c->x86_model >= 0x0e))
-		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
-
 	if (c->x86 >= 6 && !cpu_has(c, X86_FEATURE_IA64))
 		c->microcode = intel_get_microcode_revision();
 
@@ -272,6 +268,11 @@  static void early_init_intel(struct cpuinfo_x86 *c)
 		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
 	}
 
+	/* Some older CPUs have invariant TSC but may not report it architecturally via 8000_0007 */
+	if ((c->x86_vfm >= INTEL_P4_PRESCOTT && c->x86_vfm <= INTEL_P4_WILLAMETTE) ||
+	    (c->x86_vfm >= INTEL_CORE_YONAH && c->x86_vfm <= INTEL_IVYBRIDGE))
+		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+
 	/* Penwell and Cloverview have the TSC which doesn't sleep on S3 */
 	switch (c->x86_vfm) {
 	case INTEL_ATOM_SALTWELL_MID: