about system time incorrect after changing cpu frequency

vichy vichy.kuo at gmail.com
Tue Sep 1 00:21:40 PDT 2015


hi Viresh:

2015-09-01 14:02 GMT+08:00 Viresh Kumar <viresh.kumar at linaro.org>:
> On 01-09-15, 13:36, vichy wrote:
>> >> I try to call below 2 functions to change the frequency of clocksource
>> >> and clockevent, but the above b) sleep time is still incorrect when
>> >> cpu runs in 500Mhz.
>> >>     clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
>> >>     __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);
>
> How and when were you calling them? What kernel version is it ?
Belwo is what I did in my cpufreq driver and my kernel version is 3.0.33.
plat_cpufreq_target()
{
........
    cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
    PLAT_Mpll(freqs.new / 1000);
    PLAT_gt_change_freq();
    /* post change notification */
    cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
....
}

and I add  PLAT_gt_change_freq in arm_global_timer.c like below:
 PLAT_gt_change_freq calling() {
    gt_clk_rate = get_periph_clk();
    clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
    __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);
}


I also do another experiment that DIDN'T change any REAL HW setting
but change mult/shift to the half value like below:
(But I measure out the "sleep 1" --> still 1secs, even I modify mult/shift)
(in my opinion, the "seep 1" I measured should be 500ms, since HW NO
change but mult/shift change)
plat_cpufreq_target()
{
........
    cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
   //    PLAT_Mpll(freqs.new / 1000); //NO HW FREQ change
     PLAT_gt_change_freq();
    /* post change notification */
    cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
....
}

PLAT_gt_change_freq in arm_global_timer.c like below:
 PLAT_gt_change_freq calling() {
    gt_clk_rate = get_periph_clk()/2; //purposely chage 1/2
    clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
    __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);
}

>
>> Clock Event Device: arm_global_timer
>
> This driver doesn't have support to update clkevt device's freq. You
> may need to modify that based on how arch/arm/kernel/smp_twd.c is
> updated. look for: clockevents_update_freq().
I have check the latest kernel about arch/arm/kernel/smp_twd.c
it almost do the same thing like I did, except it use cpufreq notifier
for calling clockevents_update_freq like below:
(the final target of them is the same --> clling
clockevents_update_freq to change mult/shift.

static void twd_update_frequency(void *data)
{
    twd_timer_rate = clk_get_rate(twd_clk);

    clockevents_update_freq(raw_cpu_ptr(twd_evt), twd_timer_rate);
}

I know so far arm global timer seems not support cpu frequcy chage flow.
But like my experiment above to fake change gt_clk_rate, the sleep
should be 1/2 of the original.

if smp_twd call twd_update_frequency to change multi/shift can work,
why purposely adding  clockevents_update_freq in global timer not
working?

or there is something else except Mult/shift need to be modify when
gt_clk_rate changed?

appreciate your help in advance,
>
> --
> viresh



More information about the linux-arm-kernel mailing list