On Tuesday 27 January 2009 21:03:47 Mark Langsdorf wrote: > 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. > > -Mark Langsdorf > Operating System Research Center > AMD > > Signed-off-by: Mark Langsdorf <mark.langsdorf@xxxxxxx> Signed-off-by: Thomas Renninger <trenn@xxxxxxx> This finally makes the ondemand governor work nicely together with the powernow-k8 driver without the need of tweaking the sampling rate. Thanks, Thomas > 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 > @@ -931,10 +931,25 @@ static void powernow_k8_cpu_exit_acpi(st > acpi_processor_unregister_performance(&data->acpi_data, data->cpu); > } > > +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 */ > @@ -1167,7 +1182,13 @@ static int __cpuinit powernowk8_cpu_init > kfree(data); > return -ENODEV; > } > - } > + /* 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; > + } else /* ACPI _PSS objects available */ > + pol->cpuinfo.transition_latency = get_transition_latency(data); > > /* only run on specific CPU from here on */ > oldmask = current->cpus_allowed; > @@ -1197,11 +1218,6 @@ static int __cpuinit powernowk8_cpu_init > else > 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); > > -- > To unsubscribe from this list: send the line "unsubscribe cpufreq" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html