On Mon, Dec 28, 2020 at 04:31:09AM +0000, James Cook wrote:
> On Mon, Dec 28, 2020 at 01:19:19PM +1100, Jonathan Gray wrote:
> > On Sun, Dec 27, 2020 at 07:48:58PM +0000, James Cook wrote:
> > > > from your earlier bsd.mp dmesg:
> > > >
> > > > cpu0: Enhanced SpeedStep 16268 MHz: speeds: 1601, 1600, 1500, 1400,
> > > > 1300, 1200, 1100, 1000, 900, 800, 700, 600, 500, 400 MHz
> > > >
> > > > 1601 is variable/turbo speed the others are fixed. When running in
> > > > turbo mode getting the current frequency involves msrs which
> > > > hw.cpuspeed doesn't do. The initial 'x MHz:' is from cpuspeed not from
> > > > the acpi table.
> > > >
> > > > On modern machines these values are from acpicpu(4)/acpi _PSS.
> > > >
> > > > Can you show the output of running with the following diff to dump the
> > > > performance counter control values?
> > > >
> > > > MSR_PERF_FIXED_CTR_CTRL 0x38d
> > > > MSR_PERF_GLOBAL_CTRL 0x38f
> > > >
> > > > on a broadwell laptop this shows
> > > >
> > > > cpu0 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > > > cpu0 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > > > cpu0 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > > > cpu0 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > > > cpu1 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > > > cpu1 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > > > cpu1 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > > > cpu1 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > > > cpu2 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > > > cpu2 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > > > cpu2 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > > > cpu2 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > > > cpu3 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > > > cpu3 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > > > cpu3 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > > > cpu3 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > >
> > > Here's dmesg with that patch.
> >
> > Thanks, here is another diff to try. It sets the bit to be enabled
> > not just for ring 0, fixes clearing a value and shows the values
> > read out of the counter.
> >
> > Index: sys/arch/amd64/amd64/identcpu.c
> > ===================================================================
> > RCS file: /cvs/src/sys/arch/amd64/amd64/identcpu.c,v
> > retrieving revision 1.117
> > diff -u -p -r1.117 identcpu.c
> > --- sys/arch/amd64/amd64/identcpu.c 13 Sep 2020 05:57:28 -0000 1.117
> > +++ sys/arch/amd64/amd64/identcpu.c 28 Dec 2020 02:03:27 -0000
> > @@ -411,6 +411,9 @@ via_update_sensor(void *args)
> > }
> > #endif
> >
> > +#define MSR_PERF_GLOBAL_STATUS 0x38e
> > +#define MSR_PERF_GLOBAL_INUSE 0x392
> > +
> > uint64_t
> > cpu_freq_ctr(struct cpu_info *ci)
> > {
> > @@ -421,13 +424,22 @@ cpu_freq_ctr(struct cpu_info *ci)
> > CPUIDEDX_NUM_FC(cpu_perf_edx) <= 1)
> > return (0);
> >
> > + if ((cpu_perf_eax & CPUIDEAX_VERID) > 3) {
> > + msr = rdmsr(MSR_PERF_GLOBAL_INUSE);
> > + printf("%s %s MSR_PERF_GLOBAL_INUSE 0x%llx\n",
> > ci->ci_dev->dv_xname,
> > + __func__, msr);
> > + }
> > + msr = rdmsr(MSR_PERF_GLOBAL_STATUS);
> > + printf("%s %s MSR_PERF_GLOBAL_STATUS before 0x%llx\n",
> > ci->ci_dev->dv_xname,
> > + __func__, msr);
> > +
> > msr = rdmsr(MSR_PERF_FIXED_CTR_CTRL);
> > if (msr & MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK)) {
> > /* some hypervisor is dicking us around */
> > return (0);
> > }
> >
> > - msr |= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_1);
> > + msr |= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_ANY);
> > wrmsr(MSR_PERF_FIXED_CTR_CTRL, msr);
> >
> > msr = rdmsr(MSR_PERF_GLOBAL_CTRL) | MSR_PERF_GLOBAL_CTR1_EN;
> > @@ -437,13 +449,20 @@ cpu_freq_ctr(struct cpu_info *ci)
> > delay(100000);
> > count = rdmsr(MSR_PERF_FIXED_CTR1);
> >
> > + msr = rdmsr(MSR_PERF_GLOBAL_STATUS);
> > + printf("%s %s MSR_PERF_GLOBAL_STATUS after 0x%llx\n",
> > ci->ci_dev->dv_xname,
> > + __func__, msr);
> > +
> > msr = rdmsr(MSR_PERF_FIXED_CTR_CTRL);
> > - msr &= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK);
> > + msr &= ~MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK);
> > wrmsr(MSR_PERF_FIXED_CTR_CTRL, msr);
> >
> > msr = rdmsr(MSR_PERF_GLOBAL_CTRL);
> > msr &= ~MSR_PERF_GLOBAL_CTR1_EN;
> > wrmsr(MSR_PERF_GLOBAL_CTRL, msr);
> > +
> > + printf("%s %s count %lld last_count %lld freq %lld\n",
> > ci->ci_dev->dv_xname,
> > + __func__, count, last_count, ((count - last_count) * 10));
> >
> > return ((count - last_count) * 10);
> > }
>
> Here's the end of /var/log/messages, recording a boot with the above patch.
It seems there is a problem with the 8253/8254 timer used by
cpu0 for the initial delay. Does the cpu0 frequency change with the
below diff (which isn't suitable for older machines)?
>
> (dmesg is showing me output from more than one boot... I've never seen that
> before.)
If the magic bytes have not been changed by bios during reboot the
buffer is not cleared.
Index: sys/arch/amd64/amd64/identcpu.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/identcpu.c,v
retrieving revision 1.117
diff -u -p -r1.117 identcpu.c
--- sys/arch/amd64/amd64/identcpu.c 13 Sep 2020 05:57:28 -0000 1.117
+++ sys/arch/amd64/amd64/identcpu.c 28 Dec 2020 05:59:32 -0000
@@ -550,6 +550,8 @@ identifycpu(struct cpu_info *ci)
/* Check if it's an invariant TSC */
if (cpu_apmi_edx & CPUIDEDX_ITSC)
ci->ci_flags |= CPUF_INVAR_TSC;
+
+ tsc_timecounter_init(ci, freq);
}
freq = cpu_freq(ci);
@@ -761,8 +763,6 @@ identifycpu(struct cpu_info *ci)
sensordev_install(&ci->ci_sensordev);
#endif
}
-
- tsc_timecounter_init(ci, freq);
cpu_topology(ci);
#if NVMM > 0