* [PATCH][retry 1] Determine latency from ACPI
@ 2009-01-29 21:55 Mark Langsdorf
0 siblings, 0 replies; only message in thread
From: Mark Langsdorf @ 2009-01-29 21:55 UTC (permalink / raw)
To: cpufreq, linux-kernel
At this time, the PowerNow! driver for K8 uses an experimentally
derived formula to calculate transition latency. The value it
provides is orders of magnitude too large on modern systems.
This patch replaces the formula with ACPI _PSS latency values
for more accuracy and better performance.
I've tested it on two 2nd generation Opteron systems, a 3rd
generation Operton system, and a Turion X2 without seeing any
stability problems.
Resent this patch to merge with Yinghai Lu's
"x86/powernow: fix cpus_allowed brokage when acpi=off".
-Mark Langsdorf
Operating System Research Center
AMD
Signed-off-by: Mark Langsdorf <mark.langsdorf@amd.com>
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -939,10 +939,25 @@ static void powernow_k8_cpu_exit_acpi(st
free_cpumask_var(data->acpi_data.shared_cpu_map);
}
+static int get_transition_latency(struct powernow_k8_data *data)
+{
+ int max_latency = 0;
+ int i;
+ for (i = 0; i < data->acpi_data.state_count; i++) {
+ int cur_latency = data->acpi_data.states[i].transition_latency
+ + data->acpi_data.states[i].bus_master_latency;
+ if (cur_latency > max_latency)
+ max_latency = cur_latency;
+ }
+ /* value in usecs, needs to be in nanoseconds */
+ return 1000 * max_latency;
+}
+
#else
static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
+static int get_transition_latency(struct powernow_k8_data *data) { return 0; }
#endif /* CONFIG_X86_POWERNOW_K8_ACPI */
/* Take a frequency, and issue the fid/vid transition command */
@@ -1145,8 +1160,9 @@ static int __cpuinit powernowk8_cpu_init
oldmask = current->cpus_allowed;
rc = powernow_k8_cpu_init_acpi(data);
- if (!rc) {
+ if (!rc) { /* ACPI _PSS objects available */
k8_cpu_acpi_inited = 1;
+ pol->cpuinfo.transition_latency = get_transition_latency(data);
} else {
/*
* Use the PSB BIOS structure. This is only availabe on
@@ -1181,6 +1197,11 @@ static int __cpuinit powernowk8_cpu_init
if (rc) {
goto err_out;
}
+ /* Take a crude guess here.
+ * That guess was in microseconds, so multiply with 1000 */
+ pol->cpuinfo.transition_latency = (
+ ((data->rvo + 8) * data->vstable * VST_UNITS_20US) +
+ ((1 << data->irt) * 30)) * 1000;
}
/* only run on specific CPU from here on */
@@ -1210,11 +1231,6 @@ static int __cpuinit powernowk8_cpu_init
else
cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu));
data->available_cores = pol->cpus;
-
- /* Take a crude guess here.
- * That guess was in microseconds, so multiply with 1000 */
- pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US)
- + (3 * (1 << data->irt) * 10)) * 1000;
if (cpu_family == CPU_HW_PSTATE)
pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-01-29 21:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-29 21:55 [PATCH][retry 1] Determine latency from ACPI Mark Langsdorf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox