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 <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
@@ -518,6 +518,11 @@ typedef struct arch_cpu_info {
|
|||||||
|
|
||||||
uint32 logical_apic_id;
|
uint32 logical_apic_id;
|
||||||
|
|
||||||
|
uint64 mperf_prev;
|
||||||
|
uint64 aperf_prev;
|
||||||
|
bigtime_t perf_timestamp;
|
||||||
|
uint64 frequency;
|
||||||
|
|
||||||
struct X86PagingStructures* active_paging_structures;
|
struct X86PagingStructures* active_paging_structures;
|
||||||
|
|
||||||
size_t dr6; // temporary storage for debug registers (cf.
|
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);
|
x86_write_msr(IA32_MSR_TSC_AUX, cpu);
|
||||||
#endif
|
#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);
|
return __x86_patch_errata_percpu(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,22 +135,31 @@ arch_fill_topology_node(cpu_topology_node_info* node, int32 cpu)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_frequency_for(void *_frequency, int /*cpu*/)
|
get_frequency_for(void *_frequency, int cpu)
|
||||||
{
|
{
|
||||||
uint64 *frequency = (uint64*)_frequency;
|
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++)
|
bigtime_t timestamp = gCPU[cpu].arch.perf_timestamp;
|
||||||
arch_cpu_pause();
|
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 mperf2 = x86_read_msr(IA32_MSR_MPERF);
|
||||||
uint64 aperf2 = x86_read_msr(IA32_MSR_APERF);
|
uint64 aperf2 = x86_read_msr(IA32_MSR_APERF);
|
||||||
|
|
||||||
if (mperf2 == mperf)
|
if (mperf2 == mperf)
|
||||||
*frequency = 0;
|
*frequency = 0;
|
||||||
else
|
else {
|
||||||
*frequency = (aperf2 - aperf) * sCPUClockSpeed / (mperf2 - mperf);
|
*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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user