]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/x86_cpufreq_powernow-k8_acpi_latency_values.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / x86_cpufreq_powernow-k8_acpi_latency_values.patch
1 From: Mark Langsdorf <mark.langsdorf@amd.com>
2 Subject: X86 powernow-k8 cpufreq: Get transition latency from acpi _PSS object
3 References: bnc#464461
4 Patch-Mainline: not yet
5
6 The ondemand kernel governor calculates the best sampling rate (how often
7 to check for CPU load) from the CPU transition latency it gets from the
8 low level cpufreq drivers. Powernow-k8 returned too high values resulting
9 in poor performance.
10
11 The transition latency returned from the ACPI _PSS object is also used by
12 AMD's Windows PowerNow driver (thus should always be sane) and returns more
13 exact values than the previous, algorithm to guess the transition latency.
14
15 Signed-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
21 Index: 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