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-changelog

[Xen-changelog] [xen-unstable] vmx: Add support for Pause-Loop Exiting

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vmx: Add support for Pause-Loop Exiting
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 08 Jul 2009 14:15:11 -0700
Delivery-date: Wed, 08 Jul 2009 14:15:25 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1246971995 -3600
# Node ID c1541cc7e9855a9bc4cb420b2e599a6c605441f1
# Parent  65a68b980cc3027b150a52c51e9a46fef8bb8a8d
vmx: Add support for Pause-Loop Exiting

New NHM processors will support Pause-Loop Exiting by adding 2
VM-execution control fields:
PLE_Gap    - upper bound on the amount of time between two successive
             executions of PAUSE in a loop.
PLE_Window - upper bound on the amount of time a guest is allowed to
             execute in a PAUSE loop

If the time, between this execution of PAUSE and previous one, exceeds
the PLE_Gap, processor consider this PAUSE belongs to a new loop.
Otherwise, processor determins the the total execution time of this
loop(since 1st PAUSE in this loop), and triggers a VM exit if total
time exceeds the PLE_Window.
* Refer SDM volume 3b section 21.6.13 & 22.1.3.

Pause-Loop Exiting can be used to detect Lock-Holder Preemption, where
one VP is sched-out after hold a spinlock, then other VPs for same
lock are sched-in to waste the CPU time.

Our tests indicate that most spinlocks are held for less than 2^12
cycles.  Performance tests show that with 2X LP over-commitment we can
get +2% perf improvement for kernel build(Even more perf gain with
more LPs).

Signed-off-by: Zhai Edwin <edwin.zhai@xxxxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c         |    5 +++--
 xen/arch/x86/hvm/vmx/vmcs.c        |   30 +++++++++++++++++++++++++++++-
 xen/arch/x86/hvm/vmx/vmx.c         |    7 +++++--
 xen/include/asm-x86/hvm/vmx/vmcs.h |    5 +++++
 xen/include/asm-x86/perfc_defn.h   |    2 ++
 5 files changed, 44 insertions(+), 5 deletions(-)

diff -r 65a68b980cc3 -r c1541cc7e985 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Tue Jul 07 14:01:30 2009 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c        Tue Jul 07 14:06:35 2009 +0100
@@ -1504,8 +1504,9 @@ asmlinkage void svm_vmexit_handler(struc
          * The guest is running a contended spinlock and we've detected it.
          * Do something useful, like reschedule the guest
          */
-       do_sched_op_compat(SCHEDOP_yield, 0);
-       break;
+        perfc_incr(pauseloop_exits);
+        do_sched_op_compat(SCHEDOP_yield, 0);
+        break;
 
     default:
     exit_and_crash:
diff -r 65a68b980cc3 -r c1541cc7e985 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Tue Jul 07 14:01:30 2009 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Tue Jul 07 14:06:35 2009 +0100
@@ -44,6 +44,20 @@ static int opt_unrestricted_guest_enable
 static int opt_unrestricted_guest_enabled = 1;
 boolean_param("unrestricted_guest", opt_unrestricted_guest_enabled);
 
+/*
+ * These two parameters are used to config the controls for Pause-Loop Exiting:
+ * ple_gap:    upper bound on the amount of time between two successive
+ *             executions of PAUSE in a loop.
+ * ple_window: upper bound on the amount of time a guest is allowed to execute
+ *             in a PAUSE loop.
+ * Time is measured based on a counter that runs at the same rate as the TSC,
+ * refer SDM volume 3b section 21.6.13 & 22.1.3.
+ */
+static unsigned int ple_gap = 41;
+integer_param("ple_gap", ple_gap);
+static unsigned int ple_window = 4096;
+integer_param("ple_window", ple_window);
+
 /* Dynamic (run-time adjusted) execution control flags. */
 u32 vmx_pin_based_exec_control __read_mostly;
 u32 vmx_cpu_based_exec_control __read_mostly;
@@ -140,7 +154,8 @@ static void vmx_init_vmcs_config(void)
         min = 0;
         opt = (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
                SECONDARY_EXEC_WBINVD_EXITING |
-               SECONDARY_EXEC_ENABLE_EPT);
+               SECONDARY_EXEC_ENABLE_EPT |
+               SECONDARY_EXEC_PAUSE_LOOP_EXITING);
         if ( opt_vpid_enabled )
             opt |= SECONDARY_EXEC_ENABLE_VPID;
         if ( opt_unrestricted_guest_enabled )
@@ -166,6 +181,13 @@ static void vmx_init_vmcs_config(void)
             _vmx_secondary_exec_control &=
                 ~(SECONDARY_EXEC_ENABLE_EPT |
                   SECONDARY_EXEC_UNRESTRICTED_GUEST);
+    }
+
+    if ( (_vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING) &&
+          ple_gap == 0 )
+    {
+        printk("Disable Pause-Loop Exiting.\n");
+        _vmx_secondary_exec_control &= ~ SECONDARY_EXEC_PAUSE_LOOP_EXITING;
     }
 
 #if defined(__i386__)
@@ -555,6 +577,12 @@ static int construct_vmcs(struct vcpu *v
     __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control);
     __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
     __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
+
+    if ( cpu_has_vmx_ple )
+    {
+        __vmwrite(PLE_GAP, ple_gap);
+        __vmwrite(PLE_WINDOW, ple_window);
+    }
 
     if ( cpu_has_vmx_secondary_exec_control )
         __vmwrite(SECONDARY_VM_EXEC_CONTROL,
diff -r 65a68b980cc3 -r c1541cc7e985 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Jul 07 14:01:30 2009 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Tue Jul 07 14:06:35 2009 +0100
@@ -2609,13 +2609,16 @@ asmlinkage void vmx_vmexit_handler(struc
     }
 
     case EXIT_REASON_MONITOR_TRAP_FLAG:
-    {
         v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
         __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control);
         if ( v->domain->debugger_attached && v->arch.hvm_vcpu.single_step )
             domain_pause_for_debugger();
         break;
-    }
+
+    case EXIT_REASON_PAUSE_INSTRUCTION:
+        perfc_incr(pauseloop_exits);
+        do_sched_op_compat(SCHEDOP_yield, 0);
+        break;
 
     default:
     exit_and_crash:
diff -r 65a68b980cc3 -r c1541cc7e985 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue Jul 07 14:01:30 2009 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue Jul 07 14:06:35 2009 +0100
@@ -171,6 +171,7 @@ extern u32 vmx_vmentry_control;
 #define SECONDARY_EXEC_ENABLE_VPID              0x00000020
 #define SECONDARY_EXEC_WBINVD_EXITING           0x00000040
 #define SECONDARY_EXEC_UNRESTRICTED_GUEST       0x00000080
+#define SECONDARY_EXEC_PAUSE_LOOP_EXITING       0x00000400
 extern u32 vmx_secondary_exec_control;
 
 extern bool_t cpu_has_vmx_ins_outs_instr_info;
@@ -200,6 +201,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
 #define vmx_unrestricted_guest(v)               \
     ((v)->arch.hvm_vmx.secondary_exec_control & \
      SECONDARY_EXEC_UNRESTRICTED_GUEST)
+#define cpu_has_vmx_ple \
+    (vmx_secondary_exec_control & SECONDARY_EXEC_PAUSE_LOOP_EXITING)
 
 /* GUEST_INTERRUPTIBILITY_INFO flags. */
 #define VMX_INTR_SHADOW_STI             0x00000001
@@ -279,6 +282,8 @@ enum vmcs_field {
     VM_ENTRY_INSTRUCTION_LEN        = 0x0000401a,
     TPR_THRESHOLD                   = 0x0000401c,
     SECONDARY_VM_EXEC_CONTROL       = 0x0000401e,
+    PLE_GAP                         = 0x00004020,
+    PLE_WINDOW                      = 0x00004022,
     VM_INSTRUCTION_ERROR            = 0x00004400,
     VM_EXIT_REASON                  = 0x00004402,
     VM_EXIT_INTR_INFO               = 0x00004404,
diff -r 65a68b980cc3 -r c1541cc7e985 xen/include/asm-x86/perfc_defn.h
--- a/xen/include/asm-x86/perfc_defn.h  Tue Jul 07 14:01:30 2009 +0100
+++ b/xen/include/asm-x86/perfc_defn.h  Tue Jul 07 14:06:35 2009 +0100
@@ -130,4 +130,6 @@ PERFCOUNTER(realmode_emulations, "realmo
 PERFCOUNTER(realmode_emulations, "realmode instructions emulated")
 PERFCOUNTER(realmode_exits,      "vmexits from realmode")
 
+PERFCOUNTER(pauseloop_exits, "vmexits from Pause-Loop Detection")
+
 /*#endif*/ /* __XEN_PERFC_DEFN_H__ */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] vmx: Add support for Pause-Loop Exiting, Xen patchbot-unstable <=