WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH]cpuidle: mwait on softirq_pending & remove wakeup ipi

To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH]cpuidle: mwait on softirq_pending & remove wakeup ipis
From: "Wei, Gang" <gang.wei@xxxxxxxxx>
Date: Thu, 1 Apr 2010 20:38:27 +0800
Accept-language: zh-CN, en-US
Acceptlanguage: zh-CN, en-US
Cc: "Yu, Ke" <ke.yu@xxxxxxxxx>, Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, Jan Beulich <JBeulich@xxxxxxxxxx>
Delivery-date: Thu, 01 Apr 2010 05:39:21 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcrRmDo/k+uf8Zo1QYCEX86Tg1rBCQ==
Thread-topic: [PATCH]cpuidle: mwait on softirq_pending & remove wakeup ipis
cpuidle: mwait on softirq_pending & remove wakeup ipis

For cpu which enter deep C state via monitor/mwait, wakeup can be done by 
writing to the monitored memory. So once monitor softirq_pending, we can remove 
the redundant ipis.

Signed-off-by: Yu Ke <ke.yu@xxxxxxxxx>
Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>

diff -r 132ac04cbdba xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c      Tue Mar 09 18:18:19 2010 +0000
+++ b/xen/arch/x86/acpi/cpu_idle.c      Thu Mar 11 14:07:54 2010 +0800
@@ -69,6 +69,14 @@ boolean_param("lapic_timer_c2_ok", local
 
 static struct acpi_processor_power *__read_mostly processor_powers[NR_CPUS];
 
+static char* acpi_cstate_method_name[] =
+{
+    "NONE",
+    "SYSIO",
+    "FFH",
+    "HALT"
+};
+
 static void print_acpi_power(uint32_t cpu, struct acpi_processor_power *power)
 {
     uint32_t i, idle_usage = 0;
@@ -92,6 +100,7 @@ static void print_acpi_power(uint32_t cp
         printk("type[C%d] ", power->states[i].type);
         printk("latency[%03d] ", power->states[i].latency);
         printk("usage[%08d] ", power->states[i].usage);
+        printk("method[%5s] ", 
acpi_cstate_method_name[power->states[i].entry_method]);
         printk("duration[%"PRId64"]\n", res);
     }
     printk("    C0:\tusage[%08d] duration[%"PRId64"]\n",
@@ -140,11 +149,43 @@ static void acpi_safe_halt(void)
 
 #define MWAIT_ECX_INTERRUPT_BREAK   (0x1)
 
+/*
+ * The bit is set iff cpu use monitor/mwait to enter C state
+ * with this flag set, CPU can be waken up from C state
+ * by writing to specific memory address, instead of sending IPI
+ */
+static cpumask_t cpuidle_mwait_flags;
+
+void cpuidle_wakeup_mwait(cpumask_t *mask)
+{
+    cpumask_t target;
+    int cpu;
+
+    cpus_and(target, *mask, cpuidle_mwait_flags);
+
+    /* cpu is 'mwait'ing at softirq_pending,
+       writing to it will wake up CPU */
+    for_each_cpu_mask(cpu, target)
+        set_bit(TIMER_SOFTIRQ, &softirq_pending(cpu));
+
+    cpus_andnot(*mask, *mask, cpuidle_mwait_flags);
+}
+
 static void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 {
-    __monitor((void *)current, 0, 0);
+    int cpu = smp_processor_id();
+
+    __monitor((void *)&softirq_pending(cpu), 0, 0);
+
     smp_mb();
-    __mwait(eax, ecx);
+    if (!softirq_pending(cpu))
+    {
+        cpu_set(cpu, cpuidle_mwait_flags);
+
+        __mwait(eax, ecx);
+
+        cpu_clear(cpu, cpuidle_mwait_flags);
+    }
 }
 
 static void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
diff -r 132ac04cbdba xen/arch/x86/hpet.c
--- a/xen/arch/x86/hpet.c       Tue Mar 09 18:18:19 2010 +0000
+++ b/xen/arch/x86/hpet.c       Thu Mar 11 14:07:54 2010 +0800
@@ -165,6 +165,8 @@ static int evt_do_broadcast(cpumask_t ma
         raise_softirq(TIMER_SOFTIRQ);
         ret = 1;
     }
+
+    cpuidle_wakeup_mwait(&mask);
 
     if ( !cpus_empty(mask) )
     {
diff -r 132ac04cbdba xen/include/xen/cpuidle.h
--- a/xen/include/xen/cpuidle.h Tue Mar 09 18:18:19 2010 +0000
+++ b/xen/include/xen/cpuidle.h Thu Mar 11 14:07:54 2010 +0800
@@ -86,6 +86,8 @@ extern struct cpuidle_governor *cpuidle_
 extern struct cpuidle_governor *cpuidle_current_governor;
 void cpuidle_disable_deep_cstate(void);
 
+extern void cpuidle_wakeup_mwait(cpumask_t *mask);
+
 #define CPUIDLE_DRIVER_STATE_START  1
 
 #endif /* _XEN_CPUIDLE_H */

Attachment: cpuidle_mwait_fix_v2.patch
Description: cpuidle_mwait_fix_v2.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH]cpuidle: mwait on softirq_pending & remove wakeup ipis, Wei, Gang <=