/* * CPU0..CPUn * +-------------+-------------------------------+--------+-------+ * | Register | Description | Offset | Len | * +-------------+-------------------------------+--------+-------+ * | cur_perf | read this register to get | 0x0 | 0x4 | * | | the current perf (integer val | | | * | | representing perf relative to | | | * | | max performance) | | | * | | that vCPU is running at | | | * +-------------+-------------------------------+--------+-------+ * | set_perf | write to this register to set | 0x4 | 0x4 | * | | perf value of the vCPU | | | * +-------------+-------------------------------+--------+-------+ * | perftbl_len | number of entries in perf | 0x8 | 0x4 | * | | table. A single entry in the | | | * | | perf table denotes no table | | | * | | and the entry contains | | | * | | the maximum perf value | | | * | | that this vCPU supports. | | | * | | The guest can request any | | | * | | value between 1 and max perf | | | * | | when perftbls are not used. | | | * +---------------------------------------------+--------+-------+ * | perftbl_sel | write to this register to | 0xc | 0x4 | * | | select perf table entry to | | | * | | read from | | | * +---------------------------------------------+--------+-------+ * | perftbl_rd | read this register to get | 0x10 | 0x4 | * | | perf value of the selected | | | * | | entry based on perftbl_sel | | | * +---------------------------------------------+--------+-------+ * | perf_domain | performance domain number | 0x14 | 0x4 | * | | that this vCPU belongs to. | | | * | | vCPUs sharing the same perf | | | * | | domain number are part of the | | | * | | same performance domain. | | | * +-------------+-------------------------------+--------+-------+
*/
staticint virt_cpufreq_cpu_init(struct cpufreq_policy *policy)
{ struct device *cpu_dev; int ret;
cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) return -ENODEV;
ret = virt_cpufreq_get_freq_info(policy); if (ret) {
dev_warn(cpu_dev, "failed to get cpufreq info\n"); return ret;
}
ret = virt_cpufreq_get_sharing_cpus(policy); if (ret) {
dev_warn(cpu_dev, "failed to get sharing cpumask\n"); return ret;
}
/* * To simplify and improve latency of handling frequency requests on * the host side, this ensures that the vCPU thread triggering the MMIO * abort is the same thread whose performance constraints (Ex. uclamp * settings) need to be updated. This simplifies the VMM (Virtual * Machine Manager) having to find the correct vCPU thread and/or * facing permission issues when configuring other threads.
*/
policy->dvfs_possible_from_any_cpu = false;
policy->fast_switch_possible = true;
/* * Using the default SCALE_FREQ_SOURCE_CPUFREQ is insufficient since * the actual physical CPU frequency may not match requested frequency * from the vCPU thread due to frequency update latencies or other * inputs to the physical CPU frequency selection. This additional FIE * source allows for more accurate freq_scale updates and only takes * effect if another FIE source such as AMUs have not been registered.
*/
topology_set_scale_freq_source(&virt_sfd, policy->cpus);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.