All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Liran Alon <liran.alon@oracle.com>
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	kvm@vger.kernel.org, "Wanpeng Li" <wanpengli@tencent.com>
Subject: Re: [PATCH 6/7] KVM: lapic: Clean up the code for handling of a pre-expired hv_timer
Date: Tue, 16 Apr 2019 09:39:25 -0700	[thread overview]
Message-ID: <20190416163925.GA21674@linux.intel.com> (raw)
In-Reply-To: <B074B4E8-77D1-4222-A49C-4DA02C263A4C@oracle.com>

On Mon, Apr 15, 2019 at 08:25:48PM +0300, Liran Alon wrote:
> 
> 
> > On 15 Apr 2019, at 19:32, Sean Christopherson <sean.j.christopherson@intel.com> wrote:
> > 
> > On Sun, Apr 14, 2019 at 03:15:41PM +0300, Liran Alon wrote:
> >> 
> >> 
> >>> On 12 Apr 2019, at 23:18, Sean Christopherson <sean.j.christopherson@intel.com> wrote:
> >>> 
> >>> Calling apic_timer_expired() is a nop when a timer interrupt is already
> >>> pending, i.e. there's no need to call apic_timer_expired() when there's
> >>> a pending interrupt and the hv_timer wants to pend its own interrupt.
> >>> Separate the two flows to make the code more readable and to avoid an
> >>> unnecessary function call and read to ktimer->pending.
> >> 
> >> In case timer is not periodic and r==1, atomic_read(&ktimer->pending) is not executed.
> >> 
> >>> 
> >>> Cc: Wanpeng Li <wanpengli@tencent.com>
> >>> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
> >>> ---
> >>> arch/x86/kvm/lapic.c | 9 ++++++---
> >>> 1 file changed, 6 insertions(+), 3 deletions(-)
> >>> 
> >>> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> >>> index 1d649a2af04c..f0be6f148a47 100644
> >>> --- a/arch/x86/kvm/lapic.c
> >>> +++ b/arch/x86/kvm/lapic.c
> >>> @@ -1703,9 +1703,12 @@ static bool start_hv_timer(struct kvm_lapic *apic)
> >>> 	 * the window.  For periodic timer, leave the hv timer running for
> >>> 	 * simplicity, and the deadline will be recomputed on the next vmexit.
> >>> 	 */
> >>> -	if (!apic_lvtt_period(apic) && (r || atomic_read(&ktimer->pending))) {
> >>> -		if (r)
> >>> -			apic_timer_expired(apic);
> >>> +	if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending))
> >>> +		return false;
> >>> +
> >>> +	/* set_hv_timer() returns '1' when the timer has already expired. */
> >>> +	if (r) {
> >>> +		apic_timer_expired(apic);
> >>> 		return false;
> >>> 	}
> >>> 
> >>> -- 
> >>> 2.21.0
> >>> 
> >> 
> >> First, I think you should emphasise in commit message that you have actually
> >> fixed a rare bug here.  In case timer is periodic but given
> >> ktimer->tscdeadline has already expired on host, we should call
> >> apic_timer_expired().
> > 
> > Heh, I actually didn't even catch that bug, I was simply cleaning up the
> > code because I had a hard time following the logic.
> 
> LOL. So you can put me in the Reported-by tag :P

Actually, thinking about this more, I believe the original behavior was
correct, if poorly documented.  More info below.

> >> In addition, when start_hv_timer() returns false, restart_apic_timer() just
> >> calls start_sw_timer() which use hrtimer instead of VMX preemption timer.
> >> Therefore, it seems a bit ineffective to me for start_hv_timer() to return
> >> false in case ktimer->pending or when ktimer->tscdeadline already expired.
> >> Shouldn’t we return true in these cases?
> > 
> > That also seemed weird to me.  Again, I had a hell of a time following the
> > intended logic and didn't want to break anything.  AFAICT, the motivation
> > for calling start_sw_timer() is to cancel the HV timer, and possibly to
> > ensure start_sw_period() is called when necessary.
> 
> I think the motivation is that if there is any reason why hardware
> accelerated timer (i.e. VMX preemption timer), can't be used to emulate the
> LAPIC timer, then utilise a software hrtimer based implementation instead.

My comment was regarding why start_hv_timer() returns was when the hv_timer
as already expired.

> This does align with why we return false when (!kvm_x86_ops->set_hv_timer) or
> (kvm_x86_ops->set_hv_timer() < 0).  However, this doesn’t align in case we
> have a (non-periodic timer and ktimer->pending) OR ktimer->tscdeadline
> already expired OR (!ktimer->tscdeadline).
> 
> In fact, note that start_sw_timer() early-exit when non-periodic timer and
> ktimer->pending… Same is also true for start_sw_tscdeadline() early-exit when
> (!ktimer->tscdeadline).
> 
> > But the latter will be
> > handled by virtue of checking "r" after apic_lvtt_period(), so this?
> > 
> > 	if (r) {
> > 		apic_timer_expired(apic);
> > 		ktimer->hv_timer_in_use = false;
> > 		return true;
> > 	}
> 
> I think I will just submit a patch to fix all the above examples I made as
> this just seems wrong to me.  Unless you find something I have missed. :P

When the timer is periodic, we're relying on the timer handler to invoke
advance_periodic_target_expiration() by way of kvm_lapic_expired_hv_timer().
That's why the original code only checks @r if apic_lvtt_period()==false,
i.e. to actually trigger a VMX preemption timer VM-Exit.  Note that the
return from set_hv_timer() is essentially a hint, e.g. VMX is perfectly
fine programming a preemption timer with a value of zero.

I think Paolo's suggestion of moving the logic up into restart_apic_timer()
is the way to go as it reduces the multiplexing down on start_hv_timer()'s
return value.


  reply	other threads:[~2019-04-16 16:39 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-12 20:18 [PATCH 0/7] KVM: lapic: Fix a variety of timer adv issues Sean Christopherson
2019-04-12 20:18 ` [PATCH 1/7] KVM: lapic: Hard cap the auto-calculated timer advancement Sean Christopherson
2019-04-14 10:22   ` Liran Alon
2019-04-12 20:18 ` [PATCH 2/7] KVM: lapic: Delay 1ns at a time when waiting for timer to "expire" Sean Christopherson
2019-04-14 11:25   ` Liran Alon
2019-04-15 16:11     ` Sean Christopherson
2019-04-15 17:06       ` Liran Alon
2019-04-16 11:02   ` Paolo Bonzini
2019-04-16 11:04     ` Liran Alon
2019-04-16 11:09       ` Paolo Bonzini
2019-04-12 20:18 ` [PATCH 3/7] KVM: lapic: Track lapic timer advance per vCPU Sean Christopherson
2019-04-14 11:29   ` Liran Alon
2019-04-12 20:18 ` [PATCH 4/7] KVM: lapic: Allow user to override auto-tuning of timer advancement Sean Christopherson
2019-04-14 11:35   ` Liran Alon
2019-04-15 16:23     ` Sean Christopherson
2019-04-15 17:10       ` Liran Alon
2019-04-12 20:18 ` [PATCH 5/7] KVM: lapic: Busy wait for timer to expire when using hv_timer Sean Christopherson
2019-04-14 11:47   ` Liran Alon
2019-04-12 20:18 ` [PATCH 6/7] KVM: lapic: Clean up the code for handling of a pre-expired hv_timer Sean Christopherson
2019-04-14 12:15   ` Liran Alon
2019-04-15 16:32     ` Sean Christopherson
2019-04-15 17:25       ` Liran Alon
2019-04-16 16:39         ` Sean Christopherson [this message]
2019-04-16 16:48           ` Liran Alon
2019-04-16 17:27             ` Sean Christopherson
2019-04-16 17:27               ` Liran Alon
2019-04-16 11:14     ` Paolo Bonzini
2019-04-12 20:18 ` [PATCH 7/7] KVM: VMX: Skip delta_tsc shift-and-divide if the dividend is zero Sean Christopherson
2019-04-14 12:21   ` Liran Alon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190416163925.GA21674@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=liran.alon@oracle.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=wanpengli@tencent.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.