As fast_switch may get called in interrupt disable mode, it does not
update the global_pstate_info data structure. Hence the global_pstate_info
has stale data whenever pstate is updated through fast_swtich().
So the gpstate_timer can fire after a fast_switch() call has update
the pstates to a different value. Hence the timer handler cannot rely
on the cached values of local and global pstate and needs to read it
from the PMSR.
Signed-off-by: Akshay Adiga <redacted>
---
drivers/cpufreq/powernv-cpufreq.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
@@ -592,7 +592,8 @@ void gpstate_timer_handler(unsigned long data){structcpufreq_policy*policy=(structcpufreq_policy*)data;structglobal_pstate_info*gpstates=policy->driver_data;-intgpstate_idx;+intgpstate_idx,lpstate_idx;+unsignedlongval;unsignedinttime_diff=jiffies_to_msecs(jiffies)-gpstates->last_sampled_time;structpowernv_smp_call_datafreq_data;
@@ -600,21 +601,36 @@ void gpstate_timer_handler(unsigned long data)if(!spin_trylock(&gpstates->gpstate_lock))return;+/*+*IfPMCRwaslastupdatedwasusingfast_swtichthen+*Wemayhavewrongingpstate->last_lpstate_idx+*value.Hence,readfromPMCRtogetcorrectdata.+*/+val=get_pmspr(SPRN_PMCR);+freq_data.gpstate_id=(val>>(56))&0xFF;+freq_data.pstate_id=(val>>(48))&0xFF;+if(freq_data.gpstate_id==freq_data.pstate_id){+reset_gpstates(policy);+spin_unlock(&gpstates->gpstate_lock);+return;+}+gpstates->last_sampled_time+=time_diff;gpstates->elapsed_time+=time_diff;-freq_data.pstate_id=idx_to_pstate(gpstates->last_lpstate_idx);-if((gpstates->last_gpstate_idx==gpstates->last_lpstate_idx)||-(gpstates->elapsed_time>MAX_RAMP_DOWN_TIME)){+if(gpstates->elapsed_time>MAX_RAMP_DOWN_TIME){gpstate_idx=pstate_to_idx(freq_data.pstate_id);reset_gpstates(policy);gpstates->highest_lpstate_idx=gpstate_idx;}else{+lpstate_idx=pstate_to_idx(freq_data.pstate_id);gpstate_idx=calc_global_pstate(gpstates->elapsed_time,gpstates->highest_lpstate_idx,-gpstates->last_lpstate_idx);+lpstate_idx);}-+freq_data.gpstate_id=idx_to_pstate(gpstate_idx);+gpstates->last_gpstate_idx=gpstate_idx;+gpstates->last_lpstate_idx=lpstate_idx;/**Iflocalpstateisequaltoglobalpstate,rampdownisover*Sotimerisnotrequiredtobequeued.
@@ -622,10 +638,6 @@ void gpstate_timer_handler(unsigned long data)if(gpstate_idx!=gpstates->last_lpstate_idx)queue_gpstate_timer(gpstates);-freq_data.gpstate_id=idx_to_pstate(gpstate_idx);-gpstates->last_gpstate_idx=pstate_to_idx(freq_data.gpstate_id);-gpstates->last_lpstate_idx=pstate_to_idx(freq_data.pstate_id);-spin_unlock(&gpstates->gpstate_lock);/* Timer may get migrated to a different cpu on cpu hot unplug */
As fast_switch may get called in interrupt disable mode, it does not
s/in interrupt disable mode/with interrupts disabled
s/it does/it may
update the global_pstate_info data structure. Hence the global_pstate_info
has stale data whenever pstate is updated through fast_swtich().
s/has/may have
s/swtich/switch
So the gpstate_timer can fire after a fast_switch() call has update
s/So the/The
s/a fast_swtich() call has update/the fast_switch() call has updated
the pstates to a different value. Hence the timer handler cannot rely
on the cached values of local and global pstate and needs to read it
from the PMSR.
Signed-off-by: Akshay Adiga <redacted>
---
drivers/cpufreq/powernv-cpufreq.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
I am not the best guy to judge the code changes here. Can you please include
Shilpa and Gautham to the mail chain and get there feedback.
--
viresh
Thanks Viresh for taking a look at it.
I will make the mentioned changes in the next version of the patch and
will add Shilpa and Gautham to the mail chain.
Regards
Akshay Adiga
On 11/04/2016 12:11 PM, Viresh Kumar wrote:
On 04-11-16, 10:57, Akshay Adiga wrote:
quoted
As fast_switch may get called in interrupt disable mode, it does not
s/in interrupt disable mode/with interrupts disabled
s/it does/it may
quoted
update the global_pstate_info data structure. Hence the global_pstate_info
has stale data whenever pstate is updated through fast_swtich().
s/has/may have
s/swtich/switch
quoted
So the gpstate_timer can fire after a fast_switch() call has update
s/So the/The
s/a fast_swtich() call has update/the fast_switch() call has updated
quoted
the pstates to a different value. Hence the timer handler cannot rely
on the cached values of local and global pstate and needs to read it
from the PMSR.
Signed-off-by: Akshay Adiga <redacted>
---
drivers/cpufreq/powernv-cpufreq.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
I am not the best guy to judge the code changes here. Can you please include
Shilpa and Gautham to the mail chain and get there feedback.
Thanks Viresh for taking a look at it.
I will make the mentioned changes in the next version of the patch.
Regards
Akshay Adiga
On 11/04/2016 12:03 PM, Viresh Kumar wrote:
On 04-11-16, 10:57, Akshay Adiga wrote:
quoted
Adding fast_switch which does light weight operation to
set the desired pstate.
Signed-off-by: Akshay Adiga <redacted>
---
drivers/cpufreq/powernv-cpufreq.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)