All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Feng Wu <feng.wu@intel.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>,
	Kevin Tian <kevin.tian@intel.com>, Keir Fraser <keir@xen.org>,
	Jan Beulich <jbeulich@suse.com>,
	xen-devel@lists.xen.org
Subject: Re: [PATCH v5 13/17] vmx: posted-interrupt handling when vCPU is blocked
Date: Wed, 12 Aug 2015 12:59:36 -0400	[thread overview]
Message-ID: <20150812165936.GI17650@l.oracle.com> (raw)
In-Reply-To: <1439346938-31824-14-git-send-email-feng.wu@intel.com>

On Wed, Aug 12, 2015 at 10:35:34AM +0800, Feng Wu wrote:
> This patch includes the following aspects:
> - Add a global vector to wake up the blocked vCPU
>   when an interrupt is being posted to it (This
>   part was sugguested by Yang Zhang <yang.z.zhang@intel.com>).
> - Adds a new per-vCPU tasklet to wakeup the blocked
>   vCPU. It can be used in the case vcpu_unblock
>   cannot be called directly.
> - Define two per-cpu variables:
>       * pi_blocked_vcpu:
>       A list storing the vCPUs which were blocked on this pCPU.
> 
>       * pi_blocked_vcpu_lock:
>       The spinlock to protect pi_blocked_vcpu.
> 
> CC: Kevin Tian <kevin.tian@intel.com>
> CC: Keir Fraser <keir@xen.org>
> CC: Jan Beulich <jbeulich@suse.com>
> CC: Andrew Cooper <andrew.cooper3@citrix.com>
> Signed-off-by: Feng Wu <feng.wu@intel.com>
> ---
> v4:
> - Use local variables in pi_wakeup_interrupt()
> - Remove vcpu from the blocked list when pi_desc.on==1, this
> - avoid kick vcpu multiple times.
> - Remove tasklet
> 
> v3:
> - This patch is generated by merging the following three patches in v2:
>    [RFC v2 09/15] Add a new per-vCPU tasklet to wakeup the blocked vCPU
>    [RFC v2 10/15] vmx: Define two per-cpu variables
>    [RFC v2 11/15] vmx: Add a global wake-up vector for VT-d Posted-Interrupts
> - rename 'vcpu_wakeup_tasklet' to 'pi_vcpu_wakeup_tasklet'
> - Move the definition of 'pi_vcpu_wakeup_tasklet' to 'struct arch_vmx_struct'
> - rename 'vcpu_wakeup_tasklet_handler' to 'pi_vcpu_wakeup_tasklet_handler'
> - Make pi_wakeup_interrupt() static
> - Rename 'blocked_vcpu_list' to 'pi_blocked_vcpu_list'
> - move 'pi_blocked_vcpu_list' to 'struct arch_vmx_struct'
> - Rename 'blocked_vcpu' to 'pi_blocked_vcpu'
> - Rename 'blocked_vcpu_lock' to 'pi_blocked_vcpu_lock'
> 
>  xen/arch/x86/hvm/vmx/vmcs.c        |  3 ++
>  xen/arch/x86/hvm/vmx/vmx.c         | 63 ++++++++++++++++++++++++++++++++++++++
>  xen/include/asm-x86/hvm/vmx/vmcs.h |  3 ++
>  xen/include/asm-x86/hvm/vmx/vmx.h  |  5 +++
>  4 files changed, 74 insertions(+)
> 
> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
> index 28c553f..2dabf16 100644
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -661,6 +661,9 @@ int vmx_cpu_up(void)
>      if ( cpu_has_vmx_vpid )
>          vpid_sync_all();
>  
> +    INIT_LIST_HEAD(&per_cpu(pi_blocked_vcpu, cpu));
> +    spin_lock_init(&per_cpu(pi_blocked_vcpu_lock, cpu));
> +
>      return 0;
>  }
>  
> diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
> index d2a4cfb..e80d888 100644
> --- a/xen/arch/x86/hvm/vmx/vmx.c
> +++ b/xen/arch/x86/hvm/vmx/vmx.c
> @@ -83,7 +83,15 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content);
>  static void vmx_invlpg_intercept(unsigned long vaddr);
>  static int vmx_vmfunc_intercept(struct cpu_user_regs *regs);
>  
> +/*
> + * We maintian a per-CPU linked-list of vCPU, so in PI wakeup handler we

s/maintian/maintain/

> + * can find which vCPU should be waken up.

s/waken/woken/
> + */
> +DEFINE_PER_CPU(struct list_head, pi_blocked_vcpu);
> +DEFINE_PER_CPU(spinlock_t, pi_blocked_vcpu_lock);
> +
>  uint8_t __read_mostly posted_intr_vector;
> +uint8_t __read_mostly pi_wakeup_vector;
>  
>  static int vmx_domain_initialise(struct domain *d)
>  {
> @@ -106,6 +114,9 @@ static int vmx_vcpu_initialise(struct vcpu *v)
>  
>      spin_lock_init(&v->arch.hvm_vmx.vmcs_lock);
>  
> +    INIT_LIST_HEAD(&v->arch.hvm_vmx.pi_blocked_vcpu_list);
> +    INIT_LIST_HEAD(&v->arch.hvm_vmx.pi_vcpu_on_set_list);
> +
>      v->arch.schedule_tail    = vmx_do_resume;
>      v->arch.ctxt_switch_from = vmx_ctxt_switch_from;
>      v->arch.ctxt_switch_to   = vmx_ctxt_switch_to;
> @@ -1975,6 +1986,53 @@ static struct hvm_function_table __initdata vmx_function_table = {
>      .altp2m_vcpu_emulate_vmfunc = vmx_vcpu_emulate_vmfunc,
>  };
>  
> +/*
> + * Handle VT-d posted-interrupt when VCPU is blocked.
> + */
> +static void pi_wakeup_interrupt(struct cpu_user_regs *regs)
> +{
> +    struct arch_vmx_struct *vmx, *tmp;
> +    struct vcpu *v;
> +    spinlock_t *lock = &this_cpu(pi_blocked_vcpu_lock);
> +    struct list_head *blocked_vcpus = &this_cpu(pi_blocked_vcpu);
> +    LIST_HEAD(list);
> +
> +    spin_lock(lock);
> +
> +    /*
> +     * XXX: The length of the list depends on how many vCPU is current
> +     * blocked on this specific pCPU. This may hurt the interrupt latency
> +     * if the list grows to too many entries.
> +     */
> +    list_for_each_entry_safe(vmx, tmp, blocked_vcpus, pi_blocked_vcpu_list)
> +    {
> +        if ( pi_test_on(&vmx->pi_desc) )
> +        {
> +            list_del_init(&vmx->pi_blocked_vcpu_list);
> +
> +            /*
> +             * We cannot call vcpu_unblock here, since it also needs
> +             * 'pi_blocked_vcpu_lock', we store the vCPUs with ON
> +             * set in another list and unblock them after we release
> +             * 'pi_blocked_vcpu_lock'.
> +             */
> +            list_add_tail(&vmx->pi_vcpu_on_set_list, &list);
> +        }
> +    }
> +
> +    spin_unlock(lock);
> +
> +    list_for_each_entry_safe(vmx, tmp, &list, pi_vcpu_on_set_list)
> +    {
> +        v = container_of(vmx, struct vcpu, arch.hvm_vmx);
> +        list_del_init(&vmx->pi_vcpu_on_set_list);
> +        vcpu_unblock(v);
> +    }
> +
> +    ack_APIC_irq();

Could this be moved to be right after the spin_unlock?

> +    this_cpu(irq_count)++;
> +}
> +
>  const struct hvm_function_table * __init start_vmx(void)
>  {
>      set_in_cr4(X86_CR4_VMXE);
> @@ -2012,7 +2070,12 @@ const struct hvm_function_table * __init start_vmx(void)
>      }
>  
>      if ( cpu_has_vmx_posted_intr_processing )
> +    {
>          alloc_direct_apic_vector(&posted_intr_vector, event_check_interrupt);
> +
> +        if ( iommu_intpost )
> +            alloc_direct_apic_vector(&pi_wakeup_vector, pi_wakeup_interrupt);
> +    }
>      else
>      {
>          vmx_function_table.deliver_posted_intr = NULL;
> diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
> index 7e81752..9a986d0 100644
> --- a/xen/include/asm-x86/hvm/vmx/vmcs.h
> +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
> @@ -161,6 +161,9 @@ struct arch_vmx_struct {
>      struct page_info     *vmwrite_bitmap;
>  
>      struct page_info     *pml_pg;
> +
> +    struct list_head     pi_blocked_vcpu_list;
> +    struct list_head     pi_vcpu_on_set_list;
>  };
>  
>  int vmx_create_vmcs(struct vcpu *v);
> diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
> index 03c529c..3fd66ba 100644
> --- a/xen/include/asm-x86/hvm/vmx/vmx.h
> +++ b/xen/include/asm-x86/hvm/vmx/vmx.h
> @@ -28,6 +28,11 @@
>  #include <asm/hvm/trace.h>
>  #include <asm/hvm/vmx/vmcs.h>
>  
> +DECLARE_PER_CPU(struct list_head, pi_blocked_vcpu);
> +DECLARE_PER_CPU(spinlock_t, pi_blocked_vcpu_lock);
> +
> +extern uint8_t pi_wakeup_vector;
> +
>  typedef union {
>      struct {
>          u64 r       :   1,  /* bit 0 - Read permission */
> -- 
> 2.1.0
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

  reply	other threads:[~2015-08-12 16:59 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-12  2:35 [PATCH v5 00/17] Add VT-d Posted-Interrupts support Feng Wu
2015-08-12  2:35 ` [PATCH v5 01/17] VT-d Posted-intterrupt (PI) design Feng Wu
2015-08-12 15:35   ` Konrad Rzeszutek Wilk
2015-08-12 17:27     ` Andrew Cooper
2015-08-12 17:46       ` Konrad Rzeszutek Wilk
2015-08-13  1:37     ` Wu, Feng
2015-08-13  8:29       ` Jan Beulich
2015-08-12  2:35 ` [PATCH v5 02/17] Add cmpxchg16b support for x86-64 Feng Wu
2015-08-12 15:38   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 03/17] iommu: Add iommu_intpost to control VT-d Posted-Interrupts feature Feng Wu
2015-08-12 15:39   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 04/17] vt-d: VT-d Posted-Interrupts feature detection Feng Wu
2015-08-12 15:40   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 05/17] vmx: Extend struct pi_desc to support VT-d Posted-Interrupts Feng Wu
2015-08-12 15:45   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 06/17] vmx: Add some helper functions for Posted-Interrupts Feng Wu
2015-08-12 15:46   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 07/17] vmx: Initialize VT-d Posted-Interrupts Descriptor Feng Wu
2015-08-12 17:03   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 08/17] vmx: Suppress posting interrupts when 'SN' is set Feng Wu
2015-08-12 17:03   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 09/17] VT-d: Remove pointless casts Feng Wu
2015-08-12 17:03   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 10/17] vt-d: Extend struct iremap_entry to support VT-d Posted-Interrupts Feng Wu
2015-08-12  2:35 ` [PATCH v5 11/17] vt-d: Add API to update IRTE when VT-d PI is used Feng Wu
2015-08-12 16:23   ` Konrad Rzeszutek Wilk
2015-08-13  8:33     ` Jan Beulich
2015-08-13 18:27       ` Konrad Rzeszutek Wilk
2015-08-12 17:41   ` Andrew Cooper
2015-08-13  1:41     ` Wu, Feng
2015-08-12  2:35 ` [PATCH v5 12/17] Update IRTE according to guest interrupt config changes Feng Wu
2015-08-12 16:43   ` Konrad Rzeszutek Wilk
2015-08-13  1:37     ` Wu, Feng
2015-08-13  8:36       ` Jan Beulich
2015-08-12  2:35 ` [PATCH v5 13/17] vmx: posted-interrupt handling when vCPU is blocked Feng Wu
2015-08-12 16:59   ` Konrad Rzeszutek Wilk [this message]
2015-08-12  2:35 ` [PATCH v5 14/17] vmx: Properly handle notification event when vCPU is running Feng Wu
2015-08-12 17:02   ` Konrad Rzeszutek Wilk
2015-08-13  1:37     ` Wu, Feng
2015-08-12  2:35 ` [PATCH v5 15/17] vmx: Add some scheduler hooks for VT-d posted interrupts Feng Wu
2015-08-12 17:13   ` Konrad Rzeszutek Wilk
2015-08-13  9:06     ` Dario Faggioli
2015-08-13  9:15       ` Wu, Feng
2015-08-12  2:35 ` [PATCH v5 16/17] VT-d: Dump the posted format IRTE Feng Wu
2015-08-12 17:14   ` Konrad Rzeszutek Wilk
2015-08-12  2:35 ` [PATCH v5 17/17] Add a command line parameter for VT-d posted-interrupts Feng Wu
2015-08-12 17:16   ` Konrad Rzeszutek Wilk

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=20150812165936.GI17650@l.oracle.com \
    --to=konrad.wilk@oracle.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=feng.wu@intel.com \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=kevin.tian@intel.com \
    --cc=xen-devel@lists.xen.org \
    /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.