kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marcelo Tosatti <mtosatti@redhat.com>
To: Gleb Natapov <gleb@redhat.com>
Cc: kvm@vger.kernel.org, avi@redhat.com
Subject: Re: [PATCH][RFC] Use return value from kvm_set_irq() to re-inject PIT interrupts.
Date: Mon, 24 Aug 2009 13:32:56 -0300	[thread overview]
Message-ID: <20090824163256.GA8653@amt.cnet> (raw)
In-Reply-To: <20090824120623.GC30093@redhat.com>

On Mon, Aug 24, 2009 at 03:06:23PM +0300, Gleb Natapov wrote:
> Use return value from kvm_set_irq() to track coalesced PIT interrupts
> instead of ack/mask notifiers.

Gleb,

What is the advantage of doing so?

Ack notifiers are asynchronous notifications. Using the return value
from kvm_set_irq implies that timer emulation is based on a "tick
generating device" on the host side.

What I mean is that the ack notifications are useful, since they are
asynchronous.

Supposing your goal is to get rid of ack notifiers, due to their burden 
in irqchip code?

> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
> index b857ca3..0b63991 100644
> --- a/arch/x86/kvm/i8254.c
> +++ b/arch/x86/kvm/i8254.c
> @@ -231,20 +231,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_pit *pit = vcpu->kvm->arch.vpit;
>  
> -	if (pit && kvm_vcpu_is_bsp(vcpu) && pit->pit_state.irq_ack)
> -		return atomic_read(&pit->pit_state.pit_timer.pending);
> -	return 0;
> -}
> -
> -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);
> -	spin_lock(&ps->inject_lock);
> -	if (atomic_dec_return(&ps->pit_timer.pending) < 0)
> -		atomic_inc(&ps->pit_timer.pending);
> -	ps->irq_ack = 1;
> -	spin_unlock(&ps->inject_lock);
> +	return atomic_read(&pit->pit_state.pit_timer.pending);
>  }
>  
>  void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
> @@ -297,7 +284,6 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
>  	pt->vcpu = pt->kvm->bsp_vcpu;
>  
>  	atomic_set(&pt->pending, 0);
> -	ps->irq_ack = 1;
>  
>  	hrtimer_start(&pt->timer, ktime_add_ns(ktime_get(), interval),
>  		      HRTIMER_MODE_ABS);
> @@ -577,17 +563,6 @@ void kvm_pit_reset(struct kvm_pit *pit)
>  	mutex_unlock(&pit->pit_state.lock);
>  
>  	atomic_set(&pit->pit_state.pit_timer.pending, 0);
> -	pit->pit_state.irq_ack = 1;
> -}
> -
> -static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
> -{
> -	struct kvm_pit *pit = container_of(kimn, struct kvm_pit, mask_notifier);
> -
> -	if (!mask) {
> -		atomic_set(&pit->pit_state.pit_timer.pending, 0);
> -		pit->pit_state.irq_ack = 1;
> -	}
>  }
>  
>  static const struct kvm_io_device_ops pit_dev_ops = {
> @@ -619,7 +594,6 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
>  
>  	mutex_init(&pit->pit_state.lock);
>  	mutex_lock(&pit->pit_state.lock);
> -	spin_lock_init(&pit->pit_state.inject_lock);
>  
>  	kvm->arch.vpit = pit;
>  	pit->kvm = kvm;
> @@ -628,17 +602,11 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
>  	pit_state->pit = pit;
>  	hrtimer_init(&pit_state->pit_timer.timer,
>  		     CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
> -	pit_state->irq_ack_notifier.gsi = 0;
> -	pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
> -	kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
>  	pit_state->pit_timer.reinject = true;
>  	mutex_unlock(&pit->pit_state.lock);
>  
>  	kvm_pit_reset(pit);
>  
> -	pit->mask_notifier.func = pit_mask_notifer;
> -	kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
> -
>  	kvm_iodevice_init(&pit->dev, &pit_dev_ops);
>  	ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
>  	if (ret < 0)
> @@ -670,10 +638,6 @@ void kvm_free_pit(struct kvm *kvm)
>  	struct hrtimer *timer;
>  
>  	if (kvm->arch.vpit) {
> -		kvm_unregister_irq_mask_notifier(kvm, 0,
> -					       &kvm->arch.vpit->mask_notifier);
> -		kvm_unregister_irq_ack_notifier(kvm,
> -				&kvm->arch.vpit->pit_state.irq_ack_notifier);
>  		mutex_lock(&kvm->arch.vpit->pit_state.lock);
>  		timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
>  		hrtimer_cancel(timer);
> @@ -683,12 +647,12 @@ void kvm_free_pit(struct kvm *kvm)
>  	}
>  }
>  
> -static void __inject_pit_timer_intr(struct kvm *kvm)
> +static int __inject_pit_timer_intr(struct kvm *kvm)
>  {
>  	struct kvm_vcpu *vcpu;
> -	int i;
> +	int i, r;
>  
> -	kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
> +	r = kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
>  	kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
>  
>  	/*
> @@ -703,6 +667,8 @@ static void __inject_pit_timer_intr(struct kvm *kvm)
>  	if (kvm->arch.vapics_in_nmi_mode > 0)
>  		kvm_for_each_vcpu(i, vcpu, kvm)
>  			kvm_apic_nmi_wd_deliver(vcpu);
> +
> +	return r;
>  }
>  
>  void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
> @@ -711,20 +677,14 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
>  	struct kvm *kvm = vcpu->kvm;
>  	struct kvm_kpit_state *ps;
>  
> -	if (pit) {
> -		int inject = 0;
> -		ps = &pit->pit_state;
> -
> -		/* Try to inject pending interrupts when
> -		 * last one has been acked.
> -		 */
> -		spin_lock(&ps->inject_lock);
> -		if (atomic_read(&ps->pit_timer.pending) && ps->irq_ack) {
> -			ps->irq_ack = 0;
> -			inject = 1;
> -		}
> -		spin_unlock(&ps->inject_lock);
> -		if (inject)
> -			__inject_pit_timer_intr(kvm);
> -	}
> +	if (!pit)
> +		return;
> +
> +	ps = &pit->pit_state;
> +
> +	if (!atomic_read(&ps->pit_timer.pending))
> +		return;
> +
> +	if (__inject_pit_timer_intr(kvm))
> +		atomic_dec(&ps->pit_timer.pending);
>  }
> diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
> index d4c1c7f..19937da 100644
> --- a/arch/x86/kvm/i8254.h
> +++ b/arch/x86/kvm/i8254.h
> @@ -28,8 +28,6 @@ struct kvm_kpit_state {
>  	struct mutex lock;
>  	struct kvm_pit *pit;
>  	spinlock_t inject_lock;
> -	unsigned long irq_ack;
> -	struct kvm_irq_ack_notifier irq_ack_notifier;
>  };
>  
>  struct kvm_pit {
> @@ -39,7 +37,6 @@ struct kvm_pit {
>  	struct kvm *kvm;
>  	struct kvm_kpit_state pit_state;
>  	int irq_source_id;
> -	struct kvm_irq_mask_notifier mask_notifier;
>  };
>  
>  #define KVM_PIT_BASE_ADDRESS	    0x40
> --
> 			Gleb.

  reply	other threads:[~2009-08-24 16:33 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-24 12:06 [PATCH][RFC] Use return value from kvm_set_irq() to re-inject PIT interrupts Gleb Natapov
2009-08-24 16:32 ` Marcelo Tosatti [this message]
2009-08-24 17:16   ` Gleb Natapov
2009-08-24 17:44     ` Marcelo Tosatti
2009-08-24 18:19       ` Gleb Natapov
2009-08-24 19:01         ` Gleb Natapov
2009-08-26 12:45           ` Marcelo Tosatti
2009-08-26 12:43         ` Marcelo Tosatti
2009-08-26 13:19           ` Gleb Natapov
2009-08-26 13:38             ` Marcelo Tosatti
2009-08-26 13:48               ` Avi Kivity
2009-08-26 13:50               ` Gleb Natapov
2009-08-26 13:49             ` Marcelo Tosatti

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=20090824163256.GA8653@amt.cnet \
    --to=mtosatti@redhat.com \
    --cc=avi@redhat.com \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).