All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: avi@redhat.com, gleb@redhat.com, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, jan.kiszka@siemens.com
Subject: Re: [PATCH v5 3/4] kvm: Create kvm_clear_irq()
Date: Tue, 17 Jul 2012 17:08:58 +0300	[thread overview]
Message-ID: <20120717140858.GB10822@redhat.com> (raw)
In-Reply-To: <1342533369.3229.4.camel@ul30vt>

On Tue, Jul 17, 2012 at 07:56:09AM -0600, Alex Williamson wrote:
> On Tue, 2012-07-17 at 13:14 +0300, Michael S. Tsirkin wrote:
> > On Mon, Jul 16, 2012 at 02:34:03PM -0600, Alex Williamson wrote:
> > > This is an alternative to kvm_set_irq(,,,0) which returns the previous
> > > assertion state of the interrupt and does nothing if it isn't changed.
> > > 
> > > Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
> > > ---
> > > 
> > >  include/linux/kvm_host.h |    3 ++
> > >  virt/kvm/irq_comm.c      |   78 ++++++++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 81 insertions(+)
> > > 
> > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > > index a7661c0..6c168f1 100644
> > > --- a/include/linux/kvm_host.h
> > > +++ b/include/linux/kvm_host.h
> > > @@ -219,6 +219,8 @@ struct kvm_kernel_irq_routing_entry {
> > >  	u32 type;
> > >  	int (*set)(struct kvm_kernel_irq_routing_entry *e,
> > >  		   struct kvm *kvm, int irq_source_id, int level);
> > > +	int (*clear)(struct kvm_kernel_irq_routing_entry *e,
> > > +		     struct kvm *kvm, int irq_source_id);
> > >  	union {
> > >  		struct {
> > >  			unsigned irqchip;
> > > @@ -629,6 +631,7 @@ void kvm_get_intr_delivery_bitmask(struct kvm_ioapic *ioapic,
> > >  				   unsigned long *deliver_bitmask);
> > >  #endif
> > >  int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level);
> > > +int kvm_clear_irq(struct kvm *kvm, int irq_source_id, u32 irq);
> > >  int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
> > >  		int irq_source_id, int level);
> > >  void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
> > > diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
> > > index 5afb431..76e8f22 100644
> > > --- a/virt/kvm/irq_comm.c
> > > +++ b/virt/kvm/irq_comm.c
> > > @@ -68,6 +68,42 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
> > >  	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, level);
> > >  }
> > >  
> > > +static inline int kvm_clear_irq_line_state(unsigned long *irq_state,
> > > +					    int irq_source_id)
> > > +{
> > > +	return !!test_and_clear_bit(irq_source_id, irq_state);
> > > +}
> > > +
> > > +static int kvm_clear_pic_irq(struct kvm_kernel_irq_routing_entry *e,
> > > +			     struct kvm *kvm, int irq_source_id)
> > > +{
> > > +#ifdef CONFIG_X86
> > > +	struct kvm_pic *pic = pic_irqchip(kvm);
> > > +	int level = kvm_clear_irq_line_state(&pic->irq_states[e->irqchip.pin],
> > > +					     irq_source_id);
> > > +	if (level)
> > > +		kvm_pic_set_irq(pic, e->irqchip.pin,
> > > +				!!pic->irq_states[e->irqchip.pin]);
> > > +	return level;
> > 
> > I think I begin to understand: if (level) checks it was previously set,
> > and then we clear if needed?
> 
> It's actually very simple, if we change anything in irq_states, then
> update via the chip specific set_irq function.
> 
> >  I think it's worthwhile to rename
> > level to orig_level and rewrite as:
> > 
> > 	if (orig_level && !pic->irq_states[e->irqchip.pin])
> > 		kvm_pic_set_irq(pic, e->irqchip.pin, 0);
> > 
> > This both makes the logic clear without need for comments and
> > saves some cycles on pic in case nothing actually changed.
> 
> That may work, but it's not actually the same thing.  kvm_set_irq(,,,0)
> will clear the bit and call kvm_pic_set_irq with the new irq_states
> value, whether it's 0 or 1.  The optimization I make is to only call
> kvm_pic_set_irq if we've "changed" irq_states.  You're taking that one
> step further to "changed and is now 0".  I don't know if that's correct
> behavior.

If not then I don't understand. You clear a bit
in a word. You never change it to 1, do you?

But this brings another question:

static inline int kvm_irq_line_state(unsigned long *irq_state,
                                     int irq_source_id, int level)
{
        /* Logical OR for level trig interrupt */
        if (level)
                set_bit(irq_source_id, irq_state);
        else
                clear_bit(irq_source_id, irq_state);


^^^^^^^^^^^
above uses locked instructions

        return !!(*irq_state);


above doesn't

}


why the insonsistency?

> > > +#else
> > > +	return -1;
> > > +#endif
> > > +}
> > > +
> > > +static int kvm_clear_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
> > > +				struct kvm *kvm, int irq_source_id)
> > > +{
> > > +	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
> > > +	int level;
> > > +
> > > +	level = kvm_clear_irq_line_state(&ioapic->irq_states[e->irqchip.pin],
> > > +					 irq_source_id);
> > > +	if (level)
> > > +		kvm_ioapic_set_irq(ioapic, e->irqchip.pin,
> > > +				   !!ioapic->irq_states[e->irqchip.pin]);
> > > +	return level;
> > > +}
> > > +
> > >  inline static bool kvm_is_dm_lowest_prio(struct kvm_lapic_irq *irq)
> > >  {
> > >  #ifdef CONFIG_IA64
> > > @@ -190,6 +226,45 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level)
> > >  	return ret;
> > >  }
> > >  
> > > +/*
> > > + * Return value:
> > > + *  < 0   Error
> > > + *  = 0   Interrupt was not set, did nothing
> > > + *  > 0   Interrupt was pending, cleared
> > > + */
> > > +int kvm_clear_irq(struct kvm *kvm, int irq_source_id, u32 irq)
> > > +{
> > > +	struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS];
> > > +	int ret = -EINVAL, i = 0;
> > > +	struct kvm_irq_routing_table *irq_rt;
> > > +	struct hlist_node *n;
> > > +
> > > +	/* Not possible to detect if the guest uses the PIC or the
> > > +	 * IOAPIC.  So clear the bit in both. The guest will ignore
> > > +	 * writes to the unused one.
> > > +	 */
> > > +	rcu_read_lock();
> > > +	irq_rt = rcu_dereference(kvm->irq_routing);
> > > +	if (irq < irq_rt->nr_rt_entries)
> > > +		hlist_for_each_entry(e, n, &irq_rt->map[irq], link)
> > > +			irq_set[i++] = *e;
> > > +	rcu_read_unlock();
> > > +
> > > +	while (i--) {
> > > +		int r = -EINVAL;
> > > +
> > > +		if (irq_set[i].clear)
> > > +			r = irq_set[i].clear(&irq_set[i], kvm, irq_source_id);
> > > +
> > > +		if (r < 0)
> > > +			continue;
> > > +
> > > +		ret = r + ((ret < 0) ? 0 : ret);
> > > +	}
> > > +
> > > +	return ret;
> > > +}
> > > +
> > >  void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
> > >  {
> > >  	struct kvm_irq_ack_notifier *kian;
> > > @@ -344,16 +419,19 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
> > >  		switch (ue->u.irqchip.irqchip) {
> > >  		case KVM_IRQCHIP_PIC_MASTER:
> > >  			e->set = kvm_set_pic_irq;
> > > +			e->clear = kvm_clear_pic_irq;
> > >  			max_pin = 16;
> > >  			break;
> > >  		case KVM_IRQCHIP_PIC_SLAVE:
> > >  			e->set = kvm_set_pic_irq;
> > > +			e->clear = kvm_clear_pic_irq;
> > >  			max_pin = 16;
> > >  			delta = 8;
> > >  			break;
> > >  		case KVM_IRQCHIP_IOAPIC:
> > >  			max_pin = KVM_IOAPIC_NUM_PINS;
> > >  			e->set = kvm_set_ioapic_irq;
> > > +			e->clear = kvm_clear_ioapic_irq;
> > >  			break;
> > >  		default:
> > >  			goto out;
> 
> 

  reply	other threads:[~2012-07-17 14:08 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-16 20:33 [PATCH v5 0/4] kvm: level irqfd and new eoifd Alex Williamson
2012-07-16 20:33 ` [PATCH v5 1/4] kvm: Extend irqfd to support level interrupts Alex Williamson
2012-07-17 21:26   ` Michael S. Tsirkin
2012-07-17 21:57     ` Alex Williamson
2012-07-17 22:00       ` Michael S. Tsirkin
2012-07-17 22:16         ` Alex Williamson
2012-07-17 22:28           ` Michael S. Tsirkin
2012-07-18 10:41   ` Michael S. Tsirkin
2012-07-18 10:44     ` Gleb Natapov
2012-07-18 10:48       ` Michael S. Tsirkin
2012-07-18 10:49         ` Gleb Natapov
2012-07-18 10:53           ` Michael S. Tsirkin
2012-07-18 10:55             ` Gleb Natapov
2012-07-18 11:22               ` Michael S. Tsirkin
2012-07-18 11:39                 ` Michael S. Tsirkin
2012-07-18 11:48                   ` Gleb Natapov
2012-07-18 12:07                     ` Michael S. Tsirkin
2012-07-18 14:47                       ` Alex Williamson
2012-07-18 15:38                         ` Michael S. Tsirkin
2012-07-18 15:48                           ` Alex Williamson
2012-07-18 15:58                             ` Michael S. Tsirkin
2012-07-18 18:42                               ` Marcelo Tosatti
2012-07-18 19:00                                 ` Gleb Natapov
2012-07-18 19:07                                 ` Alex Williamson
2012-07-18 19:13                                   ` Alex Williamson
2012-07-18 19:16                                     ` Michael S. Tsirkin
2012-07-18 20:28                                     ` Alex Williamson
2012-07-18 21:23                                       ` Marcelo Tosatti
2012-07-18 21:30                                         ` Michael S. Tsirkin
2012-07-16 20:33 ` [PATCH v5 2/4] kvm: KVM_EOIFD, an eventfd for EOIs Alex Williamson
2012-07-17 10:21   ` Michael S. Tsirkin
2012-07-17 13:59     ` Alex Williamson
2012-07-17 14:10       ` Michael S. Tsirkin
2012-07-17 14:29         ` Alex Williamson
2012-07-17 14:42           ` Michael S. Tsirkin
2012-07-17 14:57             ` Alex Williamson
2012-07-17 15:13               ` Michael S. Tsirkin
2012-07-17 15:41                 ` Alex Williamson
2012-07-17 15:53                   ` Michael S. Tsirkin
2012-07-17 16:06                     ` Alex Williamson
2012-07-17 16:19                       ` Michael S. Tsirkin
2012-07-17 16:52                         ` Alex Williamson
2012-07-17 18:58                           ` Michael S. Tsirkin
2012-07-17 20:03                             ` Alex Williamson
2012-07-17 21:23                               ` Michael S. Tsirkin
2012-07-17 22:09                                 ` Alex Williamson
2012-07-17 22:24                                   ` Michael S. Tsirkin
2012-07-18  2:44                                     ` Alex Williamson
2012-07-18 10:31                                       ` Michael S. Tsirkin
2012-07-16 20:34 ` [PATCH v5 3/4] kvm: Create kvm_clear_irq() Alex Williamson
2012-07-17  0:51   ` Michael S. Tsirkin
2012-07-17  2:42     ` Alex Williamson
2012-07-17  0:55   ` Michael S. Tsirkin
2012-07-17 10:14   ` Michael S. Tsirkin
2012-07-17 13:56     ` Alex Williamson
2012-07-17 14:08       ` Michael S. Tsirkin [this message]
2012-07-17 14:21         ` Alex Williamson
2012-07-17 14:53           ` Michael S. Tsirkin
2012-07-17 15:20             ` Alex Williamson
2012-07-17 15:36               ` Michael S. Tsirkin
2012-07-17 15:51                 ` Alex Williamson
2012-07-17 15:57                   ` Michael S. Tsirkin
2012-07-17 16:01                     ` Gleb Natapov
2012-07-17 16:08                     ` Alex Williamson
2012-07-17 16:14                       ` Michael S. Tsirkin
2012-07-17 16:17                         ` Alex Williamson
2012-07-17 16:21                           ` Michael S. Tsirkin
2012-07-17 16:45                             ` Alex Williamson
2012-07-17 18:55                               ` Michael S. Tsirkin
2012-07-17 19:51                                 ` Alex Williamson
2012-07-17 21:05                                   ` Michael S. Tsirkin
2012-07-17 22:01                                     ` Alex Williamson
2012-07-17 22:05                                       ` Michael S. Tsirkin
2012-07-17 22:22                                         ` Alex Williamson
2012-07-17 22:31                                           ` Michael S. Tsirkin
2012-07-18  6:27                         ` Gleb Natapov
2012-07-18 10:20                           ` Michael S. Tsirkin
2012-07-18 10:27                             ` Gleb Natapov
2012-07-18 10:33                               ` Michael S. Tsirkin
2012-07-18 10:36                                 ` Gleb Natapov
2012-07-18 10:51                                   ` Michael S. Tsirkin
2012-07-18 10:53                                     ` Gleb Natapov
2012-07-18 11:08                                       ` Michael S. Tsirkin
2012-07-18 11:50                                         ` Gleb Natapov
2012-07-18 21:55                           ` Michael S. Tsirkin
2012-07-17 16:36                       ` Michael S. Tsirkin
2012-07-17 17:09                         ` Gleb Natapov
2012-07-17 10:18   ` Michael S. Tsirkin
2012-07-16 20:34 ` [PATCH v5 4/4] kvm: Convert eoifd to use kvm_clear_irq Alex Williamson
2012-07-18 10:43 ` [PATCH v5 0/4] kvm: level irqfd and new eoifd Michael S. Tsirkin
2012-07-19 16:59 ` Michael S. Tsirkin
2012-07-19 17:29   ` Alex Williamson
2012-07-19 17:45     ` Michael S. Tsirkin
2012-07-19 18:48       ` Alex Williamson
2012-07-20 10:07         ` Michael S. Tsirkin
2012-07-22 15:09           ` 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=20120717140858.GB10822@redhat.com \
    --to=mst@redhat.com \
    --cc=alex.williamson@redhat.com \
    --cc=avi@redhat.com \
    --cc=gleb@redhat.com \
    --cc=jan.kiszka@siemens.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@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 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.