acpi-cpufreq: get the cur_freq from acpi_processor_performance states
PATCH RESEND 1/1 acpi-cpufreq: get the cur_freq from acpi_processor_performance states
As the initialized freq_tables maybe different from the p-states values, so the array index is different as well.
p-states value: [2400 2400 2000 ...], while the freq_tables:
[2400 2000 ... CPUFREQ_TABLE_END]. After setted the freqs 2000, the perf->state is 3 while the freqs_table's index should be 2. So when call the get_cur_freq_on_cpu, the freqs value we get is 2400.
So, fix the problem with the correct tables.
--- drivers/cpufreq/acpi-cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/cpufreq/acpi-cpufreq.c +3 -1
@@ -365,6 +365,7 @@ static u32 get_cur_val(const struct cpumask *mask)static unsigned int get_cur_freq_on_cpu (unsigned int cpu) {struct acpi_cpufreq_data *data =per_cpu (acfreq_data, cpu); +struct acpi_processor_performance *perf;unsigned int freq;unsigned int cached_freq;
@@ -375,7 +376,8 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)return 0 ; } - cached_freq = data->freq_table[data->acpi_data->state].frequency; + perf = data->acpi_data; + cached_freq = perf->states[perf->state].core_frequency *1000 ; freq =extract_freq (get_cur_val (cpumask_of (cpu)), data);if (freq != cached_freq) {/*
Signature · 1 line
1.7.12
Viresh Kumar
maintainerQuoted 29 lines · Wang Weidong
As the initialized
freq_tablesmaybe different from the p-states values, so the array index is different as well.p-states value: [2400 2400 2000 ...], while the
freq_tables:
[2400 2000 ...CPUFREQ_TABLE_END]. After setted the freqs 2000, theperf->stateis 3 while the freqs_table's index should be 2. So when call theget_cur_freq_on_cpu, the freqs value we get is 2400.So, fix the problem with the correct tables.
Signed-off-by Wang Weidong <[email protected]>--- drivers/cpufreq/acpi-cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/cpufreq/acpi-cpufreq.c +1
-0@@ -365,6 +365,7 @@ static u32 get_cur_val(const struct cpumask *mask)static unsigned int get_cur_freq_on_cpu (unsigned int cpu) {struct acpi_cpufreq_data *data =per_cpu (acfreq_data, cpu); +struct acpi_processor_performance *perf;unsigned int freq;unsigned int cached_freq;
drivers/cpufreq/acpi-cpufreq.c static unsigned int get_cur_freq_on_cpu(unsigned int cpu) · line 383
Quoted 9 lines
drivers/cpufreq/acpi-cpufreq.c +2
-1@@ -375,7 +376,8 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)return 0 ; } - cached_freq = data->freq_table[data->acpi_data->state].frequency; + perf = data->acpi_data; + cached_freq = perf->states[perf->state].core_frequency *1000 ; freq =extract_freq (get_cur_val (cpumask_of (cpu)), data);if (freq != cached_freq) {/*
The problem looks real but I am not very well aware of this driver and so it would
be more appropriate if Rafael replies/Applies..
Quoted 10 lines · Wang Weidong
As the initialized
freq_tablesmaybe different from the p-states values, so the array index is different as well.p-states value: [2400 2400 2000 ...], while the
freq_tables:
[2400 2000 ...CPUFREQ_TABLE_END]. After setted the freqs 2000, theperf->stateis 3 while the freqs_table's index should be 2. So when call theget_cur_freq_on_cpu, the freqs value we get is 2400.So, fix the problem with the correct tables.
What you're saying is basically that freq_table and perf->states diverge at one point. Shouldn't we re-generate freq_table in that case instead of fixing up get_cur_freq_on_cpu() only in a quite indirect way?
Quoted 28 lines
Signed-off-by Wang Weidong <[email protected]>--- drivers/cpufreq/acpi-cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/cpufreq/acpi-cpufreq.c +3
-1@@ -365,6 +365,7 @@ static u32 get_cur_val(const struct cpumask *mask)static unsigned int get_cur_freq_on_cpu (unsigned int cpu) {struct acpi_cpufreq_data *data =per_cpu (acfreq_data, cpu); +struct acpi_processor_performance *perf;unsigned int freq;unsigned int cached_freq;@@ -375,7 +376,8 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)return 0 ; } - cached_freq = data->freq_table[data->acpi_data->state].frequency; + perf = data->acpi_data; + cached_freq = perf->states[perf->state].core_frequency *1000 ; freq =extract_freq (get_cur_val (cpumask_of (cpu)), data);if (freq != cached_freq) {/*
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 10 lines · Rafael J. Wysocki
Quoted 9 lines · Wang Weidong
As the initialized
freq_tablesmaybe different from the p-states values, so the array index is different as well.p-states value: [2400 2400 2000 ...], while the
freq_tables:
[2400 2000 ...CPUFREQ_TABLE_END]. After setted the freqs 2000, theperf->stateis 3 while the freqs_table's index should be 2. So when call theget_cur_freq_on_cpu, the freqs value we get is 2400.
Quoted 7 lines
Quoted 1 line
So, fix the problem with the correct tables.
What you're saying is basically that
freq_tableandperf->statesdiverge at one point. Shouldn't we re-generatefreq_tablein that case instead of fixing upget_cur_freq_on_cpu()only in a quite indirect way?
Hi Rafael,
Thanks for your reply.
You mean that we should re-generate the freq_table in that case? Could we fix the table init like this:
drivers/cpufreq/acpi-cpufreq.c +1 -1
@@ -779,7 +779,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)/* table init */ for (i =0 ; i < perf->state_count; i++) { -if (i >0 && perf->states[i].core_frequency >= +if (i >0 && perf->states[i].core_frequency > data->freq_table[valid_states-1 ].frequency /1000 )continue ;
when the value is same, we just keep the value into the freq_table.
Regards,
Wang
Quoted 29 lines
Quoted 28 lines
Signed-off-by Wang Weidong <[email protected]>--- drivers/cpufreq/acpi-cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/cpufreq/acpi-cpufreq.c +3
-1@@ -365,6 +365,7 @@ static u32 get_cur_val(const struct cpumask *mask)static unsigned int get_cur_freq_on_cpu (unsigned int cpu) {struct acpi_cpufreq_data *data =per_cpu (acfreq_data, cpu); +struct acpi_processor_performance *perf;unsigned int freq;unsigned int cached_freq;@@ -375,7 +376,8 @@ static unsigned int get_cur_freq_on_cpu(unsigned int cpu)return 0 ; } - cached_freq = data->freq_table[data->acpi_data->state].frequency; + perf = data->acpi_data; + cached_freq = perf->states[perf->state].core_frequency *1000 ; freq =extract_freq (get_cur_val (cpumask_of (cpu)), data);if (freq != cached_freq) {/*
Quoted 36 lines · Wang Weidong
Quoted 10 lines · Rafael J. Wysocki
Quoted 9 lines · Wang Weidong
As the initialized
freq_tablesmaybe different from the p-states values, so the array index is different as well.p-states value: [2400 2400 2000 ...], while the
freq_tables:
[2400 2000 ...CPUFREQ_TABLE_END]. After setted the freqs 2000, theperf->stateis 3 while the freqs_table's index should be 2. So when call theget_cur_freq_on_cpu, the freqs value we get is 2400.Quoted 7 lines
Quoted 1 line
So, fix the problem with the correct tables.
What you're saying is basically that
freq_tableandperf->statesdiverge at one point. Shouldn't we re-generatefreq_tablein that case instead of fixing upget_cur_freq_on_cpu()only in a quite indirect way?Hi Rafael,
Thanks for your reply.
You mean that we should re-generate the
freq_tablein that case? Could we fix the table init like this:drivers/cpufreq/acpi-cpufreq.c +1
-1@@ -779,7 +779,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)/* table init */ for (i =0 ; i < perf->state_count; i++) { -if (i >0 && perf->states[i].core_frequency >= +if (i >0 && perf->states[i].core_frequency > data->freq_table[valid_states-1 ].frequency /1000 )continue ;
Quoted 1 line
when the value is same, we just keep the value into the
freq_table.
That would only be OK if it is guaranteed that the set of available states hasn't changed, which I'm not sure is the case.
Rafael
Quoted 37 lines · Rafael J. Wysocki
Quoted 36 lines · Wang Weidong
Quoted 10 lines · Rafael J. Wysocki
Quoted 9 lines · Wang Weidong
As the initialized
freq_tablesmaybe different from the p-states values, so the array index is different as well.p-states value: [2400 2400 2000 ...], while the
freq_tables:
[2400 2000 ...CPUFREQ_TABLE_END]. After setted the freqs 2000, theperf->stateis 3 while the freqs_table's index should be 2. So when call theget_cur_freq_on_cpu, the freqs value we get is 2400.Quoted 7 lines
Quoted 1 line
So, fix the problem with the correct tables.
What you're saying is basically that
freq_tableandperf->statesdiverge at one point. Shouldn't we re-generatefreq_tablein that case instead of fixing upget_cur_freq_on_cpu()only in a quite indirect way?Hi Rafael,
Thanks for your reply.
You mean that we should re-generate the
freq_tablein that case? Could we fix the table init like this:drivers/cpufreq/acpi-cpufreq.c +1
-1@@ -779,7 +779,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)/* table init */ for (i =0 ; i < perf->state_count; i++) { -if (i >0 && perf->states[i].core_frequency >= +if (i >0 && perf->states[i].core_frequency > data->freq_table[valid_states-1 ].frequency /1000 )continue ;
Quoted 7 lines
Quoted 1 line
when the value is same, we just keep the value into the
freq_table.That would only be OK if it is guaranteed that the set of available states hasn't changed, which I'm not sure is the case.
Rafael
Yep, ACPI maybe will dynamic to report the states to the OS . So I should consider it again.
Regards,
Wang
Quoted 3 lines
.