From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Bonzini Subject: Re: [PATCH v2 4/6] KVM: VMX: dynamise PLE window Date: Thu, 21 Aug 2014 10:26:38 +0200 Message-ID: <53F5AD3E.3050800@redhat.com> References: <1408567997-21222-1-git-send-email-rkrcmar@redhat.com> <1408567997-21222-5-git-send-email-rkrcmar@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-kernel@vger.kernel.org, Gleb Natapov , Raghavendra KT , Vinod Chegu , Hui-Zhi , Christian Borntraeger To: =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= , kvm@vger.kernel.org Return-path: In-Reply-To: <1408567997-21222-5-git-send-email-rkrcmar@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-Id: kvm.vger.kernel.org Il 20/08/2014 22:53, Radim Kr=C4=8Dm=C3=A1=C5=99 ha scritto: > Window is increased on every PLE exit and decreased on every sched_in= =2E > The idea is that we don't want to PLE exit if there is no preemption > going on. > We do this with sched_in() because it does not hold rq lock. >=20 > There are two new kernel parameters for changing the window: > ple_window_grow and ple_window_shrink > ple_window_grow affects the window on PLE exit and ple_window_shrink > does it on sched_in; depending on their value, the window is modifie= r > like this: (ple_window is kvm_intel's global) >=20 > ple_window_shrink/ | > ple_window_grow | PLE exit | sched_in > -------------------+--------------------+--------------------- > < 1 | =3D ple_window | =3D ple_window > < ple_window | *=3D ple_window_grow | /=3D ple_window_shrink > otherwise | +=3D ple_window_grow | -=3D ple_window_shrink >=20 > A third new parameter, ple_window_max, controls a maximal ple_window. > A minimum equals to ple_window. >=20 > Signed-off-by: Radim Kr=C4=8Dm=C3=A1=C5=99 > --- > arch/x86/kvm/vmx.c | 80 ++++++++++++++++++++++++++++++++++++++++++++= ++++++++-- > 1 file changed, 78 insertions(+), 2 deletions(-) >=20 > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 18e0e52..e63d7ac 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -125,14 +125,32 @@ module_param(nested, bool, S_IRUGO); > * 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. > */ > -#define KVM_VMX_DEFAULT_PLE_GAP 128 > -#define KVM_VMX_DEFAULT_PLE_WINDOW 4096 > +#define KVM_VMX_DEFAULT_PLE_GAP 128 > +#define KVM_VMX_DEFAULT_PLE_WINDOW 4096 > +#define KVM_VMX_DEFAULT_PLE_WINDOW_GROW 2 > +#define KVM_VMX_DEFAULT_PLE_WINDOW_SHRINK 0 > +#define KVM_VMX_DEFAULT_PLE_WINDOW_MAX \ > + INT_MAX / KVM_VMX_DEFAULT_PLE_WINDOW_GROW > + > static int ple_gap =3D KVM_VMX_DEFAULT_PLE_GAP; > module_param(ple_gap, int, S_IRUGO); > =20 > static int ple_window =3D KVM_VMX_DEFAULT_PLE_WINDOW; > module_param(ple_window, int, S_IRUGO); > =20 > +/* Default doubles per-vcpu window every exit. */ > +static int ple_window_grow =3D KVM_VMX_DEFAULT_PLE_WINDOW_GROW; > +module_param(ple_window_grow, int, S_IRUGO); > + > +/* Default resets per-vcpu window every exit to ple_window. */ > +static int ple_window_shrink =3D KVM_VMX_DEFAULT_PLE_WINDOW_SHRINK; > +module_param(ple_window_shrink, int, S_IRUGO); > + > +/* Default is to compute the maximum so we can never overflow. */ > +static int ple_window_actual_max =3D KVM_VMX_DEFAULT_PLE_WINDOW_MAX; > +static int ple_window_max =3D KVM_VMX_DEFAULT_PLE_WINDOW_MAX; > +module_param(ple_window_max, int, S_IRUGO); > + > extern const ulong vmx_return; > =20 > #define NR_AUTOLOAD_MSRS 8 > @@ -5679,12 +5697,66 @@ out: > return ret; > } > =20 > +static int __grow_ple_window(int val) > +{ > + if (ple_window_grow < 1) > + return ple_window; > + > + val =3D min(val, ple_window_actual_max); > + > + if (ple_window_grow < ple_window) > + val *=3D ple_window_grow; > + else > + val +=3D ple_window_grow; > + > + return val; > +} > + > +static int __shrink_ple_window(int val, int shrinker, int minimum) s/shrinker/factor/ or s/shrinker/param/ (shrinker has another meaning i= n the kernel). > +{ > + if (shrinker < 1) > + return ple_window; > + > + if (shrinker < ple_window) > + val /=3D shrinker; > + else > + val -=3D shrinker; > + > + return max(val, minimum); Any reason to use anything but ple_window as the minimum, even in update_ple_window_actual_max? > +} > + > +static void modify_ple_window(struct kvm_vcpu *vcpu, int grow) > +{ > + struct vcpu_vmx *vmx =3D to_vmx(vcpu); > + int new; > + > + if (grow) > + new =3D __grow_ple_window(vmx->ple_window); > + else > + new =3D __shrink_ple_window(vmx->ple_window, ple_window_shrink, > + ple_window); > + > + vmx->ple_window =3D max(new, ple_window); > +} > +#define grow_ple_window(vcpu) modify_ple_window(vcpu, 1) > +#define shrink_ple_window(vcpu) modify_ple_window(vcpu, 0) No macros please. :) Paolo > + > +static void update_ple_window_actual_max(void) > +{ > + ple_window_actual_max =3D > + __shrink_ple_window(max(ple_window_max, ple_window), > + ple_window_grow, INT_MIN); > +} > + > /* > * Indicate a busy-waiting vcpu in spinlock. We do not enable the PA= USE > * exiting, so only get here on cpu with PAUSE-Loop-Exiting. > */ > static int handle_pause(struct kvm_vcpu *vcpu) > { > + if (ple_gap) > + grow_ple_window(vcpu); > + > skip_emulated_instruction(vcpu); > kvm_vcpu_on_spin(vcpu); > =20 > @@ -8854,6 +8926,8 @@ static int vmx_check_intercept(struct kvm_vcpu = *vcpu, > =20 > void vmx_sched_in(struct kvm_vcpu *vcpu, int cpu) > { > + if (ple_gap) > + shrink_ple_window(vcpu); > } > =20 > static struct kvm_x86_ops vmx_x86_ops =3D { > @@ -9077,6 +9151,8 @@ static int __init vmx_init(void) > } else > kvm_disable_tdp(); > =20 > + update_ple_window_actual_max(); > + > return 0; > =20 > out7: >=20