diff -purN img/2.6_kernel/arch/arm/kernel/irq.c 2.6_kernel/arch/arm/kernel/irq.c --- img/2.6_kernel/arch/arm/kernel/irq.c 2008-04-03 22:43:09.000000000 -0500 +++ 2.6_kernel/arch/arm/kernel/irq.c 2008-07-14 15:09:48.000000000 -0500 @@ -122,6 +131,8 @@ asmlinkage void __exception asm_do_IRQ(u irq_enter(); + kstat_irq_stamp(); + desc_handle_irq(irq, desc); /* AT91 specific workaround */ diff -purN img/2.6_kernel/drivers/cpuidle/governors/menu.c 2.6_kernel/drivers/cpuidle/governors/menu.c --- img/2.6_kernel/drivers/cpuidle/governors/menu.c 2008-07-04 15:31:23.000000000 -0500 +++ 2.6_kernel/drivers/cpuidle/governors/menu.c 2008-07-14 15:22:55.000000000 -0500 @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -70,6 +71,7 @@ static void menu_reflect(struct cpuidle_ unsigned int measured_us = cpuidle_get_last_residency(dev) + data->elapsed_us; struct cpuidle_state *target = &dev->states[last_idx]; + const unsigned int cpu = smp_processor_id(); /* * Ugh, this idle state doesn't support residency measurements, so we @@ -92,6 +94,10 @@ static void menu_reflect(struct cpuidle_ data->elapsed_us = -1; data->predicted_us = max(measured_us, data->last_measured_us); } + + /* Guess & factor in interrupt wake rate */ + data->predicted_us = min((s64)data->predicted_us, ktime_to_us( + ktime_sub(kstat_cpu(cpu).irq_now, kstat_cpu(cpu).irq_last))); } /** diff -purN img/2.6_kernel/include/linux/kernel_stat.h 2.6_kernel/include/linux/kernel_stat.h --- img/2.6_kernel/include/linux/kernel_stat.h 2008-04-03 21:51:50.000000000 -0500 +++ 2.6_kernel/include/linux/kernel_stat.h 2008-07-14 13:11:09.000000000 -0500 @@ -7,6 +7,7 @@ #include #include #include +#include /* * 'kernel_stat.h' contains the definitions needed for doing @@ -29,6 +30,8 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; unsigned int irqs[NR_IRQS]; + ktime_t irq_now; + ktime_t irq_last; }; DECLARE_PER_CPU(struct kernel_stat, kstat); @@ -52,6 +55,16 @@ static inline int kstat_irqs(int irq) return sum; } +/* + * Provide hook to try and understand interrupt rate on a processor + */ +static inline void kstat_irq_stamp(void) +{ + const unsigned int cpu = smp_processor_id(); + kstat_cpu(cpu).irq_last = kstat_cpu(cpu).irq_now; + kstat_cpu(cpu).irq_now = ktime_get(); +} + extern void account_user_time(struct task_struct *, cputime_t); extern void account_user_time_scaled(struct task_struct *, cputime_t); extern void account_system_time(struct task_struct *, int, cputime_t);