[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [LINUX] Implement the idle=poll option in the kernel when running on Xen.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1167833322 0
# Node ID bf25488db8ebbc513d7f20e12a514691e54b6436
# Parent  55be48549bb11b38377f3f6c0fc0c37ea7b0d9c2
[LINUX] Implement the idle=poll option in the kernel when running on Xen.

This causes the kernel to use a polling loop rather than hypercall
down to block. I have found this useful to profile the amount of sleep
cycles when using xenoprof, there may be other uses.

Signed-off-by: Amitabha Roy <amitabha.roy@xxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c   |   43 ++++++++++++++---
 linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c |   45 +++++++++++++++---
 2 files changed, 76 insertions(+), 12 deletions(-)

diff -r 55be48549bb1 -r bf25488db8eb 
linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c       Wed Jan 03 
13:55:53 2007 +0000
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c       Wed Jan 03 
14:08:42 2007 +0000
@@ -101,8 +101,24 @@ void enable_hlt(void)
 
 EXPORT_SYMBOL(enable_hlt);
 
-/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-void xen_idle(void)
+/*
+ * On SMP it's slightly faster (but much more power-consuming!)
+ * to poll the ->work.need_resched flag instead of waiting for the
+ * cross-CPU IPI to arrive. Use this option with caution.
+ */
+static void poll_idle(void)
+{
+       local_irq_enable();
+
+       asm volatile(
+               "2:"
+               "testl %0, %1;"
+               "rep; nop;"
+               "je 2b;"
+               : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
+}
+
+static void xen_idle(void)
 {
        local_irq_disable();
 
@@ -162,7 +178,7 @@ void cpu_idle(void)
                                play_dead();
 
                        __get_cpu_var(irq_stat).idle_timestamp = jiffies;
-                       xen_idle();
+                       pm_idle();
                }
                preempt_enable_no_resched();
                schedule();
@@ -198,9 +214,24 @@ void cpu_idle_wait(void)
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
-/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
-/* Always use xen_idle() instead. */
-void __devinit select_idle_routine(const struct cpuinfo_x86 *c) {}
+void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
+{
+       if (!pm_idle)
+               pm_idle = xen_idle;
+}
+
+static int __init idle_setup (char *str)
+{
+       if (!strncmp(str, "poll", 4)) {
+               printk("using polling idle threads.\n");
+               pm_idle = poll_idle;
+       }
+
+       boot_option_idle_override = 1;
+       return 1;
+}
+
+__setup("idle=", idle_setup);
 
 void show_regs(struct pt_regs * regs)
 {
diff -r 55be48549bb1 -r bf25488db8eb 
linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Wed Jan 03 
13:55:53 2007 +0000
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c     Wed Jan 03 
14:08:42 2007 +0000
@@ -119,8 +119,26 @@ void exit_idle(void)
        __exit_idle();
 }
 
-/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-void xen_idle(void)
+/*
+ * On SMP it's slightly faster (but much more power-consuming!)
+ * to poll the ->need_resched flag instead of waiting for the
+ * cross-CPU IPI to arrive. Use this option with caution.
+ */
+static void poll_idle(void)
+{
+       local_irq_enable();
+
+       asm volatile(
+               "2:"
+               "testl %0,%1;"
+               "rep; nop;"
+               "je 2b;"
+               : :
+               "i" (_TIF_NEED_RESCHED),
+               "m" (current_thread_info()->flags));
+}
+
+static void xen_idle(void)
 {
        local_irq_disable();
 
@@ -171,7 +189,7 @@ void cpu_idle (void)
                        if (cpu_is_offline(smp_processor_id()))
                                play_dead();
                        enter_idle();
-                       xen_idle();
+                       pm_idle();
                        __exit_idle();
                }
 
@@ -210,9 +228,24 @@ void cpu_idle_wait(void)
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
-/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
-/* Always use xen_idle() instead. */
-void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) {}
+void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 
+{
+       if (!pm_idle)
+               pm_idle = xen_idle;
+}
+
+static int __init idle_setup (char *str)
+{
+       if (!strncmp(str, "poll", 4)) {
+               printk("using polling idle threads.\n");
+               pm_idle = poll_idle;
+       }
+
+       boot_option_idle_override = 1;
+       return 1;
+}
+
+__setup("idle=", idle_setup);
 
 /* Prints also some state that isn't saved in the pt_regs */ 
 void __show_regs(struct pt_regs * regs)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.