From: Marcelo Tosatti <mtosatti@redhat.com>
To: Chris Lalancette <clalance@redhat.com>
Cc: kvm@vger.kernel.org, Gleb Natapov <gleb@redhat.com>,
Zachary Amsden <zamsden@redhat.com>,
"Yang, Sheng" <sheng.yang@intel.com>
Subject: Re: [PATCH 1/3] Introduce a workqueue to deliver PIT timer interrupts.
Date: Fri, 11 Jun 2010 14:35:23 -0300 [thread overview]
Message-ID: <20100611173523.GD6913@amt.cnet> (raw)
In-Reply-To: <1276202647-1598-2-git-send-email-clalance@redhat.com>
On Thu, Jun 10, 2010 at 04:44:05PM -0400, Chris Lalancette wrote:
> We really want to "kvm_set_irq" during the hrtimer callback,
> but that is risky because that is during interrupt context.
> Instead, offload the work to a workqueue, which is a bit safer
> and should provide most of the same functionality.
>
> Signed-off-by: Chris Lalancette <clalance@redhat.com>
> ---
> arch/x86/kvm/i8254.c | 117 ++++++++++++++++++++++++++++----------------------
> arch/x86/kvm/i8254.h | 4 +-
> arch/x86/kvm/irq.c | 1 -
> 3 files changed, 69 insertions(+), 53 deletions(-)
>
> diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
> index 188d827..99c7472 100644
> --- a/arch/x86/kvm/i8254.c
> +++ b/arch/x86/kvm/i8254.c
> @@ -34,6 +34,7 @@
>
> #include <linux/kvm_host.h>
> #include <linux/slab.h>
> +#include <linux/workqueue.h>
>
> #include "irq.h"
> #include "i8254.h"
> @@ -244,11 +245,11 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
> {
> struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
> irq_ack_notifier);
> - raw_spin_lock(&ps->inject_lock);
> + spin_lock(&ps->inject_lock);
> if (atomic_dec_return(&ps->pit_timer.pending) < 0)
> atomic_inc(&ps->pit_timer.pending);
> ps->irq_ack = 1;
> - raw_spin_unlock(&ps->inject_lock);
> + spin_unlock(&ps->inject_lock);
> }
>
> void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
> @@ -281,6 +282,58 @@ static struct kvm_timer_ops kpit_ops = {
> .is_periodic = kpit_is_periodic,
> };
>
> +static void pit_do_work(struct work_struct *work)
> +{
> + struct kvm_pit *pit = container_of(work, struct kvm_pit, expired);
> + struct kvm *kvm = pit->kvm;
> + struct kvm_vcpu *vcpu;
> + int i;
> + struct kvm_kpit_state *ps = &pit->pit_state;
> + int inject = 0;
> +
> + /* Try to inject pending interrupts when
> + * last one has been acked.
> + */
> + spin_lock(&ps->inject_lock);
> + if (ps->irq_ack) {
> + ps->irq_ack = 0;
> + inject = 1;
> + }
> + spin_unlock(&ps->inject_lock);
> + if (inject) {
> + kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
> + kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
> +
> + /*
> + * Provides NMI watchdog support via Virtual Wire mode.
> + * The route is: PIT -> PIC -> LVT0 in NMI mode.
> + *
> + * Note: Our Virtual Wire implementation is simplified, only
> + * propagating PIT interrupts to all VCPUs when they have set
> + * LVT0 to NMI delivery. Other PIC interrupts are just sent to
> + * VCPU0, and only if its LVT0 is in EXTINT mode.
> + */
> + if (kvm->arch.vapics_in_nmi_mode > 0)
> + kvm_for_each_vcpu(i, vcpu, kvm)
> + kvm_apic_nmi_wd_deliver(vcpu);
> + }
> +}
> +
> +static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
> +{
> + struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
> + struct kvm_pit *pt = ktimer->kvm->arch.vpit;
> +
> + queue_work(pt->wq, &pt->expired);
So this disables interrupt reinjection. Older RHEL3 guests do not
compensate for lost ticks, and as such are likely to drift without
it (but RHEL3 is EOL, should one care?).
Are there other guests which rely on PIT reinjection, or is it OK
to remove it completly?
> +
> + if (ktimer->t_ops->is_periodic(ktimer)) {
> + hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
> + return HRTIMER_RESTART;
> + }
> + else
> + return HRTIMER_NORESTART;
> +}
Also need to cancel the pending work whenever the current code cancels
the hrtimer (destroy_pit_timer, etc).
next prev parent reply other threads:[~2010-06-11 17:47 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-10 20:44 [PATCH 0/3]: Fixes to IRQ routing Chris Lalancette
2010-06-10 20:44 ` [PATCH 1/3] Introduce a workqueue to deliver PIT timer interrupts Chris Lalancette
2010-06-11 17:35 ` Marcelo Tosatti [this message]
2010-06-12 4:15 ` Yang, Sheng
2010-06-12 5:18 ` Zachary Amsden
2010-06-10 20:44 ` [PATCH 2/3] Allow any LAPIC to accept PIC interrupts Chris Lalancette
2010-06-10 20:44 ` [PATCH 3/3] In DM_LOWEST, only deliver interrupts to vcpus with enabled LAPIC's Chris Lalancette
2010-06-14 11:21 ` [PATCH 0/3]: Fixes to IRQ routing Gleb Natapov
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=20100611173523.GD6913@amt.cnet \
--to=mtosatti@redhat.com \
--cc=clalance@redhat.com \
--cc=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=sheng.yang@intel.com \
--cc=zamsden@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox