• alex.shi's avatar
    acpi: fix of pmtimer overflow that make Cx states time incorrect · ff69f2bb
    alex.shi authored
    We found Cx states time abnormal in our some of machines which have 16
    LCPUs, the C0 take too many time while system is really idle when kernel
    enabled tickless and highres.  powertop output is below:
    
         PowerTOP version 1.9       (C) 2007 Intel Corporation
    
    Cn                Avg residency       P-states (frequencies)
    C0 (cpu running)        (40.5%)         2.53 Ghz     0.0%
    C1                0.0ms ( 0.0%)         2.53 Ghz     0.0%
    C2              128.8ms (59.5%)         2.40 Ghz     0.0%
                                            1.60 Ghz   100.0%
    
    Wakeups-from-idle per second :  4.7     interval: 20.0s
    no ACPI power usage estimate available
    
    Top causes for wakeups:
      41.4% ( 24.9)       <interrupt> : extra timer interrupt
      20.2% ( 12.2)     <kernel core> : usb_hcd_poll_rh_status
    (rh_timer_func)
    
    After tacking detailed for this issue, Yakui and I find it is due to 24
    bit PM timer overflows when some of cpu sleep more than 4 seconds.  With
    tickless kernel, the CPU want to sleep as much as possible when system
    idle.  But the Cx sleep time are recorded by pmtimer which length is
    determined by BIOS.  The current Cx time was gotten in the following
    function from driver/acpi/processor_idle.c:
    
    static inline u32 ticks_elapsed(u32 t1, u32 t2)
    {
           if (t2 >= t1)
                   return (t2 - t1);
           else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
                   return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
           else
                   return ((0xFFFFFFFF - t1) + t2);
    }
    
    If pmtimer is 24 bits and it take 5 seconds from t1 to t2, in above
    function, just about 1 seconds ticks was recorded.  So the Cx time will be
    reduced about 4 seconds.  and this is why we see above powertop output.
    
    To resolve this problem, Yakui and I use ktime_get() to record the Cx
    states time instead of PM timer as the following patch.  the patch was
    tested with i386/x86_64 modes on several platforms.
    Acked-by: default avatarVenkatesh Pallipadi <venkatesh.pallipadi@intel.com>
    Tested-by: default avatarAlex Shi <alex.shi@intel.com>
    Signed-off-by: default avatarAlex Shi <alex.shi@intel.com>
    Signed-off-by: default avatarYakui.zhao <yakui.zhao@intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLen Brown <len.brown@intel.com>
    ff69f2bb
processor_idle.c 32.6 KB