Pallipadi, Venkatesh wrote:
> Recent Linux kernels have support for percpu HPET timer. These timers appear 
> as
> hpet<num> in /proc/timer_list and /proc/interrupts. powertop should not list
> these interrupts as wake events as they are delivering timer events which are
> already accounted for by one of the waking timers. Skipping these percpu timer
> is similar to skipping LOC (local apic timer) and timer 0 in powertop.


ack, nice patch, I'll merge this - thanks!

Auke


> 
> Example:
> 
> Before the patch wakeup data
> 
> Top causes for wakeups:
>   23.6% (  9.9)     <kernel core> : hrtimer_start_range_ns (tick_sched_timer) 
>   21.4% (  8.9)     <kernel core> : hrtimer_start (tick_sched_timer) 
>   10.2% (  4.3)     <kernel core> : schedule_delayed_work_on 
> (delayed_work_timer_fn) 
>   10.1% (  4.2)       <interrupt> : hpet2 
>    9.9% (  4.1)       <interrupt> : hpet5 
>    4.6% (  1.9)       <interrupt> : hpet6 
>    4.3% (  1.8)       <interrupt> : hpet4 
>    3.8% (  1.6)       <interrupt> : ata_piix, ata_piix, uhci_hcd:usb5, 
> uhci_hcd:usb6 
>    3.4% (  1.4)       <interrupt> : hpet3 
>    2.7% (  1.1)       <interrupt> : ehci_hcd:usb1, uhci_hcd:usb7, eth0 
>    1.3% (  0.5)     <kernel core> : add_timer (neigh_periodic_timer) 
>    1.1% (  0.5)     <kernel core> : e1000_intr (e1000_watchdog) 
> : : :
> : : :
> : : :
> 
> After the patch wakeup data
> 
> Top causes for wakeups:
>   33.9% (  8.9)     <kernel core> : hrtimer_start (tick_sched_timer) 
>   30.4% (  8.0)     <kernel core> : hrtimer_start_range_ns (tick_sched_timer) 
>   14.2% (  3.7)     <kernel core> : schedule_delayed_work_on 
> (delayed_work_timer_fn) 
>    7.3% (  1.9)       <interrupt> : ata_piix, ata_piix, uhci_hcd:usb5, 
> uhci_hcd:usb6 
>    5.3% (  1.4)       <interrupt> : ehci_hcd:usb1, uhci_hcd:usb7, eth0 
>    2.0% (  0.5)     <kernel core> : e1000_intr (e1000_watchdog) 
>    2.0% (  0.5)     <kernel core> : add_timer (neigh_periodic_timer) 
> : : :
> : : :
> : : :
> 
> 
> Patch records the percpu hpet timer info from /proc/timer_list and filters
> /proc/interrupts based on that.
> 
> Signed-off-by: Venkatesh Pallipadi <[email protected]>
> 
> diff -purN powertop-1.11/powertop.c powertop-1.11-new/powertop.c
> --- powertop-1.11/powertop.c  2008-12-30 10:52:54.000000000 -0800
> +++ powertop-1.11-new/powertop.c      2009-05-28 00:52:32.000000000 -0700
> @@ -35,6 +35,7 @@
>  #include <assert.h>
>  #include <locale.h>
>  #include <time.h>
> +#include <limits.h>
>  #include <sys/stat.h>
>  
>  #include "powertop.h"
> @@ -171,6 +172,58 @@ int update_irq(int irq, uint64_t count, 
>       return count;
>  }
>  
> +static int percpu_hpet_timer(char *name)
> +{
> +     static int timer_list_read;
> +     static int percpu_hpet_start = INT_MAX, percpu_hpet_end = INT_MIN;
> +     char *c;
> +     long hpet_chan;
> +
> +     if (!timer_list_read) {
> +             char file_name[20];
> +             char ln[80];
> +             FILE *fp;
> +
> +             timer_list_read = 1;
> +             snprintf(file_name, sizeof(file_name), "/proc/timer_list");
> +             fp = fopen(file_name, "r");
> +             if (fp == NULL)
> +                     return 0;
> +
> +             while (fgets(ln, sizeof(ln), fp) != NULL)
> +             {
> +                     c = strstr(ln, "Clock Event Device: hpet");
> +                     if (!c)
> +                             continue;
> +
> +                     c += 24;
> +                     if (!isdigit(c[0]))
> +                             continue;
> +
> +                     hpet_chan = strtol(c, NULL, 10);
> +                     if (hpet_chan < percpu_hpet_start)
> +                             percpu_hpet_start = hpet_chan;
> +                     if (hpet_chan > percpu_hpet_end)
> +                             percpu_hpet_end = hpet_chan;
> +             }
> +             fclose(fp);
> +     }
> +
> +     c = strstr(name, "hpet");
> +     if (!c)
> +             return 0;
> +
> +     c += 4;
> +     if (!isdigit(c[0]))
> +             return 0;
> +
> +     hpet_chan = strtol(c, NULL, 10);
> +     if (percpu_hpet_start <= hpet_chan && hpet_chan <= percpu_hpet_end)
> +             return 1;
> +
> +     return 0;
> +}
> +
>  static void do_proc_irq(void)
>  {
>       FILE *file;
> @@ -253,6 +306,10 @@ static void do_proc_irq(void)
>               else
>                       sprintf(line2, _("    <interrupt> : %s"), _("PS/2 
> keyboard/mouse/touchpad"));
>  
> +             /* skip per CPU timer interrupts */
> +             if (percpu_hpet_timer(name))
> +                     delta = 0;
> +
>               if (nr > 0 && delta > 0)
>                       push_line(line2, delta);
>               if (nr==0)

_______________________________________________
Power mailing list
[email protected]
http://www.bughost.org/mailman/listinfo/power

Reply via email to