From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Gregory Haskins <ghaskins-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: [PATCH 3/4] KVM: Adds ability to preempt an executing VCPU
Date: Mon, 07 May 2007 12:57:08 +0300 [thread overview]
Message-ID: <463EF7F4.9020106@qumranet.com> (raw)
In-Reply-To: <20070502214325.16738.42702.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
Gregory Haskins wrote:
> The VCPU executes synchronously w.r.t. userspace today, and therefore
> interrupt injection is pretty straight forward. However, we will soon need
> to be able to inject interrupts asynchronous to the execution of the VCPU
> due to the introduction of SMP, paravirtualized drivers, and asynchronous
> hypercalls. This patch adds support to the interrupt mechanism to force
> a VCPU to VMEXIT when a new interrupt is pending.
>
> Signed-off-by: Gregory Haskins <ghaskins-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
> ---
>
> drivers/kvm/kvm.h | 5 +++
> drivers/kvm/kvm_main.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++-
> drivers/kvm/svm.c | 43 ++++++++++++++++++++++++++++
> drivers/kvm/vmx.c | 43 ++++++++++++++++++++++++++++
> 4 files changed, 164 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
> index d41d653..15c8bec 100644
> --- a/drivers/kvm/kvm.h
> +++ b/drivers/kvm/kvm.h
> @@ -321,6 +321,8 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
>
> #define NR_IRQ_WORDS KVM_IRQ_BITMAP_SIZE(unsigned long)
>
> +#define KVM_SIGNAL_VIRTUAL_INTERRUPT 33 /* Hardcoded for now */
> +
> /*
> * structure for maintaining info for interrupting an executing VCPU
> */
> @@ -329,6 +331,9 @@ struct kvm_vcpu_irq {
> struct kvm_irqdevice dev;
> int pending;
> int deferred;
> + struct task_struct *task;
> + int signo;
> + int guest_mode;
> };
>
> struct kvm_vcpu {
> diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
> index 9aeb2f7..6acbd9b 100644
> --- a/drivers/kvm/kvm_main.c
> +++ b/drivers/kvm/kvm_main.c
> @@ -304,6 +304,10 @@ static struct kvm *kvm_create_vm(void)
> memset(&vcpu->irq, 0, sizeof(vcpu->irq));
> spin_lock_init(&vcpu->irq.lock);
> vcpu->irq.deferred = -1;
> + /*
> + * This should be settable by userspace someday
> + */
> + vcpu->irq.signo = KVM_SIGNAL_VIRTUAL_INTERRUPT;
>
This needs to be fixed prior to merging. Hopefully not by setting the
signal number, bit by making the vcpu fd writable (userspace can attach
a signal to the fd if it wishes).
>
> vcpu->cpu = -1;
> vcpu->kvm = kvm;
> @@ -366,13 +370,20 @@ static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
>
> static void kvm_free_vcpu(struct kvm_vcpu *vcpu)
> {
> + unsigned long irqsave;
> +
> if (!vcpu->vmcs)
> return;
>
> vcpu_load(vcpu);
> kvm_mmu_destroy(vcpu);
> vcpu_put(vcpu);
> +
> + spin_lock_irqsave(&vcpu->irq.lock, irqsave);
> + vcpu->irq.task = NULL;
> + spin_unlock_irqrestore(&vcpu->irq.lock, irqsave);
>
Can irq.task be non-NULL here at all? Also, we only free vcpus when we
destroy the vm, and paravirt drivers would hopefully hold a ref to the
vm, so there's nobody to race against here.
> kvm_irqdevice_destructor(&vcpu->irq.dev);
>
> @@ -1868,6 +1880,10 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
> kvm_arch_ops->decache_regs(vcpu);
> }
>
> + spin_lock_irqsave(&vcpu->irq.lock, irqsaved);
> + vcpu->irq.task = current;
> + spin_unlock_irqrestore(&vcpu->irq.lock, irqsaved);
> +
>
Just assignment + __smp_wmb().
> +/*
> * This function will be invoked whenever the vcpu->irq.dev raises its INTR
> * line
> */
> @@ -2318,10 +2348,52 @@ static void kvm_vcpu_intr(struct kvm_irqsink *this,
> {
> struct kvm_vcpu *vcpu = (struct kvm_vcpu*)this->private;
> unsigned long flags;
> + int direct_ipi = -1;
>
> spin_lock_irqsave(&vcpu->irq.lock, flags);
> - __set_bit(pin, &vcpu->irq.pending);
> +
> + if (!test_bit(pin, &vcpu->irq.pending)) {
> + /*
> + * Record the change..
> + */
> + __set_bit(pin, &vcpu->irq.pending);
> +
> + /*
> + * then wake up the vcpu (if necessary)
> + */
> + if (vcpu->irq.task && (vcpu->irq.task != current)) {
> + if (vcpu->irq.guest_mode) {
> + /*
> + * If we are in guest mode, we can optimize
> + * the IPI by executing a function directly
> + * on the owning processor.
> + */
> + direct_ipi = task_cpu(vcpu->irq.task);
> + BUG_ON(direct_ipi == smp_processor_id());
> + } else
> + /*
> + * otherwise, we must assume that we could be
> + * blocked anywhere, including userspace. Send
> + * a signal to give everyone a chance to get
> + * notification
> + */
> + send_sig(vcpu->irq.signo, vcpu->irq.task, 0);
> + }
> + }
> +
> spin_unlock_irqrestore(&vcpu->irq.lock, flags);
> +
> + if (direct_ipi != -1) {
> + /*
> + * Not sure if disabling preemption is needed.
> + * The kick_process() code does this so I copied it
> + */
> + preempt_disable();
> + smp_call_function_single(direct_ipi,
> + kvm_vcpu_guest_intr,
> + vcpu, 0, 0);
> + preempt_enable();
> + }
>
I see why you must issue the IPI outside the spin_lock_irqsave(), but
aren't you now opening a race? vcpu enters guest mode, irq on other
cpu, irq sets direct_ipi to wakeup guest, releases lock, vcpu exits to
userspace (or migrates to another cpu), ipi is issued but nobody cares.
> /*
> + * Signal that we have transitioned back to host mode
> + */
> + spin_lock_irqsave(&vcpu->irq.lock, irq_flags);
> + vcpu->irq.guest_mode = 0;
> + spin_unlock_irqrestore(&vcpu->irq.lock, irq_flags);
> +
>
Assign + __smp_wmb().
> + /*
> + * Signal that we have transitioned back to host mode
> + */
> + spin_lock_irqsave(&vcpu->irq.lock, irq_flags);
> + vcpu->irq.guest_mode = 0;
> + spin_unlock_irqrestore(&vcpu->irq.lock, irq_flags);
>
Again.
--
error compiling committee.c: too many arguments to function
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
next prev parent reply other threads:[~2007-05-07 9:57 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-02 21:43 [PATCH 0/4] Kernel side patches for in-kernel APIC Gregory Haskins
[not found] ` <20070502212713.16738.8133.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-02 21:43 ` [PATCH 1/4] KVM: Adds support for in-kernel mmio handlers Gregory Haskins
[not found] ` <20070502214315.16738.68984.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07 9:30 ` Avi Kivity
[not found] ` <463EF198.1050303-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:37 ` Gregory Haskins
2007-05-02 21:43 ` [PATCH 2/4] KVM: Add irqdevice object Gregory Haskins
[not found] ` <20070502214320.16738.21505.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07 9:42 ` Avi Kivity
[not found] ` <463EF493.9070300-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:39 ` Gregory Haskins
2007-05-02 21:43 ` [PATCH 3/4] KVM: Adds ability to preempt an executing VCPU Gregory Haskins
[not found] ` <20070502214325.16738.42702.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07 9:57 ` Avi Kivity [this message]
[not found] ` <463EF7F4.9020106-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:52 ` Gregory Haskins
[not found] ` <463F04D8.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08 8:13 ` Avi Kivity
[not found] ` <46403117.2070000-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-08 11:48 ` Gregory Haskins
[not found] ` <46402B25.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08 11:56 ` Avi Kivity
2007-05-07 15:17 ` Gregory Haskins
[not found] ` <463F0AC7.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08 8:26 ` Avi Kivity
[not found] ` <4640341E.6090905-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-08 12:00 ` Gregory Haskins
2007-05-02 21:43 ` [PATCH 4/4] KVM: Add support for in-kernel LAPIC model Gregory Haskins
[not found] ` <20070502214330.16738.51436.stgit-sLgBBP33vUGnsjUZhwzVf9HuzzzSOjJt@public.gmane.org>
2007-05-07 10:17 ` Avi Kivity
[not found] ` <463EFCC5.8050408-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 10:22 ` Avi Kivity
2007-05-07 15:10 ` Gregory Haskins
[not found] ` <463F0914.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-08 8:19 ` Avi Kivity
[not found] ` <464032A3.2010303-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-08 11:59 ` Gregory Haskins
[not found] ` <46402DC0.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-13 10:21 ` Avi Kivity
2007-05-03 18:57 ` [PATCH 0/4] Kernel side patches for in-kernel APIC Nakajima, Jun
[not found] ` <8FFF7E42E93CC646B632AB40643802A8028B114D-1a9uaKK1+wJcIJlls4ac1rfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-05-03 21:18 ` Gregory Haskins
[not found] ` <463A1935.BA47.005A.0-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
2007-05-06 7:49 ` Avi Kivity
[not found] ` <463D8887.5020007-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-05-07 14:36 ` Gregory Haskins
2007-05-06 7:45 ` Avi Kivity
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=463EF7F4.9020106@qumranet.com \
--to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
--cc=ghaskins-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.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.