From: Jacob Pan <[email protected]>

Moorestown/Medfield add percpu APB timers similar to percpu HPET timer.
We need to filter them out for the same reason explained in commit
1a8abdc44d333c11ace42c11f39d39dd9a8e8b50.
Example result before the patch:
Wakeups-from-idle per second : 70.8     interval: 15.0s
no ACPI power usage estimate available
Top causes for wakeups:
  28.6% ( 10.0)   USB device  1-3 : SMC2209USB/ETH (SMC)
  27.4% (  9.6)   [ehci_hcd:usb1] <interrupt>
  12.0% (  4.2)   [kernel core] hrtimer_start (tick_sched_timer)
  10.9% (  3.8)   [apbt1] <interrupt>
   8.6% (  3.0)   [kernel scheduler] Load balancing tick
   5.3% (  1.9)   [Function call interrupts] <kernel IPI>
   1.3% (  0.5)   events/1

Example result after the patch:
Wakeups-from-idle per second : 72.8     interval: 15.0s
no ACPI power usage estimate available
Top causes for wakeups:
  28.6% (  9.9)   USB device  1-3 : SMC2209USB/ETH (SMC)
  27.8% (  9.6)   [ehci_hcd:usb1] <interrupt>
  19.7% (  6.8)   [kernel scheduler] Load balancing tick
  10.8% (  3.7)   [kernel core] hrtimer_start (tick_sched_timer)
   4.6% (  1.6)   [Function call interrupts] <kernel IPI>
   1.7% (  0.6)   events/0
   1.5% (  0.5)   events/1

Signed-off-by: Jacob Pan <[email protected]>
---
 powertop.c |   67 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/powertop.c b/powertop.c
index 74eb328..1704388 100644
--- a/powertop.c
+++ b/powertop.c
@@ -173,12 +173,52 @@ int update_irq(int irq, uint64_t count, char *name)
        return count;
 }
 
-static int percpu_hpet_timer(char *name)
+static const char *clockevent_device[] = {
+       "apbt",
+       "hpet",
+       NULL,
+};
+
+static const char *timerlist_clockevent[] = {
+       "Clock Event Device: apbt",
+       "Clock Event Device: hpet",
+       NULL,
+};
+
+static char *is_percpu_clockevent(char *name)
+{
+       char *c;
+       int i = 0;
+
+       while (clockevent_device[i]) {
+               c = strstr(name, clockevent_device[i]);
+               if (c)
+                       return c;
+               i++;
+       }
+       return NULL;
+}
+
+static char *is_timerlist_clockevent(char *name)
+{
+       char *c;
+       int i = 0;
+
+       while (timerlist_clockevent[i]) {
+               c = strstr(name, timerlist_clockevent[i]);
+               if (c)
+                       return c;
+               i++;
+       }
+       return NULL;
+}
+
+static int is_percpu_timer(char *name)
 {
        static int timer_list_read;
-       static int percpu_hpet_start = INT_MAX, percpu_hpet_end = INT_MIN;
+       static int percpu_timer_start = INT_MAX, percpu_timer_end = INT_MIN;
        char *c;
-       long hpet_chan;
+       long timer_chan;
 
        if (!timer_list_read) {
                char file_name[20];
@@ -193,24 +233,23 @@ static int percpu_hpet_timer(char *name)
 
                while (fgets(ln, sizeof(ln), fp) != NULL)
                {
-                       c = strstr(ln, "Clock Event Device: hpet");
+                       c = is_timerlist_clockevent(ln);
                        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;
+                       timer_chan = strtol(c, NULL, 10);
+                       if (timer_chan < percpu_timer_start)
+                               percpu_timer_start = timer_chan;
+                       if (timer_chan > percpu_timer_end)
+                               percpu_timer_end = timer_chan;
                }
                fclose(fp);
        }
 
-       c = strstr(name, "hpet");
+       c = is_percpu_clockevent(name);
        if (!c)
                return 0;
 
@@ -218,8 +257,8 @@ static int percpu_hpet_timer(char *name)
        if (!isdigit(c[0]))
                return 0;
 
-       hpet_chan = strtol(c, NULL, 10);
-       if (percpu_hpet_start <= hpet_chan && hpet_chan <= percpu_hpet_end)
+       timer_chan = strtol(c, NULL, 10);
+       if (percpu_timer_start <= timer_chan && timer_chan <= percpu_timer_end)
                return 1;
 
        return 0;
@@ -317,7 +356,7 @@ static void do_proc_irq(void)
                        sprintf(line2, _("%s interrupt"), _("PS/2 
keyboard/mouse/touchpad"));
 
                /* skip per CPU timer interrupts */
-               if (percpu_hpet_timer(name))
+               if (is_percpu_timer(name))
                        delta = 0;
 
                if (nr > 0 && delta > 0)
-- 
1.7.0.4

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

Reply via email to