Hi,
Any comments on the following?
I'm finding with high interrupt rates for some USB devices the menu governo=
r guesses wrong enough that throughput drops.
With the below tweak tests with fixed data sizes which were taking 12s to c=
omplete drop back to 9s. Also my standby idle doesn't change before and af=
ter activity with our with out the patch.
What it does is simply timestamp incoming irqs, then in the menu governor w=
ill use current & last irq time delta to refine its guess as to how long sl=
eep will happen.
Regards,
Richard W.
Signed-off-by: Richard Woodruff <r-woodruff2@ti.com>
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.0000000=
00 -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/drive=
rs/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.0000000=
00 -0500
@@ -7,6 +7,7 @@
*/
#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
#include <linux/cpuidle.h>
#include <linux/latency.h>
#include <linux/time.h>
@@ -70,6 +71,7 @@ static void menu_reflect(struct cpuidle_
unsigned int measured_us =3D
cpuidle_get_last_residency(dev) + data->elapsed_us;
struct cpuidle_state *target =3D &dev->states[last_idx];
+ const unsigned int cpu =3D 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 =3D -1;
data->predicted_us =3D max(measured_us, data->last_measured=
_us);
}
+
+ /* Guess & factor in interrupt wake rate */
+ data->predicted_us =3D 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/li=
nux/kernel_stat.h
--- img/2.6_kernel/include/linux/kernel_stat.h 2008-04-03 21:51:50.0000000=
00 -0500
+++ 2.6_kernel/include/linux/kernel_stat.h 2008-07-14 13:11:09.0000000=
00 -0500
@@ -7,6 +7,7 @@
#include <linux/percpu.h>
#include <linux/cpumask.h>
#include <asm/cputime.h>
+#include <linux/hrtimer.h>
/*
* '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 =3D smp_processor_id();
+ kstat_cpu(cpu).irq_last =3D kstat_cpu(cpu).irq_now;
+ kstat_cpu(cpu).irq_now =3D 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);| Al Viro | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Greg KH | [2.6.22.2 review 05/84] Fix deadlocks in sparc serial console. |
| Linus Torvalds | Linux 2.6.27-rc8 |
| Greg Kroah-Hartman | [PATCH 006/196] Chinese: add translation of oops-tracing.txt |
git: | |
| Natalie Protasevich | [BUG] New Kernel Bugs |
| Jarek Poplawski | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Linus Torvalds | Re: [GIT]: Networking |
| Gerrit Renker | [PATCH 0/37] dccp: Feature negotiation - last call for comments |
| Manuel Bouyer | Re: Interactive performance in -current |
| YAMAMOTO Takashi | Re: statvfs(2) replacement for statfs(2) patch |
| Nathan Langford | microkernels |
| Garrett D'Amore | Re: wsmux inject |
