Re: [PATCH] Determine latency from ACPI

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Devel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Forum]     [Linux SCSI]

  Powered by Linux