kernel/x86: rework get_frequency_for
we don't sample if the last sample is too recent and use the cached result. Change-Id: I17ed29bda7fe7276f1a4148b3e1985c9d32ae032 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4101 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com> Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
parent
7c2c355f17
commit
4106e3f146
@ -518,6 +518,11 @@ typedef struct arch_cpu_info {
|
||||
|
||||
uint32 logical_apic_id;
|
||||
|
||||
uint64 mperf_prev;
|
||||
uint64 aperf_prev;
|
||||
bigtime_t perf_timestamp;
|
||||
uint64 frequency;
|
||||
|
||||
struct X86PagingStructures* active_paging_structures;
|
||||
|
||||
size_t dr6; // temporary storage for debug registers (cf.
|
||||
|
@ -1425,6 +1425,12 @@ arch_cpu_init_percpu(kernel_args* args, int cpu)
|
||||
x86_write_msr(IA32_MSR_TSC_AUX, cpu);
|
||||
#endif
|
||||
|
||||
if (x86_check_feature(IA32_FEATURE_APERFMPERF, FEATURE_6_ECX)) {
|
||||
gCPU[cpu].arch.mperf_prev = x86_read_msr(IA32_MSR_MPERF);
|
||||
gCPU[cpu].arch.aperf_prev = x86_read_msr(IA32_MSR_APERF);
|
||||
gCPU[cpu].arch.frequency = 0;
|
||||
gCPU[cpu].arch.perf_timestamp = 0;
|
||||
}
|
||||
return __x86_patch_errata_percpu(cpu);
|
||||
}
|
||||
|
||||
|
@ -135,22 +135,31 @@ arch_fill_topology_node(cpu_topology_node_info* node, int32 cpu)
|
||||
|
||||
|
||||
static void
|
||||
get_frequency_for(void *_frequency, int /*cpu*/)
|
||||
get_frequency_for(void *_frequency, int cpu)
|
||||
{
|
||||
uint64 *frequency = (uint64*)_frequency;
|
||||
uint64 mperf = x86_read_msr(IA32_MSR_MPERF);
|
||||
uint64 aperf = x86_read_msr(IA32_MSR_APERF);
|
||||
|
||||
for (int i = 0; i < 1000; i++)
|
||||
arch_cpu_pause();
|
||||
bigtime_t timestamp = gCPU[cpu].arch.perf_timestamp;
|
||||
bigtime_t timestamp2 = system_time();
|
||||
if (timestamp2 - timestamp < 100) {
|
||||
*frequency = gCPU[cpu].arch.frequency;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 mperf = gCPU[cpu].arch.mperf_prev;
|
||||
uint64 aperf = gCPU[cpu].arch.aperf_prev;
|
||||
uint64 mperf2 = x86_read_msr(IA32_MSR_MPERF);
|
||||
uint64 aperf2 = x86_read_msr(IA32_MSR_APERF);
|
||||
|
||||
if (mperf2 == mperf)
|
||||
*frequency = 0;
|
||||
else
|
||||
else {
|
||||
*frequency = (aperf2 - aperf) * sCPUClockSpeed / (mperf2 - mperf);
|
||||
gCPU[cpu].arch.mperf_prev = mperf2;
|
||||
gCPU[cpu].arch.aperf_prev = aperf2;
|
||||
gCPU[cpu].arch.perf_timestamp = timestamp2;
|
||||
gCPU[cpu].arch.frequency = *frequency;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user