All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	yang.zhang.wz@gmail.com, feng.wu@intel.com, rkrcmar@redhat.com
Subject: Re: [PATCH 3/3] KVM: x86: do not scan IRR twice on APICv vmentry
Date: Wed, 28 Sep 2016 17:00:08 +0300	[thread overview]
Message-ID: <20160928165515-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <1475011213-34225-4-git-send-email-pbonzini@redhat.com>

On Tue, Sep 27, 2016 at 11:20:13PM +0200, Paolo Bonzini wrote:
> Calling apic_find_highest_irr results in IRR being scanned twice,
> once in vmx_sync_pir_from_irr and once in apic_search_irr.  Change
> vcpu_enter_guest to use sync_pir_from_irr (with a new argument to
> trigger the RVI write), and let sync_pir_from_irr get the new RVI
> directly from kvm_apic_update_irr.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Acked-by: Michael S. Tsirkin <mst@redhat.com>

> ---
>  arch/x86/include/asm/kvm_host.h |  2 +-
>  arch/x86/kvm/lapic.c            | 25 ++++++++++++++++---------
>  arch/x86/kvm/lapic.h            |  4 ++--
>  arch/x86/kvm/svm.c              |  2 +-
>  arch/x86/kvm/vmx.c              | 25 ++++++++++++++-----------
>  arch/x86/kvm/x86.c              |  7 +++----
>  6 files changed, 37 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 4b20f7304b9c..f73eea243567 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -941,7 +941,7 @@ struct kvm_x86_ops {
>  	void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set);
>  	void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
>  	void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
> -	void (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
> +	void (*sync_pir_to_irr)(struct kvm_vcpu *vcpu, bool sync_rvi);
>  	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
>  	int (*get_tdp_level)(void);
>  	u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index be8b7ad56dd1..85b79b90e3d0 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -317,7 +317,7 @@ static int find_highest_vector(void *bitmap)
>  	     vec >= 0; vec -= APIC_VECTORS_PER_REG) {
>  		reg = bitmap + REG_POS(vec);
>  		if (*reg)
> -			return fls(*reg) - 1 + vec;
> +			return __fls(*reg) + vec;
>  	}
>  
>  	return -1;

We checked that *reg is != 0 so __fls is safe.
It's a correct micro-optimization but why stick it in this patch?

> @@ -337,25 +337,32 @@ static u8 count_vectors(void *bitmap)
>  	return count;
>  }
>  
> -void __kvm_apic_update_irr(u32 *pir, void *regs)
> +int __kvm_apic_update_irr(u32 *pir, void *regs)
>  {
> -	u32 i, pir_val;
> +	u32 i, vec;
> +	u32 pir_val, irr_val;
> +	int max_irr = -1;
>  
> -	for (i = 0; i <= 7; i++) {
> +	for (i = vec = 0; i <= 7; i++, vec += 32) {
>  		pir_val = READ_ONCE(pir[i]);
> +		irr_val = *((u32 *)(regs + APIC_IRR + i * 0x10));
>  		if (pir_val) {
> -			pir_val = xchg(&pir[i], 0);
> -			*((u32 *)(regs + APIC_IRR + i * 0x10)) |= pir_val;
> +			irr_val |= xchg(&pir[i], 0);
> +			*((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val;
>  		}
> +		if (irr_val)
> +			max_irr = __fls(irr_val) + vec;
>  	}
> +
> +	return max_irr;
>  }
>  EXPORT_SYMBOL_GPL(__kvm_apic_update_irr);
>  
> -void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir)
> +int kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir)
>  {
>  	struct kvm_lapic *apic = vcpu->arch.apic;
>  
> -	__kvm_apic_update_irr(pir, apic->regs);
> +	return __kvm_apic_update_irr(pir, apic->regs);
>  }
>  EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
>  
> @@ -376,7 +383,7 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic)
>  		return -1;
>  
>  	if (apic->vcpu->arch.apicv_active)
> -		kvm_x86_ops->sync_pir_to_irr(apic->vcpu);
> +		kvm_x86_ops->sync_pir_to_irr(apic->vcpu, false);
>  	result = apic_search_irr(apic);
>  	ASSERT(result == -1 || result >= 16);
>  
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index f60d01c29d51..fc72828c3782 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -70,8 +70,8 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
>  bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
>  			   int short_hand, unsigned int dest, int dest_mode);
>  
> -void __kvm_apic_update_irr(u32 *pir, void *regs);
> -void kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
> +int __kvm_apic_update_irr(u32 *pir, void *regs);
> +int kvm_apic_update_irr(struct kvm_vcpu *vcpu, u32 *pir);
>  int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
>  		     struct dest_map *dest_map);
>  int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index 9b4221471e3d..60e53fa2b554 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -4383,7 +4383,7 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
>  	return;
>  }
>  
> -static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu)
> +static void svm_sync_pir_to_irr(struct kvm_vcpu *vcpu, bool sync_rvi)
>  {
>  	return;
>  }
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 207b9aa32915..1edefab54d01 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -4852,17 +4852,6 @@ static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
>  		kvm_vcpu_kick(vcpu);
>  }
>  
> -static void vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu)
> -{
> -	struct vcpu_vmx *vmx = to_vmx(vcpu);
> -
> -	if (!pi_test_on(&vmx->pi_desc) ||
> -	    !pi_test_and_clear_on(&vmx->pi_desc))
> -		return;
> -
> -	kvm_apic_update_irr(vcpu, vmx->pi_desc.pir);
> -}
> -
>  /*
>   * Set up the vmcs's constant host-state fields, i.e., host-state fields that
>   * will not change in the lifetime of the guest.
> @@ -8609,6 +8598,20 @@ static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
>  	}
>  }
>  
> +static void vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu, bool sync_rvi)
> +{
> +	struct vcpu_vmx *vmx = to_vmx(vcpu);
> +	int max_irr;
> +
> +	if (!pi_test_on(&vmx->pi_desc) ||
> +	    !pi_test_and_clear_on(&vmx->pi_desc))
> +		return;
> +
> +	max_irr = kvm_apic_update_irr(vcpu, vmx->pi_desc.pir);
> +	if (sync_rvi)
> +		vmx_hwapic_irr_update(vcpu, max_irr);
> +}
> +
>  static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
>  {
>  	if (!kvm_vcpu_apicv_active(vcpu))
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 604cfbfc5bee..148e14fdc55d 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2821,7 +2821,7 @@ static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
>  				    struct kvm_lapic_state *s)
>  {
>  	if (vcpu->arch.apicv_active)
> -		kvm_x86_ops->sync_pir_to_irr(vcpu);
> +		kvm_x86_ops->sync_pir_to_irr(vcpu, false);
>  
>  	return kvm_apic_get_state(vcpu, s);
>  }
> @@ -6448,7 +6448,7 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
>  		kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
>  	else {
>  		if (vcpu->arch.apicv_active)
> -			kvm_x86_ops->sync_pir_to_irr(vcpu);
> +			kvm_x86_ops->sync_pir_to_irr(vcpu, false);
>  		kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
>  	}
>  	bitmap_or((ulong *)eoi_exit_bitmap, vcpu->arch.ioapic_handled_vectors,
> @@ -6611,8 +6611,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
>  		 * virtual interrupt delivery.
>  		 */
>  		if (vcpu->arch.apicv_active)
> -			kvm_x86_ops->hwapic_irr_update(vcpu,
> -				kvm_lapic_find_highest_irr(vcpu));
> +			kvm_x86_ops->sync_pir_to_irr(vcpu, true);
>  	}
>  
>  	if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
> -- 
> 1.8.3.1

  reply	other threads:[~2016-09-28 14:00 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-27 21:20 [RFC PATCH 0/3] kvm: x86: speedups for APICv Paolo Bonzini
2016-09-27 21:20 ` [PATCH 1/3] kvm: x86: avoid atomic operations on APICv vmentry Paolo Bonzini
2016-09-27 21:20 ` [PATCH 2/3] kvm: x86: do not use KVM_REQ_EVENT for APICv interrupt injection Paolo Bonzini
2016-09-27 23:07   ` Michael S. Tsirkin
2016-09-28  8:21     ` Paolo Bonzini
2016-09-28 11:40       ` Wu, Feng
2016-09-28 11:50         ` Paolo Bonzini
2016-09-28 12:06           ` Wu, Feng
2016-09-28 12:14             ` Paolo Bonzini
2016-10-14  7:37           ` Yang Zhang
2016-10-14  8:12             ` Paolo Bonzini
2016-09-28 13:46       ` Michael S. Tsirkin
2016-09-28 14:08         ` Paolo Bonzini
2016-09-28 10:04   ` Wu, Feng
2016-09-28 10:16     ` Paolo Bonzini
2016-09-28 11:53       ` Wu, Feng
2016-09-28 11:55         ` Paolo Bonzini
2016-09-28 12:07           ` Wu, Feng
2016-10-14  7:12   ` Yang Zhang
2016-09-27 21:20 ` [PATCH 3/3] KVM: x86: do not scan IRR twice on APICv vmentry Paolo Bonzini
2016-09-28 14:00   ` Michael S. Tsirkin [this message]
2016-09-28 14:44     ` Paolo Bonzini
2016-09-29  2:51   ` Wu, Feng
2016-10-14  7:32   ` Yang Zhang
2016-10-14  7:45     ` Paolo Bonzini
2016-09-29 19:55 ` [RFC PATCH 0/3] kvm: x86: speedups for APICv Radim Krčmář
2016-09-29 21:41   ` Paolo Bonzini
2016-09-30 13:23     ` Radim Krčmář
2016-09-30 13:33     ` Radim Krčmář

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=20160928165515-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=feng.wu@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=yang.zhang.wz@gmail.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.