diff mbox

[09/37] KVM: arm64: Move debug dirty flag calculation out of world switch

Message ID 20171012104141.26902-10-christoffer.dall@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Christoffer Dall Oct. 12, 2017, 10:41 a.m. UTC
There is no need to figure out inside the world-switch if we should
save/restore the debug registers or not, we can might as well do that in
the higher level debug setup code, making it easier to optimize down the
line.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 arch/arm64/kvm/debug.c        | 9 +++++++++
 arch/arm64/kvm/hyp/debug-sr.c | 6 ------
 2 files changed, 9 insertions(+), 6 deletions(-)

Comments

Andrew Jones Nov. 7, 2017, 2:09 p.m. UTC | #1
On Thu, Oct 12, 2017 at 12:41:13PM +0200, Christoffer Dall wrote:
> There is no need to figure out inside the world-switch if we should
> save/restore the debug registers or not, we can might as well do that in
> the higher level debug setup code, making it easier to optimize down the
> line.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  arch/arm64/kvm/debug.c        | 9 +++++++++
>  arch/arm64/kvm/hyp/debug-sr.c | 6 ------
>  2 files changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index dbadfaf..62550de19 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -193,6 +193,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
>  	if (trap_debug)
>  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
>  
> +	/*
> +	 * If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
> +	 * a full save/restore cycle.

The commit message implies testing KVM_ARM64_DEBUG_DIRTY, but it only
tests KDE and MDE.

> +	 */
> +	if ((vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_KDE) ||
> +	    (vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_MDE))

nit: could also write as

 if (vcpu_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))

> +		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
> +

It looks like there's only one flag for debug_flags - this dirty flag,
which I guess is also used to trigger trapping. So maybe this could be a
second flag of a "lazy state" field, as I suggested earlier?

> +
>  	trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
>  	trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1));
>  }
> diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
> index f5154ed..0fc0758 100644
> --- a/arch/arm64/kvm/hyp/debug-sr.c
> +++ b/arch/arm64/kvm/hyp/debug-sr.c
> @@ -172,12 +172,6 @@ void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
>  
>  void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
>  {
> -	/* If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
> -	 * a full save/restore cycle. */
> -	if ((vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_KDE) ||
> -	    (vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_MDE))
> -		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
> -
>  	__debug_save_state(vcpu, &vcpu->arch.host_debug_state.regs,
>  			   kern_hyp_va(vcpu->arch.host_cpu_context));
>  	__debug_save_spe()(&vcpu->arch.host_debug_state.pmscr_el1);
> -- 
> 2.9.0
>

Also, while grepping, I noticed __debug_cond_restore_host_state() unsets
KVM_ARM64_DEBUG_DIRTY on that condition that it's set. A micro
optimization could be to do it unconditionally, removing the branch.

Thanks,
drew
Yury Norov Nov. 25, 2017, 8:09 a.m. UTC | #2
On Tue, Nov 07, 2017 at 03:09:19PM +0100, Andrew Jones wrote:
> On Thu, Oct 12, 2017 at 12:41:13PM +0200, Christoffer Dall wrote:
> > There is no need to figure out inside the world-switch if we should
> > save/restore the debug registers or not, we can might as well do that in
> > the higher level debug setup code, making it easier to optimize down the
> > line.
> > 
> > Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> > ---
> >  arch/arm64/kvm/debug.c        | 9 +++++++++
> >  arch/arm64/kvm/hyp/debug-sr.c | 6 ------
> >  2 files changed, 9 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> > index dbadfaf..62550de19 100644
> > --- a/arch/arm64/kvm/debug.c
> > +++ b/arch/arm64/kvm/debug.c
> > @@ -193,6 +193,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
> >  	if (trap_debug)
> >  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
> >  
> > +	/*
> > +	 * If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
> > +	 * a full save/restore cycle.
> 
> The commit message implies testing KVM_ARM64_DEBUG_DIRTY, but it only
> tests KDE and MDE.
> 
> > +	 */
> > +	if ((vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_KDE) ||
> > +	    (vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_MDE))
> 
> nit: could also write as
> 
>  if (vcpu_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))
 
Another nit: two empty lines at the end of this chunk.

> > +		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
> > +
> 
> It looks like there's only one flag for debug_flags - this dirty flag,
> which I guess is also used to trigger trapping. So maybe this could be a
> second flag of a "lazy state" field, as I suggested earlier?
> 
> > +
> >  	trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
> >  	trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1));
> >  }
> > diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
> > index f5154ed..0fc0758 100644
> > --- a/arch/arm64/kvm/hyp/debug-sr.c
> > +++ b/arch/arm64/kvm/hyp/debug-sr.c
> > @@ -172,12 +172,6 @@ void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
> >  
> >  void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
> >  {
> > -	/* If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
> > -	 * a full save/restore cycle. */
> > -	if ((vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_KDE) ||
> > -	    (vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_MDE))
> > -		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
> > -
> >  	__debug_save_state(vcpu, &vcpu->arch.host_debug_state.regs,
> >  			   kern_hyp_va(vcpu->arch.host_cpu_context));
> >  	__debug_save_spe()(&vcpu->arch.host_debug_state.pmscr_el1);
> > -- 
> > 2.9.0
> >
> 
> Also, while grepping, I noticed __debug_cond_restore_host_state() unsets
> KVM_ARM64_DEBUG_DIRTY on that condition that it's set. A micro
> optimization could be to do it unconditionally, removing the branch.
> 
> Thanks,
> drew
Christoffer Dall Dec. 1, 2017, 5:25 p.m. UTC | #3
On Tue, Nov 07, 2017 at 03:09:19PM +0100, Andrew Jones wrote:
> On Thu, Oct 12, 2017 at 12:41:13PM +0200, Christoffer Dall wrote:
> > There is no need to figure out inside the world-switch if we should
> > save/restore the debug registers or not, we can might as well do that in
> > the higher level debug setup code, making it easier to optimize down the
> > line.
> > 
> > Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> > ---
> >  arch/arm64/kvm/debug.c        | 9 +++++++++
> >  arch/arm64/kvm/hyp/debug-sr.c | 6 ------
> >  2 files changed, 9 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> > index dbadfaf..62550de19 100644
> > --- a/arch/arm64/kvm/debug.c
> > +++ b/arch/arm64/kvm/debug.c
> > @@ -193,6 +193,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
> >  	if (trap_debug)
> >  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
> >  
> > +	/*
> > +	 * If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
> > +	 * a full save/restore cycle.
> 
> The commit message implies testing KVM_ARM64_DEBUG_DIRTY, but it only
> tests KDE and MDE.
> 

You meant the comment, right?

> > +	 */
> > +	if ((vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_KDE) ||
> > +	    (vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_MDE))
> 
> nit: could also write as
> 
>  if (vcpu_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))
> 

I actually prefer it the other way, and I think the compiler will figure
out what to do in terms of efficiency.

> > +		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
> > +
> 
> It looks like there's only one flag for debug_flags - this dirty flag,
> which I guess is also used to trigger trapping. So maybe this could be a
> second flag of a "lazy state" field, as I suggested earlier?
> 

I'm going to leave this one for now, but we can improve that later on if
we want to save a little space in the vcpu struct, or rather if we want
to rearrange things to make frequently accessed fields fit in the same
cache line.

Thanks,
-Christoffer
Andrew Jones Dec. 3, 2017, 1:17 p.m. UTC | #4
On Fri, Dec 01, 2017 at 06:25:46PM +0100, Christoffer Dall wrote:
> On Tue, Nov 07, 2017 at 03:09:19PM +0100, Andrew Jones wrote:
> > On Thu, Oct 12, 2017 at 12:41:13PM +0200, Christoffer Dall wrote:
> > > There is no need to figure out inside the world-switch if we should
> > > save/restore the debug registers or not, we can might as well do that in
> > > the higher level debug setup code, making it easier to optimize down the
> > > line.
> > > 
> > > Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> > > ---
> > >  arch/arm64/kvm/debug.c        | 9 +++++++++
> > >  arch/arm64/kvm/hyp/debug-sr.c | 6 ------
> > >  2 files changed, 9 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> > > index dbadfaf..62550de19 100644
> > > --- a/arch/arm64/kvm/debug.c
> > > +++ b/arch/arm64/kvm/debug.c
> > > @@ -193,6 +193,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
> > >  	if (trap_debug)
> > >  		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
> > >  
> > > +	/*
> > > +	 * If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
> > > +	 * a full save/restore cycle.
> > 
> > The commit message implies testing KVM_ARM64_DEBUG_DIRTY, but it only
> > tests KDE and MDE.
> > 
> 
> You meant the comment, right?

yup

> 
> > > +	 */
> > > +	if ((vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_KDE) ||
> > > +	    (vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_MDE))
> > 
> > nit: could also write as
> > 
> >  if (vcpu_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))
> > 
> 
> I actually prefer it the other way, and I think the compiler will figure
> out what to do in terms of efficiency.

I won't argue about code aesthetics (although I disagree here :-). I will
point out that in this case the compiler will no doubt do the right thing,
as vcpu_sys_reg() is just a macro, but for a pointer taking function in
general there would be potential to get both calls emitted, as the
compiler wouldn't be sure there would be no side effect.

> 
> > > +		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
> > > +
> > 
> > It looks like there's only one flag for debug_flags - this dirty flag,
> > which I guess is also used to trigger trapping. So maybe this could be a
> > second flag of a "lazy state" field, as I suggested earlier?
> > 
> 
> I'm going to leave this one for now, but we can improve that later on if
> we want to save a little space in the vcpu struct, or rather if we want
> to rearrange things to make frequently accessed fields fit in the same
> cache line.
>

OK

Thanks,
drew
diff mbox

Patch

diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index dbadfaf..62550de19 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -193,6 +193,15 @@  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 	if (trap_debug)
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+	/*
+	 * If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
+	 * a full save/restore cycle.
+	 */
+	if ((vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_KDE) ||
+	    (vcpu_sys_reg(vcpu, MDSCR_EL1) & DBG_MDSCR_MDE))
+		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+
+
 	trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
 	trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index f5154ed..0fc0758 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -172,12 +172,6 @@  void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
 
 void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
 {
-	/* If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY is set, perform
-	 * a full save/restore cycle. */
-	if ((vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_KDE) ||
-	    (vcpu->arch.ctxt.sys_regs[MDSCR_EL1] & DBG_MDSCR_MDE))
-		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
-
 	__debug_save_state(vcpu, &vcpu->arch.host_debug_state.regs,
 			   kern_hyp_va(vcpu->arch.host_cpu_context));
 	__debug_save_spe()(&vcpu->arch.host_debug_state.pmscr_el1);