]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/x86_cpufreq_powernow-k8_acpi_latency_values.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / x86_cpufreq_powernow-k8_acpi_latency_values.patch
CommitLineData
2cb7cef9
BS
1From: Mark Langsdorf <mark.langsdorf@amd.com>
2Subject: X86 powernow-k8 cpufreq: Get transition latency from acpi _PSS object
3References: bnc#464461
4Patch-Mainline: not yet
5
6The ondemand kernel governor calculates the best sampling rate (how often
7to check for CPU load) from the CPU transition latency it gets from the
8low level cpufreq drivers. Powernow-k8 returned too high values resulting
9in poor performance.
10
11The transition latency returned from the ACPI _PSS object is also used by
12AMD's Windows PowerNow driver (thus should always be sane) and returns more
13exact values than the previous, algorithm to guess the transition latency.
14
15Signed-off-by: Thomas Renninger <trenn@suse.de>
16
17---
18 arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 30 ++++++++++++++++++++++++------
19 1 file changed, 24 insertions(+), 6 deletions(-)
20
21Index: linux-2.6.27/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
22===================================================================
23--- linux-2.6.27.orig/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
24+++ linux-2.6.27/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
25@@ -927,10 +927,23 @@ static void powernow_k8_cpu_exit_acpi(st
26 acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
27 }
28
29+static int get_transition_latency(struct powernow_k8_data *data)
30+{
31+ int max_latency = 0;
32+ int i;
33+ for (i = 0; i < data->acpi_data.state_count; i++) {
34+ int cur_latency = data->acpi_data.states[i].transition_latency
35+ + data->acpi_data.states[i].bus_master_latency;
36+ if (cur_latency > max_latency)
37+ max_latency = cur_latency;
38+ }
39+ return max_latency;
40+}
41 #else
42 static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
43 static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
44 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
45+static int get_transition_latency(struct powernow_k8_data *data) { return 0; }
46 #endif /* CONFIG_X86_POWERNOW_K8_ACPI */
47
48 /* Take a frequency, and issue the fid/vid transition command */
49@@ -1030,6 +1043,7 @@ static int powernowk8_target(struct cpuf
50 unsigned int newstate;
51 int ret = -EIO;
52
53+
54 if (!data)
55 return -EINVAL;
56
57@@ -1161,7 +1175,16 @@ static int __cpuinit powernowk8_cpu_init
58 kfree(data);
59 return -ENODEV;
60 }
61- }
62+ /* Take a crude guess here.
63+ * That guess was in microseconds, so multiply with 1000 */
64+ pol->cpuinfo.transition_latency = (
65+ ( (data->rvo + 8) * data->vstable * VST_UNITS_20US) +
66+ ( (1 << data->irt) * 30)
67+ ) * 1000;
68+ }
69+ else /* ACPI _PSS objects available */
70+ pol->cpuinfo.transition_latency =
71+ get_transition_latency(data) * 1000;
72
73 /* only run on specific CPU from here on */
74 oldmask = current->cpus_allowed;
75@@ -1192,11 +1215,6 @@ static int __cpuinit powernowk8_cpu_init
76 pol->cpus = per_cpu(cpu_core_map, pol->cpu);
77 data->available_cores = &(pol->cpus);
78
79- /* Take a crude guess here.
80- * That guess was in microseconds, so multiply with 1000 */
81- pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US)
82- + (3 * (1 << data->irt) * 10)) * 1000;
83-
84 if (cpu_family == CPU_HW_PSTATE)
85 pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
86 else