Skip to contentSkip to conversation

acpi-cpufreq: get the cur_freq from acpi_processor_performance states

PATCH RESEND In review Wang Weidong 3 participants 6 messages Aug 21, 2014 – Sep 30, 2014 CPU frequency scaling framework

lore
Share & tools
lore
#0 lore raw

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
index b0c18ed..ac93885 100644
@@ -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
maintainer
#1 lore raw
Quoted 29 lines · Wang Weidong

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 +1 -0
index b0c18ed..ac93885 100644
@@ -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..

#2 lore raw
In reply to Wang Weidong
Quoted 10 lines · Wang Weidong

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.

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
---
 drivers/cpufreq/acpi-cpufreq.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/cpufreq/acpi-cpufreq.c +3 -1
index b0c18ed..ac93885 100644
@@ -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.
#3 lore raw
Quoted 10 lines · Rafael J. Wysocki
Quoted 9 lines · Wang Weidong

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.

Quoted 7 lines
Quoted 1 line

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?

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
---
 drivers/cpufreq/acpi-cpufreq.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/cpufreq/acpi-cpufreq.c +3 -1
index b0c18ed..ac93885 100644
@@ -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) {
 		/*
#4 lore raw
Quoted 36 lines · Wang Weidong
Quoted 10 lines · Rafael J. Wysocki
Quoted 9 lines · Wang Weidong

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.

Quoted 7 lines
Quoted 1 line

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?

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;
 
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

#5 lore raw
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_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.

Quoted 7 lines
Quoted 1 line

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?

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;
 
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

.